208 lines
5.9 KiB
TypeScript
208 lines
5.9 KiB
TypeScript
import { request, uploadFile, redirectToLogin } from '../../utils/request'
|
|
import * as auth from '../../utils/auth'
|
|
import { UserInfo, QuotaItem } from '../../types/models'
|
|
import { QuotaType, STORAGE_KEYS } from '../../utils/config'
|
|
import { formatDate } from '../../utils/format'
|
|
|
|
function getZodiac(birthDay: number): string {
|
|
if (!birthDay) return ''
|
|
const d = new Date(birthDay * 1000)
|
|
const m = d.getMonth() + 1
|
|
const day = d.getDate()
|
|
const arr = [
|
|
[120, '摩羯座'], [218, '水瓶座'], [320, '双鱼座'], [419, '白羊座'],
|
|
[520, '金牛座'], [621, '双子座'], [722, '巨蟹座'], [822, '狮子座'],
|
|
[922, '处女座'], [1023, '天秤座'], [1122, '天蝎座'], [1221, '射手座'],
|
|
]
|
|
const val = m * 100 + day
|
|
for (let i = 0; i < arr.length; i++) {
|
|
if (val <= (arr[i][0] as number)) return arr[i][1] as string
|
|
}
|
|
return '摩羯座'
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
userInfo: {} as UserInfo,
|
|
uploadRemain: 0,
|
|
zodiac: '',
|
|
editVisible: false,
|
|
avatarUploading: false,
|
|
avatarChanged: false,
|
|
saving: false,
|
|
editForm: {
|
|
username: '',
|
|
sex: 0,
|
|
birth_day: 0,
|
|
avatar: '',
|
|
},
|
|
birthDateStr: '',
|
|
today: '',
|
|
},
|
|
|
|
onLoad() {
|
|
this.setToday()
|
|
},
|
|
|
|
// 跨零点后回到本页时,生日选择器上限需重算,不能停留在昨天
|
|
setToday() {
|
|
const d = new Date()
|
|
const pad = (n: number) => (n < 10 ? `0${n}` : `${n}`)
|
|
this.setData({ today: `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` })
|
|
},
|
|
|
|
onShow() {
|
|
this.syncTabBar()
|
|
this.setToday()
|
|
// 未登录直接回登录页(幂等跳转),不再发出必然 401 的请求
|
|
if (!auth.isLoggedIn()) {
|
|
redirectToLogin()
|
|
return
|
|
}
|
|
this.fetchUser()
|
|
this.fetchQuota()
|
|
},
|
|
|
|
syncTabBar() {
|
|
const tabBar = (this as any).getTabBar && (this as any).getTabBar()
|
|
// 红点由 tabBar 自身在登录态下同步,这里只更新选中态
|
|
if (tabBar) tabBar.setData({ selected: 4 })
|
|
},
|
|
|
|
fetchUser() {
|
|
request<UserInfo>({ url: '/user/info', showError: false })
|
|
.then((user) => {
|
|
wx.setStorageSync(STORAGE_KEYS.USER_INFO, user)
|
|
this.setData({ userInfo: user, zodiac: getZodiac(user.birth_day) })
|
|
})
|
|
.catch(() => {})
|
|
},
|
|
|
|
fetchQuota() {
|
|
request<{ quotas: QuotaItem[] }>({ url: '/quota/info', showError: false, silentAuth: true })
|
|
.then((res) => {
|
|
const upload = res.quotas.find((q) => q.quota_type === QuotaType.UPLOAD)
|
|
if (upload) this.setData({ uploadRemain: upload.remain })
|
|
})
|
|
.catch(() => {})
|
|
},
|
|
|
|
onEdit() {
|
|
const u = this.data.userInfo
|
|
this.setData({
|
|
editVisible: true,
|
|
avatarChanged: false,
|
|
editForm: {
|
|
username: u.username || '',
|
|
sex: u.sex || 0,
|
|
birth_day: u.birth_day || 0,
|
|
avatar: u.avatar || '',
|
|
},
|
|
birthDateStr: u.birth_day ? formatDate(u.birth_day) : '',
|
|
})
|
|
},
|
|
|
|
onCloseEdit() {
|
|
this.setData({ editVisible: false })
|
|
},
|
|
|
|
noop() {},
|
|
|
|
onChooseAvatar(e: WechatMiniprogram.CustomEvent) {
|
|
this.setData({ 'editForm.avatar': e.detail.avatarUrl, avatarChanged: true })
|
|
},
|
|
|
|
onNameInput(e: WechatMiniprogram.Input) {
|
|
this.setData({ 'editForm.username': e.detail.value })
|
|
},
|
|
|
|
onSexSelect() {
|
|
wx.showActionSheet({
|
|
itemList: ['男', '女'],
|
|
success: (res) => this.setData({ 'editForm.sex': res.tapIndex + 1 }),
|
|
fail: () => {}, // 取消选择属正常操作,不必抛错日志
|
|
})
|
|
},
|
|
|
|
onBirthChange(e: WechatMiniprogram.CustomEvent) {
|
|
const dateStr = e.detail.value as string
|
|
const ts = Math.floor(new Date(dateStr.replace(/-/g, '/')).getTime() / 1000)
|
|
this.setData({ 'editForm.birth_day': ts, birthDateStr: dateStr })
|
|
},
|
|
|
|
onSaveProfile() {
|
|
if (this.data.avatarUploading || this.data.saving) return
|
|
const f = this.data.editForm
|
|
const avatar = f.avatar || ''
|
|
const username = (f.username || '').trim()
|
|
if (!username) {
|
|
wx.showToast({ title: '昵称不能为空', icon: 'none' })
|
|
return
|
|
}
|
|
|
|
const finish = () => {
|
|
this.setData({
|
|
editVisible: false,
|
|
avatarUploading: false,
|
|
saving: false,
|
|
avatarChanged: false,
|
|
})
|
|
this.fetchUser()
|
|
}
|
|
|
|
const saveProfile = () => {
|
|
const u = this.data.userInfo
|
|
const body: Record<string, any> = {}
|
|
// 只提交真正变更的字段,避免无意义请求与误清空
|
|
if (username !== (u.username || '')) body.username = username
|
|
if (f.sex && f.sex !== u.sex) body.sex = f.sex
|
|
if (f.birth_day && f.birth_day !== u.birth_day) body.birth_day = f.birth_day
|
|
|
|
if (!Object.keys(body).length && !this.data.avatarChanged) {
|
|
this.setData({ editVisible: false })
|
|
return
|
|
}
|
|
|
|
this.setData({ saving: true })
|
|
request({ url: '/user/profile', method: 'PUT', data: body })
|
|
.then(() => {
|
|
wx.showToast({ title: '已保存', icon: 'success' })
|
|
finish()
|
|
})
|
|
.catch(() => this.setData({ avatarUploading: false, saving: false }))
|
|
}
|
|
|
|
if (this.data.avatarChanged && avatar) {
|
|
this.setData({ avatarUploading: true })
|
|
uploadFile<{ avatar: string }>(avatar, 'file', '/user/avatar/upload')
|
|
.then(() => saveProfile())
|
|
.catch(() => this.setData({ avatarUploading: false, saving: false }))
|
|
} else {
|
|
saveProfile()
|
|
}
|
|
},
|
|
|
|
onTapMall() {
|
|
wx.navigateTo({ url: '/pages/mall/mall' })
|
|
},
|
|
onTapOrder() {
|
|
wx.navigateTo({ url: '/pages/order/order' })
|
|
},
|
|
onTapNotification() {
|
|
wx.navigateTo({ url: '/pages/notification/notification' })
|
|
},
|
|
onTapCollect() {
|
|
wx.setStorageSync(STORAGE_KEYS.OPEN_COLLECT, 1)
|
|
wx.switchTab({ url: '/pages/outfit/outfit' })
|
|
},
|
|
onTapFlow() {
|
|
wx.navigateTo({ url: '/pages/mall/mall?tab=flow' })
|
|
},
|
|
onTapService() {
|
|
wx.showToast({ title: '客服与反馈敬请期待', icon: 'none' })
|
|
},
|
|
onTapAbout() {
|
|
wx.showToast({ title: '纸条AI衣橱 v1.0.0', icon: 'none' })
|
|
},
|
|
})
|