front/src/api/workplace.ts
zzh 8a865c0a53 feat: 管理端人文关怀双工作台与接口/H5体验优化
拆分客户/员工工作台,落地登录关怀、待办统计、公告双栏布局;同步接口映射 AI、H5 订单与相关页面优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 19:06:51 +08:00

184 lines
5.7 KiB
TypeScript

import { axiosInstance } from '@/api/rbac'
import { resolveAdminApiPath } from '@/utils/adminApi'
function orderUrl(path: string): string {
return resolveAdminApiPath(path)
}
function assertBusinessOk(body: unknown) {
if (body == null) throw new Error('空响应')
const payload = body as Record<string, unknown>
const code = payload.code ?? payload.Code
const ok =
code === undefined ||
code === null ||
code === 0 ||
code === 200 ||
code === '0' ||
code === '200' ||
payload.success === true ||
payload.Success === true
if (!ok) {
throw new Error(
String(payload.msg ?? payload.Msg ?? payload.message ?? payload.Message ?? '请求失败'),
)
}
}
function unwrapData<T>(body: unknown): T {
assertBusinessOk(body)
const payload = body as Record<string, unknown>
return (payload.data ?? payload.Data ?? body) as T
}
export interface OrderWorkplaceStats {
total: number
counts: Record<string, number>
todayCreated: number
yesterdayCreated: number
dayOverDayGrowthPercent: number | null
pendingShip: number
shipped: number
pendingPayment: number
problematic: number
claimed: number
storeCount: number
storeOrderPending: number
}
export interface OrderWorkplaceTrendPoint {
label: string
forecastCount: number
shippedCount: number
}
export interface OrderWorkplaceTrend {
dimension: string
points: OrderWorkplaceTrendPoint[]
}
export interface OrderWorkplaceSpendTrendPoint {
label: string
orderCount: number
spendAmount: number
avgAmount: number
}
export interface OrderWorkplaceSpendTrend {
dimension: string
totalSpend: number
totalOrders: number
avgAmount: number
points: OrderWorkplaceSpendTrendPoint[]
}
function normalizeStats(raw: Record<string, unknown>): OrderWorkplaceStats {
const countsRaw = raw.counts ?? raw.Counts
const counts =
typeof countsRaw === 'object' && countsRaw != null
? (countsRaw as Record<string, number>)
: {}
const countOf = (...keys: string[]) => {
for (const key of keys) {
const v = counts[key]
if (v != null && Number.isFinite(Number(v))) return Number(v) || 0
}
return 0
}
return {
total: Number(raw.total ?? raw.Total ?? 0) || 0,
counts,
todayCreated: Number(raw.todayCreated ?? raw.TodayCreated ?? 0) || 0,
yesterdayCreated: Number(raw.yesterdayCreated ?? raw.YesterdayCreated ?? 0) || 0,
dayOverDayGrowthPercent:
raw.dayOverDayGrowthPercent ?? raw.DayOverDayGrowthPercent ?? null,
pendingShip: Number(raw.pendingShip ?? raw.PendingShip ?? 0) || 0,
shipped: Number(raw.shipped ?? raw.Shipped ?? 0) || 0,
pendingPayment: Number(raw.pendingPayment ?? raw.PendingPayment ?? 0) || 0,
problematic: Number(raw.problematic ?? raw.Problematic ?? 0) || 0,
claimed:
Number(raw.claimed ?? raw.Claimed ?? countOf('claimed', 'Claimed') ?? 0) || 0,
storeCount: Number(raw.storeCount ?? raw.StoreCount ?? 0) || 0,
storeOrderPending: Number(raw.storeOrderPending ?? raw.StoreOrderPending ?? 0) || 0,
}
}
function normalizeTrend(raw: Record<string, unknown>): OrderWorkplaceTrend {
const pointsRaw = raw.points ?? raw.Points
const points = Array.isArray(pointsRaw)
? pointsRaw.map((item) => {
const row = item as Record<string, unknown>
return {
label: String(row.label ?? row.Label ?? ''),
forecastCount: Number(row.forecastCount ?? row.ForecastCount ?? 0) || 0,
shippedCount: Number(row.shippedCount ?? row.ShippedCount ?? 0) || 0,
}
})
: []
return {
dimension: String(raw.dimension ?? raw.Dimension ?? 'day'),
points,
}
}
function normalizeSpendTrend(raw: Record<string, unknown>): OrderWorkplaceSpendTrend {
const pointsRaw = raw.points ?? raw.Points
const points = Array.isArray(pointsRaw)
? pointsRaw.map((item) => {
const row = item as Record<string, unknown>
return {
label: String(row.label ?? row.Label ?? ''),
orderCount: Number(row.orderCount ?? row.OrderCount ?? 0) || 0,
spendAmount: Number(row.spendAmount ?? row.SpendAmount ?? 0) || 0,
avgAmount: Number(row.avgAmount ?? row.AvgAmount ?? 0) || 0,
}
})
: []
return {
dimension: String(raw.dimension ?? raw.Dimension ?? 'day'),
totalSpend: Number(raw.totalSpend ?? raw.TotalSpend ?? 0) || 0,
totalOrders: Number(raw.totalOrders ?? raw.TotalOrders ?? 0) || 0,
avgAmount: Number(raw.avgAmount ?? raw.AvgAmount ?? 0) || 0,
points,
}
}
/** 工作台订单统计 GET /order/workplace-stats */
export async function getOrderWorkplaceStats(): Promise<OrderWorkplaceStats> {
const res = await axiosInstance.get(orderUrl('/order/workplace-stats'))
const data = unwrapData<Record<string, unknown>>(res.data)
return normalizeStats(data)
}
/** 工作台订单趋势 GET /order/workplace-trend */
export async function getOrderWorkplaceTrend(params: {
dimension: 'day' | 'week' | 'month'
count?: number
}): Promise<OrderWorkplaceTrend> {
const res = await axiosInstance.get(orderUrl('/order/workplace-trend'), {
params: {
dimension: params.dimension,
count: params.count,
},
})
const data = unwrapData<Record<string, unknown>>(res.data)
return normalizeTrend(data)
}
/** 工作台费用趋势 GET /order/workplace-spend-trend */
export async function getOrderWorkplaceSpendTrend(params: {
dimension: 'day' | 'week' | 'month'
count?: number
}): Promise<OrderWorkplaceSpendTrend> {
const res = await axiosInstance.get(orderUrl('/order/workplace-spend-trend'), {
params: {
dimension: params.dimension,
count: params.count,
},
})
const data = unwrapData<Record<string, unknown>>(res.data)
return normalizeSpendTrend(data)
}