feat(admin): merge stash changes into comclib-analytics (order/finance/product + rpc sql)

This commit is contained in:
comlibmb
2026-02-10 18:49:21 +08:00
parent bf394eb65d
commit 80e5a1ddeb
23 changed files with 1599 additions and 143 deletions

View File

@@ -0,0 +1,151 @@
import { rpcOrNull, rpcOrValue, rpcOrEmptyArray } from '@/services/analytics/rpc.uts'
import { FinanceOverview, ExtractRecord, UserBillRecord, PagedResult } from '@/types/admin/finance.uts'
/**
* 财务核心服务
*/
/**
* 获取财务概况统计
*/
export async function fetchFinanceOverview(startTime : string, endTime : string) : Promise<FinanceOverview | null> {
const res = await rpcOrNull('rpc_admin_finance_overview', {
p_start_time: startTime,
p_end_time: endTime
} as UTSJSONObject)
if (res == null) return null
return {
recharge_amount: (res as any).recharge_amount ?? 0,
recharge_count: (res as any).recharge_count ?? 0,
extract_amount: (res as any).extract_amount ?? 0,
extract_count: (res as any).extract_count ?? 0,
total_user_balance: (res as any).total_user_balance ?? 0,
total_user_brokerage: (res as any).total_user_brokerage ?? 0
} as FinanceOverview
}
/**
* 审核提现申请
*/
export async function reviewExtract(extractId : string, status : number, refusalReason : string | null = null) : Promise<boolean> {
try {
await rpcOrValue('rpc_admin_extract_review', {
p_extract_id: extractId,
p_status: status,
p_refusal_reason: refusalReason
} as UTSJSONObject)
return true
} catch (e : any) {
console.error('reviewExtract failed:', e)
return false
}
}
/**
* 充值补单审计
*/
export async function auditRecharge(rechargeId : string, mark : string | null = null) : Promise<boolean> {
try {
await rpcOrValue('rpc_admin_recharge_audit', {
p_recharge_id: rechargeId,
p_mark: mark
} as UTSJSONObject)
return true
} catch (e : any) {
console.error('auditRecharge failed:', e)
return false
}
}
/**
* 获取提现列表
*/
export async function fetchExtractList(
page: number,
pageSize: number,
status: number | null = null,
startTime: string | null = null,
endTime: string | null = null,
search: string | null = null
): Promise<PagedResult<ExtractRecord>> {
const res = await rpcOrNull('rpc_admin_extract_list', {
p_page: page,
p_page_size: pageSize,
p_status: status,
p_start_time: startTime,
p_end_time: endTime,
p_search: search
} as UTSJSONObject)
if (res == null) return { total: 0, items: [] as Array<ExtractRecord> }
const data = res as any
return {
total: data.total ?? 0,
items: (data.items as Array<ExtractRecord>) ?? ([] as Array<ExtractRecord>)
} as PagedResult<ExtractRecord>
}
/**
* 获取充值记录列表
*/
export async function fetchRechargeList(
page: number,
pageSize: number,
paid: number | null = null,
startTime: string | null = null,
endTime: string | null = null,
search: string | null = null
): Promise<PagedResult<any>> {
const res = await rpcOrNull('rpc_admin_recharge_list', {
p_page: page,
p_page_size: pageSize,
p_paid: paid,
p_start_time: startTime,
p_end_time: endTime,
p_search: search
} as UTSJSONObject)
if (res == null) return { total: 0, items: [] as Array<any> }
const data = res as any
return {
total: data.total ?? 0,
items: (data.items as Array<any>) ?? ([] as Array<any>)
} as PagedResult<any>
}
/**
* 获取资金流水列表
*/
export async function fetchUserBillList(
page: number,
pageSize: number,
category: string | null = null,
type: string | null = null,
pm: number | null = null,
startTime: string | null = null,
endTime: string | null = null,
search: string | null = null
): Promise<PagedResult<UserBillRecord>> {
const res = await rpcOrNull('rpc_admin_user_bill_list', {
p_page: page,
p_page_size: pageSize,
p_category: category,
p_type: type,
p_pm: pm,
p_start_time: startTime,
p_end_time: endTime,
p_search: search
} as UTSJSONObject)
if (res == null) return { total: 0, items: [] as Array<UserBillRecord> }
const data = res as any
return {
total: data.total ?? 0,
items: (data.items as Array<UserBillRecord>) ?? ([] as Array<UserBillRecord>)
} as PagedResult<UserBillRecord>
}

