172 lines
6.3 KiB
TypeScript
172 lines
6.3 KiB
TypeScript
/**
|
||
* 管理后台统一数据查询 - MongoDB 版
|
||
* 与 admin-queries.ts 接口一致,供 API 路由使用
|
||
*/
|
||
|
||
import { ObjectId } from "mongodb"
|
||
import { getCollection } from "./mongo"
|
||
|
||
export type AdminOrderType = "product" | "service" | "recharge" | "hotel" | "cafe" | "course" | "pawn" | "pointCard"
|
||
|
||
export interface AdminOrder {
|
||
id: string
|
||
orderNo: string
|
||
type: AdminOrderType
|
||
itemName: string
|
||
amount: number
|
||
status: string
|
||
userId?: string
|
||
createdAt: string
|
||
sourceTable: "productOrders" | "companionOrders" | "pointCardOrders" | "rechargeOrders" | "venueBookings" | "accountPawns"
|
||
}
|
||
|
||
/** 获取管理端统一订单列表(多表聚合) */
|
||
export async function getAllOrdersForAdminMongo(): Promise<AdminOrder[]> {
|
||
const result: AdminOrder[] = []
|
||
const now = new Date().toISOString()
|
||
|
||
const [productOrders, companionOrders, pointCardOrders, rechargeOrders, venueBookings, accountPawns] =
|
||
await Promise.all([
|
||
(await getCollection("productOrders")).find({}).sort({ createdAt: -1 }).limit(500).toArray(),
|
||
(await getCollection("companionOrders")).find({}).sort({ createdAt: -1 }).limit(500).toArray(),
|
||
(await getCollection("pointCardOrders")).find({}).sort({ createdAt: -1 }).limit(500).toArray(),
|
||
(await getCollection("rechargeOrders")).find({}).sort({ createdAt: -1 }).limit(500).toArray(),
|
||
(await getCollection("venueBookings")).find({}).sort({ createdAt: -1 }).limit(500).toArray(),
|
||
(await getCollection("accountPawns")).find({}).sort({ createdAt: -1 }).limit(500).toArray(),
|
||
])
|
||
|
||
for (const o of productOrders) {
|
||
const doc = o as { _id: ObjectId; orderNo: string; userId?: string; items?: { productName?: string }[]; finalAmount?: number; totalAmount?: number; status: string; createdAt?: string }
|
||
const title = doc.items?.[0]?.productName ?? "商品订单"
|
||
result.push({
|
||
id: doc._id.toString(),
|
||
orderNo: doc.orderNo,
|
||
type: "product",
|
||
itemName: title,
|
||
amount: doc.finalAmount ?? doc.totalAmount ?? 0,
|
||
status: doc.status,
|
||
userId: doc.userId,
|
||
createdAt: doc.createdAt ?? now,
|
||
sourceTable: "productOrders",
|
||
})
|
||
}
|
||
for (const o of companionOrders) {
|
||
const doc = o as { _id: ObjectId; orderNo: string; type: string; game: string; hours: number; totalAmount?: number; userId?: string; status: string; createdAt?: string }
|
||
result.push({
|
||
id: doc._id.toString(),
|
||
orderNo: doc.orderNo,
|
||
type: "service",
|
||
itemName: `${doc.type === "cp" ? "CP" : "陪练"} - ${doc.game} ${doc.hours}小时`,
|
||
amount: doc.totalAmount ?? 0,
|
||
status: doc.status,
|
||
userId: doc.userId,
|
||
createdAt: doc.createdAt ?? now,
|
||
sourceTable: "companionOrders",
|
||
})
|
||
}
|
||
for (const o of pointCardOrders) {
|
||
const doc = o as { _id: ObjectId; orderNo: string; game: string; faceValue: number; quantity: number; totalAmount?: number; userId?: string; status: string; createdAt?: string }
|
||
result.push({
|
||
id: doc._id.toString(),
|
||
orderNo: doc.orderNo,
|
||
type: "pointCard",
|
||
itemName: `点卡 ${doc.game} 面值${doc.faceValue} x${doc.quantity}`,
|
||
amount: doc.totalAmount ?? 0,
|
||
status: doc.status,
|
||
userId: doc.userId,
|
||
createdAt: doc.createdAt ?? now,
|
||
sourceTable: "pointCardOrders",
|
||
})
|
||
}
|
||
for (const o of rechargeOrders) {
|
||
const doc = o as { _id: ObjectId; orderNo: string; amount: number; totalAmount?: number; userId?: string; status: string; createdAt?: string }
|
||
result.push({
|
||
id: doc._id.toString(),
|
||
orderNo: doc.orderNo,
|
||
type: "recharge",
|
||
itemName: `充值 ¥${doc.amount}`,
|
||
amount: doc.totalAmount ?? doc.amount,
|
||
status: doc.status,
|
||
userId: doc.userId,
|
||
createdAt: doc.createdAt ?? now,
|
||
sourceTable: "rechargeOrders",
|
||
})
|
||
}
|
||
for (const o of venueBookings) {
|
||
const doc = o as { _id: ObjectId; orderNo: string; type: string; totalAmount?: number; userId?: string; status: string; createdAt?: string }
|
||
result.push({
|
||
id: doc._id.toString(),
|
||
orderNo: doc.orderNo,
|
||
type: doc.type === "hotel" ? "hotel" : "cafe",
|
||
itemName: doc.type === "hotel" ? "酒店预订" : "网咖预订",
|
||
amount: doc.totalAmount ?? 0,
|
||
status: doc.status,
|
||
userId: doc.userId,
|
||
createdAt: doc.createdAt ?? now,
|
||
sourceTable: "venueBookings",
|
||
})
|
||
}
|
||
for (const o of accountPawns) {
|
||
const doc = o as { _id: ObjectId; orderNo?: string; game: string; pawnAmount?: number; userId?: string; status: string; createdAt?: string }
|
||
result.push({
|
||
id: doc._id.toString(),
|
||
orderNo: (doc as { orderNo?: string }).orderNo ?? doc._id.toString(),
|
||
type: "pawn",
|
||
itemName: `典当 ${doc.game}`,
|
||
amount: doc.pawnAmount ?? 0,
|
||
status: doc.status,
|
||
userId: doc.userId,
|
||
createdAt: doc.createdAt ?? now,
|
||
sourceTable: "accountPawns",
|
||
})
|
||
}
|
||
|
||
result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
|
||
return result
|
||
}
|
||
|
||
/** 更新订单状态(根据来源表,id 为 _id 字符串) */
|
||
export async function updateOrderStatusInSourceMongo(
|
||
sourceTable: AdminOrder["sourceTable"],
|
||
id: string,
|
||
status: string
|
||
): Promise<void> {
|
||
const oid = new ObjectId(id)
|
||
const now = new Date().toISOString()
|
||
|
||
switch (sourceTable) {
|
||
case "productOrders": {
|
||
const coll = await getCollection("productOrders")
|
||
await coll.updateOne({ _id: oid }, { $set: { status, updatedAt: now } })
|
||
break
|
||
}
|
||
case "companionOrders": {
|
||
const coll = await getCollection("companionOrders")
|
||
await coll.updateOne({ _id: oid }, { $set: { status, updatedAt: now } })
|
||
break
|
||
}
|
||
case "pointCardOrders": {
|
||
const coll = await getCollection("pointCardOrders")
|
||
await coll.updateOne({ _id: oid }, { $set: { status } })
|
||
break
|
||
}
|
||
case "rechargeOrders": {
|
||
const coll = await getCollection("rechargeOrders")
|
||
await coll.updateOne({ _id: oid }, { $set: { status } })
|
||
break
|
||
}
|
||
case "venueBookings": {
|
||
const coll = await getCollection("venueBookings")
|
||
await coll.updateOne({ _id: oid }, { $set: { status } })
|
||
break
|
||
}
|
||
case "accountPawns": {
|
||
const coll = await getCollection("accountPawns")
|
||
await coll.updateOne({ _id: oid }, { $set: { status, updatedAt: now } })
|
||
break
|
||
}
|
||
default:
|
||
throw new Error(`Unknown sourceTable: ${sourceTable}`)
|
||
}
|
||
}
|