chore:悬浮按钮可以自定义调节
This commit is contained in:
@@ -257,7 +257,7 @@ const localDevConfig = ({
|
|||||||
// })['2811']; // 本地
|
// })['2811']; // 本地
|
||||||
// })['5g-317']; // 电磁兼容
|
// })['5g-317']; // 电磁兼容
|
||||||
// })['5g-351']; //
|
// })['5g-351']; //
|
||||||
})['5g-248']; // 本地
|
})['5g-97']; // 本地
|
||||||
// })['local-2']; // 本地
|
// })['local-2']; // 本地
|
||||||
// })['local-11']; // 本地
|
// })['local-11']; // 本地
|
||||||
// })['1-test']; // test
|
// })['1-test']; // test
|
||||||
|
|||||||
@@ -629,16 +629,16 @@ function loadLangPackSync(lang, path) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* 语言切换开关钩子(由后台 shop_info.ischia 决定,经 store/index.js 的 setShopInfo 写入)。
|
* 语言切换开关钩子(由后台 shop_info.ischina 决定,经 store/index.js 的 setShopInfo 写入)。
|
||||||
*
|
*
|
||||||
* 设计原则: 只"在关闭时清理持久化语种", 绝不在开启态加任何门控 —— 否则一旦 ischia
|
* 设计原则: 只"在关闭时清理持久化语种", 绝不在开启态加任何门控 —— 否则一旦 ischina
|
||||||
* 取值/语义判断偏差, 就会误伤"开启双语后切换英文"的正常行为(回归)。
|
* 取值/语义判断偏差, 就会误伤"开启双语后切换英文"的正常行为(回归)。
|
||||||
*
|
*
|
||||||
* 行为:
|
* 行为:
|
||||||
* - 后台关闭双语/小程序(ischia 为假): 清掉用户此前持久化到 storage 的语种 + 缓存,
|
* - 后台关闭双语/小程序(ischina 为假): 清掉用户此前持久化到 storage 的语种 + 缓存,
|
||||||
* 使刷新/重新进入时 getCurrentLocale() 回退默认中文, 满足
|
* 使刷新/重新进入时 getCurrentLocale() 回退默认中文, 满足
|
||||||
* "后台关闭双语后, 刷新重新进入必须是中文" 的需求。
|
* "后台关闭双语后, 刷新重新进入必须是中文" 的需求。
|
||||||
* - 后台开启双语(ischia 为真): 不做任何拦截, 完全保持原有"切换英文"行为不变。
|
* - 后台开启双语(ischina 为真): 不做任何拦截, 完全保持原有"切换英文"行为不变。
|
||||||
*/
|
*/
|
||||||
function setLangSwitchEnabled(enabled) {
|
function setLangSwitchEnabled(enabled) {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
@@ -994,7 +994,7 @@ export default {
|
|||||||
getCurrentLocale,
|
getCurrentLocale,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 语言切换功能开关(后台 shop_info.ischia 决定)。
|
* 语言切换功能开关(后台 shop_info.ischina 决定)。
|
||||||
* 关闭后 getCurrentLocale() 强制返回默认语言(中文),并清掉已持久化的语种。
|
* 关闭后 getCurrentLocale() 强制返回默认语言(中文),并清掉已持久化的语种。
|
||||||
* 详见本文件 setLangSwitchEnabled 函数与 store/index.js 的 setShopInfo 钩子。
|
* 详见本文件 setLangSwitchEnabled 函数与 store/index.js 的 setShopInfo 钩子。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- Vue 2 / uni-app 单根约束:用 view 包一层 -->
|
<!-- Vue 2 / uni-app 单根约束:用 view 包一层 -->
|
||||||
<view>
|
<view>
|
||||||
<view v-if="pageCount === 1 || need" class="fixed-box"
|
<view v-if="(pageCount === 1 || need) && fbVisible && hasAnyButton" class="fixed-box"
|
||||||
:style="[customContainerStyle, {
|
:style="[customContainerStyle, {
|
||||||
height: containerHeight,
|
height: containerHeight,
|
||||||
bottom: containerBottom,
|
bottom: containerBottom,
|
||||||
@@ -11,18 +11,18 @@
|
|||||||
}]">
|
}]">
|
||||||
<!-- 多语言切换按钮:根据语言数智能切换交互 -->
|
<!-- 多语言切换按钮:根据语言数智能切换交互 -->
|
||||||
<view
|
<view
|
||||||
v-if="isLanguageSwitchEnabled && fixBtnShow"
|
v-if="isLanguageSwitchEnabled && hasLangButton"
|
||||||
class="btn-item common-bg"
|
class="btn-item common-bg"
|
||||||
:style="btnItemStyle"
|
:style="[btnItemStyle, { order: orderIndex.lang }]"
|
||||||
@click="handleLangButtonClick"
|
@click="handleLangButtonClick"
|
||||||
>
|
>
|
||||||
<view class="lang-btn-text">{{ currentLangDisplayName }}</view>
|
<view class="lang-btn-text">{{ langButtonText }}</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 微信官方客服按钮-->
|
<!-- 微信官方客服按钮-->
|
||||||
<button
|
<button
|
||||||
v-if="fixBtnShow && hasValidKefuConfig && isWeappOfficialKefu"
|
v-if="hasKefuButton && hasValidKefuConfig && isWeappOfficialKefu"
|
||||||
class="btn-item common-bg"
|
class="btn-item common-bg"
|
||||||
:style="btnItemStyle"
|
:style="[btnItemStyle, { order: orderIndex.kefu }]"
|
||||||
open-type="contact"
|
open-type="contact"
|
||||||
>
|
>
|
||||||
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
|
|
||||||
<!-- 其他类型客服按钮(智能客服、企业微信等)-->
|
<!-- 其他类型客服按钮(智能客服、企业微信等)-->
|
||||||
<view
|
<view
|
||||||
v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && !showWeappSystemKefu"
|
v-if="hasKefuButton && hasValidKefuConfig && !isWeappOfficialKefu && !showWeappSystemKefu"
|
||||||
class="btn-item common-bg"
|
class="btn-item common-bg"
|
||||||
:style="btnItemStyle"
|
:style="[btnItemStyle, { order: orderIndex.kefu }]"
|
||||||
@click="handleUnifiedKefuClick"
|
@click="handleUnifiedKefuClick"
|
||||||
>
|
>
|
||||||
<image
|
<image
|
||||||
@@ -48,9 +48,9 @@
|
|||||||
|
|
||||||
<!-- 智能客服按钮(当同时显示小程序系统客服时)-->
|
<!-- 智能客服按钮(当同时显示小程序系统客服时)-->
|
||||||
<view
|
<view
|
||||||
v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && showWeappSystemKefu"
|
v-if="hasKefuButton && hasValidKefuConfig && !isWeappOfficialKefu && showWeappSystemKefu"
|
||||||
class="btn-item common-bg"
|
class="btn-item common-bg"
|
||||||
:style="btnItemStyle"
|
:style="[btnItemStyle, { order: orderIndex.kefu }]"
|
||||||
@click="handleUnifiedKefuClick"
|
@click="handleUnifiedKefuClick"
|
||||||
>
|
>
|
||||||
<image
|
<image
|
||||||
@@ -66,9 +66,9 @@
|
|||||||
|
|
||||||
<!-- 小程序系统客服按钮 -->
|
<!-- 小程序系统客服按钮 -->
|
||||||
<button
|
<button
|
||||||
v-if="fixBtnShow && hasValidKefuConfig && showWeappSystemKefu"
|
v-if="hasKefuButton && hasValidKefuConfig && showWeappSystemKefu"
|
||||||
class="btn-item common-bg"
|
class="btn-item common-bg"
|
||||||
:style="btnItemStyle"
|
:style="[btnItemStyle, { order: orderIndex.kefu }]"
|
||||||
open-type="contact"
|
open-type="contact"
|
||||||
>
|
>
|
||||||
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
||||||
@@ -76,9 +76,9 @@
|
|||||||
|
|
||||||
<!-- 电话按钮 -->
|
<!-- 电话按钮 -->
|
||||||
<view
|
<view
|
||||||
v-if="fixBtnShow"
|
v-if="hasPhoneButton"
|
||||||
class="btn-item common-bg"
|
class="btn-item common-bg"
|
||||||
:style="[btnItemStyle, { backgroundImage: phoneimg ? `url(${phoneimg})` : '', backgroundSize: '100% 100%' }, customButtonStyle]"
|
:style="[btnItemStyle, { order: orderIndex.phone }, { backgroundImage: phoneimg ? `url(${phoneimg})` : '', backgroundSize: '100% 100%' }, customButtonStyle]"
|
||||||
@click="call"
|
@click="call"
|
||||||
>
|
>
|
||||||
<text class="iconfont icon-dianhua" v-if="!phoneimg"></text>
|
<text class="iconfont icon-dianhua" v-if="!phoneimg"></text>
|
||||||
@@ -109,6 +109,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createCustomerService } from '@/common/js/customer-service.js';
|
import { createCustomerService } from '@/common/js/customer-service.js';
|
||||||
import i18nLazyMixin from '@/common/mixin/i18n-lazy.js';
|
import i18nLazyMixin from '@/common/mixin/i18n-lazy.js';
|
||||||
|
import {
|
||||||
|
getCurrentRoute, shouldShowOnPage, resolveVisibleButtons,
|
||||||
|
resolveLangButtonText, isLangButtonVisible,
|
||||||
|
} from '@/common/js/floating-button.js';
|
||||||
|
|
||||||
// 语言短码映射表(currentLangDisplayName 展示用,可按需扩展)
|
// 语言短码映射表(currentLangDisplayName 展示用,可按需扩展)
|
||||||
// key: 语言 value,value: 显示短码(按钮上展示)
|
// key: 语言 value,value: 显示短码(按钮上展示)
|
||||||
@@ -170,7 +174,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pageCount: 0,
|
pageCount: 0,
|
||||||
fixBtnShow: true,
|
currentRoute: '', // 当前页面路由(onShow / created 时刷新, 供页面范围判定)
|
||||||
shopInfo: null,
|
shopInfo: null,
|
||||||
currentLangIndex: 0,
|
currentLangIndex: 0,
|
||||||
langIndexMap: {},
|
langIndexMap: {},
|
||||||
@@ -237,6 +241,57 @@ export default {
|
|||||||
customButtonStyle() {
|
customButtonStyle() {
|
||||||
return this.shopInfo?.floatingButton?.button || {};
|
return this.shopInfo?.floatingButton?.button || {};
|
||||||
},
|
},
|
||||||
|
// ============================================================
|
||||||
|
// 浮动侧边栏配置消费 (来源: /api/config/init → data.floating_button,
|
||||||
|
// store/index.js 的 floatingButtonConfig, 初始 state 已声明 → 响应式)
|
||||||
|
// fbConfig 为 null (老缓存响应缺字段) 时, 各判定全部走老行为兜底。
|
||||||
|
// ============================================================
|
||||||
|
// 接口下发的浮动侧边栏配置 (老缓存响应 → null)
|
||||||
|
fbConfig() {
|
||||||
|
return (this.$store && this.$store.state && this.$store.state.floatingButtonConfig) || null;
|
||||||
|
},
|
||||||
|
// 总开关 + 强制隐藏 + 页面范围 判定结果
|
||||||
|
fbVisible() {
|
||||||
|
return shouldShowOnPage(this.fbConfig, this.currentRoute, true);
|
||||||
|
},
|
||||||
|
// 最终要渲染的按钮 (已按 button_order 排序 + 显隐过滤); null = 用老行为
|
||||||
|
visibleButtons() {
|
||||||
|
return resolveVisibleButtons(this.fbConfig);
|
||||||
|
},
|
||||||
|
hasAnyButton() {
|
||||||
|
const b = this.visibleButtons;
|
||||||
|
return b ? b.length > 0 : true; // 老行为: 电话按钮恒显
|
||||||
|
},
|
||||||
|
hasLangButton() {
|
||||||
|
const b = this.visibleButtons;
|
||||||
|
return b ? b.indexOf('lang') !== -1
|
||||||
|
: isLangButtonVisible(this.fbConfig, this.shopInfo, this.langList.length);
|
||||||
|
},
|
||||||
|
hasKefuButton() {
|
||||||
|
const b = this.visibleButtons;
|
||||||
|
return b ? b.indexOf('kefu') !== -1 : true;
|
||||||
|
},
|
||||||
|
hasPhoneButton() {
|
||||||
|
const b = this.visibleButtons;
|
||||||
|
return b ? b.indexOf('phone') !== -1 : true;
|
||||||
|
},
|
||||||
|
// 语言按钮文案: 商家可配「目标语言 / 当前语言 / 固定文案」。
|
||||||
|
// 配置缺失时回退老行为 currentLangDisplayName(展示当前语言)。
|
||||||
|
langButtonText() {
|
||||||
|
if (!this.fbConfig) return this.currentLangDisplayName;
|
||||||
|
return resolveLangButtonText(this.fbConfig, this.langList, this.currentLangIndex);
|
||||||
|
},
|
||||||
|
// 按钮渲染顺序 (button_order 自上而下); .fixed-box 是 flex-direction: column,
|
||||||
|
// 用 CSS order 控制三段(语言/客服/电话)的先后, 配置缺失时退回老顺序。
|
||||||
|
orderIndex() {
|
||||||
|
const order = (this.fbConfig && Array.isArray(this.fbConfig.button_order))
|
||||||
|
? this.fbConfig.button_order
|
||||||
|
: ['lang', 'kefu', 'phone'];
|
||||||
|
const map = {};
|
||||||
|
for (let i = 0; i < order.length; i++) map[order[i]] = i + 1;
|
||||||
|
map.lang = map.lang || 1; map.kefu = map.kefu || 2; map.phone = map.phone || 3;
|
||||||
|
return map;
|
||||||
|
},
|
||||||
// 所有 .btn-item 的 inline-style 兜底:
|
// 所有 .btn-item 的 inline-style 兜底:
|
||||||
// 1) 测试发现 .btn-item 的 min-*/max-*/aspect-ratio/flex-shrink 等 !important
|
// 1) 测试发现 .btn-item 的 min-*/max-*/aspect-ratio/flex-shrink 等 !important
|
||||||
// 规则在 scoped 样式下,被某些 flex 布局的隐式约束吃掉,只 width/height/border-radius
|
// 规则在 scoped 样式下,被某些 flex 布局的隐式约束吃掉,只 width/height/border-radius
|
||||||
@@ -301,18 +356,19 @@ export default {
|
|||||||
// 每个按钮槽位:72rpx(按钮,与 to-top 一致) + 14rpx(上 margin) + 14rpx(下 margin) = 100rpx
|
// 每个按钮槽位:72rpx(按钮,与 to-top 一致) + 14rpx(上 margin) + 14rpx(下 margin) = 100rpx
|
||||||
// 容器 padding:20rpx 上 + 20rpx 下 = 40rpx
|
// 容器 padding:20rpx 上 + 20rpx 下 = 40rpx
|
||||||
// 总高度 (rpx):buttonCount × 100 + 40
|
// 总高度 (rpx):buttonCount × 100 + 40
|
||||||
// 修复:改返回 rpx 而非 px(原 *0.5 硬编码 iPhone 6 375px 转换比),
|
// 新配置生效时按 visibleButtons 的实际按钮数算,避免隐藏按钮后留下空白档;
|
||||||
// 在微信小程序/其他设备(iPhone 13 390px、iPad 等)下由 uni-app 框架
|
// 全部按钮被关掉时返回 0rpx(根节点 v-if 已含 hasAnyButton, 这里是双保险);
|
||||||
// 按 windowWidth 动态换算,避免 4+ 按钮时容器偏小导致内容被裁切
|
// 配置缺失(fbConfig 为 null)时保持老行为: 电话恒显 + 可选语言 + 可选系统客服。
|
||||||
// 关联:按钮尺寸与 to-top 同步(72rpx),所以槽位高度也是 100rpx;
|
// extraKefuSlot: 小程序系统客服与客服主按钮并存时模板会多渲染一个按钮,
|
||||||
// 之前按钮 80rpx 时槽位 108rpx,改为 72rpx 后槽位缩小 8rpx,容器整体更紧凑
|
// 需要为它多留一个槽位(fallback 分支与老逻辑等价)。
|
||||||
containerHeight() {
|
containerHeight() {
|
||||||
if (!this.fixBtnShow) return '320rpx';
|
const b = this.visibleButtons;
|
||||||
|
if (b && b.length === 0) return '0rpx';
|
||||||
|
|
||||||
let buttonCount = 1;
|
const extraKefuSlot = (this.hasKefuButton && this.showWeappSystemKefu) ? 1 : 0;
|
||||||
if (this.isLanguageSwitchEnabled) buttonCount++;
|
const buttonCount = b
|
||||||
if (this.showWeappSystemKefu) buttonCount++;
|
? b.length + extraKefuSlot
|
||||||
buttonCount++;
|
: 1 + (this.isLanguageSwitchEnabled ? 1 : 0) + extraKefuSlot;
|
||||||
const totalRpx = buttonCount * 100 + 40;
|
const totalRpx = buttonCount * 100 + 40;
|
||||||
|
|
||||||
return `${totalRpx}rpx`;
|
return `${totalRpx}rpx`;
|
||||||
@@ -337,7 +393,6 @@ export default {
|
|||||||
// 与 Top 按钮的 .mescroll-totop { margin-bottom: var(--window-bottom) } 一致,
|
// 与 Top 按钮的 .mescroll-totop { margin-bottom: var(--window-bottom) } 一致,
|
||||||
// 两者会被安全区同步上推,space 保持不变
|
// 两者会被安全区同步上推,space 保持不变
|
||||||
containerBottom() {
|
containerBottom() {
|
||||||
if (!this.fixBtnShow) return '240rpx';
|
|
||||||
let space = 18 * 5;
|
let space = 18 * 5;
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
space = 18 * 1;
|
space = 18 * 1;
|
||||||
@@ -357,7 +412,6 @@ export default {
|
|||||||
// - right edge 对齐(46rpx):左侧突出 28rpx,中心错位 14rpx
|
// - right edge 对齐(46rpx):左侧突出 28rpx,中心错位 14rpx
|
||||||
// center 对齐不仅中心精准,突出量也更小
|
// center 对齐不仅中心精准,突出量也更小
|
||||||
containerRight() {
|
containerRight() {
|
||||||
if (!this.fixBtnShow) return '0rpx';
|
|
||||||
const offset = this.layoutTopRight + this.layoutTopSize / 2 - this.layoutFloatingWidth / 2;
|
const offset = this.layoutTopRight + this.layoutTopSize / 2 - this.layoutFloatingWidth / 2;
|
||||||
return `${offset}rpx`;
|
return `${offset}rpx`;
|
||||||
},
|
},
|
||||||
@@ -420,9 +474,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 页面生命周期: hover-nav 是常驻组件, 路由变化必须靠 onShow 通知,
|
||||||
|
// 否则 currentRoute 停留在首次加载页, 页面范围判定(fbVisible)会失效。
|
||||||
|
onShow() {
|
||||||
|
this.refreshRoute();
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initLanguage();
|
this.initLanguage();
|
||||||
this.pageCount = getCurrentPages().length;
|
this.refreshRoute();
|
||||||
|
|
||||||
// 三源兜底(store / 同步 storage / 异步 storage),
|
// 三源兜底(store / 同步 storage / 异步 storage),
|
||||||
// 任何一个先就绪就先使用,后续由 initStatus watcher 再次同步
|
// 任何一个先就绪就先使用,后续由 initStatus watcher 再次同步
|
||||||
@@ -523,6 +582,11 @@ export default {
|
|||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 刷新当前路由与页面栈深度(供 fbVisible 的页面范围判定 / pageCount 老判定)
|
||||||
|
refreshRoute() {
|
||||||
|
this.currentRoute = getCurrentRoute();
|
||||||
|
this.pageCount = getCurrentPages().length;
|
||||||
|
},
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
/**
|
/**
|
||||||
* 从 :root 读取 CSS 变量(App.vue 中定义)到 data,
|
* 从 :root 读取 CSS 变量(App.vue 中定义)到 data,
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ const store = new Vuex.Store({
|
|||||||
wap_valid_time: 0,
|
wap_valid_time: 0,
|
||||||
},
|
},
|
||||||
copyright: null,
|
copyright: null,
|
||||||
|
floatingButtonConfig: null, // 来自 /api/config/init 的 data.floating_button (浮动侧边栏配置)
|
||||||
initStatus: false,
|
initStatus: false,
|
||||||
offlineWhiteList: ['pages_order/payment', 'pages_order/list', 'pages_order/detail'],//线下支付白名单
|
offlineWhiteList: ['pages_order/payment', 'pages_order/list', 'pages_order/detail'],//线下支付白名单
|
||||||
canReceiveRegistergiftInfo: {
|
canReceiveRegistergiftInfo: {
|
||||||
@@ -164,10 +165,23 @@ const store = new Vuex.Store({
|
|||||||
setShopInfo(state, value) {
|
setShopInfo(state, value) {
|
||||||
state.shopInfo = value;
|
state.shopInfo = value;
|
||||||
uni.setStorageSync('shopInfo', value); // 初始化数据调用
|
uni.setStorageSync('shopInfo', value); // 初始化数据调用
|
||||||
// 语言切换开关: 后台 shop_info.ischia 决定。
|
// 语言切换开关 fallback: 后台 shop_info.ischina 决定(老「双语模式」)。
|
||||||
// 关闭(ischia 为假)时强制返回默认中文,并清掉用户此前持久化到 storage 的语种,
|
// 新配置下发后由 setFloatingButtonConfig 里的 lang_switch.enabled 接管,
|
||||||
|
// 这里的 ischina 只是配置缺失(老缓存响应)时的兜底。
|
||||||
|
// 关闭时强制返回默认中文,并清掉用户此前持久化到 storage 的语种,
|
||||||
// 满足"后台关闭双语/小程序后,刷新重新进入必须是中文"的需求。
|
// 满足"后台关闭双语/小程序后,刷新重新进入必须是中文"的需求。
|
||||||
try { LangConfig.setLangSwitchEnabled(!!(value && value.ischia)); } catch (e) {}
|
try { LangConfig.setLangSwitchEnabled(!!(value && value.ischina)); } catch (e) {}
|
||||||
|
},
|
||||||
|
// 浮动侧边栏配置 (来自 /api/config/init → data.floating_button)
|
||||||
|
setFloatingButtonConfig(state, value) {
|
||||||
|
state.floatingButtonConfig = value || null;
|
||||||
|
uni.setStorageSync('floatingButtonConfig', value || null);
|
||||||
|
// 与 setShopInfo 的 setLangSwitchEnabled 配对: 新配置存在时以新配置为准
|
||||||
|
try {
|
||||||
|
if (value && value.lang_switch) {
|
||||||
|
LangConfig.setLangSwitchEnabled(Number(value.lang_switch.enabled) === 1);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
},
|
},
|
||||||
setCartChange(state) {
|
setCartChange(state) {
|
||||||
state.cartChange += 1;
|
state.cartChange += 1;
|
||||||
@@ -315,6 +329,8 @@ const store = new Vuex.Store({
|
|||||||
//联系我们
|
//联系我们
|
||||||
|
|
||||||
this.commit('setShopInfo', data.shop_info);
|
this.commit('setShopInfo', data.shop_info);
|
||||||
|
// 浮动侧边栏配置; 缺失时显式置 null → 前端走老行为兜底
|
||||||
|
this.commit('setFloatingButtonConfig', data.floating_button || null);
|
||||||
this.commit('setWechatConfigStatus', data?.wechat_config_status);
|
this.commit('setWechatConfigStatus', data?.wechat_config_status);
|
||||||
// 默认总店
|
// 默认总店
|
||||||
if (data.store_info) {
|
if (data.store_info) {
|
||||||
|
|||||||
Reference in New Issue
Block a user