Compare commits
4 Commits
temp2797
...
yuanlaide3
| Author | SHA1 | Date | |
|---|---|---|---|
| a137f3533c | |||
| 059630ba2c | |||
| 1ac0fb2484 | |||
| 1143ef7b72 |
@@ -37,8 +37,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
/**
|
/**
|
||||||
* 当前运行平台标识(与后端 formConfig.terminal 键名对齐)
|
* 当前运行平台标识(与后端 formConfig.terminal 键名对齐)
|
||||||
* 后端在 formConfig.terminal 下挂的差异化配置键:h5 / weapp / mp-harmony / app
|
* 后端 terminal 键:h5 / weapp / harmony / app / mp-alipay / mp-baidu / mp-toutiao
|
||||||
* 这里返回的 key 必须与后端设计器输出的 terminal 字段名一致
|
|
||||||
*/
|
*/
|
||||||
platform() {
|
platform() {
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@@ -69,8 +68,8 @@ export default {
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 后端键名 → 内部 platform 名 兼容层
|
* 后端键名 → 内部 platform 名 兼容层
|
||||||
* 不同后端序列化路径可能用 mp-weixin / wechat / mp-harmony 等不同的 key,
|
* canonical 与 platform() 返回值一致;别名为兼容 DB 旧 app_type(upgrade-to-ai-agent.sql)
|
||||||
* 在这里统一映射到内部 platform 名,避免 config() 里到处写 if/else。
|
* 及 uniapp / 设计器的历史命名。键名严格区分大小写。
|
||||||
*/
|
*/
|
||||||
platformAliases() {
|
platformAliases() {
|
||||||
return {
|
return {
|
||||||
@@ -80,7 +79,15 @@ export default {
|
|||||||
'wechat': 'weapp',
|
'wechat': 'weapp',
|
||||||
'harmony': 'harmony',
|
'harmony': 'harmony',
|
||||||
'app': 'app',
|
'app': 'app',
|
||||||
'app-plus': 'app'
|
'app-plus': 'app',
|
||||||
|
'mp-alipay': 'mp-alipay',
|
||||||
|
'aliapp': 'mp-alipay',
|
||||||
|
'alipay': 'mp-alipay',
|
||||||
|
'mp-baidu': 'mp-baidu',
|
||||||
|
'baiduapp': 'mp-baidu',
|
||||||
|
'baidu': 'mp-baidu',
|
||||||
|
'mp-toutiao': 'mp-toutiao',
|
||||||
|
'toutiao': 'mp-toutiao'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 处理商品详情数据
|
// 处理商品详情数据
|
||||||
handleGoodsSkuData() {
|
async handleGoodsSkuData() {
|
||||||
// this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
|
// this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
|
||||||
//设置标题
|
//设置标题
|
||||||
// this.$langConfig.title(this.navbarData.title);
|
// this.$langConfig.title(this.navbarData.title);
|
||||||
@@ -186,7 +186,7 @@ export default {
|
|||||||
|
|
||||||
// this.getBarrageData();
|
// this.getBarrageData();
|
||||||
if (this.addonIsExist.form) {
|
if (this.addonIsExist.form) {
|
||||||
this.getGoodsForm();
|
await this.getGoodsForm();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -321,17 +321,54 @@ export default {
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 获取商品表单
|
* 获取商品表单
|
||||||
|
* 后端 goodsform 接口与 info() 对齐,返回 {json_data, form_config(camelCase),
|
||||||
|
* form_name, form_tip, form_banner, show_banner, show_tip}。
|
||||||
|
* 全部字段都落到 goodsSkuDetail 上:表单字段 / 样式 / banner / tip 元数据,
|
||||||
|
* 给 detail.vue 的 diy-form 直接消费。所有分支都做兜底初始化,避免下游拿到 undefined。
|
||||||
*/
|
*/
|
||||||
getGoodsForm() {
|
async getGoodsForm() {
|
||||||
this.$api.sendRequest({
|
const res = await this.$api.sendRequest({
|
||||||
url: "/form/api/form/goodsform",
|
url: "/form/api/form/goodsform",
|
||||||
data: {
|
data: {
|
||||||
goods_id: this.goodsSkuDetail.goods_id
|
goods_id: this.goodsSkuDetail.goods_id
|
||||||
},
|
},
|
||||||
success: res => {
|
async: false
|
||||||
if (res.code == 0 && res.data) this.$set(this.goodsSkuDetail, 'goods_form', res.data);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
const empty = () => {
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form', []);
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_config', {});
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_name', '');
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_tip', '');
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_banner', '');
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_show_banner', false);
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_show_tip', false);
|
||||||
|
};
|
||||||
|
if (!res || res.code != 0 || !res.data) {
|
||||||
|
empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(res.data)) {
|
||||||
|
// 旧版扁平数组兼容
|
||||||
|
empty();
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form', res.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form', res.data.json_data || []);
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_config', res.data.form_config || {});
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_name', res.data.form_name || '');
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_tip', res.data.form_tip || '');
|
||||||
|
this.$set(this.goodsSkuDetail, 'goods_form_banner', res.data.form_banner || '');
|
||||||
|
// show_banner/show_tip 后端存 0/1,归一化 boolean
|
||||||
|
this.$set(
|
||||||
|
this.goodsSkuDetail,
|
||||||
|
'goods_form_show_banner',
|
||||||
|
res.data.show_banner == 1 ? true : (res.data.show_banner === 0 ? false : true)
|
||||||
|
);
|
||||||
|
this.$set(
|
||||||
|
this.goodsSkuDetail,
|
||||||
|
'goods_form_show_tip',
|
||||||
|
res.data.show_tip == 1 ? true : (res.data.show_tip === 0 ? false : true)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -701,13 +701,15 @@ export function _safeEncodeForPlatform(v) {
|
|||||||
|
|
||||||
// 微信小程序: split on '&' / '=' 解析 url,但不 decode value 给 onLoad。
|
// 微信小程序: split on '&' / '=' 解析 url,但不 decode value 给 onLoad。
|
||||||
// - 中文 / 字母 / 数字 → 原样保留(否则 onLoad 拿到 %xx 乱码)
|
// - 中文 / 字母 / 数字 → 原样保留(否则 onLoad 拿到 %xx 乱码)
|
||||||
// - `&` `=` `?` `#` 空格 → 必须 encode(否则 query 边界被破坏, src 等含 URL 的字段被截断)
|
// - `&` `=` `?` `#` 空格 → 必须 encode(否则 query 边界被破坏, src 等含 URL 的字段被截断,webview 打不开)
|
||||||
if (platform === 'mp-weixin') {
|
if (platform === 'mp-weixin') {
|
||||||
return _encodeUrlDelimiters(once);
|
return _encodeUrlDelimiters(once);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鸿蒙元服务: 整体 encode url(包括中文和已编码的 %xx)。
|
// 鸿蒙元服务: uni.navigateTo 内部整体 encode url(把中文、& 等都 encode)。
|
||||||
// JS 侧完全不 encode,直接返回 decode roundtrip 后的原文,让鸿蒙原生做唯一一次 encode。
|
// JS 侧完全不 encode,直接返回 decode roundtrip 后的原文,让鸿蒙原生做唯一一次 encode。
|
||||||
|
// (再 encode 会双重编码 → onLoad 拿到 %E6%B2%99%E5%8F%91 乱码)
|
||||||
|
// webview URL 含 & 时, JS 不 encode,鸿蒙原生 encode 后 & 变 %26,webview 能正常打开。
|
||||||
if (platform === 'mp-harmony') {
|
if (platform === 'mp-harmony') {
|
||||||
return once;
|
return once;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,9 @@ export default {
|
|||||||
labelColor: pick('labelColor', 'label_color'),
|
labelColor: pick('labelColor', 'label_color'),
|
||||||
requiredColor: pick('requiredColor', 'required_color'),
|
requiredColor: pick('requiredColor', 'required_color'),
|
||||||
checkedColor: pick('checkedColor', 'checked_color'),
|
checkedColor: pick('checkedColor', 'checked_color'),
|
||||||
|
// 占位符:遗漏会被 ns-newform SCSS 默认值回退覆盖
|
||||||
|
placeholderColor: pick('placeholderColor', 'placeholder_color'),
|
||||||
|
placeholderFontSize: pick('placeholderFontSize', 'placeholder_font_size'),
|
||||||
submitText: pick('submitText', 'submit_text'),
|
submitText: pick('submitText', 'submit_text'),
|
||||||
submitColor: pick('submitColor', 'submit_color'),
|
submitColor: pick('submitColor', 'submit_color'),
|
||||||
submitBgColor: pick('submitBgColor', 'submit_bg_color'),
|
submitBgColor: pick('submitBgColor', 'submit_bg_color'),
|
||||||
|
|||||||
@@ -411,7 +411,12 @@
|
|||||||
</view> -->
|
</view> -->
|
||||||
<!-- v-if="goodsSkuDetail.goodsForm" -->
|
<!-- v-if="goodsSkuDetail.goodsForm" -->
|
||||||
<view style="padding: 0 30rpx;">
|
<view style="padding: 0 30rpx;">
|
||||||
<ns-form :data="informationform" ref="form"></ns-form>
|
<diy-form
|
||||||
|
:value="formDiyValue"
|
||||||
|
dataMode="raw"
|
||||||
|
:show-submit="false"
|
||||||
|
ref="form"
|
||||||
|
></diy-form>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="button-box"><button type="primary" @click="saveubfirnation()">{{ $lang('goods.detail.confirm') }}</button></view>
|
<view class="button-box"><button type="primary" @click="saveubfirnation()">{{ $lang('goods.detail.confirm') }}</button></view>
|
||||||
@@ -545,6 +550,21 @@ export default {
|
|||||||
nsGoodsPromotion
|
nsGoodsPromotion
|
||||||
},
|
},
|
||||||
mixins: [base, detail, scroll],
|
mixins: [base, detail, scroll],
|
||||||
|
computed: {
|
||||||
|
// diy-form raw 模式 value:banner/tip 由独立列归一化后的 goods_form_* 提供,
|
||||||
|
// 与 formdata.vue 的 diyValue 同源;本页 :show-submit="false" 走外部"确定"按钮提交。
|
||||||
|
formDiyValue() {
|
||||||
|
const sku = this.goodsSkuDetail || {};
|
||||||
|
return {
|
||||||
|
jsonData: sku.goods_form || [],
|
||||||
|
formConfig: sku.goods_form_config || {},
|
||||||
|
show_banner: sku.goods_form_show_banner === true,
|
||||||
|
form_banner: sku.goods_form_banner || '',
|
||||||
|
show_tip: sku.goods_form_show_tip === true,
|
||||||
|
form_tip: sku.goods_form_tip || ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
* 发送商品信息到智能客服
|
* 发送商品信息到智能客服
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ export default {
|
|||||||
|
|
||||||
membercard: null, // 会员卡信息
|
membercard: null, // 会员卡信息
|
||||||
hackReset: true,
|
hackReset: true,
|
||||||
cardOff: false,
|
cardOff: false
|
||||||
informationform:[]//留言表单
|
// 留言表单数据不再在 data() 维护:detail.vue 的 computed formDiyValue
|
||||||
|
// 直接从 goodsSkuDetail.goods_form / goods_form_config / goods_form_* 实时读取并打包成
|
||||||
|
// diy-form raw 模式期望的 value 结构。
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -156,7 +157,7 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 处理商品数据
|
// 处理商品数据
|
||||||
this.handleGoodsSkuData();
|
await this.handleGoodsSkuData();
|
||||||
|
|
||||||
// 限时折扣
|
// 限时折扣
|
||||||
if (this.goodsSkuDetail.promotion_type == 1 && this.addonIsExist.discount) {
|
if (this.goodsSkuDetail.promotion_type == 1 && this.addonIsExist.discount) {
|
||||||
@@ -221,7 +222,6 @@ export default {
|
|||||||
|
|
||||||
//商品留言打开
|
//商品留言打开
|
||||||
showinformation(){
|
showinformation(){
|
||||||
this.informationform = this.goodsSkuDetail.goods_form
|
|
||||||
this.$refs.informationPopup.open();
|
this.$refs.informationPopup.open();
|
||||||
},
|
},
|
||||||
//商品留言关闭
|
//商品留言关闭
|
||||||
@@ -230,18 +230,18 @@ export default {
|
|||||||
},
|
},
|
||||||
//保存商品留言
|
//保存商品留言
|
||||||
saveubfirnation(){
|
saveubfirnation(){
|
||||||
//缺少
|
// ref 指向 <diy-form>:diy-form 只暴露 getFormData() 方法,无 formData 属性
|
||||||
if (!this.$refs.form.verify()) return;
|
if (!this.$refs.form.verify()) return;
|
||||||
|
|
||||||
// uni.setStorageSync('goodFormData', {
|
// uni.setStorageSync('goodFormData', {
|
||||||
// goods_id: this.goodsSkuDetail.goods_id,
|
// goods_id: this.goodsSkuDetail.goods_id,
|
||||||
// form_data: this.$refs.form.formData
|
// form_data: this.$refs.form.getFormData()
|
||||||
// });
|
// });
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
url: '/api/goods/information',
|
url: '/api/goods/information',
|
||||||
data: {
|
data: {
|
||||||
goods_id: this.goodsSkuDetail.goods_id,
|
goods_id: this.goodsSkuDetail.goods_id,
|
||||||
form_data: JSON.stringify(this.$refs.form.formData)
|
form_data: JSON.stringify(this.$refs.form.getFormData())
|
||||||
},
|
},
|
||||||
success: res => {
|
success: res => {
|
||||||
var data = res.data;
|
var data = res.data;
|
||||||
|
|||||||
@@ -240,8 +240,9 @@ test('_safeEncodeForPlatform: H5 / 华为快应用 → 主动 encode', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('_safeEncodeForPlatform: 鸿蒙元服务 → JS 侧不做 encode', () => {
|
test('_safeEncodeForPlatform: 鸿蒙元服务 → JS 侧不做 encode(让平台去做)', () => {
|
||||||
// 2026-07-17 修正(二次): 鸿蒙整体 encode url, JS 完全不 encode
|
// 2026-07-17 修正: 鸿蒙整体 encode url, JS 完全不 encode
|
||||||
|
// (再 encode 会双重编码; webview src 含 & 时,鸿蒙原生 encode 会自动变 %26,webview 能正常打开)
|
||||||
const nav = loadNavInSandbox();
|
const nav = loadNavInSandbox();
|
||||||
const api = nav.createNavigateApi({ platform: 'mp-harmony' });
|
const api = nav.createNavigateApi({ platform: 'mp-harmony' });
|
||||||
const r = api._safeEncodeForPlatform('a&b');
|
const r = api._safeEncodeForPlatform('a&b');
|
||||||
|
|||||||
Reference in New Issue
Block a user