更新了AI页和我的页,一级页面都重构完成。

This commit is contained in:
lik
2026-10-04 21:21:50 +08:00
parent 428fb7c52c
commit f542b1dced
26 changed files with 1482 additions and 1141 deletions
+120 -110
View File
@@ -3,11 +3,13 @@ const API = require('../../utils/api.js')
Page({
data: {
userInfo: {
// 默认头像:暖墨色品牌标记(home-ink #9B4508)。
// home.png 本体是 tabBar 未选中态的灰色 #8A8A8A,故另存一份重上色位图;
// 与 ai-ink.png 同一做法(位图着色走不了 CSS 变量,改色须手改,见 DESIGN.md §7.3)
avatar: '/images/home-ink.png',
// 留空表示"没有真头像",模板据此渲染暖橙实心底 + 白色 user 线标的默认头像
// (与首页 .brand-mark 同源)。默认头像不走位图:位图着色读不到 CSS 变量,
// 改主色时须整图重上色(见 DESIGN.md §7.3),用 t-icon + 令牌则自动跟随
avatar: '',
name: '用户',
// 身份行副行,loadUserInfo 时由手机号脱敏填入
account: '',
phone: '',
sex: '',
birth: '',
@@ -16,16 +18,21 @@ Page({
ssn: '',
isLoggedIn: false
},
profileVisible: false,
// 菜单分组:按"用途"而非"是不是陪诊"分,三组才立得住。
// 图标与首页同目的地同图形(同一含义只对应一个表达,从色值延伸到图标):
// 预约记录 calendar-1、健康档案 user-checked、联系我们 call 均与首页一致。
// requiresLogin 的组在未登录时整组隐藏——这些入口都依赖用户身份
menuGroups: [{
groupName: '个人服务',
groupName: '我的服务',
requiresLogin: true,
items: [{
name: '个人信息',
icon: 'verify',
bindtap: 'onTapProfile'
// 陪诊产品的「我的」页核心是订单,故排全页第一项
name: '预约记录',
icon: 'calendar-1',
bindtap: 'onTapEscortRecord'
}, {
name: '健康档案',
icon: 'attach',
icon: 'user-checked',
bindtap: 'onTapHealth'
}, {
name: '邮寄地址',
@@ -33,14 +40,26 @@ Page({
bindtap: 'onTapAddress'
}]
}, {
groupName: '陪诊',
groupName: '帮助与支持',
requiresLogin: false,
items: [{
name: '预约记录',
icon: 'assignment',
bindtap: 'onTapEscortRecord'
name: '联系我们',
icon: 'call',
bindtap: 'onTapContact'
}, {
// 口径统一为「服务指南」(首页区块标题行、列表页说明卡都用此名),
// 不另起「陪诊指南」这一第三叫法;与列表页「服务指南 │ 用户协议」同一配对
name: '服务指南',
icon: 'book-open',
bindtap: 'onTapGuide'
}, {
name: '用户协议',
icon: 'secured',
bindtap: 'onTapAgreement'
}]
}, {
groupName: '其他',
requiresLogin: false,
items: [{
name: '关于我们',
icon: 'info-circle',
@@ -70,16 +89,41 @@ Page({
this.setData({
'userInfo.isLoggedIn': true,
'userInfo.name': profile.name || '用户',
// 头像补读后端返回值;取不到留空,由模板渲染暖橙默认头像。
// 注:profileedit 页里新选的图目前不会落库——utils/api.js 没有文件上传接口,
// 微信返回的是本地临时路径,存进库里也会失效,所以这里只修"显示"这一半
'userInfo.avatar': profile.avatar || '',
'userInfo.phone': profile.mobile || '',
// 身份行副行(微信那行是微信号):本应用没有账号体系,
// 等价标识是手机号,脱敏成 138****1234 后再上屏
'userInfo.account': this.maskMobile(profile.mobile || ''),
'userInfo.sex': profile.sex || '',
'userInfo.birth': profile.birth ? this.formatDate(profile.birth) : '',
'userInfo.email': profile.email || '',
'userInfo.idnumber': profile.idnumber || '',
'userInfo.ssn': profile.ssn || ''
})
} else {
// 未登录(含刚退出登录):身份行收敛回默认态。
// 少了这个分支,globalData.user 被清空后页面仍停在"已登录"的样子——
// 「我的服务」组和退出块都不会消失
this.setData({
'userInfo.isLoggedIn': false,
'userInfo.avatar': '',
'userInfo.name': '用户',
'userInfo.account': '',
'userInfo.phone': ''
})
}
},
// 手机号脱敏:11 位取前三后四;位数不符时原样返回,不制造错位星号
maskMobile(mobile) {
const digits = String(mobile).replace(/\D/g, '')
if (digits.length !== 11) return mobile || ''
return `${digits.slice(0, 3)}****${digits.slice(7)}`
},
formatDate(date) {
if (!date) return ''
const d = new Date(date)
@@ -89,49 +133,20 @@ Page({
return `${year}-${month}-${day}`
},
// 顶部身份行整行可点,但未登录时不该跳进"填完才被拦"的资料页
// (个人信息与邮寄地址改真页面后系统返回键归页面栈管,
// 不再像原来的浮层那样被系统返回键直接退出小程序)
onTapProfile() {
this.setData({ profileVisible: true })
if (!this.data.userInfo.isLoggedIn) return
wx.navigateTo({
url: '/pages/mine/profileedit'
})
},
onTapAddress() {
this.setData({ addressVisible: true })
},
onAddressClose() {
this.setData({ addressVisible: false })
},
onAddressSave(e) {
const app = getApp()
const user = app.globalData.user
if (!user || !user._id) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
wx.showLoading({ title: '保存中...' })
const updateData = {
_id: user._id,
addresses: e.detail.addresses
}
API.user.update(updateData)
.then((data) => {
if (data.code === 0) {
app.globalData.user = data.data.user
wx.showToast({ title: '保存成功', icon: 'success' })
} else {
wx.showToast({ title: data.msg || '保存失败', icon: 'none' })
}
})
.catch(() => {
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
.finally(() => {
wx.hideLoading()
})
wx.navigateTo({
url: '/pages/mine/addressedit'
})
},
onTapHealth() {
@@ -140,26 +155,39 @@ Page({
})
},
onHealthClose() {
this.setData({ healthVisible: false })
},
onTapEscortRecord() {
wx.navigateTo({
url: '/pages/escort/recordlist'
})
},
// 帮助与支持:联系我们(页面已存在,与首页「常用功能」同目的地)
onTapContact() {
wx.navigateTo({
url: '/pages/mine/contact'
})
},
// 帮助与支持:服务指南(与首页区块标题行、列表页说明卡同一页面)
onTapGuide() {
wx.navigateTo({
url: '/pages/escort/guide'
})
},
// 帮助与支持:用户协议(与陪诊服务列表页的「用户协议」同一页面)
onTapAgreement() {
wx.navigateTo({
url: '/pages/escort/agreement'
})
},
onTapAboutUs() {
wx.navigateTo({
url: '/pages/mine/about'
})
},
onTapSetting() {
this.setData({ settingVisible: true })
},
// 页脚 B 端合作链接:暂无独立页面,统一转接人工客服
onFooterTap() {
wx.makePhoneCall({
@@ -167,58 +195,38 @@ Page({
})
},
onSettingClose() {
this.setData({ settingVisible: false })
// 退出登录:二次确认 → 调后端登出 → 清全局与本地缓存
onLogout() {
wx.showModal({
title: '退出登录',
content: '退出后需要重新授权手机号,才能查看预约记录与健康档案',
confirmText: '退出',
// confirmColor 是属性值,读不到 CSS 变量,取值须与令牌同步(DESIGN.md §5.1)
confirmColor: '#B8520A',
success: (res) => {
if (!res.confirm) return
wx.showLoading({ title: '退出中...' })
// 必须先调接口:token 由 request.js 从 globalData.user 里取,
// 先清全局对象就带不上 token 了
API.user.signout({})
.then(() => this.doLogout())
// 接口失败也要把本地退干净,不把用户卡在"已登录"的假象里
.catch(() => this.doLogout())
.finally(() => wx.hideLoading())
}
})
},
onProfileClose() {
this.setData({ profileVisible: false })
},
onProfileSave(e) {
const newUserInfo = e.detail.editData
doLogout() {
const app = getApp()
const user = app.globalData.user
if (!user || !user._id) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
wx.showLoading({ title: '保存中...' })
const updateData = {
_id: user._id,
profile: {
name: newUserInfo.name,
sex: newUserInfo.sex,
birth: newUserInfo.birth ? new Date(newUserInfo.birth).toISOString() : null,
mobile: newUserInfo.phone
},
location: {
province: newUserInfo.province,
city: newUserInfo.city,
district: newUserInfo.district,
},
}
API.user.update(updateData)
.then((data) => {
if (data.code === 0) {
app.globalData.user = data.data.user
this.loadUserInfo()
wx.showToast({ title: '保存成功', icon: 'success' })
this.setData({ profileVisible: false })
} else {
wx.showToast({ title: data.msg || '保存失败', icon: 'none' })
}
})
.catch(() => {
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
.finally(() => {
wx.hideLoading()
})
app.globalData.user = null
wx.removeStorageSync('user_phonenumber')
// 落一个"已主动退出"标记:app.js 的 onShow 每次都会静默重登
// (wxsignin 只凭 code 换 openid 即可重新签发 token),不拦这一下,
// 退出就形同虚设——切后台再回来又变成登录态
wx.setStorageSync('has_logout', true)
this.loadUserInfo()
wx.showToast({ title: '已退出登录', icon: 'success' })
},
handleLogin(e) {
@@ -235,6 +243,8 @@ Page({
if (data.code == 0) {
const app = getApp()
app.globalData.user = data.data.user
// 用户重新授权登录,解除对静默重登的拦截
wx.removeStorageSync('has_logout')
this.loadUserInfo()
}
})