移除不需要的文件
Some checks failed
build / build (api, amd64, linux) (push) Failing after -51s
build / build (api, arm64, linux) (push) Failing after -51s
build / build (api.exe, amd64, windows) (push) Failing after -51s

This commit is contained in:
CN-JS-HuiBai
2026-04-18 20:14:03 +08:00
parent f4af50299c
commit 9d95a7c650
333 changed files with 3 additions and 498637 deletions

View File

@@ -1,404 +0,0 @@
import { makeRecoveredPage } from "../../runtime/makeRecoveredPage.js";
import UserManagePageView from "./UserManagePage.jsx";
export default makeRecoveredPage({
title: "User Manage",
routePath: "/user/manage",
moduleId: "u8t",
featureKey: "user.manage",
component: UserManagePageView,
translationNamespaces: ["user", "common", "order", "traffic"],
summary:
"The user management page is one of the heaviest admin pages in the bundle: it combines a server-side data table, advanced filter sheet, batch actions, email sending, user generation, traffic history dialog, inline order assignment, reset-secret/reset-traffic flows, and a full edit side sheet.",
api: [
{
name: "user.fetch",
method: "POST",
path: "{secure}/user/fetch",
queryKey: ["userList", "{pagination}", "{filters}", "{sorting}"],
purpose: "Loads paginated user table data from server-side filters and sorting.",
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",
email: "string",
is_admin: "boolean",
is_staff: "boolean",
banned: "boolean",
balance: "number",
commission_balance: "number",
online_count: "number",
device_limit: "number | null",
transfer_enable: "number",
total_used: "number",
u: "number",
d: "number",
expired_at: "unix timestamp | null",
next_reset_at: "unix timestamp | null",
created_at: "unix timestamp",
subscribe_url: "string",
uuid: "string",
token: "string",
remarks: "string | null",
plan: {
id: "number",
name: "string",
},
group: {
id: "number",
name: "string",
},
invite_user: {
id: "number",
email: "string",
},
invite_user_id: "number | null",
commission_type: "number",
commission_rate: "number | null",
},
],
total: "number",
},
},
{
name: "user.update",
method: "POST",
path: "{secure}/user/update",
purpose: "Persists edited user fields from the edit side sheet.",
notes: [
"Only dirty fields are submitted beyond the required id.",
"Upload/download fields are edited in GB in the form and converted back to bytes before submit.",
],
},
{
name: "user.resetSecret",
method: "POST",
path: "{secure}/user/resetSecret",
purpose: "Resets a user's secret/token from the actions menu.",
},
{
name: "user.generate",
method: "POST",
path: "{secure}/user/generate",
purpose: "Bulk generates users from the toolbar dialog, optionally downloading CSV output.",
},
{
name: "user.getStatUser",
method: "POST",
path: "{secure}/stat/getStatUser",
purpose: "Loads per-user traffic history rows for the traffic records dialog.",
},
{
name: "user.destroy",
method: "POST",
path: "{secure}/user/destroy",
purpose: "Deletes a user after confirmation from the row action menu.",
},
{
name: "user.sendMail",
method: "POST",
path: "{secure}/user/sendMail",
purpose: "Sends email to selected users, filtered users, or all users from the send-mail dialog.",
},
{
name: "user.dumpCsv",
method: "POST",
path: "{secure}/user/dumpCSV",
purpose: "Exports current selection/filter scope as CSV from the toolbar menu.",
},
{
name: "user.ban",
method: "POST",
path: "{secure}/user/ban",
purpose: "Batch-bans users by selected rows, current filtered scope, or all users.",
payloadExamples: [
{ scope: "selected", user_ids: [1, 2, 3] },
{ scope: "filtered", filter: [{ id: "email", value: "foo" }], sort: "id", sort_type: "DESC" },
{ scope: "all" },
],
},
{
name: "trafficReset.resetUser",
method: "POST",
path: "{secure}/traffic-reset/reset-user",
purpose: "Resets user traffic through the row action dialog.",
},
{
name: "order.assign",
method: "POST",
path: "{secure}/order/assign",
purpose: "Embedded assign-order flow reused from the order page.",
},
{
name: "plan.fetch",
method: "GET",
path: "{secure}/plan/fetch",
purpose: "Provides subscription plan options for filters, editing, generation, and assign-order.",
},
{
name: "server.group.fetch",
method: "GET",
path: "{secure}/server/group/fetch",
purpose: "Provides permission group options for toolbar and edit form.",
},
],
stateModel: {
list: {
rowSelection: {},
columnVisibility: {
is_admin: false,
is_staff: false,
},
columnFilters: [],
sorting: [],
pagination: {
pageIndex: 0,
pageSize: 20,
},
initialHiddenColumns: [
"commission_balance",
"created_at",
"is_admin",
"is_staff",
"permission_group",
"plan_id",
],
initialColumnPinning: {
right: ["actions"],
},
},
routeBootstrap: {
searchParamsToFilters: [{ key: "email", parser: "string" }],
},
toolbarDialogs: {
generateUsers: false,
sendMail: false,
batchBanConfirm: false,
advancedFilterSheet: false,
},
editSheet: {
open: false,
editingUser: null,
planOptions: [],
},
},
toolbarModel: {
primaryActions: [
"Generate users dialog",
"Email search filter on the email column",
"Advanced filter sheet",
"Column visibility menu",
"Bulk action dropdown",
],
advancedFilters: [
"email",
"id",
"plan_id",
"transfer_enable",
"total_used",
"online_count",
"expired_at",
"uuid",
"token",
"banned",
"remarks",
"invite_user.email",
"invite_user_id",
"is_admin",
"is_staff",
],
bulkMenu: [
"Send mail",
"Export CSV",
"Batch ban",
],
scopeResolution:
"Selection scope is selected rows when any row is checked, otherwise filtered scope when filters exist, otherwise all users.",
},
tableModel: {
columns: [
{
key: "select",
titleKey: "columns.select_row",
renderer: "Checkbox column with select-all checkbox in header.",
},
{
key: "is_admin",
titleKey: "columns.is_admin",
hiddenByDefault: true,
filterBehavior: "Facet filter based on boolean values.",
},
{
key: "is_staff",
titleKey: "columns.is_staff",
hiddenByDefault: true,
filterBehavior: "Facet filter based on boolean values.",
},
{
key: "id",
titleKey: "columns.id",
renderer: "Outline badge",
sortable: true,
},
{
key: "email",
titleKey: "columns.email",
renderer:
"Composite identity cell rendered by a dedicated user summary component, including email, UUID/token-related context, and online/offline indicators.",
},
{
key: "online_count",
titleKey: "columns.online_count",
renderer:
"Online devices badge showing current online_count against device_limit, with tooltip for unlimited vs limited semantics.",
sortable: true,
},
{
key: "banned",
titleKey: "columns.status",
renderer: "Status badge for banned vs normal.",
sortable: true,
},
{
key: "plan_id",
titleKey: "columns.subscription",
renderer: "Nested plan.name text",
},
{
key: "group_id",
titleKey: "columns.group",
renderer: "Nested group.name badge",
},
{
key: "total_used",
titleKey: "columns.used_traffic",
renderer:
"Usage progress bar with percentage and tooltip containing total traffic.",
},
{
key: "transfer_enable",
titleKey: "columns.total_traffic",
renderer: "Formatted total traffic text",
},
{
key: "expired_at",
titleKey: "columns.expire_time",
renderer:
"Status badge for permanent/remaining/expired with tooltip exposing full time, day delta, and next_reset_at when present.",
},
{
key: "balance",
titleKey: "columns.balance",
renderer: "Currency value",
},
{
key: "commission_balance",
titleKey: "columns.commission",
renderer: "Currency value",
},
{
key: "created_at",
titleKey: "columns.register_time",
renderer: "Registration time text",
},
{
key: "actions",
titleKey: "columns.actions",
renderer:
"Dropdown menu containing edit, assign order, copy subscribe URL, reset secret, orders link, invites filter shortcut, traffic records dialog, reset traffic dialog, and delete confirmation.",
},
],
mobileLayout: {
primaryField: "email",
gridFields: ["online_count", "transfer_enable", "used_traffic", "expired_at"],
},
},
dialogs: {
generateUsers: {
formFields: [
"email_prefix",
"email_suffix",
"password",
"expired_at",
"plan_id",
"generate_count",
"download_csv",
],
behavior: [
"If generate_count is empty, email_prefix becomes required.",
"If download_csv is enabled and generate_count is used, the response is handled as a Blob download.",
],
},
sendMail: {
scopes: ["selected", "filtered", "all"],
fields: ["subject", "content"],
templateSupport:
"Supports placeholder variables such as {{app.name}}, {{user.email}}, {{user.plan_name}}, etc.",
specialAction: "Apply system notice template button fills subject and content from built-in defaults.",
},
editUser: {
fields: [
"email",
"invite_user_email",
"password",
"balance",
"commission_balance",
"u",
"d",
"transfer_enable",
"expired_at",
"plan_id",
"banned",
"commission_type",
"commission_rate",
"discount",
"speed_limit",
"device_limit",
"is_admin",
"is_staff",
"remarks",
],
conversions: [
"u and d are displayed in GB with three decimals and converted back to bytes on submit.",
"transfer_enable is edited in GB and converted back to bytes on change.",
],
expireTimePresets: [
"permanent",
"1 month",
"3 months",
"specific datetime",
],
},
trafficRecords: {
columns: ["record_at", "u", "d", "server_rate", "total"],
purpose: "Shows paginated traffic usage history for a single user.",
},
},
interactions: [
"If the route opens with ?email=... the page seeds that value into the email column filter automatically.",
"Export CSV and batch ban both resolve their target scope from selected rows first, then filtered data, then all users.",
"Invites action does not navigate away; it rewrites current columnFilters to invite_user_id=eq:<current user id>.",
"Orders action deep-links into /finance/order?user_id=eq:<current user id>.",
"Copy URL action copies subscribe_url directly from the current row.",
"Reset secret, reset traffic, and delete all refetch the list after success.",
],
notes: [
"The page uses a provider to share edit-sheet state and refreshData across the table and side sheet.",
"Advanced filters are composed into table column filters, using operator prefixes such as eq:, gt:, lt:, and raw contains values.",
"Column visibility is user-controlled through a generic shared table view-options dropdown.",
],
sourceRefs: [
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:27389",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:300842",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:301426",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:303321",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:303835",
"frontend/admin/reverse/output/index-CO3BwsT2.pretty.js:304646",
],
});