Files
one-pipe-system/src/api/modules/asset.ts
break cfb6b52cc2
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m12s
倒计时限制
2026-06-24 15:06:05 +08:00

309 lines
9.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 资产管理 API 服务
* 对应文档asset-detail-refactor-api-changes.md
*/
import { BaseService } from '../BaseService'
import {
assertAssetActionAllowed,
markAssetActionCalled,
type AssetRateLimitedAction
} from '@/utils/business/apiRateLimit'
import type {
BaseResponse,
AssetResolveResponse,
AssetRealtimeStatusResponse,
AssetRefreshResponse,
AssetPackageListResponse,
AssetPackageParams,
AssetCurrentPackageResponse,
DeviceStopResponse,
AssetWalletTransactionListResponse,
AssetWalletTransactionParams,
AssetWalletResponse,
AssetOrdersParams,
AssetOrdersResponse,
UpdateAssetRealnameStatusRequest,
DtoUpdateAssetRealnameStatusResponse,
AssetOperationLogsResponse,
AssetOperationLogsParams,
AssetPackageUsageRecord,
UpdateAssetPackageUsedDataRequest,
UpdateAssetPackageExpiresAtRequest
} from '@/types/api'
const runRateLimitedAssetAction = async <T>(
action: AssetRateLimitedAction,
identifier: string,
request: () => Promise<T>
): Promise<T> => {
assertAssetActionAllowed(action, identifier)
markAssetActionCalled(action, identifier)
const response = await request()
return response
}
export class AssetService extends BaseService {
/**
* 通过任意标识符查询设备或卡的完整详情
* 支持虚拟号、ICCID、IMEI、SN、MSISDN
* GET /api/admin/assets/resolve/:identifier
* @param identifier 资产标识符虚拟号、ICCID、IMEI、SN、MSISDN
*/
static resolveAsset(identifier: string): Promise<BaseResponse<AssetResolveResponse>> {
return this.getOne<AssetResolveResponse>(`/api/admin/assets/resolve/${identifier}`)
}
/**
* 读取资产实时状态(直接读 DB/Redis不调网关
* GET /api/admin/assets/:identifier/realtime-status
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static getRealtimeStatus(identifier: string): Promise<BaseResponse<AssetRealtimeStatusResponse>> {
return this.getOne<AssetRealtimeStatusResponse>(
`/api/admin/assets/${identifier}/realtime-status`,
undefined,
{
requestOptions: {
show404Error: false // 404时不显示错误提示
}
}
)
}
/**
* 主动调网关拉取最新数据后返回
* POST /api/admin/assets/:identifier/refresh
* 前端按资产标识限制 5 分钟内只能调用一次
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static refreshAsset(identifier: string): Promise<BaseResponse<AssetRefreshResponse>> {
return runRateLimitedAssetAction('refresh', identifier, () =>
this.post<BaseResponse<AssetRefreshResponse>>(
`/api/admin/assets/${identifier}/refresh`,
{},
{ timeout: 60000 }
)
)
}
/**
* 查询该资产所有套餐记录,含虚流量换算字段(分页)
* GET /api/admin/assets/:identifier/packages?page=1&page_size=50
* @param identifier 资产标识符ICCID 或 VirtualNo
* @param params 查询参数(可选分页参数)
*/
static getAssetPackages(
identifier: string,
params?: AssetPackageParams
): Promise<BaseResponse<AssetPackageListResponse>> {
return this.get<BaseResponse<AssetPackageListResponse>>(
`/api/admin/assets/${identifier}/packages`,
params,
{
requestOptions: {
show404Error: false // 404时不显示错误提示
}
}
)
}
/**
* 查询当前生效中的主套餐
* GET /api/admin/assets/:identifier/current-package
* 无生效套餐时返回 404
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static getCurrentPackage(identifier: string): Promise<BaseResponse<AssetCurrentPackageResponse>> {
return this.getOne<AssetCurrentPackageResponse>(
`/api/admin/assets/${identifier}/current-package`,
undefined,
{
requestOptions: {
show404Error: false // 404时不显示错误提示
}
}
)
}
/**
* 修改套餐真实已用量
* PATCH /api/admin/assets/:identifier/packages/:package_usage_id/used-data
*/
static updateAssetPackageUsedData(
identifier: string,
packageUsageId: number,
data: UpdateAssetPackageUsedDataRequest
): Promise<BaseResponse<AssetPackageUsageRecord>> {
return this.patch<BaseResponse<AssetPackageUsageRecord>>(
`/api/admin/assets/${identifier}/packages/${packageUsageId}/used-data`,
data as Record<string, any>
)
}
/**
* 修改套餐过期时间
* PATCH /api/admin/assets/:identifier/packages/:package_usage_id/expires-at
*/
static updateAssetPackageExpiresAt(
identifier: string,
packageUsageId: number,
data: UpdateAssetPackageExpiresAtRequest
): Promise<BaseResponse<AssetPackageUsageRecord>> {
return this.patch<BaseResponse<AssetPackageUsageRecord>>(
`/api/admin/assets/${identifier}/packages/${packageUsageId}/expires-at`,
data as Record<string, any>
)
}
// ========== 资产停复机操作(统一接口)==========
/**
* 停机资产(卡或设备)
* POST /api/admin/assets/:identifier/stop
* 停机成功后设置 1 小时停机保护期(保护期内禁止复机)
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static stopAsset(identifier: string): Promise<BaseResponse<DeviceStopResponse | void>> {
return this.post<BaseResponse<DeviceStopResponse | void>>(
`/api/admin/assets/${identifier}/stop`,
{}
)
}
/**
* 复机资产(卡或设备)
* POST /api/admin/assets/:identifier/start
* 前端按资产标识限制 5 分钟内只能调用一次
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static startAsset(identifier: string): Promise<BaseResponse<void>> {
return runRateLimitedAssetAction('start', identifier, () =>
this.post<BaseResponse<void>>(`/api/admin/assets/${identifier}/start`, {})
)
}
// ========== 资产停用 ==========
/**
* 手动停用资产(卡或设备)
* PATCH /api/admin/assets/:identifier/deactivate
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static deactivateAsset(identifier: string): Promise<BaseResponse> {
return this.patch<BaseResponse>(`/api/admin/assets/${identifier}/deactivate`, {})
}
// ========== 钱包查询 ==========
/**
* 查询指定卡或设备的钱包余额概况
* GET /api/admin/assets/:identifier/wallet
* 企业账号禁止调用
* @param identifier 资产标识符ICCID 或 VirtualNo
*/
static getAssetWallet(identifier: string): Promise<BaseResponse<AssetWalletResponse>> {
return this.getOne<AssetWalletResponse>(`/api/admin/assets/${identifier}/wallet`, undefined, {
requestOptions: {
show404Error: false // 404时不显示错误提示
}
})
}
/**
* 分页查询指定资产的钱包收支流水
* GET /api/admin/assets/:identifier/wallet/transactions
* 企业账号禁止调用
* @param identifier 资产标识符ICCID 或 VirtualNo
* @param params 查询参数
*/
static getWalletTransactions(
identifier: string,
params?: AssetWalletTransactionParams
): Promise<BaseResponse<AssetWalletTransactionListResponse>> {
return this.get<BaseResponse<AssetWalletTransactionListResponse>>(
`/api/admin/assets/${identifier}/wallet/transactions`,
params
)
}
// ========== 轮询状态更新 ==========
/**
* 更新资产轮询状态
* PATCH /api/admin/assets/:identifier/polling-status
* @param identifier 资产标识符ICCID 或 VirtualNo
* @param data 轮询状态数据
*/
static updatePollingStatus(
identifier: string,
data: { enable_polling: boolean }
): Promise<BaseResponse> {
return this.patch<BaseResponse>(`/api/admin/assets/${identifier}/polling-status`, data)
}
// ========== 资产历史订单 ==========
/**
* 查询资产历史订单
* GET /api/admin/assets/:identifier/orders
* @param identifier 资产标识符ICCID 或 VirtualNo
* @param params 查询参数
*/
static getAssetOrders(
identifier: string,
params?: AssetOrdersParams
): Promise<BaseResponse<AssetOrdersResponse>> {
return this.get<BaseResponse<AssetOrdersResponse>>(
`/api/admin/assets/${identifier}/orders`,
params
)
}
/**
* 更新资产实名认证策略
* PATCH /api/admin/assets/:identifier/realname-mode
* @param identifier 资产标识符ICCID 或 VirtualNo
* @param realname_policy 实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)
*/
static updateRealnamePolicy(identifier: string, realname_policy: string): Promise<BaseResponse> {
return this.patch<BaseResponse>(`/api/admin/assets/${identifier}/realname-mode`, {
realname_policy
})
}
/**
* 手动更新资产实名状态
* PATCH /api/admin/assets/:identifier/realname-status
* @param identifier 资产标识符ICCID 或 VirtualNo
* @param data 实名状态数据
*/
static updateRealnameStatus(
identifier: string,
data: UpdateAssetRealnameStatusRequest
): Promise<BaseResponse<DtoUpdateAssetRealnameStatusResponse>> {
return this.patch<BaseResponse<DtoUpdateAssetRealnameStatusResponse>>(
`/api/admin/assets/${identifier}/realname-status`,
data
)
}
// ========== 资产操作审计日志 ==========
/**
* 查询资产操作审计日志
* GET /api/admin/assets/:identifier/operation-logs
* @param identifier 资产标识符
* @param params 查询参数
*/
static getOperationLogs(
identifier: string,
params?: AssetOperationLogsParams
): Promise<BaseResponse<AssetOperationLogsResponse>> {
return this.get<BaseResponse<AssetOperationLogsResponse>>(
`/api/admin/assets/${identifier}/operation-logs`,
params
)
}
}