Files
SingBox-Gopanel/frontend/admin/src-reverse/pages/finance/FinanceOrderPage.js
CN-JS-HuiBai 609ab002b3
Some checks failed
build / build (api, amd64, linux) (push) Failing after -52s
build / build (api, arm64, linux) (push) Failing after -52s
build / build (api.exe, amd64, windows) (push) Failing after -52s
修复丢失的前端文件
2026-04-18 22:03:26 +08:00

323 lines
9.6 KiB
JavaScript

import { makeRecoveredPage } from "../../runtime/makeRecoveredPage.js";
import FinanceOrderPageView from "./FinanceOrderPage.jsx";
export default makeRecoveredPage({
title: "Finance Order",
routePath: "/finance/order",
moduleId: "R3t",
featureKey: "finance.order",
component: FinanceOrderPageView,
translationNamespaces: ["order", "common"],
summary:
"The order management page is a server-driven data table with a lightweight create/assign dialog, multi-dimensional faceted filters, detail dialog drill-down, pending-order action menu, and commission workflow updates.",
api: [
{
name: "order.fetch",
method: "POST",
path: "{secure}/order/fetch",
queryKey: ["orderList", "{pagination}", "{filters}", "{sorting}"],
purpose: "Loads paginated order table data for the main management view.",
requestShape: {
pageSize: "number",
current: "1-based page number",
filter: [{ id: "column id", value: "raw value or operator:value string" }],
sort: [{ id: "column id", desc: "boolean" }],
},
responseShape: {
data: [
{
id: "number",
trade_no: "string",
type: "number",
period: "string",
status: "number",
total_amount: "number",
balance_amount: "number",
discount_amount: "number",
refund_amount: "number",
surplus_amount: "number",
commission_balance: "number",
commission_status: "number",
created_at: "unix timestamp",
updated_at: "unix timestamp",
callback_no: "string | null",
user: {
id: "number",
email: "string",
},
plan: {
id: "number",
name: "string",
},
invite_user: {
id: "number",
email: "string",
},
},
],
total: "number",
},
},
{
name: "order.detail",
method: "POST",
path: "{secure}/order/detail",
purpose: "Loads the order detail dialog on demand when the trade number trigger is opened.",
payloadExamples: [{ id: 1001 }],
},
{
name: "order.paid",
method: "POST",
path: "{secure}/order/paid",
purpose: "Marks a pending order as paid from the row action menu.",
payloadExamples: [{ trade_no: "202604170001" }],
},
{
name: "order.cancel",
method: "POST",
path: "{secure}/order/cancel",
purpose: "Cancels a pending order from the row action menu.",
payloadExamples: [{ trade_no: "202604170001" }],
},
{
name: "order.update",
method: "POST",
path: "{secure}/order/update",
purpose: "Transitions commission workflow state from the commission status action menu.",
payloadExamples: [
{ trade_no: "202604170001", commission_status: 1 },
{ trade_no: "202604170001", commission_status: 3 },
],
},
{
name: "order.assign",
method: "POST",
path: "{secure}/order/assign",
purpose: "Creates an admin-assigned order from the toolbar dialog or user-row embedded trigger.",
payloadExamples: [
{
email: "user@example.com",
plan_id: 1,
period: "month_price",
total_amount: 1999,
},
],
},
{
name: "plan.fetch",
method: "GET",
path: "{secure}/plan/fetch",
purpose: "Supplies plan options for the assign-order dialog.",
},
],
enums: {
orderStatus: {
PENDING: 0,
PROCESSING: 1,
CANCELLED: 2,
COMPLETED: 3,
DISCOUNTED: 4,
},
orderType: {
NEW: 1,
RENEWAL: 2,
UPGRADE: 3,
RESET_FLOW: 4,
},
commissionStatus: {
PENDING: 0,
PROCESSING: 1,
VALID: 2,
INVALID: 3,
},
periodKeys: [
"month_price",
"quarter_price",
"half_year_price",
"year_price",
"two_year_price",
"three_year_price",
"onetime_price",
"reset_price",
],
},
stateModel: {
list: {
rowSelection: {},
columnVisibility: {},
columnFilters: [],
sorting: [],
pagination: {
pageIndex: 0,
pageSize: 20,
},
initialColumnPinning: {
right: ["actions"],
},
},
routeBootstrap: {
searchParamsToFilters: [
{ key: "user_id", parser: "string" },
{ key: "order_id", parser: "string" },
{ key: "commission_status", parser: "number" },
{ key: "status", parser: "number" },
{ key: "commission_balance", parser: "string" },
],
},
assignDialog: {
open: false,
defaultValues: {
email: "",
plan_id: 0,
period: "",
total_amount: 0,
},
planOptions: "Loaded lazily when the dialog is opened.",
},
detailDialog: {
open: false,
orderId: null,
data: null,
},
},
toolbarModel: {
quickActions: [
"Assign/create order dialog button",
"Trade number search on trade_no column",
],
facetedFilters: [
{
column: "type",
source: "order type enum",
},
{
column: "period",
source: "order period enum",
},
{
column: "status",
source: "order status enum",
},
{
column: "commission_status",
source: "commission status enum",
},
],
resetBehavior: "Reset button appears when any column filter exists and clears all filters.",
},
tableModel: {
columns: [
{
key: "trade_no",
titleKey: "table.columns.tradeNo",
renderer:
"Truncated trade number button that opens an on-demand detail dialog for the current order.",
},
{
key: "type",
titleKey: "table.columns.type",
renderer: "Enum badge with per-type color token mapping.",
},
{
key: "plan.name",
titleKey: "table.columns.plan",
renderer: "Plan name text cell using nested plan relation.",
},
{
key: "period",
titleKey: "table.columns.period",
renderer: "Period badge using period color mapping.",
},
{
key: "total_amount",
titleKey: "table.columns.amount",
renderer: "Currency text using fen-to-yuan formatting.",
sortable: true,
},
{
key: "status",
titleKey: "table.columns.status",
renderer:
"Status cell with icon + text. Pending rows expose a dropdown action menu for mark-as-paid and cancel.",
sortable: true,
},
{
key: "commission_balance",
titleKey: "table.columns.commission",
renderer: "Currency text, hidden when absent.",
sortable: true,
},
{
key: "commission_status",
titleKey: "table.columns.commissionStatus",
renderer:
"Commission status badge with conditional action menu. Only shown as actionable when commission_balance is non-zero and order status is COMPLETED.",
sortable: true,
},
{
key: "created_at",
titleKey: "table.columns.createdAt",
renderer: "Timestamp rendered as yyyy/MM/dd HH:mm:ss.",
sortable: true,
},
],
mobileLayout: {
primaryField: "trade_no",
gridFields: ["plan.name", "total_amount", "status", "created_at"],
},
},
dialogs: {
assignOrder: {
formFields: ["email", "plan_id", "period", "total_amount"],
amountBehavior: "UI edits in yuan, submitted as fen by multiplying the numeric input by 100.",
successBehavior: "Refetch list, reset form, close dialog, show success toast.",
},
orderDetail: {
sections: [
"basicInfo",
"amountInfo",
"timeInfo",
"commissionInfo",
],
fields: [
"user.email",
"period",
"plan.name",
"callback_no",
"total_amount",
"balance_amount",
"discount_amount",
"refund_amount",
"surplus_amount",
"created_at",
"updated_at",
"commission_balance",
"commission_status",
],
links: [
"user email links to /user/manage?email=<email>",
"invite user email links to /user/manage?email=<email> when present",
],
},
},
interactions: [
"Opening the page with query parameters such as user_id, status, or commission_status preloads matching column filters from the URL.",
"Trade number cells are the primary detail entrypoint and fetch full order data only when the dialog opens.",
"Pending orders expose mark-as-paid and cancel actions from the status dropdown menu.",
"Pending commissions on completed orders expose PROCESSING and INVALID transitions through order.update.",
"Assign order dialog is reused from user-row actions and prefilled with the current user email when launched there.",
],
notes: [
"The list is fully server-driven: pagination, filtering, and sorting all flow back through order.fetch.",
"The compiled page uses the shared generic faceted-filter popover component for type/period/status/commission filters.",
"Actions are concentrated on status and commission_status columns instead of a dedicated trailing actions column.",
],
sourceRefs: [
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:27362",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:296650",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:296936",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:297228",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:297575",
],
});