View File

@@ -0,0 +1,116 @@
import { rpcOrNull, rpcOrValue } from '@/services/analytics/rpc.uts'
export type AdminCategory = {
id: string
name: string
parent_id: string | null
icon: string | null
sort: number
is_active: boolean
level: number
created_at: string
}
/**
* 获取分类列表
*/
export async function fetchAdminCategoryList(filters: {
name?: string,
isActive?: boolean
}): Promise<Array<AdminCategory>> {
const res = await rpcOrNull('rpc_admin_category_list', {
p_name: filters.name ?? null,
p_is_active: filters.isActive ?? null
} as UTSJSONObject)
if (res == null) return [] as Array<AdminCategory>
const anyItems = (res as any).items
return Array.isArray(anyItems) ? anyItems : [] as Array<AdminCategory>
}
/**
* 创建分类
*/
export async function createAdminCategory(payload: {
parentId?: string | null,
name: string,
slug?: string,
description?: string,
iconUrl?: string,
bannerUrl?: string,
sortOrder?: number,
isActive?: boolean
}): Promise<string | null> {
try {
const id = await rpcOrValue('rpc_admin_category_create', {
p_parent_id: payload.parentId ?? null,
p_name: payload.name,
p_slug: payload.slug ?? null,
p_description: payload.description ?? null,
p_icon_url: payload.iconUrl ?? null,
p_banner_url: payload.bannerUrl ?? null,
p_sort_order: payload.sortOrder ?? 0,
p_is_active: payload.isActive ?? true
} as UTSJSONObject)
return typeof id === 'string' ? id as string : null
} catch (e: any) {
console.error('创建分类失败:', e)
throw e
}
}
/**
* 更新分类
*/
export async function updateAdminCategory(payload: {
id: string,
parentId?: string | null,
name: string,
slug?: string,
description?: string,
iconUrl?: string,
bannerUrl?: string,
sortOrder?: number,
isActive?: boolean
}): Promise<boolean> {
try {
const ok = await rpcOrValue('rpc_admin_category_update', {
p_id: payload.id,
p_parent_id: payload.parentId ?? null,
p_name: payload.name,
p_slug: payload.slug ?? null,
p_description: payload.description ?? null,
p_icon_url: payload.iconUrl ?? null,
p_banner_url: payload.bannerUrl ?? null,
p_sort_order: payload.sortOrder ?? 0,
p_is_active: payload.isActive ?? true
} as UTSJSONObject)
return ok === true
} catch (e: any) {
console.error('更新分类失败:', e)
throw e
}
}
/**
* 删除分类
*/
export async function deleteAdminCategory(id: string): Promise<boolean> {
try {
const ok = await rpcOrValue('rpc_admin_category_delete', {
p_id: id
} as UTSJSONObject)
return ok === true
} catch (e: any) {
const error = e as UTSJSONObject
const message = error.getString('message') ?? ''
if (message.includes('子分类')) {
throw new Error('请先删除该分类下的子分类')
}
if (message.includes('商品')) {
throw new Error('该分类下仍有商品,无法删除')
}
throw e
}
}

View File

