From 4983006317431ba90c0225980d8ebf2303eaa289 Mon Sep 17 00:00:00 2001 From: leiking <2570985092@qq.com> Date: Mon, 29 Jun 2026 10:54:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 24 + common/aiRules.js | 94 + common/demoOrders.js | 82 + common/mockData.js | 157 + common/orderRepo.js | 47 + components/AiFloat.vue | 51 + components/ProjectCard.vue | 96 + components/ProjectGridCard.vue | 87 + main.js | 22 + manifest.json | 24 + pages.json | 165 + pages/ai/chat.vue | 190 + pages/appointments/list.vue | 320 + pages/auth/login.vue | 108 + pages/booking/create.vue | 425 + pages/coupons/list.vue | 233 + pages/home/index.vue | 341 + pages/legal/privacy.vue | 37 + pages/legal/terms.vue | 37 + pages/member/index.vue | 256 + pages/messages/settings.vue | 79 + pages/order/confirm.vue | 339 + pages/orders/detail.vue | 255 + pages/orders/list.vue | 176 + pages/profile/skin.vue | 42 + pages/projects/detail.vue | 428 + pages/projects/list.vue | 111 + pages/records/list.vue | 286 + pages/store/detail.vue | 135 + pages/verify/code.vue | 208 + scripts/patch-mp-weixin-vendor.js | 35 + styles/global.scss | 60 + uni.scss | 11 + .../dev/.automator/mp-weixin/.automator.json | 0 .../.sourcemap/mp-weixin/common/main.js.map | 1 + .../mp-weixin/common/runtime.js.map | 1 + .../.sourcemap/mp-weixin/common/vendor.js.map | 1 + .../mp-weixin/components/AiFloat.js.map | 1 + .../mp-weixin/components/ProjectCard.js.map | 1 + .../components/ProjectGridCard.js.map | 1 + .../.sourcemap/mp-weixin/pages/ai/chat.js.map | 1 + .../mp-weixin/pages/appointments/list.js.map | 1 + .../mp-weixin/pages/auth/login.js.map | 1 + .../mp-weixin/pages/booking/create.js.map | 1 + .../mp-weixin/pages/coupons/list.js.map | 1 + .../mp-weixin/pages/home/index.js.map | 1 + .../mp-weixin/pages/legal/privacy.js.map | 1 + .../mp-weixin/pages/legal/terms.js.map | 1 + .../mp-weixin/pages/member/index.js.map | 1 + .../mp-weixin/pages/messages/settings.js.map | 1 + .../mp-weixin/pages/order/confirm.js.map | 1 + .../mp-weixin/pages/orders/detail.js.map | 1 + .../mp-weixin/pages/orders/list.js.map | 1 + .../mp-weixin/pages/profile/skin.js.map | 1 + .../mp-weixin/pages/projects/detail.js.map | 1 + .../mp-weixin/pages/projects/list.js.map | 1 + .../mp-weixin/pages/records/list.js.map | 1 + .../mp-weixin/pages/store/detail.js.map | 1 + .../mp-weixin/pages/verify/code.js.map | 1 + unpackage/dist/dev/mp-weixin/app.js | 4 + unpackage/dist/dev/mp-weixin/app.json | 57 + unpackage/dist/dev/mp-weixin/app.wxss | 3 + unpackage/dist/dev/mp-weixin/common/main.js | 174 + unpackage/dist/dev/mp-weixin/common/main.wxss | 49 + .../dist/dev/mp-weixin/common/runtime.js | 234 + unpackage/dist/dev/mp-weixin/common/vendor.js | 12384 ++++++++++++++++ .../dist/dev/mp-weixin/components/AiFloat.js | 184 + .../dev/mp-weixin/components/AiFloat.json | 4 + .../dev/mp-weixin/components/AiFloat.wxml | 1 + .../dev/mp-weixin/components/AiFloat.wxss | 30 + .../dev/mp-weixin/components/ProjectCard.js | 213 + .../dev/mp-weixin/components/ProjectCard.json | 4 + .../dev/mp-weixin/components/ProjectCard.wxml | 1 + .../dev/mp-weixin/components/ProjectCard.wxss | 48 + .../mp-weixin/components/ProjectGridCard.js | 199 + .../mp-weixin/components/ProjectGridCard.json | 4 + .../mp-weixin/components/ProjectGridCard.wxml | 1 + .../mp-weixin/components/ProjectGridCard.wxss | 51 + unpackage/dist/dev/mp-weixin/pages/ai/chat.js | 285 + .../dist/dev/mp-weixin/pages/ai/chat.json | 5 + .../dist/dev/mp-weixin/pages/ai/chat.wxml | 1 + .../dist/dev/mp-weixin/pages/ai/chat.wxss | 94 + .../dev/mp-weixin/pages/appointments/list.js | 401 + .../mp-weixin/pages/appointments/list.json | 7 + .../mp-weixin/pages/appointments/list.wxml | 1 + .../mp-weixin/pages/appointments/list.wxss | 72 + .../dist/dev/mp-weixin/pages/auth/login.js | 235 + .../dist/dev/mp-weixin/pages/auth/login.json | 5 + .../dist/dev/mp-weixin/pages/auth/login.wxml | 1 + .../dist/dev/mp-weixin/pages/auth/login.wxss | 54 + .../dev/mp-weixin/pages/booking/create.js | 365 + .../dev/mp-weixin/pages/booking/create.json | 7 + .../dev/mp-weixin/pages/booking/create.wxml | 1 + .../dev/mp-weixin/pages/booking/create.wxss | 155 + .../dist/dev/mp-weixin/pages/coupons/list.js | 340 + .../dev/mp-weixin/pages/coupons/list.json | 7 + .../dev/mp-weixin/pages/coupons/list.wxml | 1 + .../dev/mp-weixin/pages/coupons/list.wxss | 64 + .../dist/dev/mp-weixin/pages/home/index.js | 304 + .../dist/dev/mp-weixin/pages/home/index.json | 8 + .../dist/dev/mp-weixin/pages/home/index.wxml | 1 + .../dist/dev/mp-weixin/pages/home/index.wxss | 148 + .../dist/dev/mp-weixin/pages/legal/privacy.js | 188 + .../dev/mp-weixin/pages/legal/privacy.json | 7 + .../dev/mp-weixin/pages/legal/privacy.wxml | 1 + .../dev/mp-weixin/pages/legal/privacy.wxss | 12 + .../dist/dev/mp-weixin/pages/legal/terms.js | 188 + .../dist/dev/mp-weixin/pages/legal/terms.json | 7 + .../dist/dev/mp-weixin/pages/legal/terms.wxml | 1 + .../dist/dev/mp-weixin/pages/legal/terms.wxss | 12 + .../dist/dev/mp-weixin/pages/member/index.js | 254 + .../dev/mp-weixin/pages/member/index.json | 7 + .../dev/mp-weixin/pages/member/index.wxml | 1 + .../dev/mp-weixin/pages/member/index.wxss | 102 + .../dev/mp-weixin/pages/messages/settings.js | 213 + .../mp-weixin/pages/messages/settings.json | 7 + .../mp-weixin/pages/messages/settings.wxml | 1 + .../mp-weixin/pages/messages/settings.wxss | 20 + .../dist/dev/mp-weixin/pages/order/confirm.js | 379 + .../dev/mp-weixin/pages/order/confirm.json | 7 + .../dev/mp-weixin/pages/order/confirm.wxml | 1 + .../dev/mp-weixin/pages/order/confirm.wxss | 87 + .../dist/dev/mp-weixin/pages/orders/detail.js | 360 + .../dev/mp-weixin/pages/orders/detail.json | 7 + .../dev/mp-weixin/pages/orders/detail.wxml | 1 + .../dev/mp-weixin/pages/orders/detail.wxss | 67 + .../dist/dev/mp-weixin/pages/orders/list.js | 317 + .../dist/dev/mp-weixin/pages/orders/list.json | 5 + .../dist/dev/mp-weixin/pages/orders/list.wxml | 1 + .../dist/dev/mp-weixin/pages/orders/list.wxss | 78 + .../dist/dev/mp-weixin/pages/profile/skin.js | 188 + .../dev/mp-weixin/pages/profile/skin.json | 7 + .../dev/mp-weixin/pages/profile/skin.wxml | 1 + .../dev/mp-weixin/pages/profile/skin.wxss | 13 + .../dev/mp-weixin/pages/projects/detail.js | 398 + .../dev/mp-weixin/pages/projects/detail.json | 7 + .../dev/mp-weixin/pages/projects/detail.wxml | 1 + .../dev/mp-weixin/pages/projects/detail.wxss | 130 + .../dist/dev/mp-weixin/pages/projects/list.js | 230 + .../dev/mp-weixin/pages/projects/list.json | 8 + .../dev/mp-weixin/pages/projects/list.wxml | 1 + .../dev/mp-weixin/pages/projects/list.wxss | 45 + .../dist/dev/mp-weixin/pages/records/list.js | 363 + .../dev/mp-weixin/pages/records/list.json | 7 + .../dev/mp-weixin/pages/records/list.wxml | 1 + .../dev/mp-weixin/pages/records/list.wxss | 78 + .../dist/dev/mp-weixin/pages/store/detail.js | 208 + .../dev/mp-weixin/pages/store/detail.json | 7 + .../dev/mp-weixin/pages/store/detail.wxml | 1 + .../dev/mp-weixin/pages/store/detail.wxss | 62 + .../dist/dev/mp-weixin/pages/verify/code.js | 296 + .../dist/dev/mp-weixin/pages/verify/code.json | 7 + .../dist/dev/mp-weixin/pages/verify/code.wxml | 1 + .../dist/dev/mp-weixin/pages/verify/code.wxss | 49 + .../dist/dev/mp-weixin/project.config.json | 36 + vue.config.js | 18 + 156 files changed, 25687 insertions(+) create mode 100644 App.vue create mode 100644 common/aiRules.js create mode 100644 common/demoOrders.js create mode 100644 common/mockData.js create mode 100644 common/orderRepo.js create mode 100644 components/AiFloat.vue create mode 100644 components/ProjectCard.vue create mode 100644 components/ProjectGridCard.vue create mode 100644 main.js create mode 100644 manifest.json create mode 100644 pages.json create mode 100644 pages/ai/chat.vue create mode 100644 pages/appointments/list.vue create mode 100644 pages/auth/login.vue create mode 100644 pages/booking/create.vue create mode 100644 pages/coupons/list.vue create mode 100644 pages/home/index.vue create mode 100644 pages/legal/privacy.vue create mode 100644 pages/legal/terms.vue create mode 100644 pages/member/index.vue create mode 100644 pages/messages/settings.vue create mode 100644 pages/order/confirm.vue create mode 100644 pages/orders/detail.vue create mode 100644 pages/orders/list.vue create mode 100644 pages/profile/skin.vue create mode 100644 pages/projects/detail.vue create mode 100644 pages/projects/list.vue create mode 100644 pages/records/list.vue create mode 100644 pages/store/detail.vue create mode 100644 pages/verify/code.vue create mode 100644 scripts/patch-mp-weixin-vendor.js create mode 100644 styles/global.scss create mode 100644 uni.scss create mode 100644 unpackage/dist/dev/.automator/mp-weixin/.automator.json create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/common/main.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/common/runtime.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/common/vendor.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/components/AiFloat.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/components/ProjectCard.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/components/ProjectGridCard.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/ai/chat.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/appointments/list.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/auth/login.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/booking/create.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/coupons/list.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/home/index.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/legal/privacy.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/legal/terms.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/member/index.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/messages/settings.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/order/confirm.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/orders/detail.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/orders/list.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/profile/skin.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/projects/detail.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/projects/list.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/records/list.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/store/detail.js.map create mode 100644 unpackage/dist/dev/.sourcemap/mp-weixin/pages/verify/code.js.map create mode 100644 unpackage/dist/dev/mp-weixin/app.js create mode 100644 unpackage/dist/dev/mp-weixin/app.json create mode 100644 unpackage/dist/dev/mp-weixin/app.wxss create mode 100644 unpackage/dist/dev/mp-weixin/common/main.js create mode 100644 unpackage/dist/dev/mp-weixin/common/main.wxss create mode 100644 unpackage/dist/dev/mp-weixin/common/runtime.js create mode 100644 unpackage/dist/dev/mp-weixin/common/vendor.js create mode 100644 unpackage/dist/dev/mp-weixin/components/AiFloat.js create mode 100644 unpackage/dist/dev/mp-weixin/components/AiFloat.json create mode 100644 unpackage/dist/dev/mp-weixin/components/AiFloat.wxml create mode 100644 unpackage/dist/dev/mp-weixin/components/AiFloat.wxss create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectCard.js create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectCard.json create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectCard.wxml create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectCard.wxss create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectGridCard.js create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectGridCard.json create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectGridCard.wxml create mode 100644 unpackage/dist/dev/mp-weixin/components/ProjectGridCard.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/ai/chat.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/ai/chat.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/ai/chat.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/ai/chat.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/appointments/list.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/appointments/list.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/appointments/list.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/appointments/list.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/auth/login.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/auth/login.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/auth/login.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/auth/login.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/booking/create.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/booking/create.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/booking/create.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/booking/create.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/coupons/list.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/coupons/list.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/coupons/list.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/coupons/list.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/home/index.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/home/index.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/home/index.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/home/index.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/privacy.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/privacy.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/privacy.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/privacy.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/terms.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/terms.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/terms.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/legal/terms.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/member/index.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/member/index.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/member/index.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/member/index.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/messages/settings.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/messages/settings.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/messages/settings.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/messages/settings.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/order/confirm.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/order/confirm.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/order/confirm.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/order/confirm.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/detail.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/detail.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/detail.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/detail.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/list.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/list.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/list.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/orders/list.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/profile/skin.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/profile/skin.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/profile/skin.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/profile/skin.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/detail.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/detail.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/detail.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/detail.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/list.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/list.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/list.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/projects/list.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/records/list.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/records/list.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/records/list.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/records/list.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/store/detail.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/store/detail.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/store/detail.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/store/detail.wxss create mode 100644 unpackage/dist/dev/mp-weixin/pages/verify/code.js create mode 100644 unpackage/dist/dev/mp-weixin/pages/verify/code.json create mode 100644 unpackage/dist/dev/mp-weixin/pages/verify/code.wxml create mode 100644 unpackage/dist/dev/mp-weixin/pages/verify/code.wxss create mode 100644 unpackage/dist/dev/mp-weixin/project.config.json create mode 100644 vue.config.js diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..42859b2 --- /dev/null +++ b/App.vue @@ -0,0 +1,24 @@ + + + + diff --git a/common/aiRules.js b/common/aiRules.js new file mode 100644 index 0000000..9a13c8f --- /dev/null +++ b/common/aiRules.js @@ -0,0 +1,94 @@ +import { projects, technicians } from './mockData' + +const runtimeProjects = Array.isArray(projects) && projects.length ? projects : [] + +function normalize(s) { + return (s || '').toLowerCase().replace(/\s+/g, '') +} + +function findProjectByText(text) { + const t = normalize(text) + return runtimeProjects.find((p) => normalize(p.name).includes(t) || t.includes(normalize(p.name))) || null +} + +function pickPopularProject() { + return runtimeProjects[0] || null +} + +export function aiReply(userText) { + const t = normalize(userText) + + if (!t) { + return { + text: '你想预约哪个项目?也可以告诉我“预算/时长/肤质需求”,我给你推荐。', + action: null + } + } + + if (t.includes('你好') || t.includes('在吗') || t.includes('哈哈') || t.includes('天气') || t.includes('闲聊')) { + return { + text: '我在的~我可以帮你查项目价格、匹配适合人群/禁忌,并一键发起预约。你想做“补水/清洁/舒缓/肩颈放松”哪一类?', + action: null + } + } + + if (t.includes('档期') || t.includes('时间') || t.includes('几点') || t.includes('有空')) { + return { + text: '可选时段(示例):今天 14:30 / 16:00 / 19:00;明天 10:00 / 11:30 / 17:30。你想预约哪个日期和时段?', + action: null + } + } + + if (t.includes('价格') || t.includes('多少钱') || t.includes('价位')) { + const top = runtimeProjects.slice(0, 4).map((p) => `「${p.name}」¥${p.price}(${p.durationMin} 分钟)`).join(';') + return { + text: `参考价格(示例):${top}。你想预约哪一个?我可以直接帮你打开预约页面。`, + action: null + } + } + + if (t.includes('禁忌') || t.includes('不能做') || t.includes('适合吗')) { + return { + text: '可以的。你现在的肤质/是否敏感、近期是否做过医美项目?我会按禁忌与适配人群给你建议。', + action: null + } + } + + if (t.includes('推荐') || t.includes('爆款') || t.includes('适合')) { + const p = pickPopularProject() + return { + text: p + ? `推荐你先做「${p.name}」,${p.durationMin} 分钟,¥${p.price}。要我直接帮你发起预约吗?` + : '我可以按需求给你推荐。你更关注补水、清洁还是舒缓?', + action: p ? { type: 'suggest_project', projectId: p.id } : null + } + } + + if (t.includes('预约') || t.includes('下单') || t.includes('买') || t.includes('购买')) { + const p = findProjectByText(userText) || pickPopularProject() + if (p) { + return { + text: `好的,我先为你打开「${p.name}」的预约页面。你可以选择日期、时段和技师。`, + action: { type: 'go_booking', projectId: p.id } + } + } + return { + text: '好的。你想预约哪个项目?把项目名称发我即可。', + action: null + } + } + + if (t.includes('技师') || t.includes('老师')) { + const names = technicians.map((x) => x.name).join('、') + return { + text: `我们目前可选技师:${names}。你有偏好哪位?也可以选择系统自动分配。`, + action: null + } + } + + return { + text: '我明白了。你更想做“清洁/补水/舒缓/肩颈放松”哪一类?我可以直接给你项目并发起预约。', + action: null + } +} + diff --git a/common/demoOrders.js b/common/demoOrders.js new file mode 100644 index 0000000..78d43ab --- /dev/null +++ b/common/demoOrders.js @@ -0,0 +1,82 @@ +export const demoOrders = [ + { + id: 'ord_demo_booking_001', + createdAt: Date.now() - 2 * 24 * 60 * 60 * 1000, + status: '待核销', + amount: 99, + projectId: 'p1', + projectName: '水氧净透体验', + durationMin: 60, + orderType: 'booking', + appointmentDate: '2026-06-22', + appointmentSlot: '14:30', + technicianName: '系统分配', + note: '敏感肌,想要补水修护', + verifyCode: 'VC20260622001' + }, + { + id: 'ord_demo_coupon_001', + createdAt: Date.now() - 5 * 24 * 60 * 60 * 1000, + status: '待核销', + amount: 899, + projectId: 'p5', + projectName: '皮肤管理次卡 5 次', + durationMin: 60, + orderType: 'coupon', + couponTitle: '皮肤管理次卡 5 次', + couponPlanKey: 'times5', + couponPlanLabel: '次卡 5 次', + validText: '有效期 180 天', + remainingTimes: 5, + verifyCode: 'VC20260622002' + }, + { + id: 'ord_demo_booking_002', + createdAt: Date.now() - 12 * 24 * 60 * 60 * 1000, + status: '已完成', + amount: 188, + projectId: 'p4', + projectName: '肩颈舒缓筋膜放松', + durationMin: 60, + orderType: 'booking', + appointmentDate: '2026-06-10', + appointmentSlot: '19:00', + technicianName: '周晴', + note: '', + verifyCode: 'VC20260622003', + verifiedAt: Date.now() - 12 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000 + }, + { + id: 'ord_demo_coupon_002', + createdAt: Date.now() - 20 * 24 * 60 * 60 * 1000, + status: '已完成', + amount: 299, + projectId: 'p9', + projectName: '新客体验套餐 · 3 次', + durationMin: 60, + orderType: 'coupon', + couponTitle: '新客体验套餐 · 3 次', + couponPlanKey: 'package', + couponPlanLabel: '套餐', + validText: '有效期 90 天', + remainingTimes: 0, + verifyCode: 'VC20260622004' + }, + { + id: 'ord_demo_unpaid_001', + createdAt: Date.now() - 1 * 60 * 60 * 1000, + status: '待付款', + amount: 168, + projectId: 'p2', + projectName: '深层清洁黑头管理', + durationMin: 75, + orderType: 'coupon', + couponTitle: '深层清洁黑头管理', + couponPlanKey: 'single', + couponPlanLabel: '单次券', + validText: '有效期 30 天', + remainingTimes: 1, + verifyCode: 'VC20260622005' + } +] + diff --git a/common/mockData.js b/common/mockData.js new file mode 100644 index 0000000..642ea6e --- /dev/null +++ b/common/mockData.js @@ -0,0 +1,157 @@ +export const storeProfile = { + tenantId: 'tenant_demo_001', + storeId: 'store_demo_001', + name: '智约美服 · 旗舰店', + logo: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=minimal%20luxury%20logo%20mark%2C%20letters%20ZY%2C%20black%20and%20deep%20blue%20gradient%2C%20clean%20vector%20style%2C%20centered%2C%20white%20background%2C%20high%20resolution&image_size=square', + latitude: 31.230416, + longitude: 121.473701, + address: '上海市静安区南京西路 88 号', + phone: '021-00000000', + openHours: '10:00-22:00', + restDay: '每周一' +} + +export const technicians = [ + { id: 't1', name: '林安', title: '高级美容师', tags: ['敏感肌', '深层清洁'] }, + { id: 't2', name: '许言', title: '皮肤管理师', tags: ['补水', '焕肤'] }, + { id: 't3', name: '周晴', title: '美体塑形师', tags: ['肩颈', '淋巴'] } +] + +export const categories = [ + { id: 'c1', name: '体验爆款' }, + { id: 'c2', name: '面部护理' }, + { id: 'c3', name: '身体养生' }, + { id: 'c4', name: '美甲美睫' }, + { id: 'c5', name: '特惠套餐' } +] + +export const projects = [ + { + id: 'p1', + categoryId: 'c1', + name: '水氧净透体验', + price: 99, + originPrice: 199, + durationMin: 60, + fitFor: '初次体验、暗沉、出油', + taboo: '近期激光/微针术后 7 天内不建议', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=high-end%20beauty%20spa%20facial%20treatment%2C%20minimal%20modern%20interior%2C%20soft%20blue%20lighting%2C%20photorealistic%2C%2035mm%2C%20shallow%20depth%20of%20field%2C%20ultra%20detail&image_size=landscape_16_9', + desc: + '轻盈水氧 + 净透护理,适合快速提升肤感与通透度。' + }, + { + id: 'p2', + categoryId: 'c2', + name: '深层清洁黑头管理', + price: 168, + originPrice: 268, + durationMin: 75, + fitFor: 'T 区油脂旺盛、黑头粉刺', + taboo: '炎症爆痘期需评估后进行', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=professional%20esthetician%20performing%20deep%20cleansing%20facial%2C%20clean%20modern%20spa%2C%20soft%20neutral%20lighting%2C%20photorealistic%2C%20high%20detail%2C%2035mm&image_size=landscape_16_9', + desc: + '清洁、舒缓、收敛三步走,减少反复出油与毛孔困扰。' + }, + { + id: 'p3', + categoryId: 'c2', + name: '补水修护屏障护理', + price: 238, + originPrice: 368, + durationMin: 80, + fitFor: '敏感泛红、干燥紧绷', + taboo: '过敏急性期请先咨询', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=hydrating%20facial%20mask%20treatment%20in%20luxury%20spa%2C%20serene%20atmosphere%2C%20soft%20light%2C%20photorealistic%2C%20ultra%20detail%2C%2035mm&image_size=landscape_16_9', + desc: + '修护屏障与舒缓敏感,适合换季与长期干燥人群。' + }, + { + id: 'p4', + categoryId: 'c3', + name: '肩颈舒缓筋膜放松', + price: 188, + originPrice: 288, + durationMin: 60, + fitFor: '久坐办公、肩颈僵硬', + taboo: '急性损伤与发热期不建议', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=neck%20and%20shoulder%20massage%20in%20wellness%20spa%2C%20warm%20soft%20lighting%2C%20minimal%20luxury%20interior%2C%20photorealistic%2C%20high%20detail&image_size=landscape_16_9', + desc: + '深度放松肌群与筋膜,改善紧绷与酸胀。' + }, + { + id: 'p5', + categoryId: 'c5', + name: '皮肤管理次卡 5 次', + price: 899, + originPrice: 1199, + durationMin: 60, + fitFor: '长期管理、复购人群', + taboo: '具体项目以到店评估为准', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=premium%20skincare%20membership%20card%20concept%2C%20minimal%20luxury%2C%20black%20and%20blue%20gradient%2C%20studio%20lighting%2C%20photorealistic%2C%20high%20detail&image_size=landscape_16_9', + desc: + '灵活使用,随时预约,到店核销自动扣次。' + }, + { + id: 'p6', + categoryId: 'c4', + name: '轻奢美甲 · 单色', + price: 168, + originPrice: 238, + durationMin: 75, + fitFor: '通勤、日常、显白', + taboo: '甲面破损/感染需先处理', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=minimal%20luxury%20nail%20salon%2C%20single%20color%20manicure%2C%20clean%20hands%2C%20modern%20interior%2C%20photorealistic%2C%20high%20detail&image_size=landscape_16_9', + desc: + '干净利落的通勤单色,显白耐看,可按肤色搭配色卡。' + }, + { + id: 'p7', + categoryId: 'c4', + name: '自然单根美睫 · 清透款', + price: 198, + originPrice: 298, + durationMin: 90, + fitFor: '自然放大双眼、日常耐看', + taboo: '眼部炎症/过敏期不建议', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=natural%20eyelash%20extensions%20beauty%20studio%2C%20minimal%20luxury%2C%20soft%20lighting%2C%20photorealistic%2C%20high%20detail&image_size=landscape_16_9', + desc: + '清透自然的单根嫁接,整体更轻盈,适合新手与通勤。' + }, + { + id: 'p8', + categoryId: 'c3', + name: '全身精油舒压 · 90 分钟', + price: 298, + originPrice: 398, + durationMin: 90, + fitFor: '压力大、睡眠欠佳、疲劳', + taboo: '孕期/发热/急性炎症期不建议', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=full%20body%20aromatherapy%20massage%20in%20luxury%20spa%2C%20warm%20lighting%2C%20minimal%20interior%2C%20photorealistic%2C%20high%20detail&image_size=landscape_16_9', + desc: + '精油舒压与深度放松结合,帮助缓解疲劳与紧绷。' + }, + { + id: 'p9', + categoryId: 'c5', + name: '新客体验套餐 · 3 次', + price: 299, + originPrice: 499, + durationMin: 60, + fitFor: '初次体验、想要快速改善肤感', + taboo: '具体项目以到店评估为准', + cover: + 'https://coresg-normal.trae.ai/api/ide/v1/text_to_image?prompt=premium%20beauty%20spa%20package%20promotion%2C%20minimal%20luxury%2C%20black%20blue%20gradient%2C%20photorealistic%2C%20high%20detail&image_size=landscape_16_9', + desc: + '高性价比新客套餐,适合建立基础皮肤管理节奏。' + } +] + diff --git a/common/orderRepo.js b/common/orderRepo.js new file mode 100644 index 0000000..468f77e --- /dev/null +++ b/common/orderRepo.js @@ -0,0 +1,47 @@ +const STORAGE_KEY = 'zy_orders_v1' + +function readAll() { + return uni.getStorageSync(STORAGE_KEY) || [] +} + +function writeAll(list) { + uni.setStorageSync(STORAGE_KEY, list) +} + +export function listOrders() { + return readAll().sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0)) +} + +export function getOrderById(id) { + return readAll().find((x) => x.id === id) || null +} + +export function upsertOrder(order) { + const list = readAll() + const idx = list.findIndex((x) => x.id === order.id) + if (idx >= 0) list[idx] = order + else list.unshift(order) + writeAll(list) + return order +} + +export function patchOrder(id, patch) { + const list = readAll() + const idx = list.findIndex((x) => x.id === id) + if (idx < 0) return null + list[idx] = { ...list[idx], ...patch } + writeAll(list) + return list[idx] +} + +export function ensureSeedOrders() { + const list = readAll() + if (list.length) return + writeAll([]) +} + +export function createId(prefix) { + const s = `${Date.now()}${Math.floor(Math.random() * 1000)}` + return `${prefix}_${s}` +} + diff --git a/components/AiFloat.vue b/components/AiFloat.vue new file mode 100644 index 0000000..372c034 --- /dev/null +++ b/components/AiFloat.vue @@ -0,0 +1,51 @@ + + + + + + diff --git a/components/ProjectCard.vue b/components/ProjectCard.vue new file mode 100644 index 0000000..09b5834 --- /dev/null +++ b/components/ProjectCard.vue @@ -0,0 +1,96 @@ + + + + + + diff --git a/components/ProjectGridCard.vue b/components/ProjectGridCard.vue new file mode 100644 index 0000000..0b2055d --- /dev/null +++ b/components/ProjectGridCard.vue @@ -0,0 +1,87 @@ + + + + + + diff --git a/main.js b/main.js new file mode 100644 index 0000000..835d6bf --- /dev/null +++ b/main.js @@ -0,0 +1,22 @@ +import Vue from 'vue' +import App from './App.vue' + +export function createApp() { + Vue.config.productionTip = false + App.mpType = 'app' + if (!Vue.prototype.$mp) Vue.prototype.$mp = {} + if (!Vue.prototype.$mp.query) Vue.prototype.$mp.query = {} + Vue.mixin({ + beforeCreate() { + if (!this.$mp) this.$mp = {} + if (!this.$mp.query) this.$mp.query = {} + } + }) + const app = new Vue({ + ...App + }) + return { + app + } +} + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..d50f3f3 --- /dev/null +++ b/manifest.json @@ -0,0 +1,24 @@ +{ + "name": "智约美服-用户端原型", + "appid": "", + "description": "美业微信 AI 预约 & 项目购买小程序(用户端原型)", + "versionName": "0.1.0", + "versionCode": "0100", + "transformPx": false, + "mp-weixin": { + "appid": "", + "setting": { + "urlCheck": false, + "es6": true, + "postcss": true, + "minified": true + }, + "usingComponents": true, + "permission": { + "scope.userLocation": { + "desc": "用于展示附近门店与距离" + } + } + } +} + diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..bdb745e --- /dev/null +++ b/pages.json @@ -0,0 +1,165 @@ +{ + "pages": [ + { + "path": "pages/auth/login", + "style": { + "navigationBarTitleText": "智约美服", + "navigationStyle": "default" + } + }, + { + "path": "pages/home/index", + "style": { + "navigationBarTitleText": "智约美服", + "navigationStyle": "default" + } + }, + { + "path": "pages/projects/list", + "style": { + "navigationBarTitleText": "全部项目", + "navigationStyle": "default" + } + }, + { + "path": "pages/projects/detail", + "style": { + "navigationBarTitleText": "项目详情", + "navigationStyle": "default" + } + }, + { + "path": "pages/booking/create", + "style": { + "navigationBarTitleText": "预约服务", + "navigationStyle": "default" + } + }, + { + "path": "pages/order/confirm", + "style": { + "navigationBarTitleText": "确认订单", + "navigationStyle": "default" + } + }, + { + "path": "pages/orders/list", + "style": { + "navigationBarTitleText": "订单", + "navigationStyle": "default" + } + }, + { + "path": "pages/orders/detail", + "style": { + "navigationBarTitleText": "订单详情", + "navigationStyle": "default" + } + }, + { + "path": "pages/verify/code", + "style": { + "navigationBarTitleText": "我的核销码", + "navigationStyle": "default" + } + }, + { + "path": "pages/member/index", + "style": { + "navigationBarTitleText": "我的", + "navigationStyle": "default" + } + }, + { + "path": "pages/appointments/list", + "style": { + "navigationBarTitleText": "我的预约", + "navigationStyle": "default" + } + }, + { + "path": "pages/coupons/list", + "style": { + "navigationBarTitleText": "我的卡券", + "navigationStyle": "default" + } + }, + { + "path": "pages/records/list", + "style": { + "navigationBarTitleText": "消费记录", + "navigationStyle": "default" + } + }, + { + "path": "pages/store/detail", + "style": { + "navigationBarTitleText": "门店信息", + "navigationStyle": "default" + } + }, + { + "path": "pages/profile/skin", + "style": { + "navigationBarTitleText": "肤质档案", + "navigationStyle": "default" + } + }, + { + "path": "pages/messages/settings", + "style": { + "navigationBarTitleText": "消息提醒", + "navigationStyle": "default" + } + }, + { + "path": "pages/ai/chat", + "style": { + "navigationBarTitleText": "AI 智能客服", + "navigationStyle": "default" + } + }, + { + "path": "pages/legal/privacy", + "style": { + "navigationBarTitleText": "用户隐私协议", + "navigationStyle": "default" + } + }, + { + "path": "pages/legal/terms", + "style": { + "navigationBarTitleText": "服务协议", + "navigationStyle": "default" + } + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "智约美服", + "navigationBarBackgroundColor": "#FFFFFF", + "backgroundColor": "#F6F7FB", + "backgroundTextStyle": "light" + }, + "tabBar": { + "color": "#6B7280", + "selectedColor": "#111827", + "backgroundColor": "#FFFFFF", + "borderStyle": "black", + "list": [ + { + "pagePath": "pages/home/index", + "text": "首页" + }, + { + "pagePath": "pages/projects/list", + "text": "项目" + }, + { + "pagePath": "pages/member/index", + "text": "我的" + } + ] + } +} + diff --git a/pages/ai/chat.vue b/pages/ai/chat.vue new file mode 100644 index 0000000..3b1c9cc --- /dev/null +++ b/pages/ai/chat.vue @@ -0,0 +1,190 @@ + + + + + + diff --git a/pages/appointments/list.vue b/pages/appointments/list.vue new file mode 100644 index 0000000..22bd7d5 --- /dev/null +++ b/pages/appointments/list.vue @@ -0,0 +1,320 @@ + + + + + + diff --git a/pages/auth/login.vue b/pages/auth/login.vue new file mode 100644 index 0000000..031bf1d --- /dev/null +++ b/pages/auth/login.vue @@ -0,0 +1,108 @@ + + + + + + diff --git a/pages/booking/create.vue b/pages/booking/create.vue new file mode 100644 index 0000000..b779e0e --- /dev/null +++ b/pages/booking/create.vue @@ -0,0 +1,425 @@ +