diff --git a/web/app/dashboard/config/page.tsx b/web/app/dashboard/config/page.tsx index 0f7a715..f1674bb 100644 --- a/web/app/dashboard/config/page.tsx +++ b/web/app/dashboard/config/page.tsx @@ -67,6 +67,7 @@ export default function ConfigPage() { defaultTarget: "", extensionMap: {} as Record, sizeThreshold: 0, + sizeUnit: 'MB' as 'B' | 'KB' | 'MB' | 'GB', }) const [fixedPathDialogOpen, setFixedPathDialogOpen] = useState(false) const [editingFixedPath, setEditingFixedPath] = useState(null) @@ -79,6 +80,13 @@ export default function ConfigPage() { const [editingPath, setEditingPath] = useState(null) const [newExtension, setNewExtension] = useState({ ext: "", target: "" }) + const [editingPathData, setEditingPathData] = useState<{ + path: string; + defaultTarget: string; + sizeThreshold: number; + sizeUnit: 'B' | 'KB' | 'MB' | 'GB'; + } | null>(null); + const fetchConfig = useCallback(async () => { try { const token = localStorage.getItem("token") @@ -168,11 +176,32 @@ export default function ConfigPage() { } } - const addPath = () => { + const handleEditPath = (path: string, target: PathMapping | string) => { + setPathDialogOpen(true) + if (typeof target === 'string') { + setEditingPathData({ + path, + defaultTarget: target, + sizeThreshold: 0, + sizeUnit: 'MB' + }) + } else { + const sizeThreshold = target.SizeThreshold || 0 + const { value, unit } = convertBytesToUnit(sizeThreshold) + setEditingPathData({ + path, + defaultTarget: target.DefaultTarget, + sizeThreshold: value, + sizeUnit: unit + }) + } + } + + const addOrUpdatePath = () => { if (!config) return - const { path, defaultTarget, sizeThreshold, extensionMap } = newPathData + const data = editingPathData ? editingPathData : newPathData - if (!path || !defaultTarget) { + if (!data.path || !data.defaultTarget) { toast({ title: "错误", description: "路径和默认目标不能为空", @@ -181,20 +210,39 @@ export default function ConfigPage() { return } + const sizeInBytes = convertToBytes(data.sizeThreshold, data.sizeUnit) const newConfig = { ...config } - newConfig.MAP[path] = { - DefaultTarget: defaultTarget, - ...(sizeThreshold ? { SizeThreshold: sizeThreshold } : {}), - ...(Object.keys(extensionMap).length > 0 ? { ExtensionMap: extensionMap } : {}) + const existingMapping = newConfig.MAP[data.path] + + if (editingPathData) { + if (typeof existingMapping === 'object') { + newConfig.MAP[data.path] = { + DefaultTarget: data.defaultTarget, + SizeThreshold: sizeInBytes, + ExtensionMap: existingMapping.ExtensionMap || {} + } + } else { + newConfig.MAP[data.path] = { + DefaultTarget: data.defaultTarget, + SizeThreshold: sizeInBytes + } + } + } else { + newConfig.MAP[data.path] = { + DefaultTarget: data.defaultTarget, + SizeThreshold: sizeInBytes + } } setConfig(newConfig) setPathDialogOpen(false) + setEditingPathData(null) setNewPathData({ path: "", defaultTarget: "", extensionMap: {}, sizeThreshold: 0, + sizeUnit: 'MB', }) } @@ -405,34 +453,78 @@ export default function ConfigPage() { - 添加路径映射 + {editingPathData ? "编辑路径映射" : "添加路径映射"}
- + setNewPathData({ ...newPathData, path: e.target.value })} + value={editingPathData ? editingPathData.path : newPathData.path} + onChange={(e) => editingPathData + ? setEditingPathData({ ...editingPathData, path: e.target.value }) + : setNewPathData({ ...newPathData, path: e.target.value }) + } placeholder="/example" /> +

+ 请输入需要代理的路径 +

setNewPathData({ ...newPathData, defaultTarget: e.target.value })} + value={editingPathData ? editingPathData.defaultTarget : newPathData.defaultTarget} + onChange={(e) => editingPathData + ? setEditingPathData({ ...editingPathData, defaultTarget: e.target.value }) + : setNewPathData({ ...newPathData, defaultTarget: e.target.value }) + } placeholder="https://example.com" /> +

+ 默认的回源地址,所有请求都会转发到这个地址 +

- - setNewPathData({ ...newPathData, sizeThreshold: parseInt(e.target.value) })} - /> + +
+ { + const value = parseInt(e.target.value) || 0 + if (editingPathData) { + setEditingPathData({ ...editingPathData, sizeThreshold: value }) + } else { + setNewPathData({ ...newPathData, sizeThreshold: value }) + } + }} + min={0} + /> + +
+

+ 文件大小超过此阈值时,将使用扩展名映射中的目标地址(如果存在) +

- +
@@ -442,7 +534,7 @@ export default function ConfigPage() { 路径 - 目标 + 默认目标 大小阈值 扩展名映射 操作 @@ -456,14 +548,18 @@ export default function ConfigPage() { {typeof target === 'string' ? target : target.DefaultTarget} - {typeof target === 'object' && target.SizeThreshold ? target.SizeThreshold : '-'} + {typeof target === 'object' && target.SizeThreshold ? ( + + {formatBytes(target.SizeThreshold)} + + ) : '-'} {typeof target === 'object' && target.ExtensionMap ? (
{Object.entries(target.ExtensionMap).map(([ext, url]) => (
- {ext}: {url} + {ext}: {truncateUrl(url)} +
@@ -670,4 +779,43 @@ export default function ConfigPage() {
) +} + +// 辅助函数:格式化字节大小 +const formatBytes = (bytes: number) => { + if (bytes === 0) return '0 B' + const k = 1024 + const sizes = ['B', 'KB', 'MB', 'GB'] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}` +} + +// 辅助函数:截断 URL +const truncateUrl = (url: string) => { + if (url.length > 30) { + return url.substring(0, 27) + '...' + } + return url +} + +// 辅助函数:单位转换 +const convertToBytes = (value: number, unit: 'B' | 'KB' | 'MB' | 'GB'): number => { + const multipliers = { + 'B': 1, + 'KB': 1024, + 'MB': 1024 * 1024, + 'GB': 1024 * 1024 * 1024 + } + return value * multipliers[unit] +} + +const convertBytesToUnit = (bytes: number): { value: number, unit: 'B' | 'KB' | 'MB' | 'GB' } => { + if (bytes === 0) return { value: 0, unit: 'MB' } + const k = 1024 + const sizes: Array<'B' | 'KB' | 'MB' | 'GB'> = ['B', 'KB', 'MB', 'GB'] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return { + value: Number((bytes / Math.pow(k, i)).toFixed(2)), + unit: sizes[i] + } } \ No newline at end of file