115 lines
4.2 KiB
TypeScript
115 lines
4.2 KiB
TypeScript
/**
|
||
* 应用订阅 API
|
||
* 前端路径:/api/app/subscription → 后端 /api/app/subscription
|
||
*/
|
||
import request from '@/utils/request'
|
||
import type { ApiResult, PageResult } from '@/api'
|
||
import { APP_API_URL } from '@/config/setting'
|
||
import type { AppSubscription, AppSubscriptionParam, SubscribeResult } from './model'
|
||
|
||
const BASE = APP_API_URL + '/subscription'
|
||
|
||
/** 统一成功码判断:兼容 code=0(旧约定)和 code=200(Spring Boot 默认) */
|
||
const ok = (code: number) => code === 0 || code === 200
|
||
|
||
// ============ 订阅操作 ============
|
||
|
||
/** 创建订阅(免费直接激活,付费创建待支付) */
|
||
export async function createSubscription(data: {
|
||
productId: number
|
||
priceType: 'free' | 'one_time' | 'subscription'
|
||
subscriptionPeriod?: 'month' | 'year'
|
||
quantity?: number
|
||
}) {
|
||
const res = await request.post<ApiResult<SubscribeResult>>(BASE + '/subscribe', data)
|
||
if (ok(res.data.code)) return res.data.data
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
/** 获取用户余额 */
|
||
export async function getUserBalance(): Promise<{ balance: number }> {
|
||
const res = await request.get<ApiResult<{ balance: number }>>(BASE + '/balance')
|
||
if (ok(res.data.code)) return res.data.data ?? { balance: 0 }
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
/** 发起支付(支持微信/余额支付) */
|
||
export async function paySubscription(id: number, method: 'wechat' | 'balance' | 'alipay' = 'wechat') {
|
||
const res = await request.post<ApiResult<unknown>>(BASE + '/pay/' + id, null, {
|
||
params: { method }
|
||
})
|
||
if (ok(res.data.code)) return res.data.data
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
/** 查询支付状态(轮询用),同时返回订单详情 */
|
||
export async function checkPayStatus(subscriptionNo: string) {
|
||
const res = await request.get<ApiResult<{
|
||
paid: boolean
|
||
payStatus: number
|
||
status: string
|
||
payTime?: string
|
||
transactionId?: string
|
||
// 订单详情(供支付页直接使用,无需再调 getSubscription)
|
||
id?: number
|
||
subscriptionNo?: string
|
||
productId?: number
|
||
productName?: string
|
||
productLogo?: string
|
||
priceType?: string
|
||
payPrice?: number
|
||
subscriptionPeriod?: string
|
||
}>>(BASE + '/check-status/' + subscriptionNo)
|
||
if (ok(res.data.code)) return res.data.data
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
// ============ 我的订阅 ============
|
||
|
||
/** 我的订阅列表(分页) */
|
||
export async function mySubscriptions(params?: AppSubscriptionParam) {
|
||
const res = await request.get<ApiResult<PageResult<AppSubscription>>>(BASE + '/my/page', { params })
|
||
if (ok(res.data.code)) return res.data.data
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
/** 订阅详情 */
|
||
export async function getSubscription(id: number) {
|
||
const res = await request.get<ApiResult<AppSubscription>>(BASE + '/detail/' + id)
|
||
if (ok(res.data.code)) return res.data.data
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
// ============ 订阅管理 ============
|
||
|
||
/** 续费 */
|
||
export async function renewSubscription(id: number, period: 'month' | 'year') {
|
||
const res = await request.post<ApiResult<unknown>>(BASE + '/renew/' + id, null, { params: { period } })
|
||
if (ok(res.data.code)) return res.data.data
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
/** 退订/取消 */
|
||
export async function cancelSubscription(id: number) {
|
||
const res = await request.post<ApiResult<unknown>>(BASE + '/cancel/' + id)
|
||
if (ok(res.data.code)) return res.data.message
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
/** 启用/禁用 */
|
||
export async function toggleEnable(id: number, enabled: boolean) {
|
||
const res = await request.post<ApiResult<unknown>>(BASE + '/toggle-enable/' + id, null, { params: { enabled } })
|
||
if (ok(res.data.code)) return res.data.message
|
||
return Promise.reject(new Error(res.data.message))
|
||
}
|
||
|
||
// ============ 查询 ============
|
||
|
||
/** 检查是否已购买某应用 */
|
||
export async function checkPurchased(productId: number) {
|
||
const res = await request.get<ApiResult<boolean>>(BASE + '/check-purchased/' + productId)
|
||
if (ok(res.data.code)) return res.data.data ?? false
|
||
// 接口未实现时静默返回 false,不影响主流程
|
||
return false
|
||
}
|