| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- const fs = require("fs-extra");
- const path = require("path");
- const axios = require("axios");
- const FormData = require("form-data");
- // ================= 配置区域 =================
- const CONFIG = {
- baseUrl: "https://color.jccytech.cn", // 你的服务器地址
- loginUrl: "/napi/web/auth/sign-in", // 登录接口路径
- uploadUrl: "/napi/jigstack/web/jigstack", // 上传接口路径
- credentials: {
- username: "guoziyun", // 管理员账号
- password: "PD9IV73OQoLXAiyyT6Uo", // 管理员密码
- },
- metadataFile: "./image_metadata.json", // 上一步生成的 JSON 文件
- concurrency: 1, // 并发数,建议先设为 1 稳定上传
- };
- let sessionCookie = "";
- /**
- * 1. 模拟登录获取 Session
- */
- async function login() {
- console.log("正在尝试登录...");
- try {
- const response = await axios.post(
- `${CONFIG.baseUrl}${CONFIG.loginUrl}`,
- CONFIG.credentials
- );
- // 从 set-cookie 头部提取 session id
- const cookies = response.headers["set-cookie"];
- if (!cookies) throw new Error("登录失败,未获取到 Cookie");
- // 格式通常是 connect.sid=s%3A...; Path=/; HttpOnly
- sessionCookie = cookies.map((c) => c.split(";")[0]).join("; ");
- console.log("登录成功,Session 已获取");
- } catch (err) {
- console.error("登录异常:", err.message);
- process.exit(1);
- }
- }
- /**
- * 2. 执行单张图片上传
- */
- async function uploadImage(item) {
- console.log(`正在上传: ${item.filename} (ID: ${item.id})`);
- const form = new FormData();
- // 基础参数 (注意:tags 需要转回逗号分隔的字符串,因为后端执行了 .split(','))
- form.append("tags", item.tags.join(","));
- form.append("from", item.from);
- form.append("width", item.width);
- form.append("height", item.height);
- // 文件流 (对应后端 fileHash.raw)
- // 如果你的后端 check 了字段名,必须确保这里是 'raw'
- const fileStream = fs.createReadStream(item.localPath);
- form.append("raw", fileStream);
- try {
- const response = await axios.post(
- `${CONFIG.baseUrl}${CONFIG.uploadUrl}`,
- form,
- {
- headers: {
- ...form.getHeaders(), // 必须包含 multipart 的 boundary
- Cookie: sessionCookie,
- },
- // 防止大文件上传超时
- maxContentLength: Infinity,
- maxBodyLength: Infinity,
- timeout: 60000,
- }
- );
- console.log(`✅ 上传成功: ${item.id}, Server ID: ${response.data._id}`);
- return true;
- } catch (err) {
- const errorMsg = err.response
- ? JSON.stringify(err.response.data)
- : err.message;
- console.error(`❌ 上传失败: ${item.id} | 原因: ${errorMsg}`);
- return false;
- }
- }
- /**
- * 3. 主程序逻辑
- */
- async function startUpload() {
- // 1. 登录
- await login();
- // 2. 读取元数据
- const metadata = await fs.readJson(CONFIG.metadataFile);
- console.log(`共加载 ${metadata.length} 条待上传数据`);
- // 3. 循环上传
- for (const item of metadata) {
- const success = await uploadImage(item);
- // 如果失败了,可以根据需要决定是否停止或继续
- if (!success) {
- console.log("跳过当前失败项目,继续下一个...");
- }
- // 稍微停顿一下,避免瞬时压力过大
- await new Promise((resolve) => setTimeout(resolve, 500));
- }
- console.log("🎉 所有上传任务处理完毕");
- }
- module.exports = { startUpload };
- if (require.main === module) {
- startUpload();
- }
|