Files
yuxingu-Miniprogram-dev/util/yxgApi.js
T
jackyu66gitandCursor b09d82df8d feat: 小程序统一走 Go 后台,咨询与登录切到 /api/v1
去掉协会 WebView 和魔方账密页,微信登录与咨询接口共用同一 token 和拦截器。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 00:26:28 +08:00

164 lines
6.7 KiB
JavaScript

import { YXG_API_BASE, YXG_ASSET_BASE } from './yxgConfig.js'
import $http from './requestConfig.js'
const TOKEN_KEY = 'token'
const LEGACY_TOKEN_KEY = 'yxg_token'
const DEVICE_KEY = 'yxg_device_key'
export function getYxgToken() {
return uni.getStorageSync(TOKEN_KEY) || uni.getStorageSync(LEGACY_TOKEN_KEY) || ''
}
export function setYxgToken(token) {
if (token) {
uni.setStorageSync(TOKEN_KEY, token)
uni.removeStorageSync(LEGACY_TOKEN_KEY)
} else {
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(LEGACY_TOKEN_KEY)
uni.removeStorageSync('userinfo')
}
}
export function getDeviceKey() {
return uni.getStorageSync(DEVICE_KEY) || ''
}
export function setDeviceKey(key) {
if (key) uni.setStorageSync(DEVICE_KEY, key)
}
export function assetURL(path) {
const p = String(path || '').trim()
if (!p) return ''
if (/^https?:\/\//i.test(p)) return p
return YXG_ASSET_BASE + (p.startsWith('/') ? p : `/${p}`)
}
function joinURL(base, path) {
if (/^https?:\/\//i.test(path)) return path
return `${base.replace(/\/$/, '')}${path.startsWith('/') ? path : `/${path}`}`
}
function request(method, path, body, extra = {}) {
return $http.request({
method,
url: path,
data: body === undefined ? {} : body,
isPrompt: extra.isPrompt ?? false,
load: extra.load ?? false,
timeout: extra.timeout,
}).catch((e) => {
const raw = e instanceof Error ? e.message : (e && e.errMsg) || '请求失败'
throw new Error(String(raw).replace(/^【request】/, ''))
})
}
export const yxgApi = {
authRegister: (body) => request('POST', '/api/v1/auth/register', body),
authLogin: (body) => request('POST', '/api/v1/auth/login', body),
authLogout: () => request('POST', '/api/v1/auth/logout', {}),
authMe: () => request('GET', '/api/v1/auth/me'),
authUpdateMe: (body) => request('PATCH', '/api/v1/auth/me', body),
authUploadAvatar(filePath) {
return new Promise((resolve, reject) => {
const header = {}
const token = getYxgToken()
const device = getDeviceKey()
if (token) header.Authorization = `Bearer ${token}`
if (device) header['X-Device-Key'] = device
uni.uploadFile({
url: joinURL(YXG_API_BASE, '/api/v1/auth/me/avatar'),
filePath,
name: 'file',
header,
success(res) {
let data = res.data
if (typeof data === 'string') {
try {
data = JSON.parse(data)
} catch {
reject(new Error('上传失败'))
return
}
}
if (!data || data.code !== 0) {
reject(new Error(data?.message || '上传失败'))
return
}
resolve(data.data)
},
fail(err) {
reject(new Error(err.errMsg || '上传失败'))
},
})
})
},
listProfiles: () => request('GET', '/api/v1/profiles'),
createProfile: (body) => request('POST', '/api/v1/profiles', body),
updateProfile: (id, body) => request('PATCH', `/api/v1/profiles/${id}`, body),
deleteProfile: (id) => request('DELETE', `/api/v1/profiles/${id}`),
createPortrait: (profile_id) =>
request('POST', '/api/v1/reports/portrait', { profile_id }),
createStar: (profile_id) => request('POST', '/api/v1/reports/star', { profile_id }),
createSynastry: (profile_id_a, profile_id_b, as_of) =>
request('POST', '/api/v1/reports/synastry', {
profile_id_a,
profile_id_b,
...(as_of ? { as_of } : {}),
}),
getLatestReport: (profile_id, type, peer_profile_id) => {
let q = `profile_id=${encodeURIComponent(profile_id)}&type=${encodeURIComponent(type)}`
if (peer_profile_id) q += `&peer_profile_id=${encodeURIComponent(peer_profile_id)}`
return request('GET', `/api/v1/reports/latest?${q}`)
},
listSynastryNearby: (lat, lng, radius_km = 50) =>
request('GET', `/api/v1/synastry/nearby?lat=${lat}&lng=${lng}&radius_km=${radius_km}`),
createSynastryInvite: (profile_id) =>
request('POST', '/api/v1/synastry/invites', { profile_id }),
getSynastryInvite: (token) => request('GET', `/api/v1/synastry/invites/${token}`),
acceptSynastryInvite: (token, body) =>
request('POST', `/api/v1/synastry/invites/${token}/accept`, body),
createRhythm: (profile_id) => request('POST', '/api/v1/reports/rhythm', { profile_id }),
listImageCardScenes: () => request('GET', '/api/v1/image-cards/scenes'),
getImageCardQuota: () => request('GET', '/api/v1/image-cards/quota'),
drawImageCard: (body) => request('POST', '/api/v1/image-cards/draw', body),
getSolarTermsToday: () => request('GET', '/api/v1/solar-terms/today'),
saveMood: (body) => request('POST', '/api/v1/moods', body),
getMoodToday: () => request('GET', '/api/v1/moods/today'),
getMoodsRecent: () => request('GET', '/api/v1/moods/recent'),
getExploreCatalog: () => request('GET', '/api/v1/explore/catalog'),
getExploreCategory: (key) => request('GET', `/api/v1/explore/catalog/${key}`),
listGrowthPlans: () => request('GET', '/api/v1/growth/plans'),
createGrowthPlan: (body) => request('POST', '/api/v1/growth/plans', body),
createGrowthCheckin: (planId, body) =>
request('POST', `/api/v1/growth/plans/${planId}/checkin`, body || {}),
listGrowthCheckins: (planId) => request('GET', `/api/v1/growth/plans/${planId}/checkins`),
listReports: () => request('GET', '/api/v1/reports'),
getReport: (id) => request('GET', `/api/v1/reports/${id}`),
getMembership: () => request('GET', '/api/v1/membership/me'),
createOrder: (body) => request('POST', '/api/v1/orders', body),
payMock: (orderId) => request('POST', `/api/v1/orders/${orderId}/pay-mock`, {}),
createRelationInsight: (profile_a_id, profile_b_id) =>
request('POST', '/api/v1/relation/insight', { profile_a_id, profile_b_id }),
listScales: () => request('GET', '/api/v1/scales'),
getScaleBankCatalog: () => request('GET', '/api/v1/scale-bank/catalog'),
getScaleBankCategory: (key) => request('GET', `/api/v1/scale-bank/categories/${key}`),
getScale: (slug) => request('GET', `/api/v1/scales/${slug}`),
getScaleResult: (slug) => request('GET', `/api/v1/scales/${slug}/result`),
submitScale: (slug, profile_id, answers) =>
request('POST', `/api/v1/scales/${slug}/result`, { profile_id, answers }),
getAskQuota: () => request('GET', '/api/v1/ask/quota'),
createAskThread: (body) => request('POST', '/api/v1/ask/threads', body),
clearAskThread: (threadId) => request('DELETE', `/api/v1/ask/threads/${threadId}`),
listAskMessages: (threadId) => request('GET', `/api/v1/ask/threads/${threadId}/messages`),
sendAskMessage: (threadId, content) =>
request('POST', `/api/v1/ask/threads/${threadId}/messages`, { content }, { timeout: 60000 }),
getHomeTools: () => request('GET', '/api/v1/home/tools'),
getHomeBanners: (placement = 'home') =>
request('GET', `/api/v1/home/banners?placement=${encodeURIComponent(placement)}`),
getHomeFeedSlots: (placement = 'home') =>
request('GET', `/api/v1/home/feed-slots?placement=${encodeURIComponent(placement)}`),
getHomeDailyTips: () => request('GET', '/api/v1/home/daily-tips'),
}