feat(weibo): 增加外部单协作台账

This commit is contained in:
yml2213
2026-11-08 11:41:54 +08:00
parent a0afa430ec
commit 79cfd4a634
16 changed files with 5217 additions and 4 deletions
+2
View File
@@ -32,6 +32,7 @@ const HuyaElitePage = lazy(() => import('./pages/HuyaElitePage'));
const HuyaCollabPage = lazy(() => import('./pages/HuyaCollabPage'));
const HuyaBrowserExchangePage = lazy(() => import('./pages/HuyaBrowserExchangePage'));
const WeiboAccountsPage = lazy(() => import('./pages/WeiboAccountsPage'));
const WeiboCollabPage = lazy(() => import('./pages/WeiboCollabPage'));
const YybRechargePage = lazy(() => import('./pages/YybRechargePage'));
const AuditLogsPage = lazy(() => import('./pages/AuditLogsPage'));
@@ -107,6 +108,7 @@ function AppContent() {
<Route path="huya/collab" element={lazyRoute(<HuyaCollabPage />)} />
<Route path="huya/browser-exchange" element={lazyRoute(<HuyaBrowserExchangePage />)} />
<Route path="weibo/accounts" element={lazyRoute(<WeiboAccountsPage />)} />
<Route path="weibo/collab" element={lazyRoute(<WeiboCollabPage />)} />
<Route path="yyb/recharge" element={lazyRoute(<YybRechargePage />)} />
<Route path="proxy" element={lazyRoute(<ProxyPage />)} />
<Route path="automation" element={lazyRoute(<AutomationPage />)} />
+24
View File
@@ -15,4 +15,28 @@ export { loginApi } from './login';
export { proxyApi } from './proxy';
export { userApi } from './users';
export { weiboApi } from './weibo';
export { weiboCollabApi } from './weiboCollab';
export type {
WeiboCollabAccountLookup,
WeiboCollabAccountOption,
WeiboCollabArchiveResult,
WeiboCollabArchiveScope,
WeiboCollabBalanceCheckResult,
WeiboCollabExchangeCheckResult,
WeiboCollabGoods,
WeiboCollabLiveGoods,
WeiboCollabMetric,
WeiboCollabOrder,
WeiboCollabOrderCreate,
WeiboCollabOrderList,
WeiboCollabOrderUpdate,
WeiboCollabOwner,
WeiboCollabShop,
WeiboCollabStatus,
WeiboCollabSummary,
WeiboCollabTimeline,
WeiboCollabUnarchiveResult,
WeiboCollabVerdict,
WeiboCollabVerifyBatchResult,
} from './weiboCollab';
export { yybApi } from './yyb';
+408
View File
@@ -0,0 +1,408 @@
import api from './client';
export type WeiboCollabStatus =
| 'incomplete'
| 'to_recharge'
| 'recharged'
| 'exchange_pending'
| 'done'
| 'weidou_error'
| 'failed'
| 'void';
export type WeiboCollabArchiveScope = 'active' | 'archived' | 'all';
export type WeiboCollabVerdict = 'success' | 'failed' | 'unknown' | '';
export interface WeiboCollabShop {
id: number;
name: string;
sort_order: number;
is_active: boolean;
remark: string;
created_by: number | null;
updated_by: number | null;
created_at: string | null;
updated_at: string | null;
}
export interface WeiboCollabGoods {
id: number;
name: string;
price: number;
goods_id: number | null;
goods_image: string;
sort_order: number;
is_active: boolean;
remark: string;
created_by: number | null;
updated_by: number | null;
created_at: string | null;
updated_at: string | null;
}
export interface WeiboCollabLiveGoods {
id: number;
goods_name: string;
goods_image: string;
price: number;
remain_count: number | null;
is_sold_out: boolean;
}
export interface WeiboCollabAccountLookup {
ok: boolean;
message: string;
account_id: number;
uid: string;
nickname: string;
is_enabled: boolean;
ck_check_status: string;
ck_check_message: string;
is_bound: boolean | null;
game_role_name: string;
weidou_balance: number | null;
goods: WeiboCollabLiveGoods[];
orders_using_account: Array<{
id: number;
order_no: string;
status: WeiboCollabStatus;
status_label: string;
}>;
}
export interface WeiboCollabAccountOption {
id: number;
uid: string;
nickname: string;
game_role_name: string;
weidou_balance: number | null;
ck_check_status: string;
}
export interface WeiboCollabOrder {
id: number;
order_no: string;
shop: string;
owner_id: number | null;
owner_name: string;
account_id: number | null;
account_uid: string;
account_nickname: string;
account_exists: boolean;
account_enabled: boolean;
account_ck_status: string;
account_ck_message: string;
account_is_bound: boolean | null;
game_role_name: string;
bind_snapshot_at: string | null;
goods_id: number | null;
goods_name: string;
goods_image: string;
required_weidou: number | null;
home_images: string[];
remark: string;
status: WeiboCollabStatus;
status_label: string;
next_status: WeiboCollabStatus | null;
missing_fields: string[];
weidou_balance: number | null;
weidou_required_total: number | null;
weidou_surplus: number | null;
weidou_threshold: number | null;
weidou_checked_at: string | null;
weidou_check_reason: string;
weidou_check_message: string;
weidou_check_detail: Record<string, unknown> | null;
exchange_started_at: string | null;
exchange_checked_at: string | null;
exchange_record_key: string;
exchange_record_snapshot: Record<string, unknown> | null;
exchange_verdict: WeiboCollabVerdict;
exchange_message: string;
recharged_at: string | null;
done_at: string | null;
void_reason: string;
is_archived: boolean;
archived_at: string | null;
archived_by: number | null;
archived_by_name: string;
archive_reason: string;
created_by: number | null;
created_by_name: string;
updated_by: number | null;
updated_by_name: string;
version: number;
created_at: string | null;
updated_at: string | null;
account_cluster: {
total: number;
orders: Array<{
id: number;
order_no: string;
status: WeiboCollabStatus;
status_label: string;
goods_name: string;
}>;
} | null;
last_metric_at: string | null;
last_metric_message: string;
}
export interface WeiboCollabOrderList {
items: WeiboCollabOrder[];
total: number;
page: number;
page_size: number;
}
export interface WeiboCollabSummary {
total: number;
by_status: Record<string, number>;
account_missing: number;
account_disabled: number;
ck_invalid: number;
archived_total: number;
}
export interface WeiboCollabOwner {
id: number;
username: string;
}
export interface WeiboCollabMetric {
id: number;
order_id: number;
order_no: string;
account_uid: string;
weidou_balance: number | null;
weidou_required_total: number | null;
weidou_surplus: number | null;
records_total: number;
records_matched: number;
verdict: WeiboCollabVerdict;
verdict_label: string;
message: string;
source: string;
created_at: string | null;
}
export interface WeiboCollabTimeline {
id: number;
action: string;
username: string;
detail: string;
success: boolean | null;
created_at: string | null;
}
export interface WeiboCollabOrderCreate {
order_no: string;
shop?: string;
owner_id?: number | null;
account_id?: number | null;
goods_id?: number | null;
goods_name?: string;
goods_image?: string;
required_weidou?: number | null;
home_images?: string[];
remark?: string;
draft?: boolean;
require_verified?: boolean;
}
export interface WeiboCollabOrderUpdate {
order_no?: string;
shop?: string;
owner_id?: number | null;
goods_id?: number | null;
goods_name?: string;
goods_image?: string;
required_weidou?: number | null;
home_images?: string[];
remark?: string;
expected_version?: number;
}
export interface WeiboCollabBalanceCheckResult {
total: number;
updated: number;
threshold: number;
groups: Array<{
account_id: number;
uid: string;
status: string;
status_label: string;
balance: number | null;
required_total: number;
surplus: number | null;
threshold: number;
reason: string;
message: string;
order_ids: number[];
}>;
failures: Array<{ id: number; order_no: string; message: string }>;
skipped: Array<{ id: number; order_no: string; message: string }>;
}
export interface WeiboCollabExchangeCheckResult {
total: number;
success: number;
failed: number;
unknown: number;
results: Array<{
id: number;
order_no: string;
ok: boolean;
verdict: WeiboCollabVerdict;
verdict_label: string;
message: string;
records_total: number;
records_matched: number;
status: WeiboCollabStatus;
status_label: string;
metric_id: number;
}>;
failures: Array<{ id: number; order_no: string; message: string }>;
}
export interface WeiboCollabVerifyBatchResult {
success: boolean;
results: Array<{
id: number;
order_no: string;
success: boolean;
message: string;
}>;
}
export interface WeiboCollabArchiveResult {
total: number;
archived: number;
skipped: number;
results: Array<{ id: number; order_no: string; ok: boolean; message: string }>;
}
export interface WeiboCollabUnarchiveResult {
total: number;
unarchived: number;
skipped: number;
results: Array<{ id: number; order_no: string; ok: boolean; message: string }>;
}
export const weiboCollabApi = {
accounts: () =>
api.get<WeiboCollabAccountOption[], WeiboCollabAccountOption[]>(
'/weibo/external-orders/accounts/options',
),
summary: (params: { include_void?: boolean; archive_scope?: WeiboCollabArchiveScope }) =>
api.get<WeiboCollabSummary, WeiboCollabSummary>('/weibo/external-orders/summary', {
params,
}),
owners: () =>
api.get<WeiboCollabOwner[], WeiboCollabOwner[]>('/weibo/external-orders/owners'),
listOrders: (params: Record<string, unknown>) =>
api.get<WeiboCollabOrderList, WeiboCollabOrderList>('/weibo/external-orders', {
params,
}),
getOrder: (id: number) =>
api.get<WeiboCollabOrder, WeiboCollabOrder>(`/weibo/external-orders/${id}`),
createOrder: (data: WeiboCollabOrderCreate) =>
api.post<WeiboCollabOrder, WeiboCollabOrder>('/weibo/external-orders', data, {
timeout: 120000,
}),
updateOrder: (id: number, data: WeiboCollabOrderUpdate) =>
api.put<WeiboCollabOrder, WeiboCollabOrder>(`/weibo/external-orders/${id}`, data),
setAccount: (id: number, accountId: number, expectedVersion?: number) =>
api.post<WeiboCollabOrder, WeiboCollabOrder>(
`/weibo/external-orders/${id}/account`,
{ account_id: accountId, expected_version: expectedVersion },
{ timeout: 120000 },
),
verifyOrder: (id: number) =>
api.post<WeiboCollabOrder, WeiboCollabOrder>(
`/weibo/external-orders/${id}/verify`,
undefined,
{ timeout: 120000 },
),
updateStatus: (
id: number,
data: {
status: WeiboCollabStatus;
reason?: string;
rollback?: boolean;
expected_version?: number;
},
) =>
api.post<WeiboCollabOrder, WeiboCollabOrder>(
`/weibo/external-orders/${id}/status`,
data,
),
batchStatus: (data: {
ids: number[];
status: WeiboCollabStatus;
reason?: string;
rollback?: boolean;
}) => api.post('/weibo/external-orders/status/batch', data),
verifyBatch: (ids: number[]) =>
api.post<WeiboCollabVerifyBatchResult, WeiboCollabVerifyBatchResult>(
'/weibo/external-orders/verify/batch',
ids,
{ timeout: 120000 },
),
checkBalance: (ids: number[], threshold: number) =>
api.post<WeiboCollabBalanceCheckResult, WeiboCollabBalanceCheckResult>(
'/weibo/external-orders/balances/check',
{ ids, threshold },
{ timeout: 120000 },
),
checkExchangeRecords: (ids: number[]) =>
api.post<WeiboCollabExchangeCheckResult, WeiboCollabExchangeCheckResult>(
'/weibo/external-orders/exchange-records/check',
{ ids },
{ timeout: 120000 },
),
archive: (ids: number[], reason = '') =>
api.post<WeiboCollabArchiveResult, WeiboCollabArchiveResult>(
'/weibo/external-orders/archive',
{ ids, reason },
),
unarchive: (ids: number[]) =>
api.post<WeiboCollabUnarchiveResult, WeiboCollabUnarchiveResult>(
'/weibo/external-orders/unarchive',
ids,
),
deleteOrder: (id: number) => api.delete(`/weibo/external-orders/${id}`),
metrics: (id: number) =>
api.get<WeiboCollabMetric[], WeiboCollabMetric[]>(
`/weibo/external-orders/${id}/metrics`,
),
timeline: (id: number) =>
api.get<WeiboCollabTimeline[], WeiboCollabTimeline[]>(
`/weibo/external-orders/${id}/timeline`,
),
lookupAccount: (accountId: number, withGoods = true) =>
api.post<WeiboCollabAccountLookup, WeiboCollabAccountLookup>(
'/weibo/external-orders/accounts/lookup',
{ account_id: accountId, with_goods: withGoods },
{ timeout: 120000 },
),
listShops: () =>
api.get<WeiboCollabShop[], WeiboCollabShop[]>('/weibo/collab-shops'),
createShop: (data: { name: string; remark?: string }) =>
api.post<WeiboCollabShop, WeiboCollabShop>('/weibo/collab-shops', data),
updateShop: (id: number, data: Partial<Omit<WeiboCollabShop, 'id'>>) =>
api.put<WeiboCollabShop, WeiboCollabShop>(`/weibo/collab-shops/${id}`, data),
deleteShop: (id: number) => api.delete(`/weibo/collab-shops/${id}`),
listGoods: () =>
api.get<WeiboCollabGoods[], WeiboCollabGoods[]>('/weibo/collab-goods'),
createGoods: (data: {
name: string;
price: number;
goods_id?: number | null;
goods_image?: string;
remark?: string;
}) => api.post<WeiboCollabGoods, WeiboCollabGoods>('/weibo/collab-goods', data),
updateGoods: (id: number, data: Partial<Omit<WeiboCollabGoods, 'id'>>) =>
api.put<WeiboCollabGoods, WeiboCollabGoods>(`/weibo/collab-goods/${id}`, data),
deleteGoods: (id: number) => api.delete(`/weibo/collab-goods/${id}`),
};
+3
View File
@@ -129,6 +129,9 @@ export default function MainLayout({ onLogout }: { onLogout?: () => void }) {
if (can('weibo:view')) {
weiboItems.push({ key: '/weibo/accounts', label: '账号与绑定', icon: <MessageOutlined /> });
}
if (can('weibo:collab:view')) {
weiboItems.push({ key: '/weibo/collab', label: '外部单协作', icon: <FileExcelOutlined /> });
}
if (douyuItems.length > 0) {
menuItems.push({ key: 'group-douyu', type: 'group', label: '斗鱼', children: douyuItems });
File diff suppressed because it is too large Load Diff