From a9aefed4be426f631cba56d1ddaef3218962a43d Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 12 Dec 2025 16:13:04 +0800 Subject: [PATCH] Initial commit --- admin/client/src/router/index.js | 58 +++++++++----- ...c77zs92230c8a3602901b00dc40ae2fbdae26.jpeg | Bin 0 -> 2425 bytes wechat-mini-program/pages/coupon/coupon.js | 16 +++- wechat-mini-program/pages/coupon/coupon.wxml | 2 +- wechat-mini-program/pages/login/login.js | 71 ++---------------- wechat-mini-program/pages/login/login.wxml | 6 +- .../pages/profile/profile.wxml | 2 +- 7 files changed, 59 insertions(+), 96 deletions(-) create mode 100644 admin/server/media/2025/12/12/fQi6MP0c77zs92230c8a3602901b00dc40ae2fbdae26.jpeg diff --git a/admin/client/src/router/index.js b/admin/client/src/router/index.js index 51d12d1..25009e3 100644 --- a/admin/client/src/router/index.js +++ b/admin/client/src/router/index.js @@ -119,16 +119,46 @@ export const asyncRoutes = [ meta: { title: '教学中心', icon: 'user' } }, { - path: 'coupons', - name: 'Coupons', - component: () => import('@/views/crm/coupon'), - meta: { title: '优惠券管理', icon: 'money' } + path: 'users', + name: 'CrmUsers', + component: () => import('@/views/crm/index'), + redirect: '/crm/users/students', + meta: { title: '用户管理', icon: 'peoples' }, + children: [ + { + path: 'students', + name: 'Students', + component: () => import('@/views/crm/student'), + meta: { title: '学员管理', icon: 'peoples' } + }, + { + path: 'honors', + name: 'Honors', + component: () => import('@/views/crm/honor'), + meta: { title: '学员荣誉管理', icon: 'medal' } + } + ] }, { - path: 'issued-coupons', - name: 'IssuedCoupons', - component: () => import('@/views/crm/issued_coupon'), - meta: { title: '已发优惠券', icon: 'list' } + path: 'coupon-manage', + name: 'CouponManage', + component: () => import('@/views/crm/index'), + redirect: '/crm/coupon-manage/settings', + meta: { title: '优惠券管理', icon: 'money' }, + children: [ + { + path: 'settings', + name: 'Coupons', + component: () => import('@/views/crm/coupon'), + meta: { title: '优惠券设置', icon: 'money' } + }, + { + path: 'issued', + name: 'IssuedCoupons', + component: () => import('@/views/crm/issued_coupon'), + meta: { title: '已发优惠券', icon: 'list' } + } + ] }, { path: 'banners', @@ -136,18 +166,6 @@ export const asyncRoutes = [ component: () => import('@/views/crm/banner'), meta: { title: '轮播图管理', icon: 'drag' } }, - { - path: 'students', - name: 'Students', - component: () => import('@/views/crm/student'), - meta: { title: '学员管理', icon: 'peoples' } - }, - { - path: 'honors', - name: 'Honors', - component: () => import('@/views/crm/honor'), - meta: { title: '学员荣誉管理', icon: 'medal' } - }, { path: 'showcases', name: 'Showcases', diff --git a/admin/server/media/2025/12/12/fQi6MP0c77zs92230c8a3602901b00dc40ae2fbdae26.jpeg b/admin/server/media/2025/12/12/fQi6MP0c77zs92230c8a3602901b00dc40ae2fbdae26.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..f51743a23a058099b54fabf6d7e97f21b27e0b31 GIT binary patch literal 2425 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 I2*MfqD_a*-QUCw| literal 0 HcmV?d00001 diff --git a/wechat-mini-program/pages/coupon/coupon.js b/wechat-mini-program/pages/coupon/coupon.js index 3ccf00e..67a5951 100644 --- a/wechat-mini-program/pages/coupon/coupon.js +++ b/wechat-mini-program/pages/coupon/coupon.js @@ -3,12 +3,20 @@ const app = getApp() Page({ data: { coupons: [], - user: {} + user: {}, + loading: true }, onLoad() { this.fetchCoupons(); }, onShow() { + // Optimistically update from global data + if (app.globalData.userInfo && app.globalData.userInfo.phone) { + this.setData({ + user: app.globalData.userInfo, + loading: false + }); + } this.getUserInfo(); this.fetchCoupons(); }, @@ -19,12 +27,14 @@ Page({ // Fetch latest user info from backend to check if phone exists in DB request({ url: '/user/' }).then(user => { app.globalData.userInfo = user; // Sync global data - this.setData({ user: user }); + this.setData({ user: user, loading: false }); }).catch(err => { console.error('Failed to fetch user info', err) // Fallback to global data if fetch fails if (app.globalData.userInfo) { - this.setData({ user: app.globalData.userInfo }); + this.setData({ user: app.globalData.userInfo, loading: false }); + } else { + this.setData({ loading: false }); } }) }, diff --git a/wechat-mini-program/pages/coupon/coupon.wxml b/wechat-mini-program/pages/coupon/coupon.wxml index 8cc15a0..7812a26 100644 --- a/wechat-mini-program/pages/coupon/coupon.wxml +++ b/wechat-mini-program/pages/coupon/coupon.wxml @@ -4,7 +4,7 @@ - + VIP会员权益 开通会员享受更多优惠 diff --git a/wechat-mini-program/pages/login/login.js b/wechat-mini-program/pages/login/login.js index c8e9d52..b5ee00b 100644 --- a/wechat-mini-program/pages/login/login.js +++ b/wechat-mini-program/pages/login/login.js @@ -3,7 +3,6 @@ const { request } = require('../../utils/request') Page({ data: { - hasUserInfo: false, hasPhone: false }, onLoad() { @@ -24,16 +23,14 @@ Page({ // If we are here, user probably needs to authorize. // Update UI state - const hasNick = user.wechat_nickname && user.wechat_nickname !== '微信用户'; const hasPhone = !!user.phone; this.setData({ - hasUserInfo: hasNick, hasPhone: hasPhone }) // If somehow we ended up here but profile is full, go home - if (hasNick && hasPhone) { + if (hasPhone) { wx.switchTab({ url: '/pages/index/index' }) } } else { @@ -46,46 +43,6 @@ Page({ } } }, - getUserProfile(e) { - wx.getUserProfile({ - desc: '用于完善会员资料', - success: (res) => { - const { userInfo } = res - console.log('getUserProfile success', userInfo) - - // Update backend - // We need user ID from globalData - if (app.globalData.userInfo && app.globalData.userInfo.id) { - this.updateUserInfo(userInfo) - } else { - // Should not happen if app.js login succeeded - wx.showToast({ title: '登录状态异常,请重启', icon: 'none' }) - } - }, - fail: (err) => { - console.error('getUserProfile failed', err) - wx.showToast({ title: '需要授权才能继续', icon: 'none' }) - } - }) - }, - updateUserInfo(wxUserInfo) { - request({ - url: `/students/${app.globalData.userInfo.id}/`, - method: 'PATCH', - data: { - wechat_nickname: wxUserInfo.nickName, - avatar: wxUserInfo.avatarUrl - // name: wxUserInfo.nickName // Optional: sync name too - } - }).then(res => { - console.log('Update user info success', res) - app.globalData.userInfo = { ...app.globalData.userInfo, ...res } - this.setData({ hasUserInfo: true }) - }).catch(err => { - console.error('Update user info failed', err) - wx.showToast({ title: '更新资料失败', icon: 'none' }) - }) - }, getPhoneNumber(e) { console.log('getPhoneNumber', e) if (e.detail.errMsg === 'getPhoneNumber:ok') { @@ -98,34 +55,16 @@ Page({ }).then(res => { console.log('Get phone success', res) if (res.phone) { - this.setData({ hasPhone: true }) - if (app.globalData.userInfo) { - app.globalData.userInfo.phone = res.phone - } - - wx.showToast({ - title: '登录成功', - icon: 'success' - }) - - // Redirect to home - setTimeout(() => { - wx.switchTab({ url: '/pages/index/index' }) - }, 1500) + app.globalData.userInfo = { ...app.globalData.userInfo, ...res } + this.setData({ hasPhone: true }) + wx.switchTab({ url: '/pages/index/index' }) } }).catch(err => { console.error('Get phone failed', err) wx.showToast({ title: '获取手机号失败', icon: 'none' }) }) } else { - console.log('User denied phone number') - // If user denies, we can optionally let them in anyway if that's the requirement? - // User said: "If openID exists, direct login". - // This implies for NEW users, they MIGHT need to authorize phone. - // But strictly speaking, once they authorized UserProfile (Avatar/Nick), - // the OpenID exists. - // But the "User Phone" part is usually critical. - // Let's keep strict requirement for phone for NEW users for now unless asked otherwise. + wx.showToast({ title: '需要授权手机号才能继续', icon: 'none' }) } } }) diff --git a/wechat-mini-program/pages/login/login.wxml b/wechat-mini-program/pages/login/login.wxml index a21c715..be02c77 100644 --- a/wechat-mini-program/pages/login/login.wxml +++ b/wechat-mini-program/pages/login/login.wxml @@ -8,11 +8,7 @@ 为了提供更好的服务,请授权以下信息 - - - - - + diff --git a/wechat-mini-program/pages/profile/profile.wxml b/wechat-mini-program/pages/profile/profile.wxml index 263e044..18fcd2e 100644 --- a/wechat-mini-program/pages/profile/profile.wxml +++ b/wechat-mini-program/pages/profile/profile.wxml @@ -43,7 +43,7 @@ - 个人信息 + 我的信息 {{isFormOpen ? '▲' : '▼'}}