mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 16:46:37 +08:00
裁剪
swagger 移除 merchant swagger 改造首页内容为通用后台管理系统定位 - 修改首页标题从 'LINUX DO Credit' 改为 'Modern Platform' - 更新副标题为 '为二次开发而生' - 更新首页描述为通用平台的特点 - 更新首页特性标签为 '开箱即用、高度可扩展、工业级基建' - 修改展示卡片为技术栈和二次开发相关 - 更新开发者示例代码为通用的注册和 API Key 获取示例 - 更新页脚品牌名为 'Modern Platform' - 调整页脚导航链接为通用平台相关内容 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> 去除遗留 裁剪 移除 /api/v1/user/pay-key 相关代码 - 删除后端 UpdatePayKey 处理器函数和 UpdatePayKeyRequest 结构体 - 删除 User 模型中的 PayKey 字段 - 删除 User.VerifyPayKey 方法 - 删除 EncryptPayKeyFailed 错误常量 - 删除 /api/v1/user/pay-key PUT 路由 - 删除 OAuth 返回中的 IsPayKey 字段 - 删除前端 UserService.updatePayKey 方法 - 删除前端所有支付密钥 UI 和逻辑 - 更新相关的导出和注释 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> 去除遗留 api 修正 系统配置 前端裁剪 后端裁剪 init
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import axios, { AxiosError, AxiosResponse, CancelTokenSource, InternalAxiosRequestConfig } from 'axios';
|
||||
import { toast } from 'sonner';
|
||||
import { showRiskWarningToast } from '@/components/common/risk/risk-warning-toast';
|
||||
import { apiConfig } from './config';
|
||||
import {
|
||||
ApiErrorBase,
|
||||
@@ -37,108 +36,7 @@ const cancelTokens = new Map<string, CancelTokenSource>();
|
||||
*/
|
||||
const pendingRequests = new Map<string, Promise<AxiosResponse<ApiResponse>>>();
|
||||
|
||||
const RISK_LEVEL_HEADER = 'x-credit-risk-level';
|
||||
const RISK_LABELS_HEADER = 'x-credit-risk-labels';
|
||||
const RISK_ITEMS_HEADER = 'x-credit-risks';
|
||||
const RISK_BLOCKED_CODE = 'RISK_BLOCKED';
|
||||
const RISK_BLOCKED_EVENT = 'credit-risk-blocked';
|
||||
|
||||
interface RiskItem {
|
||||
label: string;
|
||||
value?: string;
|
||||
desc?: string;
|
||||
}
|
||||
|
||||
interface RiskInfo {
|
||||
risk_level: string;
|
||||
risk_labels: string[];
|
||||
risks: RiskItem[];
|
||||
}
|
||||
|
||||
function decodeBase64JSON(value?: string): unknown {
|
||||
if (!value || typeof window === 'undefined') return [];
|
||||
|
||||
try {
|
||||
const binary = window.atob(value);
|
||||
const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
|
||||
const json = new TextDecoder().decode(bytes);
|
||||
return JSON.parse(json);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeRiskItems(value: unknown): RiskItem[] {
|
||||
if (!Array.isArray(value)) return [];
|
||||
|
||||
return value.reduce<RiskItem[]>((items, item) => {
|
||||
if (!item || typeof item !== 'object') return items;
|
||||
|
||||
const label = 'label' in item ? (item as { label?: unknown }).label : undefined;
|
||||
if (typeof label !== 'string' || !label.trim()) return items;
|
||||
|
||||
const value = 'value' in item ? (item as { value?: unknown }).value : undefined;
|
||||
const desc = 'desc' in item ? (item as { desc?: unknown }).desc : undefined;
|
||||
items.push({
|
||||
label: label.trim(),
|
||||
value: typeof value === 'string' ? value.trim() : undefined,
|
||||
desc: typeof desc === 'string' ? desc.trim() : undefined,
|
||||
});
|
||||
|
||||
return items;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function normalizeRiskLabels(value: unknown): string[] {
|
||||
return Array.isArray(value) ? value.filter((label): label is string => typeof label === 'string' && !!label.trim()).map(label => label.trim()) : [];
|
||||
}
|
||||
|
||||
function riskLabelsFromItems(items: RiskItem[]): string[] {
|
||||
return items.map(item => item.label).filter(Boolean);
|
||||
}
|
||||
|
||||
function riskInfoFromHeaders(headers: AxiosResponse['headers']): RiskInfo | null {
|
||||
const riskLevel = headers[RISK_LEVEL_HEADER];
|
||||
if (typeof riskLevel !== 'string' || !riskLevel) return null;
|
||||
|
||||
const riskLabelsHeader = headers[RISK_LABELS_HEADER];
|
||||
const riskItemsHeader = headers[RISK_ITEMS_HEADER];
|
||||
const risks = typeof riskItemsHeader === 'string' ? normalizeRiskItems(decodeBase64JSON(riskItemsHeader)) : [];
|
||||
const labels = typeof riskLabelsHeader === 'string' ? normalizeRiskLabels(decodeBase64JSON(riskLabelsHeader)) : riskLabelsFromItems(risks);
|
||||
|
||||
return {
|
||||
risk_level: riskLevel,
|
||||
risk_labels: labels,
|
||||
risks,
|
||||
};
|
||||
}
|
||||
|
||||
function riskInfoFromDetails(details: unknown): RiskInfo | null {
|
||||
if (!details || typeof details !== 'object') return null;
|
||||
|
||||
const riskLevel = 'risk_level' in details ? (details as { risk_level?: unknown }).risk_level : undefined;
|
||||
const riskLabels = 'risk_labels' in details ? (details as { risk_labels?: unknown }).risk_labels : undefined;
|
||||
const riskItems = 'risks' in details ? (details as { risks?: unknown }).risks : undefined;
|
||||
if (typeof riskLevel !== 'string' || !riskLevel) return null;
|
||||
|
||||
const risks = normalizeRiskItems(riskItems);
|
||||
const labels = normalizeRiskLabels(riskLabels);
|
||||
|
||||
return {
|
||||
risk_level: riskLevel,
|
||||
risk_labels: labels.length ? labels : riskLabelsFromItems(risks),
|
||||
risks,
|
||||
};
|
||||
}
|
||||
|
||||
function showRiskWarning(riskInfo: RiskInfo): void {
|
||||
showRiskWarningToast(riskInfo);
|
||||
}
|
||||
|
||||
function showRiskBlockedDialog(riskInfo: RiskInfo): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
window.dispatchEvent(new CustomEvent<RiskInfo>(RISK_BLOCKED_EVENT, { detail: riskInfo }));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求的唯一键
|
||||
@@ -204,11 +102,6 @@ apiClient.interceptors.response.use(
|
||||
cancelTokens.delete(requestKey);
|
||||
pendingRequests.delete(requestKey);
|
||||
|
||||
const riskInfo = riskInfoFromHeaders(response.headers);
|
||||
if (riskInfo) {
|
||||
showRiskWarning(riskInfo);
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
(error: AxiosError<ApiError>) => {
|
||||
@@ -232,17 +125,6 @@ apiClient.interceptors.response.use(
|
||||
|
||||
/* 403 权限不足错误 */
|
||||
if (error.response?.status === 403) {
|
||||
if (error.response.data?.error_code === RISK_BLOCKED_CODE) {
|
||||
const riskInfo = riskInfoFromDetails(error.response.data.details) || riskInfoFromHeaders(error.response.headers);
|
||||
if (riskInfo) {
|
||||
showRiskBlockedDialog(riskInfo);
|
||||
}
|
||||
|
||||
return Promise.reject(
|
||||
new ForbiddenError(error.response.data?.error_msg || '账号存在风险', RISK_BLOCKED_CODE, error.response.data?.details),
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.reject(
|
||||
new ForbiddenError(error.response.data?.error_msg || '权限不足,请过盾后重试', error.response.data?.error_code, error.response.data?.details),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user