feat(nsti): add nicotine personality test flow (#36)

* fix: polish logs filter and stats money display

* fix: align floating tabs on logs and stats

* feat: enhance user profile and achievement features

- Add functionality for users to update their profile picture and nickname
- Implement achievement theme selection in onboarding
- Update API integration for profile updates and achievement themes
- Refine UI elements for better user interaction and experience

* feat: 梦想清单页与戒烟相关 API

- 梦想清单:系统导航栏、浮动添加、图标来自后台预设
- dream-presets API、pages.json 导航样式

Made-with: Cursor

* feat(nsti): add nicotine personality test flow
This commit is contained in:
hello-dd-code
2026-04-11 01:49:19 +08:00
committed by GitHub
parent ef36ca072b
commit ec87a9fc55
22 changed files with 4157 additions and 508 deletions
+81
View File
@@ -2,6 +2,7 @@ import { request } from './request'
import { MINI_PROGRAM_ID } from '@/config'
import pinia, { useUserStore } from '@/stores'
import { storage, SESSION_KEY, USER_KEY, USER_MODE_KEY } from '@/utils/storage'
import { BASE_URL } from '@/config'
const H5_DEBUG_SESSION_KEY = 'FxLFPHHBw49loODmRSvqdg=='
@@ -62,3 +63,83 @@ export function logout() {
storage.remove(SESSION_KEY)
storage.remove(USER_KEY)
}
export async function updateUserProfile(data) {
const res = await request.put('/auth/profile', data)
const user = storage.get(USER_KEY)
if (user && res.data) {
if (res.data.nickname) user.nickname = res.data.nickname
if (res.data.avatar_url) user.avatar_url = res.data.avatar_url
storage.set(USER_KEY, user)
}
return res
}
export { updateUserProfile as updateProfile }
export function getUploadToken(filename) {
return request.post('/common/upload/oss/token', { filename })
}
export function downloadMiniProgramTestCode(params = {}) {
const sessionKey = storage.get(SESSION_KEY)
const path = encodeURIComponent(params.path || 'pages/nsti/test?resume=0')
const width = params.width || 280
return new Promise((resolve, reject) => {
uni.downloadFile({
url: `${BASE_URL}/auth/mini-program-test-code?path=${path}&width=${width}`,
header: {
Authorization: sessionKey ? `Bearer ${sessionKey}` : ''
},
success: (res) => {
if (res.statusCode === 200 && res.tempFilePath) {
resolve(res.tempFilePath)
return
}
reject(new Error(`下载小程序码失败: ${res.statusCode || 'unknown'}`))
},
fail: (err) => reject(err)
})
})
}
export async function uploadFile(filePath) {
const ext = filePath.split('.').pop() || 'jpg'
const tokenRes = await getUploadToken(`avatar.${ext}`)
const data = tokenRes.data
let uploadUrl = (data.upload_url || '').replace(/\/$/, '')
if (!uploadUrl || uploadUrl.indexOf('aliyuncs.com') === -1) {
uploadUrl = (data.cdn_domain || '').replace(/\/$/, '')
if (uploadUrl && uploadUrl.indexOf('http') !== 0) {
uploadUrl = 'https://' + uploadUrl
}
}
return new Promise((resolve, reject) => {
uni.uploadFile({
url: uploadUrl,
filePath,
name: 'file',
formData: {
key: data.key,
OSSAccessKeyId: data.oss_access_key_id,
policy: data.oss_policy,
Signature: data.oss_signature
},
success: (res) => {
const code = res.statusCode || 0
if (code === 200 || code === 204 || (code >= 200 && code < 300)) {
const cdnDomain = (data.cdn_domain || '').replace(/\/$/, '')
const fileUrl = cdnDomain.startsWith('http')
? `${cdnDomain}/${data.key}`
: `https://${cdnDomain}/${data.key}`
resolve({ url: fileUrl, key: data.key })
} else {
reject(new Error('上传失败: ' + (res.data || code)))
}
},
fail: (err) => reject(new Error(err.errMsg || '上传失败'))
})
})
}