From a595ea8fa17dd0dbdfb607abea93e8c0d24b13a8 Mon Sep 17 00:00:00 2001 From: malei <> Date: Sun, 2 Aug 2026 01:02:10 +0800 Subject: [PATCH] feat: add merchant onboarding and staff invite flow --- src/api/index.js | 21 +- src/pages.json | 1 + src/pages/login/Login.vue | 777 ++++++++++++---------------------- src/pages/mine/Mine.vue | 6 + src/pages/mine/Onboarding.vue | 175 ++++++++ src/pages/mine/Staff.vue | 566 ++++++++++--------------- src/utils/globalState.js | 1 + 7 files changed, 692 insertions(+), 855 deletions(-) create mode 100644 src/pages/mine/Onboarding.vue diff --git a/src/api/index.js b/src/api/index.js index 253d5dd..4db4685 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -59,11 +59,21 @@ export const login = (phone, code) => post('/user/login', { phone, code }) export const wxPhoneLogin = (phoneCode, loginCode) => post('/user/wx-phone-login', { phoneCode, loginCode: loginCode || '' }) -// 注册老板 -export const registerBoss = (data) => post('/user/register-boss', data) +// 微信核验手机号后创建门店与老板账号(不接收明文密码或手填手机号) +export const registerBoss = (data) => post('/onboarding/register-boss', data) -// 注册员工 -export const registerStaff = (data) => post('/user/register-staff', data) +// 门店开通清单 +export const getOnboardingStatus = () => get('/admin/onboarding', {}) +export const completeOnboarding = () => post('/admin/onboarding/complete', {}) + +// 员工邀请:预览/接受为公开接口;创建/列表/撤销仅老板 +export const previewStaffInvitation = (token) => get('/staff-invitations/preview', { token }) +export const acceptStaffInvitation = (token, phoneCode, loginCode) => + post('/staff-invitations/accept', { token, phoneCode, loginCode: loginCode || '' }) +export const getStaffInvitations = () => get('/admin/staff-invitations', {}) +export const createStaffInvitation = (data) => post('/admin/staff-invitations', data) +export const revokeStaffInvitation = (invitationId) => + del(`/admin/staff-invitations?invitationId=${encodeURIComponent(invitationId)}`) // 宠物档案(身份由后端从 session token 派生;保留旧签名兼容,不再传 ownerUserId/storeId 给后端) export const getPetList = (/* params */) => get('/pet/list', {}) @@ -161,9 +171,6 @@ export const deleteServiceType = (id) => del(`/service-type/delete?id=${id}`) // 员工列表(storeId 由后端从上下文派生;保留旧签名兼容) export const getStaffList = (/* storeId */) => get('/user/staff-list', {}) -// 添加员工(storeId 由后端从上下文派生) -export const createStaff = (data) => post('/user/create-staff', data) - // 删除员工 export const deleteStaff = (staffId) => del(`/user/staff?staffId=${staffId}`) diff --git a/src/pages.json b/src/pages.json index 688f7ed..436afe5 100644 --- a/src/pages.json +++ b/src/pages.json @@ -6,6 +6,7 @@ {"path": "pages/appointment/CustAppointmentCreate"}, {"path": "pages/report/Report"}, {"path": "pages/mine/Mine"}, + {"path": "pages/mine/Onboarding"}, {"path": "pages/mine/Staff"}, {"path": "pages/mine/ServiceType"}, {"path": "pages/mine/Store"}, diff --git a/src/pages/login/Login.vue b/src/pages/login/Login.vue index 07fc3da..7affa30 100644 --- a/src/pages/login/Login.vue +++ b/src/pages/login/Login.vue @@ -5,610 +5,359 @@ 用心宠小它,温暖伴一生 - 登录 - + - + - - - - - + - + - + - 员工注册 - + 员工受邀加入 + 商家入驻 - - 商家入驻 - - + 创建门店 + 手机号必须由微信核验;创建后继续补全门店资料、预约容量和服务项目。 + + + - - - - + - + - - - - - - ✓ 微信已认证手机号 - - - ← 返回登录 + ← 返回登录 - - - 员工注册 - 请输入店长提供的邀请码加入团队 - - - - - - + + 接受员工邀请 + 粘贴老板发来的邀请口令,或直接从邀请卡片进入。 + + + + + + 受邀门店 + {{ invitation.storeName }} + 受邀员工{{ invitation.invitedName }} + 核验手机号{{ invitation.maskedPhone }} + 有效期至{{ formatDate(invitation.expiresAt) }} + {{ invitationStatus }} + + + + - + 请在微信小程序内完成手机号核验与加入。 - - - - - - ✓ 微信已认证手机号 - - - ← 返回登录 + + ← 返回登录 diff --git a/src/pages/mine/Mine.vue b/src/pages/mine/Mine.vue index cae1a16..848679a 100644 --- a/src/pages/mine/Mine.vue +++ b/src/pages/mine/Mine.vue @@ -19,6 +19,11 @@ 店铺与经营 + + + 门店开通清单 + + 服务类型 @@ -115,6 +120,7 @@ const userInfo = getUserSession() const { goPage, openAppPage } = useNavigator() const goStaffPage = () => uni.navigateTo({ url: '/pages/mine/Staff' }) +const goOnboardingPage = () => uni.navigateTo({ url: '/pages/mine/Onboarding' }) const goServiceTypePage = () => uni.navigateTo({ url: '/pages/mine/ServiceType' }) const goStorePage = () => uni.navigateTo({ url: '/pages/mine/Store' }) const goSchedulePage = () => uni.navigateTo({ url: '/pages/mine/Schedule' }) diff --git a/src/pages/mine/Onboarding.vue b/src/pages/mine/Onboarding.vue new file mode 100644 index 0000000..e2c5118 --- /dev/null +++ b/src/pages/mine/Onboarding.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/src/pages/mine/Staff.vue b/src/pages/mine/Staff.vue index b714838..5c8d929 100644 --- a/src/pages/mine/Staff.vue +++ b/src/pages/mine/Staff.vue @@ -1,86 +1,89 @@ diff --git a/src/utils/globalState.js b/src/utils/globalState.js index fa2a2d4..63e22a0 100644 --- a/src/utils/globalState.js +++ b/src/utils/globalState.js @@ -8,6 +8,7 @@ const ROOT_ROUTE_MAP = { const SUB_ROUTE_MAP = { staff: '/pages/mine/Staff', + onboarding: '/pages/mine/Onboarding', serviceType: '/pages/mine/ServiceType', store: '/pages/mine/Store', profile: '/pages/mine/Profile',