Compare commits

...

30 Commits

Author SHA1 Message Date
5f60504c75 chore: 2026-08-07 11:11:38 +08:00
289e582ba1 refactor(form): 调整代码缩进与格式,优化提交逻辑
统一模板缩进为制表符,移除冗余日志,将提交数据内联至请求参数以精简代码结构
2026-08-07 10:35:26 +08:00
c26280a4d3 refactor(form): 重构提交逻辑以支持跨端统一接管
diy-form 组件将提交事件机制改为函数 prop (onSubmit) 接管,避免 $listeners 在 MP 端不可用的问题。
formdata 页面使用 bind 预绑定 this,防止子组件调用时上下文漂移。
新增防重复提交标记复位逻辑,优化网络失败时的重试体验。
2026-08-07 10:31:57 +08:00
619ca3a236 chore:微信小程序可以分享给好友表单 2026-08-06 16:52:41 +08:00
c35d0e2505 chore:微信小程序分享给好友和微信分享功能一样 2026-08-06 16:31:59 +08:00
a6e9176dbf chore:推荐码4 种样式 2026-08-06 15:03:29 +08:00
f4517be6c3 chore :推荐码样式123 2026-08-06 14:03:24 +08:00
408c40fbe9 chore:修改同意并获取推荐码页面 2026-08-06 09:57:56 +08:00
b46dc248d5 chore:去登录按钮和上面登录注册一样跳转 2026-08-06 09:39:22 +08:00
1fb2b470da chore:同意按钮改颜色 2026-08-06 09:07:57 +08:00
81ff205d2c chore:我的页面登录后显示同意获取推荐码 2026-08-06 08:56:50 +08:00
1b3dd41a4b chore:样式4正常 2026-08-05 17:17:45 +08:00
670d3f99fc Merge branch 'dev/1.0' of http://git.aigc-quickapp.com/Uniapp/lucky_shop into Branch_24cb3a09
# Conflicts:
#	.local.config.js
2026-08-05 15:50:36 +08:00
eb2839eeb8 chore:微信小程序分享链接 2026-08-05 15:48:05 +08:00
b0f7c7a15c chore:样式134推荐码居中 2026-08-05 15:02:50 +08:00
f1487e60bb chore: 2026-08-05 14:23:29 +08:00
74c24d084e chore:推荐码样式2立即分享按钮和推荐码对齐 2026-08-05 14:15:27 +08:00
5e8a1a48dd chore:删除棕色小圆点 2026-08-05 14:05:58 +08:00
66deecdcf8 chore:推荐码4可以正常显示 2026-08-05 11:48:34 +08:00
37d72381c7 chore:推荐码2的立即分享按钮正常 2026-08-05 11:09:20 +08:00
9d187bb8a4 chore:分支9 切换的新分支,把4个推荐码样式改了,但不完全可以 2026-08-05 09:57:09 +08:00
24cb3a096d chore:正常运行 2026-08-04 14:20:37 +08:00
1610f3f75d chore:可以复制链接自动更新 2026-08-04 11:18:10 +08:00
837bfbfd77 chore:链接可以复制 2026-08-04 10:21:37 +08:00
e24a6b25f2 chore:邀请码可以显示 2026-08-03 17:36:50 +08:00
318ed4028e chore 2026-08-03 16:29:01 +08:00
1cda06573e refactor: 移除旧的邀请码来源追踪逻辑
1. 删除App.vue中全局邀请码持久化逻辑与相关工具函数
2. 简化http请求的方法与请求头处理逻辑
3. 移除diy-form组件内的邀请码暂存、提交与展示逻辑
4. 清理不再使用的工具类邀请码辅助函数
2026-08-03 16:24:18 +08:00
be1e175471 chore: 2026-08-03 15:34:43 +08:00
0598f97efe chore:修改了会员中心页面弹出【网络异常,请稍后重试】,无法获取推荐码。 2026-08-03 14:55:36 +08:00
cd91ff9d49 chore:邀请码初步更改 2026-08-03 14:19:21 +08:00
10 changed files with 1676 additions and 52 deletions

View File

@@ -55,13 +55,15 @@ const localDevConfig = ({
domain: 'http://localhost:8050/',
},
'local-1': { // 测试平台
uniacid: 1,
domain: 'http://localhost:8050/',
},
'192.168.197.1-1': { // 测试平台
uniacid: 1,
domain: 'http://192.168.197.1:8050/',
},
// domain: 'http://localhost:8050/',
},
'192.168.8.118-1': { // 测试平台
uniacid: 1,
domain: 'http://192.168.8.118:8050/',
// domain: 'http://localhost:8050/',
},
'local-11': { // 测试平台
uniacid: 11,
domain: 'http://localhost:8050/',
@@ -167,10 +169,9 @@ const localDevConfig = ({
// })['2724']; // 生物菌肥
// })['2811']; // 选择要使用的环境配置
// })['local-11']; // 选择要使用的环境配置
// })['248']; // 本地
})['192.168.8.118-1']; // 本地
// })['local-2']; // 本地
// })['local-11']; // 本地
})['local-1']; // 本地
// })['1-test']; // test
// })['test-12']; // test
export default localDevConfig;

