init: 信创文件安全传输系统内外网本地 Docker 部署

包含 s-file 后端、React 前端、MeshSafe 安全检测对接,以及内外网两套
compose/nginx/配置(仅前端 28180/28280 对外发布,其余端口不暴露)。

说明:deploy/config/application-iw.yml 与 application-ow.yml 按维护者
明确要求原样入库,其中含本机 Docker 用的库口令、RabbitMQ 口令与 JWT
密钥;上生产前需替换。
This commit is contained in:
KodouWZF
2026-11-02 10:59:03 +08:00
commit 47273ae3fd
2190 changed files with 305040 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
import { useState, useEffect } from "react";
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import * as XLSX from "xlsx";
type Props = {
url?: string;
};
export function ExcelPreview({ url }: Props) {
const [sheets, setSheets] = useState<{ name: string; data: any[][] }[]>([]);
const [activeSheet, setActiveSheet] = useState(0);
const { data, isLoading, error, isError } = useQuery({
queryKey: ["excel", url],
queryFn: () => axios.get(url!, { responseType: "arraybuffer" }),
enabled: !!url,
});
useEffect(() => {
if (data?.data) {
try {
const workbook = XLSX.read(data.data, { type: "array" });
const sheetData = workbook.SheetNames.map((name) => {
const worksheet = workbook.Sheets[name];
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
return { name, data: jsonData as any[][] };
});
setSheets(sheetData);
} catch (err) {
}
}
}, [data]);
if (!url) {
return (
<div className="w-full h-full flex items-center justify-center text-muted-foreground">
Excel 文件地址无效
</div>
);
}
if (isLoading) {
return (
<div className="flex items-center justify-center h-full">
<div>加载中...</div>
</div>
);
}
if (isError) {
return (
<div className="flex items-center justify-center h-full text-red-500">
{error?.message || "加载失败"}
</div>
);
}
if (sheets.length === 0) {
return (
<div className="flex items-center justify-center h-full text-muted-foreground">
Excel 文件为空或格式不正确
</div>
);
}
const currentSheet = sheets[activeSheet];
return (
<div className="h-full flex flex-col">
{sheets.length > 1 && (
<div className="flex-none border-b bg-slate-50 dark:bg-slate-900 p-2 flex gap-2 overflow-x-auto">
{sheets.map((sheet, index) => (
<button
key={index}
onClick={() => setActiveSheet(index)}
className={`px-4 py-2 rounded text-sm whitespace-nowrap transition-colors ${
activeSheet === index
? "bg-primary text-primary-foreground"
: "bg-white dark:bg-slate-800 hover:bg-slate-100 dark:hover:bg-slate-700"
}`}
>
{sheet.name}
</button>
))}
</div>
)}
<div className="flex-auto overflow-auto">
<table className="w-full border-collapse text-sm">
<tbody>
{currentSheet.data.map((row, rowIndex) => (
<tr key={rowIndex} className="border-b">
{row.map((cell, cellIndex) => (
<td
key={cellIndex}
className="border-r px-3 py-2 whitespace-nowrap"
>
{cell !== null && cell !== undefined ? String(cell) : ""}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}