feat: 管理后台订单列表展示用户备注,用户信息摊平显示
- 新增 userNotes 字段,创建订单时从 Sub2API 读取用户 notes 保存 - 管理后台订单列表将用户名、邮箱、备注拆分为独立列,节约行高 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "orders" ADD COLUMN "user_notes" TEXT;
|
||||
@@ -11,6 +11,7 @@ model Order {
|
||||
userId Int @map("user_id")
|
||||
userEmail String? @map("user_email")
|
||||
userName String? @map("user_name")
|
||||
userNotes String? @map("user_notes")
|
||||
amount Decimal @db.Decimal(10, 2)
|
||||
rechargeCode String @unique @map("recharge_code")
|
||||
status OrderStatus @default(PENDING)
|
||||
|
||||
@@ -12,6 +12,7 @@ interface AdminOrder {
|
||||
userId: number;
|
||||
userName: string | null;
|
||||
userEmail: string | null;
|
||||
userNotes: string | null;
|
||||
amount: number;
|
||||
status: string;
|
||||
paymentType: string;
|
||||
|
||||
@@ -34,6 +34,7 @@ export async function GET(request: NextRequest) {
|
||||
userId: true,
|
||||
userName: true,
|
||||
userEmail: true,
|
||||
userNotes: true,
|
||||
amount: true,
|
||||
status: true,
|
||||
paymentType: true,
|
||||
|
||||
@@ -5,6 +5,7 @@ interface Order {
|
||||
userId: number;
|
||||
userName: string | null;
|
||||
userEmail: string | null;
|
||||
userNotes: string | null;
|
||||
amount: number;
|
||||
status: string;
|
||||
paymentType: string;
|
||||
@@ -48,7 +49,9 @@ export default function OrderTable({ orders, onRetry, onCancel, onViewDetail, da
|
||||
<thead className={dark ? 'bg-slate-800/50' : 'bg-gray-50'}>
|
||||
<tr>
|
||||
<th className={thCls}>订单号</th>
|
||||
<th className={thCls}>用户</th>
|
||||
<th className={thCls}>用户名</th>
|
||||
<th className={thCls}>邮箱</th>
|
||||
<th className={thCls}>备注</th>
|
||||
<th className={thCls}>金额</th>
|
||||
<th className={thCls}>状态</th>
|
||||
<th className={thCls}>支付方式</th>
|
||||
@@ -71,10 +74,11 @@ export default function OrderTable({ orders, onRetry, onCancel, onViewDetail, da
|
||||
{order.id.slice(0, 12)}...
|
||||
</button>
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-4 py-3 text-sm">
|
||||
<div className={dark ? 'text-slate-200' : ''}>{order.userName || '-'}</div>
|
||||
<div className={`text-xs ${dark ? 'text-slate-500' : 'text-gray-400'}`}>{order.userEmail || `ID: ${order.userId}`}</div>
|
||||
<td className={`whitespace-nowrap px-4 py-3 text-sm ${dark ? 'text-slate-200' : ''}`}>
|
||||
{order.userName || `#${order.userId}`}
|
||||
</td>
|
||||
<td className={tdMuted}>{order.userEmail || '-'}</td>
|
||||
<td className={tdMuted}>{order.userNotes || '-'}</td>
|
||||
<td className={`whitespace-nowrap px-4 py-3 text-sm font-medium ${dark ? 'text-slate-200' : ''}`}>¥{order.amount.toFixed(2)}</td>
|
||||
<td className="whitespace-nowrap px-4 py-3 text-sm">
|
||||
<span className={`inline-flex rounded-full px-2 py-1 text-xs font-semibold ${dark ? statusInfo.dark : statusInfo.light}`}>
|
||||
|
||||
@@ -102,6 +102,7 @@ export async function createOrder(input: CreateOrderInput): Promise<CreateOrderR
|
||||
userId: input.userId,
|
||||
userEmail: user.email,
|
||||
userName: user.username,
|
||||
userNotes: user.notes || null,
|
||||
amount: new Prisma.Decimal(input.amount.toFixed(2)),
|
||||
rechargeCode: '',
|
||||
status: 'PENDING',
|
||||
|
||||
@@ -4,6 +4,7 @@ export interface Sub2ApiUser {
|
||||
email: string;
|
||||
status: string; // "active", "banned", etc.
|
||||
balance: number;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface Sub2ApiRedeemCode {
|
||||
|
||||
Reference in New Issue
Block a user