chore:邀请码初步更改

This commit is contained in:
2026-08-03 14:19:21 +08:00
parent e01ba29604
commit cd91ff9d49
5 changed files with 386 additions and 14 deletions

View File

@@ -19,6 +19,12 @@
:formConfig="mergedFormConfig"
ref="nsNewform"
></ns-newform>
<!-- ✅ 邀请码归属提示(零感知:只有通过邀请链接进入才显示,纯灰色小字居中,防纠纷核对) -->
<view v-if="_inviteCodePending" class="form-invite-attribution">
<text class="attribution-text">本次提交推荐邀请码:{{ _inviteCodePending }}</text>
</view>
<!-- 提交按钮(外层 = form-bg + form-padding-x;按钮 = submit-bg + submit-color + input-height + input-radius)。
showSubmit=false 时由父级页面渲染自己的提交按钮并通过 ref 调用本组件的 verify()/getFormData()。 -->
<view v-if="showSubmit" class="form-submit-wrap" :style="submitWrapStyle">
@@ -57,11 +63,15 @@ export default {
mixins: [DiyMinx],
data() {
return {
formComponents: [] // 转换后的表单组件
formComponents: [], // 转换后的表单组件
// ✅ 表单提交邀请码(来源追踪):3 级读取 → 提交自动注入 → 成功清暂存
_inviteCodePending: ''
};
},
created() {
this.initForm();
// ✅ 初始化:从 URL query / storage / H5 location 读取邀请码暂存
this._initInviteCode();
},
watch: {
'value': {
@@ -296,22 +306,48 @@ export default {
// 若父级监听了 @submit,则把提交控制权交给父级(用于父级有自定义提交字段/反馈逻辑的页面,如 formdata.vue 传 uniacid)
if (this.$listeners && this.$listeners.submit) {
this.$emit('submit', this.getFormData());
// ✅ 父级自定义流程:把 recommend_code + invite_code 都透传给父级,双保险(formData 数组里 + 第二参数对象里)
var formDataArr = this.getFormData();
try {
if (this._inviteCodePending && Array.isArray(formDataArr)) {
formDataArr = formDataArr.slice();
formDataArr.push({
controller: 'hidden',
name: '_recommend_code',
value: this._inviteCodePending,
val: this._inviteCodePending
});
formDataArr.push({
controller: 'hidden',
name: '_invite_code',
value: this._inviteCodePending,
val: this._inviteCodePending
});
}
} catch (e) {}
this.$emit('submit', formDataArr, {
recommend_code: this._inviteCodePending,
invite_code: this._inviteCodePending
});
return;
}
// 获得保单数据
const submitFormData = this.getFormData();
var reqData = {
form_id: this.value.form_id || 0,
form_data: typeof submitFormData === 'string' ? submitFormData : JSON.stringify(submitFormData),
component_id: this.value.id || '',
form_name: this.value.form_name || '默认表单'
};
if (this._inviteCodePending) {
reqData.recommend_code = this._inviteCodePending; // 方案 B 标准
reqData.invite_code = this._inviteCodePending; // 历史兼容
}
// 提交到后端
this.$api.sendRequest({
url: '/form/api/form/create',
data: {
form_id: this.value.form_id || 0,
form_data: typeof submitFormData === 'string' ? submitFormData : JSON.stringify(submitFormData),
component_id: this.value.id || '',
form_name: this.value.form_name || '默认表单'
},
data: reqData,
success: function(res) {
if (res.code === 0) {
uni.showToast({
@@ -322,6 +358,8 @@ export default {
if (self.$refs.nsNewform && self.$refs.nsNewform.setFormData) {
self.$refs.nsNewform.setFormData();
}
// ✅ 提交成功后清暂存邀请码(防止后续重复提交归属错人)
self._clearInviteCode();
} else {
uni.showToast({
title: res.message || self.$lang('submitFail'),
@@ -330,6 +368,61 @@ export default {
}
}
});
},
/* ============================================================
✅ 邀请码(来源追踪)辅助方法
链路:分享链接 ?invite=XXX → 进入本页 3 级取码 → 暂存 data + storage
→ 提交时自动拼入 request → 成功清暂存
============================================================ */
FORM_INVITE_STORAGE_KEY: 'form_invite_pending_code',
_initInviteCode() {
var key = this.FORM_INVITE_STORAGE_KEY;
var code = '';
// P1:当前页面的 onLoad options(通过 getCurrentPages 顶页的 options 拿到)
try {
var pages = (typeof getCurrentPages === 'function') ? getCurrentPages() : [];
if (pages && pages.length) {
var top = pages[pages.length - 1];
if (top && top.options) {
if (top.options.recommend_code) {
code = String(top.options.recommend_code);
} else if (top.options.invite) {
code = String(top.options.invite);
}
}
}
} catch (e) {}
// P2:storage(App.vue onLaunch/onShow 提前写入,全局兜底)
if (!code) {
try { code = uni.getStorageSync(key) || ''; } catch (e) { code = ''; }
}
// P3:H5 冷启动从 location.search 兜底(同样优先 recommend_code)
if (!code) {
// #ifdef H5
try {
var sp = (new URL(window.location.href)).searchParams;
var s1 = sp.get('recommend_code');
var s2 = sp.get('invite');
if (s1) code = String(s1);
else if (s2) code = String(s2);
} catch (e) {}
// #endif
}
// 写回 data + storage 持久化(跨页面跳转也不丢)
if (code) {
this._inviteCodePending = code;
try { uni.setStorageSync(key, code); } catch (e) {}
}
},
// 清邀请码(提交成功后调用,避免串号)
_clearInviteCode() {
this._inviteCodePending = '';
try { uni.removeStorageSync(this.FORM_INVITE_STORAGE_KEY); } catch (e) {}
}
}
};
@@ -341,6 +434,20 @@ export default {
padding: 0;
border-radius: 10rpx;
/* ✅ 邀请码归属提示:灰色小字,零感知(只有通过邀请链接才显示) */
.form-invite-attribution {
width: 100%;
text-align: center;
box-sizing: border-box;
padding: 20rpx 30rpx 10rpx;
.attribution-text {
font-size: 22rpx;
color: #bbbbbb;
line-height: 1.5;
letter-spacing: 0.5rpx;
}
}
.form-banner {
width: 100%;
overflow: hidden;