View File

@@ -22,13 +22,18 @@
<!-- 提交按钮(外层 = 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">
<view @click.stop="submitForm" class="form-submit" :style="submitStyle">{{ submitText }}</view>
<view @click.stop="handleSubmit" class="form-submit" :style="submitStyle">{{ submitText }}</view>
</view>
</view>
</template>
<script>
// 自定义表单
// 提交接管三档(不依赖 $listeners / 事件机制,跨 H5 / MP / 鸿蒙一致):
// 1) 默认 → showSubmit=true + 不传 onSubmit → 内置按钮 + 内置 defaultSubmit
// 2) 复用按钮、自定义逻辑 → showSubmit=true + :onSubmit="fn" → 内置按钮 + 父级 fn
// 3) 完全自定义 UI → showSubmit=false + :onSubmit="fn" 或 ref.verify()/getFormData() → 父级全控
// 注:type: Function prop 在 uni-app MP 端走 Vue runtime 注入,机制与 ns-navbar.customBack 一致
import DiyMinx from './minx.js'
import NsNewform from '@/components/ns-newform/ns-newform.vue'
@@ -52,6 +57,12 @@ export default {
showSubmit: {
type: Boolean,
default: true
},
// 父级可选地接管提交:传入函数 prop 时,verify 通过后由它处理 formData;
// 不传时走组件内置 defaultSubmit(兜底)。default 必须是 null,不能写成函数返回 null
onSubmit: {
type: Function,
default: null
}
},
mixins: [DiyMinx],
@@ -148,6 +159,10 @@ export default {
submitText() {
return this.mergedFormConfig.submitText || '提交';
},
// 父级是否接管提交(集中判断,便于以后替换机制;避免多个调用点各自 typeof 校验)
hasCustomSubmit() {
return typeof this.onSubmit === 'function';
},
// 后端把表单样式配置统一存放在 data.formConfig 子对象中(与后端 design.js getDefaultFormData().formConfig 字段名一致)。
// 这里做一次归一化:优先取 formConfig;如果历史数据是扁平结构(直接挂在 value 上),也做兼容。
formCfg() {
@@ -286,24 +301,26 @@ export default {
return true;
},
// 提交表单
submitForm() {
var self = this;
// 统一提交入口:内置按钮 / 父级 ref 调用都走这里
// 不依赖 $listeners / 事件机制(MP 端 $listeners 为 undefined),跨端一致
handleSubmit() {
// 校验(同时返回 formData 数组;校验失败时 ns-newform 内部 toast 提示)
if (!this.verify()) {
return;
}
// 若父级监听了 @submit,则把提交控制权交给父级(用于父级有自定义提交字段/反馈逻辑的页面,如 formdata.vue 传 uniacid)
if (this.$listeners && this.$listeners.submit) {
this.$emit('submit', this.getFormData());
return;
const formData = this.getFormData();
// 父级显式接管:function prop 在 H5 / MP / 鸿蒙一致可用
if (this.hasCustomSubmit) {
return this.onSubmit(formData);
}
// 兜底:内置 sendRequest 流程
this.defaultSubmit(formData);
},
// 获得保单数据
const submitFormData = this.getFormData();
// 提交到后端
// 公共兜底实现:默认的 /form/api/form/create 流程;
// 父级若需"先自定义、失败回退",可经 ref.defaultSubmit(formData) 调用
defaultSubmit(submitFormData) {
var self = this;
this.$api.sendRequest({
url: '/form/api/form/create',
data: {

View File

@@ -159,7 +159,10 @@
<!-- 商品推荐 -->
<diy-goods-recommend :value="item"></diy-goods-recommend>
</template>
<template v-if="item.componentName == 'DiyRecommendCode'">
<!-- 自定义推荐码组件 -->
<diy-recommend-code :value="item"></diy-recommend-code>
</template>
<template v-if="item.componentName == 'GoodsBrand'">
<!-- 商品品牌 -->
<diy-goods-brand :value="item"></diy-goods-brand>

File diff suppressed because it is too large Load Diff

View File

@@ -10,4 +10,6 @@ export const lang = {
// Modal dialog
tip: 'Tip',
paramError: 'Parameter error',
// Back to home
backHome: 'Back to Home',
}

View File

@@ -9,4 +9,6 @@ export const lang = {
// 弹窗
tip: '提示',
paramError: '参数错误',
// 返回主页
backHome: '返回主页',
}

View File

@@ -51,6 +51,7 @@
"diy-pintuan": "view",
"diy-presale": "view",
"diy-quick-nav": "view",
"diy-recommend-code": "view",
"diy-rich-text": "view",
"diy-rubik-cube": "view",
"diy-search": "view",
@@ -1294,6 +1295,7 @@
"diy-pintuan": "view",
"diy-presale": "view",
"diy-quick-nav": "view",
"diy-recommend-code": "view",
"diy-rich-text": "view",
"diy-rubik-cube": "view",
"diy-search": "view",

View File

@@ -1,21 +1,23 @@
<template>
<view :style="themeColor">
<!-- 返回主页按钮:左上角固定,始终可见 -->
<view class="home-btn" @click="goHome">
<text class="home-btn-text">{{ $lang('form.formdata.backHome') }}</text>
</view>
<block v-if="detail">
<view class="page">
<view class="system-form-wrap">
<!-- 复用 diy-form:banner / tip / 表单字段 / 提交按钮 全部由其内部渲染,样式(bannerPaddingX/tipColor/submitBgColor 等)由 form_config 控制。
@submit 接管提交逻辑(带 uniacid + showModal) -->
<diy-form
ref="form"
:value="diyValue"
dataMode="raw"
@submit="create"
/>
:onSubmit 接管提交逻辑(带 uniacid + showModal);跨 H5 / MP 一致,不依赖 $listeners。
注意:create 重度依赖本组件 this(id/uniacid/memberInfo/$api 等),必须在 created 阶段 bind this,
否则 diy-form 通过 this.onSubmit(formData) 调用时 this 会漂移到子组件实例 -->
<diy-form ref="form" :value="diyValue" dataMode="raw" :onSubmit="handleSubmit" />
</view>
</view>
</block>
<block v-else>
<ns-empty :text="complete ? $lang('form.formdata.submitSuccess') : $lang('form.formdata.noFormInfo')" :isIndex="false"></ns-empty>
<ns-empty :text="complete ? $lang('form.formdata.submitSuccess') : $lang('form.formdata.noFormInfo')"
:isIndex="false"></ns-empty>
</block>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
@@ -44,6 +46,7 @@ export default {
isFromMpWebView: false, // 是否是从微信小程序的WebView跳转过来的
hideNavbar: false, // 查询参数中支持隐藏Navbar
urlParams: {}, // 通用 URL 透传参数收集
handleSubmit: null, // create 的 this 绑定版本,作为 :onSubmit 传给 diy-form(见 created)
// #ifdef H5
formTitle: '', // 查询参数传入的Title
@@ -51,6 +54,13 @@ export default {
// #endif
}
},
created() {
// 预绑定 this:create 重度依赖本组件 this(id/uniacid/memberInfo/$api/$lang/$util 等)。
// 若直接传 :onSubmit="create",diy-form 通过 this.onSubmit(formData) 调用时,
// 普通函数调用的 this 会指向调用者(子组件实例),导致字段全部读不到。
// bind 后无论子组件如何调用,this 始终是 formdata 实例。
this.handleSubmit = this.create.bind(this);
},
computed: {
// 构造 diy-form raw 模式期望的 value 形态:
// - jsonData:透传给 ns-newform(已是 ns-newform 期望的 [{ controller, value, val }])
@@ -71,6 +81,7 @@ export default {
}
},
onLoad(options) {
console.log("=====表单页面====", options)
if (!options.uniacid) {
uni.showModal({
title: this.$lang('form.formdata.tip'),
@@ -128,7 +139,7 @@ export default {
this.getData()
},
watch: {
storeToken(newVal, oldVal) {
newVal && this.getData()
@@ -167,11 +178,27 @@ export default {
// #endif
uni.setNavigationBarTitle({ title: formName });
},
// 由 diy-form 内置提交按钮触发:diy-form 已先做 verify(),仅在通过时才 emit('submit', formData)
// 返回主页(用 reLaunch 避免返回后还能 navigateBack 回到已提交的表单页)
goHome() {
this.$util.redirectTo(this.$util.INDEX_PAGE_URL, {}, 'reLaunch');
},
// 清空表单数据:通过 diy-form 的 ref 拿到 ns-newform 实例,调用 setFormData 重置
resetForm() {
try {
if (this.$refs.form && this.$refs.form.$refs.nsNewform && this.$refs.form.$refs.nsNewform.setFormData) {
this.$refs.form.$refs.nsNewform.setFormData();
}
} catch(e) {}
},
// 由 diy-form 内置提交按钮触发:diy-form handleSubmit 已先做 verify(),
// 仅在通过时才通过 :onSubmit 函数 prop 调用本方法(跨 H5 / MP 一致,不走 $emit / $listeners)。
// 注意:本方法通过 created 中 this.handleSubmit = this.create.bind(this) 预绑定 this,
// 因此内部所有 this.xxx 都指向 formdata 实例,不会漂移到子组件。
create(formData) {
if (this.isRepeat) return
// 防重复提交:console 在拦截之前,避免日志噪声;拦截后立即置位
if (this.isRepeat) return;
this.isRepeat = true
this.isRepeat = true;
this.$api.sendRequest({
url: '/form/api/form/create',
data: {
@@ -182,19 +209,27 @@ export default {
member_id: this.memberInfo ? this.memberInfo.id : 0
},
success: res => {
if (res.code == 0) {
uni.showModal({
title: this.$lang('form.formdata.tip'),
content: this.$lang('form.formdata.submitSuccess'),
showCancel: false,
success: () => { }
})
} else {
if (res.code == 0) {
this.complete = true
// 提交成功后清空表单
this.resetForm()
this.isRepeat = false
uni.showModal({
title: this.$lang('form.formdata.tip'),
content: this.$lang('form.formdata.submitSuccess'),
showCancel: false,
success: () => { }
})
} else {
this.isRepeat = false
this.$util.showToast({
title: res.message
})
}
},
fail: () => {
// 网络失败时复位防重复标记,允许用户重试
this.isRepeat = false
}
})
}
@@ -219,6 +254,35 @@ page {
border-radius: 0;
}
// 左上角返回主页按钮
.home-btn {
position: fixed;
left: 30rpx;
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK
// 小程序端需避开右上角胶囊按钮,下移到状态栏 + 胶囊高度之下
top: calc(var(--status-bar-height, 20px) + 10rpx);
// #endif
// #ifdef H5
top: 20rpx;
// #endif
z-index: 999;
padding: 12rpx 28rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 40rpx;
display: flex;
align-items: center;
.home-btn-text {
color: #ffffff;
font-size: 26rpx;
line-height: 1;
}
&:active {
opacity: 0.8;
}
}
::v-deep .mescroll-totop {
/* #ifdef H5 */
right: 27rpx !important;

View File

@@ -7,7 +7,7 @@
</view>
</view>
<view class="body-wrap">
<view class="form-wrap">
<view class="form-wrap">
<view class="input-wrap" v-show="loginMode == 'mobile'">
<view class="content">
<!-- <view class="area-code">+86</view> -->
@@ -324,16 +324,16 @@ export default {
}
},
mobileAuthLogin(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
var data = {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
};
if (Object.keys(this.authInfo).length) {
Object.assign(data, this.authInfo);
if (this.authInfo.nickName) data.nickname = this.authInfo.nickName;
if (this.authInfo.avatarUrl) data.headimg = this.authInfo.avatarUrl;
}
if (e.detail.errMsg == 'getPhoneNumber:ok') {
var data = {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
};
if (Object.keys(this.authInfo).length) {
Object.assign(data, this.authInfo);
if (this.authInfo.nickName) data.nickname = this.authInfo.nickName;
if (this.authInfo.avatarUrl) data.headimg = this.authInfo.avatarUrl;
}
if (uni.getStorageSync('source_member')) data.source_member = uni.getStorageSync('source_member');
if (this.isSub) return;

View File

@@ -113,6 +113,32 @@ export default {
},
onShow() {
this.$util.hideHomeButton();
},
// 覆写 mixin 的分享钩子:优先使用推荐码组件存储的分享数据
onShareAppMessage() {
try {
var shareDataStr = uni.getStorageSync('_recommendShareData');
if (shareDataStr) {
uni.removeStorageSync('_recommendShareData');
return JSON.parse(shareDataStr);
}
} catch(e) {}
return this.mpShareData?.appMessage;
},
onShareTimeline() {
try {
var shareDataStr = uni.getStorageSync('_recommendShareData');
if (shareDataStr) {
uni.removeStorageSync('_recommendShareData');
var d = JSON.parse(shareDataStr);
var query = '';
if (d.path && d.path.indexOf('?') >= 0) {
query = d.path.split('?')[1];
}
return { title: d.title, query: query, imageUrl: d.imageUrl || '' };
}
} catch(e) {}
return this.mpShareData?.timeLine;
},
methods: {