feat:第二次提交

This commit is contained in:
李伊帆
2026-10-09 15:07:38 +08:00
parent ee3ecc00eb
commit 179bd3b66c
7 changed files with 56 additions and 9 deletions

View File

@@ -1,2 +1,4 @@
VITE_API_BASE_URL=http://192.168.0.222:8082 VITE_API_BASE_URL=http://192.168.0.222:8082
VITE_API_PROXY_TARGET=http://192.168.0.222:8082 VITE_API_PROXY_TARGET=http://192.168.0.222:8082
VITE_AGREEMENT_ID_SERVICE=0
VITE_AGREEMENT_ID_PRIVACY=0

View File

@@ -3,3 +3,7 @@ VITE_API_BASE_URL=http://192.168.0.222:8082
# H5 开发:BASE_URL 留空时可走 vite 代理 /app # H5 开发:BASE_URL 留空时可走 vite 代理 /app
VITE_API_PROXY_TARGET=http://192.168.0.222:8082 VITE_API_PROXY_TARGET=http://192.168.0.222:8082
# 协议详情 agreementId(POST /app/auth/agreement/detail)
VITE_AGREEMENT_ID_SERVICE=0
VITE_AGREEMENT_ID_PRIVACY=0

View File

@@ -1,11 +1,11 @@
import { request } from '@/api/request' import { request } from '@/api/request'
import type { AgreementDetail, AgreementType } from './agreement.types' import type { AgreementDetail } from './agreement.types'
/** GET /app/auth/agreement/detail — 协议详情 */ /** POST /app/auth/agreement/detail — 协议详情(body: agreementId) */
export function fetchAgreementDetail(type: AgreementType) { export function fetchAgreementDetail(agreementId: number) {
return request<AgreementDetail>({ return request<AgreementDetail>({
url: '/app/auth/agreement/detail', url: '/app/auth/agreement/detail',
method: 'POST', method: 'POST',
data: { type }, data: { agreementId },
}) })
} }

View File

@@ -0,0 +1,25 @@
import type { AgreementType } from './agreement.types'
function parseEnvId(value: string | undefined): number | undefined {
if (value === undefined || value === '') return undefined
const n = Number(value)
return Number.isFinite(n) && n >= 0 ? n : undefined
}
/** 与后端协议主键对应,可在 .env 中配置 */
export function resolveAgreementId(type: AgreementType): number {
const fromEnv =
type === 'service'
? parseEnvId(import.meta.env.VITE_AGREEMENT_ID_SERVICE)
: parseEnvId(import.meta.env.VITE_AGREEMENT_ID_PRIVACY)
if (fromEnv !== undefined) return fromEnv
return 0
}
export function parseAgreementIdFromQuery(raw: unknown): number | undefined {
if (raw === undefined || raw === null || raw === '') return undefined
const n = Number(raw)
return Number.isFinite(n) && n >= 0 ? n : undefined
}

View File

@@ -1,6 +1,7 @@
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue' import { ref } from 'vue'
import { getErrorMessage } from '@/utils/api-error' import { getErrorMessage } from '@/utils/api-error'
import { parseAgreementIdFromQuery, resolveAgreementId } from './agreement.ids'
import { fetchAgreementDetail } from './agreement.api' import { fetchAgreementDetail } from './agreement.api'
import type { AgreementDetail, AgreementType } from './agreement.types' import type { AgreementDetail, AgreementType } from './agreement.types'
@@ -21,12 +22,13 @@ export function useAgreement() {
const content = ref('') const content = ref('')
const loading = ref(false) const loading = ref(false)
async function loadDetail(agreementType: AgreementType) { async function loadDetail(agreementType: AgreementType, agreementId?: number) {
loading.value = true loading.value = true
title.value = DEFAULT_TITLE[agreementType] title.value = DEFAULT_TITLE[agreementType]
content.value = '' content.value = ''
const id = agreementId ?? resolveAgreementId(agreementType)
try { try {
const data = await fetchAgreementDetail(agreementType) const data = await fetchAgreementDetail(id)
const normalized = normalizeDetail(agreementType, data ?? {}) const normalized = normalizeDetail(agreementType, data ?? {})
title.value = normalized.title title.value = normalized.title
content.value = normalized.content content.value = normalized.content
@@ -44,7 +46,8 @@ export function useAgreement() {
const t = query?.type as AgreementType const t = query?.type as AgreementType
const agreementType = t === 'privacy' || t === 'service' ? t : 'service' const agreementType = t === 'privacy' || t === 'service' ? t : 'service'
type.value = agreementType type.value = agreementType
loadDetail(agreementType) const agreementId = parseAgreementIdFromQuery(query?.id)
loadDetail(agreementType, agreementId)
}) })
return { title, content, loading } return { title, content, loading }

View File

@@ -2,15 +2,25 @@ import { request } from '@/api/request'
import type { ForgetPasswordVerifyBody, ForgetPasswordVerifyResult } from '@/types/api' import type { ForgetPasswordVerifyBody, ForgetPasswordVerifyResult } from '@/types/api'
import type { ForgotPasswordForm } from './forgot-password.types' import type { ForgotPasswordForm } from './forgot-password.types'
/** 后端 data 可能为令牌字符串,或 { resetToken } 对象 */
function normalizeResetToken(
data: string | ForgetPasswordVerifyResult,
): ForgetPasswordVerifyResult {
if (typeof data === 'string') {
return { resetToken: data }
}
return data
}
/** POST /app/auth/forgetPassword/verifyCode — 校验手机号与验证码,返回重置令牌 */ /** POST /app/auth/forgetPassword/verifyCode — 校验手机号与验证码,返回重置令牌 */
export function verifyForgetPasswordCode(data: ForgotPasswordForm) { export function verifyForgetPasswordCode(data: ForgotPasswordForm) {
const body: ForgetPasswordVerifyBody = { const body: ForgetPasswordVerifyBody = {
phonenumber: data.phone.trim(), phonenumber: data.phone.trim(),
smsCode: data.code.trim(), smsCode: data.code.trim(),
} }
return request<ForgetPasswordVerifyResult>({ return request<string | ForgetPasswordVerifyResult>({
url: '/app/auth/forgetPassword/verifyCode', url: '/app/auth/forgetPassword/verifyCode',
method: 'POST', method: 'POST',
data: body, data: body,
}) }).then(normalizeResetToken)
} }

View File

@@ -50,6 +50,9 @@ export interface ForgetPasswordVerifyBody {
smsCode: string smsCode: string
} }
/** 接口 JSON 中 data 常为令牌字符串;少数实现为对象 */
export type ForgetPasswordVerifyData = string | { resetToken: string }
export interface ForgetPasswordVerifyResult { export interface ForgetPasswordVerifyResult {
resetToken: string resetToken: string
} }