@@ -0,0 +1,68 @@
import { rpcOrNull, rpcOrValue } from '@/services/analytics/rpc.uts'
export type AdminProduct = {
id: string
name: string
image: string
price: number
stock: number
sales: number
status: number
created_at: string
category_name: string
}
export type ProductPageResult = {
total: number
items: Array<AdminProduct>
}
/**
* 分页获取商品列表
*/
export async function fetchAdminProductPage(
page: number,
pageSize: number,
filters: {
name?: string,
status?: number,
categoryId?: string
}
): Promise<ProductPageResult> {
const res = await rpcOrNull('rpc_admin_product_list', {
p_page: page,
p_page_size: pageSize,
p_name: filters.name ?? null,
p_status: filters.status ?? null,
p_category_id: filters.categoryId ?? null
} as UTSJSONObject)
if (res == null) {
return { total: 0, items: [] as Array<AdminProduct> }
}
const anyTotal = (res as any).total
const anyItems = (res as any).items
return {
total: typeof anyTotal === 'number' ? anyTotal : 0,
items: Array.isArray(anyItems) ? anyItems : [] as Array<AdminProduct>
}
}
/**
* 更新商品状态 (上架/下架/回收站)
* @param status 1:上架 2:下架 3:草稿 4:删除
*/
export async function updateAdminProductStatus(productId: string, status: number): Promise<boolean> {
try {
const ok = await rpcOrValue('rpc_admin_product_update_status', {
p_product_id: productId,
p_status: status
} as UTSJSONObject)
return ok === true
} catch (e: any) {
console.error('更新商品状态失败:', e)
return false
}
}

View File

@@ -1,4 +1,4 @@
import { rpcOrNull, rpcOrEmptyArray } from '@/services/analytics/rpc.uts'
import { rpcOrNull, rpcOrEmptyArray, rpcOrValue } from '@/services/analytics/rpc.uts'
export async function fetchRefundOrderPage(
page: number,
@@ -24,6 +24,28 @@ export async function fetchRefundOrderPage(
return { total, items }
}
export async function fetchWriteOffRecordPage(
page: number,
pageSize: number,
search: string | null = null
): Promise<{ total: number; items: Array<any> }> {
const res = await rpcOrNull('rpc_admin_write_off_record_list', {
p_page: page,
p_page_size: pageSize,
p_search: search
} as any)
if (res == null) return { total: 0, items: [] as Array<any> }
const anyTotal = (res as any).total
const anyItems = (res as any).items
const total = typeof anyTotal === 'number' ? anyTotal : parseInt(String(anyTotal ?? '0'))
const items = Array.isArray(anyItems) ? (anyItems as Array<any>) : ([] as Array<any>)
return { total, items }
}
export async function fetchCashierOrderPage(
page: number,
pageSize: number,
@@ -48,31 +70,24 @@ export async function fetchCashierOrderPage(
return { total, items }
}
export async function fetchWriteOffRecordPage(
page: number,
pageSize: number,
search: string | null = null
): Promise<{ total: number; items: Array<any> }> {
const res = await rpcOrNull('rpc_admin_write_off_record_list', {
p_page: page,
p_page_size: pageSize,
p_search: search
} as any)
if (res == null) return { total: 0, items: [] as Array<any> }
const anyTotal = (res as any).total
const anyItems = (res as any).items
const total = typeof anyTotal === 'number' ? anyTotal : parseInt(String(anyTotal ?? '0'))
const items = Array.isArray(anyItems) ? (anyItems as Array<any>) : ([] as Array<any>)
return { total, items }
}
export async function fetchOrderSourceStats(startTime: string, endTime: string): Promise<Array<any>> {
return (await rpcOrEmptyArray('rpc_admin_order_source_stats', {
p_start_time: startTime,
p_end_time: endTime
} as any)) as any
}
export async function getOrderSettings(): Promise<UTSJSONObject | null> {
const res = await rpcOrValue('rpc_admin_system_config_get', {
p_key: 'order_settings'
} as any)
return res as any
}
export async function saveOrderSettings(config: UTSJSONObject): Promise<boolean> {
const res = await rpcOrValue('rpc_admin_system_config_save', {
p_key: 'order_settings',
p_value: config
} as any)
return res === true
}