小程序迁移 静态页面完成!!!

This commit is contained in:
Neo
2026-03-18 05:14:35 +08:00
parent 72bb11b34f
commit 075caf067f
124 changed files with 10407 additions and 2738 deletions

View File

@@ -1,20 +1,16 @@
import { mockCustomers, mockCustomerDetail } from '../../utils/mock-data'
import type { CustomerDetail } from '../../utils/mock-data'
import { mockCustomerDetail } from "../../utils/mock-data"
/** 消费记录(三种样式) */
interface ConsumptionRecordV2 {
interface ConsumptionRecord {
id: string
type: 'table' | 'shop' | 'recharge'
type: "table" | "shop" | "recharge"
date: string
// 台桌结账
tableName?: string
startTime?: string
endTime?: string
duration?: string
tableFee?: number
tableOrigPrice?: number
// 助教
coaches?: {
coaches?: Array<{
name: string
level: string
levelColor: string
@@ -22,33 +18,29 @@ interface ConsumptionRecordV2 {
hours: string
perfHours?: string
fee: number
}[]
// 食品酒水
}>
foodAmount?: number
foodOrigPrice?: number
// 总金额
totalAmount?: number
totalOrigPrice?: number
// 充值
payMethod?: string
rechargeAmount?: number
}
/** mock 消费记录(三种样式) */
const mockConsumptionRecords: ConsumptionRecordV2[] = [
const mockRecords: ConsumptionRecord[] = [
{
id: 'r1',
type: 'table',
date: '2026-02-05',
tableName: 'A12号台',
startTime: '21:30',
endTime: '00:50',
duration: '3h20min',
id: "r1",
type: "table",
date: "2026-02-05",
tableName: "A12号台",
startTime: "21:30",
endTime: "00:50",
duration: "3h 20min",
tableFee: 180,
tableOrigPrice: 240,
coaches: [
{ name: '小燕', level: '高级', levelColor: 'pink', courseType: '基础课', hours: '2.5h', fee: 200 },
{ name: 'Lucy', level: '初级', levelColor: 'green', courseType: '激励课', hours: '0.5h', perfHours: '1h', fee: 50 },
{ name: "小燕", level: "senior", levelColor: "pink", courseType: "基础课", hours: "2.5h", fee: 200 },
{ name: "Amy", level: "junior", levelColor: "green", courseType: "激励课", hours: "0.5h", perfHours: "1h", fee: 50 },
],
foodAmount: 210,
foodOrigPrice: 260,
@@ -56,230 +48,250 @@ const mockConsumptionRecords: ConsumptionRecordV2[] = [
totalOrigPrice: 750,
},
{
id: 'r2',
type: 'table',
date: '2026-02-01',
tableName: '888号台',
startTime: '14:00',
endTime: '16:00',
duration: '2h00min',
id: "r2",
type: "table",
date: "2026-02-01",
tableName: "888号台",
startTime: "14:00",
endTime: "16:00",
duration: "2h 00min",
tableFee: 120,
coaches: [
{ name: '泡芙', level: '中级', levelColor: 'purple', courseType: '激励课', hours: '1.5h', perfHours: '2h', fee: 100 },
{ name: "泡芙", level: "middle", levelColor: "purple", courseType: "激励课", hours: "1.5h", perfHours: "2h", fee: 100 },
],
totalAmount: 220,
},
{
id: 'r3',
type: 'shop',
date: '2026-01-28',
id: "r3",
type: "shop",
date: "2026-01-28",
coaches: [
{ name: '小燕', level: '高级', levelColor: 'pink', courseType: '基础课', hours: '1h', fee: 100 },
{ name: "小燕", level: "senior", levelColor: "pink", courseType: "基础课", hours: "1h", fee: 100 },
],
foodAmount: 180,
totalAmount: 280,
},
{
id: 'r4',
type: 'recharge',
date: '2026-01-20',
payMethod: '微信支付',
rechargeAmount: 5000,
},
]
Page({
data: {
/** 页面状态 */
pageState: 'loading' as 'loading' | 'empty' | 'error' | 'normal',
/** 客户 ID */
customerId: '',
/** 客户详情 */
detail: null as CustomerDetail | null,
/** 消费记录(三种样式) */
consumptionRecords: [] as ConsumptionRecordV2[],
/** 是否正在加载更多 */
loadingMore: false,
/** 是否还有更多记录 */
hasMoreRecords: true,
/** 备注弹窗 */
noteModalVisible: false,
/** AI 洞察 */
pageState: "loading" as "loading" | "empty" | "error" | "normal",
detail: {
id: "cust_001",
name: "王先生",
avatarChar: "王",
phone: "13812345678",
balance: "8,600",
consumption60d: "2,800",
idealInterval: "7天",
daysSinceVisit: "12天",
},
phoneVisible: false,
aiColor: "indigo" as "red" | "orange" | "yellow" | "blue" | "indigo" | "purple",
aiInsight: {
summary: '高价值 VIP 客户,月均到店 4-5 次,偏好夜场中式台球,近期对斯诺克产生兴趣。社交属性强,常带固定球搭子,有拉新能力。储值余额充足,对促销活动响应积极。',
summary: "高价值 VIP 客户,月均到店 4-5 次,偏好夜场中式台球,近期对斯诺克产生兴趣。社交属性强,常带固定球搭子,有拉新能力。储值余额充足,对促销活动响应积极。",
strategies: [
{ color: 'green', text: '最后到店距今 12 天,超出理想间隔 7 天,建议尽快安排助教主动联系召回' },
{ color: 'amber', text: '客户提到想练斯诺克走位,可推荐斯诺克专项课程包,结合储值优惠提升客单价' },
{ color: 'pink', text: '社交属性强,可邀请参加门店球友赛事活动,带动球搭子到店消费' },
{ color: "green", text: "最后到店距今 12 天,超出理想间隔 7 天,建议尽快安排助教小燕主动联系召回" },
{ color: "amber", text: "客户提到想练斯诺克走位,可推荐斯诺克专项课程包,结合储值优惠提升客单价" },
{ color: "pink", text: "社交属性强,可邀请参加门店球友赛事活动,带动球搭子到店消费" },
],
},
/** 维客线索 */
clues: [
{ category: '客户\n基础', categoryColor: 'primary', text: '🎂 生日 3月15日 · VIP会员 · 注册2年', source: '系统' },
{ category: '消费\n习惯', categoryColor: 'success', text: '🌙 常来夜场 · 月均4-5次', source: '系统' },
{ category: '消费\n习惯', categoryColor: 'success', text: '💰 高客单价', source: '系统', detail: '近60天场均消费 ¥420高于门店均值 ¥180偏好夜场时段酒水附加消费占比 35%' },
{ category: '玩法\n偏好', categoryColor: 'purple', text: '🎱 偏爱中式 · 斯诺克进阶中', source: '系统' },
{ category: '促销\n接受', categoryColor: 'warning', text: '🍷 爱点酒水套餐 · 对储值活动敏感', source: '系统', detail: '最近3次到店均点了酒水套餐上次 ¥5000 储值活动当天即充值,对满赠类活动响应率高' },
{ category: '社交\n关系', categoryColor: 'pink', text: '👥 常带朋友 · 固定球搭子2人', source: '系统', detail: '近60天 80% 的到店为多人局常与「李哥」「阿杰」同行曾介绍2位新客办卡' },
{ category: '重要\n反馈', categoryColor: 'error', text: '⚠️ 上次提到想练斯诺克走位对球桌维护质量比较在意建议优先安排VIP房', source: '小燕' },
{
category: "客户\n基础",
categoryColor: "primary",
text: "🎂 生日 3月15日 · VIP会员 · 注册2年",
source: "系统",
},
{
category: "消费\n习惯",
categoryColor: "success",
text: "🌙 常来夜场 · 月均4-5次",
source: "系统",
},
{
category: "消费\n习惯",
categoryColor: "success",
text: "💰 高客单价",
source: "系统",
detail: "近60天场均消费 ¥420高于门店均值 ¥180偏好夜场时段酒水附加消费占比 35%",
},
{
category: "玩法\n偏好",
categoryColor: "purple",
text: "🎱 偏爱中式 · 斯诺克进阶中",
source: "系统",
},
{
category: "促销\n接受",
categoryColor: "warning",
text: "🍷 爱点酒水套餐 · 对储值活动敏感",
source: "系统",
detail: "最近3次到店均点了酒水套餐上次 ¥5000 储值活动当天即充值,对满赠类活动响应率高",
},
{
category: "社交\n关系",
categoryColor: "pink",
text: "👥 常带朋友 · 固定球搭子2人",
source: "系统",
detail: "近60天 80% 的到店为多人局常与「李哥」「阿杰」同行曾介绍2位新客办卡",
},
{
category: "重要\n反馈",
categoryColor: "error",
text: "⚠️ 上次提到想练斯诺克走位对球桌维护质量比较在意建议优先安排VIP房",
source: "小燕",
},
],
/** Banner 统计 */
bannerStats: {
balance: '¥8,600',
spend60d: '¥2,800',
idealInterval: '7天',
daysSinceVisit: '12天',
},
/** 助教任务 */
coachTasks: [
{
name: '小燕',
level: '高级助教',
levelColor: 'pink',
taskType: '高优先召回',
taskColor: 'red',
lastService: '02-20 21:30 · 2.5h',
bgClass: 'coach-card-red',
name: "小燕",
level: "senior",
levelColor: "pink",
taskType: "高优先召回",
taskColor: "red",
bgClass: "coach-card-red",
status: "normal",
lastService: "02-20 21:30 · 2.5h",
metrics: [
{ label: '近60天次数', value: '18次', color: 'primary' },
{ label: '总时长', value: '17h', color: '' },
{ label: '次均时长', value: '0.9h', color: 'warning' },
{ label: "近60天次数", value: "18次", color: "primary" },
{ label: "总时长", value: "17h" },
{ label: "次均时长", value: "0.9h", color: "warning" },
],
},
{
name: '泡芙',
level: '中级助教',
levelColor: 'purple',
taskType: '关系构建',
taskColor: 'pink',
lastService: '02-15 14:00 · 1.5h',
bgClass: 'coach-card-pink',
name: "泡芙",
level: "middle",
levelColor: "purple",
taskType: "优先召回",
taskColor: "orange",
bgClass: "coach-card-orange",
status: "pinned",
lastService: "02-15 14:00 · 1.5h",
metrics: [
{ label: '近60天次数', value: '12次', color: 'primary' },
{ label: '总时长', value: '11h', color: '' },
{ label: '次均时长', value: '0.9h', color: 'warning' },
{ label: "近60天次数", value: "12次", color: "primary" },
{ label: "总时长", value: "11h" },
{ label: "次均时长", value: "0.9h", color: "warning" },
],
},
{
name: "Amy",
level: "junior",
levelColor: "green",
taskType: "关系构建",
taskColor: "pink",
bgClass: "coach-card-pink",
status: "normal",
lastService: "02-10 19:00 · 1.0h",
metrics: [
{ label: "近60天次数", value: "8次", color: "primary" },
{ label: "总时长", value: "6h" },
{ label: "次均时长", value: "0.75h", color: "warning" },
],
},
{
name: "Lucy",
level: "senior",
levelColor: "pink",
taskType: "客户回访",
taskColor: "teal",
bgClass: "coach-card-teal",
status: "abandoned",
lastService: "01-28 20:30 · 2.0h",
metrics: [
{ label: "近60天次数", value: "6次", color: "primary" },
{ label: "总时长", value: "9h" },
{ label: "次均时长", value: "1.5h", color: "warning" },
],
},
],
/** 最喜欢的助教 */
favoriteCoaches: [
{
name: '小燕',
emoji: '❤️',
relationIndex: '0.92',
indexColor: 'success',
bgClass: 'fav-card-pink',
emoji: "❤️",
name: "小燕",
relationIndex: "9.2",
indexColor: "success",
bgClass: "fav-card-pink",
stats: [
{ label: '基础', value: '12h', color: 'primary' },
{ label: '激励', value: '5h', color: 'warning' },
{ label: '上课', value: '18次', color: '' },
{ label: '充值', value: '¥5,000', color: 'success' },
{ label: "基础", value: "12h", color: "primary" },
{ label: "激励", value: "5h", color: "warning" },
{ label: "上课", value: "18次" },
{ label: "充值", value: "¥5,000", color: "success" },
],
},
{
name: '泡芙',
emoji: '💛',
relationIndex: '0.78',
indexColor: 'warning',
bgClass: 'fav-card-amber',
emoji: "💛",
name: "泡芙",
relationIndex: "7.8",
indexColor: "warning",
bgClass: "fav-card-amber",
stats: [
{ label: '基础', value: '8h', color: 'primary' },
{ label: '激励', value: '3h', color: 'warning' },
{ label: '上课', value: '12次', color: '' },
{ label: '充值', value: '¥3,000', color: 'success' },
{ label: "基础", value: "8h", color: "primary" },
{ label: "激励", value: "3h", color: "warning" },
{ label: "上课", value: "12次" },
{ label: "充值", value: "¥3,000", color: "success" },
],
},
],
consumptionRecords: mockRecords,
loadingMore: false,
noteModalVisible: false,
sortedNotes: [
{ id: 'n1', tagLabel: '管理员', createdAt: '2026-03-05 14:30', content: '本月到店积极,对斯诺克课程感兴趣,建议持续跟进推荐相关课程包' },
{ id: 'n2', tagLabel: '小燕', createdAt: '2026-02-20 16:45', content: '客户反馈服务态度很好,提到下次想带朋友一起来' },
{ id: 'n3', tagLabel: '管理员', createdAt: '2026-02-10 10:00', content: '上次储值活动当天即充值 ¥5000对满赠类活动响应积极' },
] as Array<{ id: string; tagLabel: string; createdAt: string; content: string }>,
},
onLoad(options) {
const id = options?.id || ''
this.setData({ customerId: id })
this.loadData(id)
onLoad(options: any) {
// 随机 AI 配色
const aiColors = ['red', 'orange', 'yellow', 'blue', 'indigo', 'purple'] as const
const aiColor = aiColors[Math.floor(Math.random() * aiColors.length)]
this.setData({ aiColor })
this.loadDetail()
},
loadData(id: string) {
this.setData({ pageState: 'loading' })
setTimeout(() => {
try {
// TODO: 替换为真实 API 调用
const customer = mockCustomers.find((c) => c.id === id)
const detail = customer
? { ...mockCustomerDetail, id: customer.id, name: customer.name, heartScore: customer.heartScore, tags: customer.tags }
: mockCustomerDetail
if (!detail) {
this.setData({ pageState: 'empty' })
return
}
this.setData({
pageState: 'normal',
detail,
consumptionRecords: mockConsumptionRecords,
hasMoreRecords: false,
})
} catch {
this.setData({ pageState: 'error' })
}
}, 500)
loadDetail() {
this.setData({ pageState: "normal" })
},
/** 重试 */
onRetry() {
this.loadData(this.data.customerId)
this.loadDetail()
},
/** 触底加载更多消费记录 */
onReachBottom() {
if (this.data.loadingMore || !this.data.hasMoreRecords) return
this.setData({ loadingMore: true })
// TODO: 真实 API 分页加载
setTimeout(() => {
this.setData({ loadingMore: false, hasMoreRecords: false })
}, 500)
/** 查看/隐藏手机号 */
onTogglePhone() {
this.setData({ phoneVisible: !this.data.phoneVisible })
},
/** 发起对话 */
onStartChat() {
const id = this.data.customerId || this.data.detail?.id || ''
wx.navigateTo({
url: `/pages/chat/chat?customerId=${id}`,
fail: () => wx.showToast({ title: '页面跳转失败', icon: 'none' }),
/** 复制手机号 */
onCopyPhone() {
const phone = this.data.detail.phone
wx.setClipboardData({
data: phone,
success: () => {
wx.showToast({ title: '手机号码已复制', icon: 'none' })
},
})
},
/** 添加备注 */
onViewServiceRecords() {
wx.navigateTo({ url: "/pages/customer-service-records/customer-service-records" })
},
onStartChat() {
wx.navigateTo({ url: "/pages/chat/chat" })
},
onAddNote() {
this.setData({ noteModalVisible: true })
},
/** 备注确认 */
onNoteConfirm(e: WechatMiniprogram.CustomEvent) {
onNoteConfirm(e: any) {
this.setData({ noteModalVisible: false })
const { content } = e.detail || {}
if (content) {
wx.showToast({ title: '备注已保存', icon: 'success' })
}
},
/** 备注取消 */
onNoteCancel() {
this.setData({ noteModalVisible: false })
},
/** 查看服务记录 */
onViewServiceRecords() {
const id = this.data.customerId || this.data.detail?.id || ''
wx.navigateTo({
url: `/pages/customer-service-records/customer-service-records?customerId=${id}`,
fail: () => wx.showToast({ title: '页面跳转失败', icon: 'none' }),
})
},
/** 返回 */
onBack() {
wx.navigateBack()
},
})