| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import { post } from '@/core/http/http-client'
- import { buildRestPath } from '@/core/config/api-paths'
- import { fetchUploadConfig, uploadImageFile } from '@/features/dynamics/publish-gateway'
- const ROUTE_PROFILE = buildRestPath('user/profile')
- /** 仅允许写入资料字段,避免接口回包覆盖 token / isLogin */
- const PROFILE_PATCH_KEYS = [
- 'nickname',
- 'username',
- 'bio',
- 'gender',
- 'birthday',
- 'avatar',
- 'mobile',
- 'level',
- 'score',
- 'money',
- 'area_code'
- ]
- function isProfileLike(obj) {
- if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return false
- if (obj.userinfo && typeof obj.userinfo === 'object') return false
- return (
- obj.nickname != null ||
- obj.avatar != null ||
- obj.username != null ||
- obj.bio != null
- )
- }
- function unwrapProfilePayload(data, raw) {
- const candidates = [
- data,
- data && data.userinfo,
- data && data.data,
- raw?.data,
- raw?.data?.userinfo,
- raw?.res?.data,
- raw?.res?.data?.userinfo
- ]
- for (const c of candidates) {
- if (!c || typeof c !== 'object') continue
- if (c.userinfo && typeof c.userinfo === 'object') return c.userinfo
- if (isProfileLike(c)) return c
- if (c.data && typeof c.data === 'object' && isProfileLike(c.data)) {
- return c.data
- }
- }
- return {}
- }
- /**
- * 从接口或表单中提取可安全 merge 到 user store 的字段
- * @param {Record<string, unknown>} source
- */
- export function pickProfilePatch(source) {
- if (!source || typeof source !== 'object') return {}
- let row = source
- if (row.userinfo && typeof row.userinfo === 'object') {
- row = row.userinfo
- }
- const out = {}
- for (const key of PROFILE_PATCH_KEYS) {
- if (row[key] !== undefined && row[key] !== null) {
- out[key] = row[key]
- }
- }
- return out
- }
- /**
- * 上传头像并更新用户资料
- * @param {string} filePath 本地临时路径
- * @returns {Promise<string>} 更新后的 avatar 字段
- */
- export async function uploadAndUpdateAvatar(filePath) {
- const config = await fetchUploadConfig()
- const uploadedUrl = await uploadImageFile(filePath, config)
- const profile = await updateUserProfile({ avatar: uploadedUrl })
- return profile.avatar || uploadedUrl
- }
- /**
- * @param {Record<string, unknown>} fields
- */
- export async function updateUserProfile(fields) {
- const { data, raw } = await post(ROUTE_PROFILE, fields)
- const body = unwrapProfilePayload(data, raw)
- return pickProfilePatch(body)
- }
- /**
- * @param {{ nickname?: string }} form
- */
- export function validateProfileForm(form) {
- const nickname = String(form.nickname || '').trim()
- if (nickname.length < 3 || nickname.length > 32) {
- return { ok: false, messageKey: 'profileEdit.nicknameLengthError' }
- }
- return { ok: true }
- }
|