diff --git a/custom-tab-bar/index.vue b/custom-tab-bar/index.vue index af0de6f..17864d3 100644 --- a/custom-tab-bar/index.vue +++ b/custom-tab-bar/index.vue @@ -70,6 +70,27 @@ export default { iconPath: '/static/tabbar/insight.png', selectedIconPath: '/static/tabbar/insight_active.png', }, + { + key: 'furniture_reception', + text: '接待', + pagePath: '/pages/furniture_reception/furniture_reception', + iconPath: '/static/tabbar/reception.png', + selectedIconPath: '/static/tabbar/reception_active.png', + }, + { + key: 'furniture_customer', + text: '客户', + pagePath: '/pages/furniture_customer/furniture_customer', + iconPath: '/static/tabbar/customer.png', + selectedIconPath: '/static/tabbar/customer_active.png', + }, + { + key: 'furniture_top_sales', + text: '销冠', + pagePath: '/pages/furniture_top_sales/furniture_top_sales', + iconPath: '/static/tabbar/insight.png', + selectedIconPath: '/static/tabbar/insight_active.png', + }, ], }; }, @@ -145,11 +166,40 @@ export default { return; } if (this.currentPath === item.pagePath) return; + + // uni.switchTab 需要相对路径(去掉前导斜杠) + const url = item.pagePath.startsWith('/') ? item.pagePath.substring(1) : item.pagePath; + uni.switchTab({ - url: item.pagePath, - complete: () => { + url: url, + success: () => { + console.log('[TabBar][switchTab] success:', url); this.updateActivePath(); }, + fail: (err) => { + console.error('[TabBar][switchTab] fail:', err, 'url:', url); + // 如果 switchTab 失败,尝试使用 reLaunch(适用于 tabBar 页面) + uni.reLaunch({ + url: url, + fail: (err2) => { + console.error('[TabBar][reLaunch] fail:', err2, 'url:', url); + uni.showToast({ + title: '页面跳转失败,请检查页面配置', + icon: 'none', + duration: 2000 + }); + }, + success: () => { + this.updateActivePath(); + } + }); + }, + complete: () => { + // 延迟更新,确保页面切换完成 + setTimeout(() => { + this.updateActivePath(); + }, 100); + }, }); }, handleExternalRefresh() { @@ -165,10 +215,18 @@ export default { const isStudent = roles.includes('speaking_training_students'); const isAdmin = roles.includes('admin'); const isMeetingAdmin = roles.includes('meeting_admin'); + const isAdminFurniture = roles.includes('admin_furniture'); // 会议相关的tab key列表 const meetingTabKeys = ['meeting_summary']; + // admin_furniture 角色:只显示家具相关的tab和ucenter + if (isAdminFurniture) { + const furnitureTabs = ['furniture_reception', 'furniture_customer', 'furniture_top_sales', 'ucenter']; + console.log('[TabBar][allowed] admin_furniture ->', furnitureTabs); + return furnitureTabs; + } + if (isMeetingAdmin) { // meeting_admin 角色:显示会议相关的tab和ucenter(我的) const meetingAdminTabs = [...meetingTabKeys, 'ucenter']; @@ -178,10 +236,10 @@ export default { // 非 meeting_admin 角色:排除所有会议相关的tab if (isAdmin) { - // admin 角色:显示所有tab(包括 ucenter),但排除会议相关的tab + // admin 角色:显示所有tab(包括 ucenter),但排除会议相关的tab和家具相关的tab const all = this.allTabs .map((t) => t.key) - .filter((key) => !meetingTabKeys.includes(key)); + .filter((key) => !meetingTabKeys.includes(key) && !['furniture_reception', 'furniture_customer', 'furniture_top_sales'].includes(key)); // 确保 ucenter 被包含(用于"我的"页面) console.log('[TabBar][allowed] admin ->', all, 'includes ucenter:', all.includes('ucenter')); return all; @@ -198,10 +256,10 @@ export default { return studentTabs; } - // 其他角色:隐藏作业/教务/语音/表达,同时排除会议相关的tab,但确保包含ucenter + // 其他角色:隐藏作业/教务/语音/表达,同时排除会议相关的tab和家具相关的tab,但确保包含ucenter const otherTabs = this.allTabs .map((t) => t.key) - .filter((key) => !['homework', 'edu', 'voice', 'expression', ...meetingTabKeys].includes(key)); + .filter((key) => !['homework', 'edu', 'voice', 'expression', 'furniture_reception', 'furniture_customer', 'furniture_top_sales', ...meetingTabKeys].includes(key)); // 确保 ucenter 被包含(任何角色都应该能看到"我的") if (!otherTabs.includes('ucenter')) { otherTabs.push('ucenter'); @@ -212,8 +270,8 @@ export default { // #ifdef H5 toggleNativeTabs() { // H5 平台自定义 tabbar 不生效,直接根据角色显隐原生 tabbar 项 - // 当前位置顺序:接待、客户、团队、销冠、工作台、我的、总结和统计 - const ORDER = ['reception', 'customer', 'team', 'champion', 'workspace', 'ucenter', 'meeting_summary']; + // 当前位置顺序:接待、客户、团队、销冠、工作台、我的、总结和统计、家具接待、家具客户、家具销冠 + const ORDER = ['reception', 'customer', 'team', 'champion', 'workspace', 'ucenter', 'meeting_summary', 'furniture_reception', 'furniture_customer', 'furniture_top_sales']; const allowed = this.getAllowedKeys(); // 限制重试次数,防止渲染时机未就绪 this._h5TabRetries = (this._h5TabRetries || 0) + 1; diff --git a/pages.json b/pages.json index 6e1534c..dde3568 100644 --- a/pages.json +++ b/pages.json @@ -172,6 +172,24 @@ "navigationStyle": "custom" } }, + { + "path": "pages/furniture_reception/furniture_reception", + "style": { + "navigationStyle": "custom" + } + }, + { + "path": "pages/furniture_customer/furniture_customer", + "style": { + "navigationStyle": "custom" + } + }, + { + "path": "pages/furniture_top_sales/furniture_top_sales", + "style": { + "navigationStyle": "custom" + } + }, { "path": "pages/meeting_prepare/meeting_prepare", "style": { @@ -435,6 +453,21 @@ "iconPath": "static/tabbar/insight.png", "selectedIconPath": "static/tabbar/insight_active.png", "text": "总结和统计" + }, { + "pagePath": "pages/furniture_reception/furniture_reception", + "iconPath": "static/tabbar/reception.png", + "selectedIconPath": "static/tabbar/reception_active.png", + "text": "接待" + }, { + "pagePath": "pages/furniture_customer/furniture_customer", + "iconPath": "static/tabbar/customer.png", + "selectedIconPath": "static/tabbar/customer_active.png", + "text": "客户" + }, { + "pagePath": "pages/furniture_top_sales/furniture_top_sales", + "iconPath": "static/tabbar/insight.png", + "selectedIconPath": "static/tabbar/insight_active.png", + "text": "销冠" }] }, "uniIdRouter": { diff --git a/pages/car_sales/prepare/prepare.vue b/pages/car_sales/prepare/prepare.vue index 026b1a0..33e02f4 100644 --- a/pages/car_sales/prepare/prepare.vue +++ b/pages/car_sales/prepare/prepare.vue @@ -74,3 +74,4 @@ + diff --git a/pages/car_sales/process/process.vue b/pages/car_sales/process/process.vue index 7ca1d00..040731a 100644 --- a/pages/car_sales/process/process.vue +++ b/pages/car_sales/process/process.vue @@ -74,3 +74,4 @@ + diff --git a/pages/car_sales/summary/summary.vue b/pages/car_sales/summary/summary.vue index b71aef5..2849881 100644 --- a/pages/car_sales/summary/summary.vue +++ b/pages/car_sales/summary/summary.vue @@ -74,3 +74,4 @@ + diff --git a/pages/furniture_customer/components/ConversationSummaryFurniture.vue b/pages/furniture_customer/components/ConversationSummaryFurniture.vue new file mode 100644 index 0000000..ff15c2a --- /dev/null +++ b/pages/furniture_customer/components/ConversationSummaryFurniture.vue @@ -0,0 +1,755 @@ + + + + + \ No newline at end of file diff --git a/pages/furniture_customer/components/CustomerList.vue b/pages/furniture_customer/components/CustomerList.vue new file mode 100644 index 0000000..6c0ab92 --- /dev/null +++ b/pages/furniture_customer/components/CustomerList.vue @@ -0,0 +1,289 @@ + + + + + + diff --git a/pages/furniture_customer/components/CustomerProfileModal.vue b/pages/furniture_customer/components/CustomerProfileModal.vue new file mode 100644 index 0000000..d69b4a7 --- /dev/null +++ b/pages/furniture_customer/components/CustomerProfileModal.vue @@ -0,0 +1,368 @@ + + + + + + diff --git a/pages/furniture_customer/components/ServiceList.vue b/pages/furniture_customer/components/ServiceList.vue new file mode 100644 index 0000000..22a36c1 --- /dev/null +++ b/pages/furniture_customer/components/ServiceList.vue @@ -0,0 +1,420 @@ + + + + + + diff --git a/pages/furniture_customer/furniture_customer.vue b/pages/furniture_customer/furniture_customer.vue new file mode 100644 index 0000000..3c1d267 --- /dev/null +++ b/pages/furniture_customer/furniture_customer.vue @@ -0,0 +1,3495 @@ + + + + + + diff --git a/pages/furniture_customer/utils/dataInit.js b/pages/furniture_customer/utils/dataInit.js new file mode 100644 index 0000000..735f053 --- /dev/null +++ b/pages/furniture_customer/utils/dataInit.js @@ -0,0 +1,190 @@ +// 客户档案数据初始化 +export function initCustomerProfile(item) { + if (item.name === '李女士') { + return { + name: '李女士', + intent: '高', + serviceCount: 1, + lastService: '2025-08-17', + phone: '185****3677', + serviceStaff: '三多', + wechatStatus: '已添加', + address: '江融府', + source: '自然到店', + followStage: '意向客户', + systemTags: [ + '新房装修', + '客厅,卧室', + '沙发,餐桌,床,床垫', + '关注环保', + '预算4万-5万', + '价格敏感度中', + '与孩同住子女幼年', + '现代简约', + '80m²-120m²', + '关注儿童安全设计', + '关注售后服务' + ], + customTags: [ + '关注优惠活动', + '关注颜色搭配', + '夫妻两一起来' + ], + intentDescription: '客户是一对即将入住新房的三口之家,注重家具的环保性与实用性,偏好简约现代风格、灰白色系、耐脏易打理的材质。对布艺沙发、岩板餐桌椅、真皮软包床、乳胶床垫及护脊床垫表现出兴趣。客户对价格较为敏感,关注年终活动优惠,并与竞品进行过对比。客户最终表现出较高购买意向,已同意加微信进一步沟通方案,并考虑本周下单。' + }; + } else if (item.name === '彭总') { + return { + name: '彭总', + intent: '高', + serviceCount: 3, + lastService: '2526-09-16', + phone: '', + serviceStaff: '沈易', + wechatStatus: '已添加', + address: '', + source: '', + followStage: '意向客户', + systemTags: [ + '新房装修', + '餐厅,客厅,卧室,定制', + '沙发,床,床垫,茶几,餐桌', + '关注产品颜值' + ], + customTags: [], + intentDescription: '客户为四层别墅新房装修,关注真皮、高脚、舒适靠背的床和沙发,偏好灰色和咖啡色系,倾向于购买整屋套餐以获得更大折扣,决策期预计在12月前。' + }; + } else { + // 默认数据 + return { + name: item.name, + intent: item.intent, + serviceCount: item.serviceCount, + lastService: item.lastService, + phone: item.phone || '', + serviceStaff: item.serviceStaff, + wechatStatus: '未添加', + address: '', + source: '', + followStage: '意向客户', + systemTags: item.tags ? item.tags.filter(t => t.color === 'blue').map(t => t.text) : [], + customTags: item.tags ? item.tags.filter(t => t.color === 'orange').map(t => t.text) : [], + intentDescription: '' + }; + } +} + +// 服务记录总结列表初始化 +export function initSummaryList(item) { + if (item.title === '三多的服务记录') { + return [ + { + label: '客户类型', + value: '新房装修' + }, + { + label: '家庭结构', + value: '三口之家, 有一个5岁的小孩, 注重家具安全性与环保性' + }, + { + label: '意向产品清单', + value: '沙发,床,床垫,餐桌椅,定制家居' + }, + { + label: '一句话总结', + value: '三口之家新房装修, 偏好简约现代风格, 注重环保与安全性, 对整套搭配和交付周期敏感, 预算约4.5万, 关注活动优惠与售后服务' + }, + { + label: '成交关键点', + value: '年终活动优惠, 整套搭配, 环保安全, 快速交付, 无忧退换服务' + } + ]; + } else { + return [ + { + label: '客户类型', + value: item.description + }, + { + label: '一句话总结', + value: item.description + } + ]; + } +} + +// 服务表现数据初始化 +export function initPerformanceData() { + return { + totalScore: 81, + categories: [ + { + name: '迎宾探寻', + completed: false, + expanded: true, + showBanner: false, + showAudio: false, + items: [ + { name: '破冰', completed: false, points: 5 }, + { name: '品牌介绍', completed: false, points: 5 } + ] + }, + { + name: '展厅体验', + completed: true, + expanded: true, + showBanner: false, + showAudio: false, + items: [ + { name: '黄金三问', completed: true, points: 9 }, + { name: '需求引导', completed: true, points: 15 } + ] + }, + { + name: '落座规划', + completed: true, + expanded: true, + showBanner: false, + showAudio: false, + items: [ + { name: '服务递进', completed: true, points: 5 }, + { name: 'SGS放心手册', completed: false, points: 5 } + ] + }, + { + name: '方案报价', + completed: true, + expanded: true, + showBanner: false, + showAudio: false, + items: [ + { name: '三级报价', completed: true, points: 20 } + ] + }, + { + name: '促单成交', + completed: true, + expanded: true, + showBanner: false, + showAudio: false, + items: [ + { name: '解答异议', completed: true, points: 6 } + ] + }, + { + name: '送客跟进', + completed: true, + expanded: true, + showBanner: false, + showAudio: false, + items: [ + { name: '活动植入', completed: true, points: 8 }, + { name: '压单配合', completed: true, points: 6 }, + { name: '主动添加微信', completed: true, points: 4 }, + { name: '邀约量尺时间', completed: false, points: 4 }, + { name: '礼貌道别', completed: true, points: 2 } + ] + } + ] + }; +} + diff --git a/pages/furniture_reception/common_begin_reception.vue b/pages/furniture_reception/common_begin_reception.vue new file mode 100644 index 0000000..fe0356e --- /dev/null +++ b/pages/furniture_reception/common_begin_reception.vue @@ -0,0 +1,704 @@ + + + + + \ No newline at end of file diff --git a/pages/furniture_reception/furniture_reception.vue b/pages/furniture_reception/furniture_reception.vue new file mode 100644 index 0000000..ae18647 --- /dev/null +++ b/pages/furniture_reception/furniture_reception.vue @@ -0,0 +1,2106 @@ +