/** * 资料接口模块 * Requirements: 4.4, 4.5 */ import { get, post, del } from './request' import { getToken } from '../utils/storage' import config from '../config/index' // 从统一配置获取地址 const BASE_URL = config.API_BASE_URL const STATIC_URL = config.STATIC_BASE_URL /** * 提交/更新用户资料 * WHEN a user completes all required fields and submits, * THE XiangYi_MiniApp SHALL call endpoint to save the profile * Requirements: 4.5 * * @param {Object} data - 资料数据 * @param {number} data.relationship - 关系:1父亲 2母亲 3本人 * @param {string} data.surname - 姓氏 * @param {number} data.childGender - 子女性别:1男 2女 * @param {number} data.birthYear - 出生年份 * @param {number} data.education - 学历 * @param {string} data.workProvince - 工作省份 * @param {string} data.workCity - 工作城市 * @param {string} data.workDistrict - 工作区县 * @param {string} data.occupation - 职业 * @param {number} data.monthlyIncome - 月收入 * @param {number} data.height - 身高 * @param {number} data.weight - 体重 * @param {number} data.houseStatus - 房产状态 * @param {number} data.carStatus - 车辆状态 * @param {number} data.marriageStatus - 婚姻状态 * @param {number} data.expectMarryTime - 期望结婚时间 * @param {string} data.introduction - 自我介绍 * @param {boolean} data.isPhotoPublic - 照片是否公开 * @param {string} data.weChatNo - 微信号 * @param {Object} data.requirement - 择偶要求 * @returns {Promise} 资料ID */ export async function createOrUpdate(data) { const response = await post('/profile', data) return response } /** * 获取我的资料 * * @returns {Promise} 用户资料 */ export async function getMyProfile() { const response = await get('/profile') return response } /** * 上传照片 * WHEN a user uploads photos, THE XiangYi_MiniApp SHALL limit to maximum 5 photos * Requirements: 4.4 * * @param {Array} filePaths - 本地文件路径数组 * @returns {Promise} 上传结果,包含 photos 数组 [{url: string}] */ export async function uploadPhotos(filePaths) { const token = getToken() // 逐个上传文件(uni.uploadFile 不支持一次上传多个文件) const uploadedPhotos = [] for (const filePath of filePaths) { try { const result = await new Promise((resolve, reject) => { uni.uploadFile({ url: `${BASE_URL}/profile/photos`, filePath: filePath, name: 'files', // 后端期望的参数名 header: { 'Authorization': `Bearer ${token}` }, success: (uploadRes) => { console.log('上传响应:', uploadRes) if (uploadRes.statusCode === 200) { try { const data = JSON.parse(uploadRes.data) // 后端返回格式: { code: 0, message: "success", data: {...} } if (data.code === 0 && data.data) { resolve(data.data) } else { reject(new Error(data.message || '上传失败')) } } catch (e) { console.error('解析响应失败:', e, uploadRes.data) reject(new Error('解析响应失败')) } } else if (uploadRes.statusCode === 401) { reject(new Error('未授权,请重新登录')) } else { // 尝试解析错误信息 try { const errData = JSON.parse(uploadRes.data) reject(new Error(errData.message || '上传失败')) } catch { reject(new Error(`上传失败: ${uploadRes.statusCode}`)) } } }, fail: (err) => { console.error('上传网络错误:', err) reject(new Error('网络连接失败')) } }) }) // 后端返回 { photos: [{id, photoUrl}], totalCount: number } // 转换为前端需要的格式,拼接完整URL if (result.photos && result.photos.length > 0) { result.photos.forEach(photo => { // 如果是相对路径,拼接服务器地址 const fullUrl = photo.photoUrl.startsWith('http') ? photo.photoUrl : `${STATIC_URL}${photo.photoUrl}` uploadedPhotos.push({ id: photo.id, url: fullUrl }) }) } } catch (error) { console.error('上传照片失败:', error) throw error } } return { success: true, data: { photos: uploadedPhotos } } } /** * 删除照片 * * @param {number} photoId - 照片ID * @returns {Promise} 删除结果 */ export async function deletePhoto(photoId) { const response = await del(`/profile/photos/${photoId}`) return response } /** * 清理未提交资料的孤立照片 * 进入填写资料页面时调用,如果用户没有Profile记录,清理之前上传的照片 * * @returns {Promise} 清理结果 */ export async function cleanupOrphanPhotos() { const response = await post('/profile/photos/cleanup') return response } /** * 更新头像 * * @param {string} avatarUrl - 头像URL * @returns {Promise} 更新结果 */ export async function updateAvatar(avatarUrl) { const response = await post('/profile/avatar', { avatarUrl }) return response } export default { createOrUpdate, getMyProfile, uploadPhotos, deletePhoto, cleanupOrphanPhotos, updateAvatar }