Commit 90fd3ed3 by linjinhong

feat:修改下载素材 下载排版方法

parent 26c55257
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -39,6 +39,7 @@
"express": "^4.17.1",
"fabric": "^6.7.0",
"html2canvas": "^1.4.1",
"lodash": "^4.18.1",
"lodash-id": "^0.14.0",
"log4js": "^6.9.1",
"moment": "^2.30.1",
......
......@@ -4,8 +4,11 @@ import { app, protocol, BrowserWindow, globalShortcut } from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import { createServer } from "@/server/index.js";
import { autoUpdater } from "electron-updater";
const registerDownloadIpc = require("@/utils/download-file.js");
import downloadQueue from "@/utils/download-queue";
const {
registerTypesettingDownloadIpc
} = require("@/utils/download-typesetting");
const fs = require("fs");
import path from "path"; // 引入 path 模块
......@@ -30,6 +33,8 @@ const winURL =
? "http://localhost:8050"
: `file://${__dirname}/index.html`;
registerDownloadIpc();
registerTypesettingDownloadIpc();
async function createWindow() {
win = new BrowserWindow({
width: 1500,
......
......@@ -52,7 +52,9 @@ export const pathMap = {
listOperationByBatch: "factory/podOrderBatchDownload/listOperationByBatch",
//排版
replenishmentComposingDesignImages:
"factory/podOrderOperation/replenishmentComposingDesignImages"
"factory/podOrderOperation/replenishmentComposingDesignImages",
//获取单个批次号信息
podOrderBatchDownload: "factory/podOrderBatchDownload/get"
};
// 操作单状态枚举
export const statusMap = {
......
......@@ -7,7 +7,7 @@ import {
createBatchFolder,
downloadDTFFiles
} from "@/server/utils";
const { downloadPngList } = require("@/utils/download-queue");
const {
cropImageTransparentEdges,
cropTransparentEdges,
......@@ -564,7 +564,8 @@ export default {
//获取国家名称及代码
getAllCountry: async (req, res) => {
const token = req.headers["jwt-token"];
let url = "https://factory.jomalls.com/api/logisticsAddress/getAllCountry";
env = getHostApi().apiApiHost;
let url = `${env}/logisticsAddress/getAllCountry`;
try {
let { data } = await axios.get(url, { headers: { "jwt-token": token } });
......@@ -671,16 +672,7 @@ export default {
res.json({ code: 500, msg: error });
}
},
downloadMaterial: async (req, res) => {
try {
const { urls, targetPath } = req.body;
const data = await downloadPngList(urls, targetPath);
res.send(data);
} catch (error) {
console.log("downloadMaterial", error);
res.json({ code: 500, msg: error });
}
},
//获取生产配置
productionConfig: async (req, res) => {
env = getHostApi().apiApiHost;
......@@ -816,5 +808,22 @@ export default {
console.log("checkInventory", error);
res.json({ code: 500, msg: error });
}
},
podOrderBatchDownload: async (req, res) => {
env = getHostApi().apiApiHost;
const token = req.headers["jwt-token"];
const { id } = req.body;
let url = pathMap["podOrderBatchDownload"];
try {
let { data } = await axios.get(`${env}/${url}?id=${id}`, {
headers: { "jwt-token": token }
});
res.json({ code: 200, data });
} catch (error) {
console.log("checkInventory", error);
res.json({ code: 500, msg: error });
}
}
};
......@@ -54,9 +54,6 @@ router.post("/saveImgByUrl", fn.saveImgByUrl);
//获取目标路径文件夹下所以文件
router.post("/createBatchFolder", fn.createBatchFolder);
//获下载原素材
router.post("/downloadMaterial", fn.downloadMaterial);
//复制文件夹下文件
router.post("/copySingleImageFn", fn.copySingleImageFn);
......@@ -74,12 +71,14 @@ autoRegisterRouter(
"psReComposingDesignImages",
fn.psReComposingDesignImages
);
//重新合成排版
//排版
autoRegisterRouter(
router,
"replenishmentComposingDesignImages",
fn.replenishmentComposingDesignImages
);
//排版
autoRegisterRouter(router, "podOrderBatchDownload", fn.podOrderBatchDownload);
//根据批次分页查询操作单
autoRegisterRouter(router, "listOperationByBatch", fn.listOperationByBatch);
......
......@@ -58,9 +58,9 @@ service.interceptors.response.use(
showClose: true,
message: res.msg || res.message || "Error"
});
setTimeout(() => {
location.reload();
}, 500);
// setTimeout(() => {
// location.reload();
// }, 500);
return Promise.reject(new Error(res.msg || res.message || "Error"));
}
......
const path = require("path");
const fs = require("fs");
const http = require("http");
const https = require("https");
const url = require("url");
/* ===================== 基础工具函数 ===================== */
/**
* 从URL提取文件名
*/
function getFileName(urlStr) {
const formatUrl = urlStr.replace(/\\/g, "/");
return path.basename(formatUrl);
}
/**
* 判断是否为绝对URL
*/
function isAbsoluteUrl(urlStr) {
return /^https?:\/\//i.test(urlStr);
}
/**
* 补全相对路径为完整URL
*/
function resolveUrl(urlStr, baseUrl) {
if (isAbsoluteUrl(urlStr)) return urlStr;
return `${baseUrl.replace(/\/$/, "")}/${urlStr.replace(/^\//, "")}`;
}
/**
* 递归创建目录
*/
async function ensureDir(dirPath) {
await fs.promises.mkdir(dirPath, { recursive: true });
}
/**
* 判断文件是否存在
*/
async function isFileExists(filePath) {
try {
await fs.promises.access(filePath, fs.constants.F_OK);
return true;
} catch (e) {
return false;
}
}
/**
* 并发限制器
*/
function pLimit(concurrency) {
let activeCount = 0;
const queue = [];
const next = () => {
if (queue.length > 0 && activeCount < concurrency) {
activeCount++;
const task = queue.shift();
task().finally(() => {
activeCount--;
next();
});
}
};
return fn => {
return new Promise((resolve, reject) => {
queue.push(() =>
fn()
.then(resolve)
.catch(reject)
);
next();
});
};
}
/* ===================== 核心下载能力 ===================== */
/**
* 单文件流式下载(支持重定向、超时、自动清理残文件)
* @param {string} fileUrl 完整下载链接
* @param {string} filePath 本地保存路径
* @param {number} timeout 超时时间ms
* @param {number} redirectCount 已重定向次数
*/
function streamDownload(fileUrl, filePath, timeout = 30000, redirectCount = 0) {
return new Promise((resolve, reject) => {
try {
const requestModule = fileUrl.startsWith("https") ? https : http;
const req = requestModule.get(fileUrl, { timeout }, res => {
// 重定向处理,最多3次防死循环
if ([301, 302, 307, 308].includes(res.statusCode)) {
if (redirectCount >= 3) {
res.resume();
reject(new Error("重定向次数超过3次"));
return;
}
const redirectUrl = url.resolve(fileUrl, res.headers.location);
streamDownload(redirectUrl, filePath, timeout, redirectCount + 1)
.then(resolve)
.catch(reject);
return;
}
if (res.statusCode !== 200) {
res.resume();
reject(new Error(`HTTP状态码异常: ${res.statusCode}`));
return;
}
let writeStream;
try {
writeStream = fs.createWriteStream(filePath);
} catch (err) {
res.resume();
reject(new Error(`路径创建失败:${err.message}`));
return;
}
res.pipe(writeStream);
writeStream.on("finish", () => {
writeStream.close(() => resolve(filePath));
});
writeStream.on("error", err => {
writeStream.destroy();
fs.promises.unlink(filePath).catch(() => {});
reject(err);
});
res.on("error", err => {
writeStream.destroy();
fs.promises.unlink(filePath).catch(() => {});
reject(new Error(`网络响应异常: ${err.message}`));
});
});
req.on("error", err => reject(new Error(`网络请求失败: ${err.message}`)));
req.on("timeout", () => {
req.destroy();
reject(new Error("下载超时"));
});
} catch (syncErr) {
reject(new Error(`请求初始化失败: ${syncErr.message}`));
}
});
}
/**
* 带失败重试的单文件下载
*/
async function downloadWithRetry(
fileUrl,
filePath,
retryTimes = 0,
timeout = 30000
) {
const attempt = async remain => {
try {
return await streamDownload(fileUrl, filePath, timeout);
} catch (err) {
if (remain > 0) {
console.log(`[下载重试] 剩余 ${remain} 次:${path.basename(filePath)}`);
return attempt(remain - 1);
}
throw err;
}
};
return attempt(retryTimes);
}
/* ===================== 批量下载封装 ===================== */
/**
* 批量下载(URL数组版本)
* @param {string[]} urlList URL数组
* @param {string} targetDir 目标目录
* @param {Object} options 配置
* @returns {Promise<{success: string[], failed: Array<{url:string, error:string}>}>}
*/
async function batchDownloadByList(urlList, targetDir, options = {}) {
const {
concurrency = 5,
timeout = 30000,
retryTimes = 0,
baseUrl = "",
skipExists = true,
fileNameFormatter = null // 新增:自定义文件名回调
} = options;
const success = [];
const failed = [];
// 1. 创建目标目录
try {
await ensureDir(targetDir);
} catch (dirErr) {
const errMsg = `目标目录创建失败:${dirErr.message}`;
console.error(`[批量下载][路径错误] ${errMsg} | 目录: ${targetDir}`);
return {
success: [],
failed: [{ url: "", error: errMsg }]
};
}
// 2. 并发执行下载
const limit = pLimit(concurrency);
const tasks = urlList.map(urlStr =>
limit(async () => {
const fullUrl = baseUrl ? resolveUrl(urlStr, baseUrl) : urlStr;
const fileName = fileNameFormatter
? fileNameFormatter(urlStr, baseUrl)
: getFileName(urlStr);
const savePath = path.join(targetDir, fileName);
try {
// 已存在则跳过
if (skipExists && (await isFileExists(savePath))) {
console.log(`[批量下载][跳过] 文件已存在: ${fileName}`);
success.push(savePath);
return;
}
await downloadWithRetry(fullUrl, savePath, retryTimes, timeout);
console.log(`[批量下载][成功] ${fileName}`);
success.push(savePath);
} catch (err) {
// 识别路径类错误
const isPathError =
["ENOENT", "EINVAL", "ENAMETOOLONG", "EPERM", "EACCES"].includes(
err.code
) || /路径|path|file/i.test(err.message);
const errorType = isPathError ? "路径错误" : "下载失败";
console.error(
`[批量下载][${errorType}] 跳过文件: ${fileName} | 链接: ${fullUrl} | 原因: ${err.message}`
);
failed.push({ url: fullUrl, error: err.message });
}
})
);
await Promise.all(tasks);
console.log(`批量下载完成,成功: ${success.length},失败: ${failed.length}`);
return { success, failed };
}
/**
* 批量下载(逗号分隔URL字符串版本)
* @param {string} urlStr 逗号分隔的URL字符串
* @param {string} targetDir 目标目录
* @param {Object} options 配置
*/
async function batchDownloadByStr(urlStr, targetDir, options = {}) {
// 参数校验
if (!urlStr || typeof urlStr !== "string") {
console.error("[批量下载][参数错误] 传入的URL字符串为空或格式无效");
return { success: [], failed: [{ url: "", error: "URL字符串无效" }] };
}
// 拆分URL
const urlList = urlStr
.split(",")
.map(u => u.trim())
.filter(u => u);
if (urlList.length === 0) {
console.warn("[批量下载][无有效链接] 拆分后无可用URL,直接跳过");
return { success: [], failed: [] };
}
return batchDownloadByList(urlList, targetDir, options);
}
module.exports = {
// 工具函数
getFileName,
isAbsoluteUrl,
resolveUrl,
ensureDir,
isFileExists,
pLimit,
// 核心下载
streamDownload,
downloadWithRetry,
// 批量下载
batchDownloadByList,
batchDownloadByStr
};
const { ipcMain, BrowserWindow } = require("electron");
const { getHostApi } = require("@/server/utils/store");
const { batchDownloadByList } = require("./download-core");
/* ========== 任务管理模块(全局互斥锁 + 状态广播) ========== */
const taskState = {
isRunning: false,
currentBatchNo: "",
latestResult: { success: [], failed: [] }
};
function broadcastStatus() {
const allWindows = BrowserWindow.getAllWindows();
allWindows.forEach(win => {
if (!win.isDestroyed()) {
win.webContents.send("download:status", {
isRunning: taskState.isRunning,
currentBatchNo: taskState.currentBatchNo,
result: taskState.latestResult
});
}
});
}
function submitTask(params) {
const { urls, targetPath, batchArrangeNum } = params;
if (taskState.isRunning) {
return {
code: 1,
msg: `当前正在下载批次【${taskState.currentBatchNo}】,请等待完成后再操作`,
data: { isRunning: true }
};
}
if (!Array.isArray(urls) || urls.length === 0) {
return { code: 1, msg: "下载链接数组为空" };
}
taskState.isRunning = true;
taskState.currentBatchNo = batchArrangeNum || "未知批次";
taskState.latestResult = { success: [], failed: [] };
broadcastStatus();
// 调用核心下载能力
batchDownloadByList(urls, targetPath, {
concurrency: 2,
timeout: 30000,
retryTimes: 1,
baseUrl: getHostApi().fileApiUrl
})
.then(result => {
taskState.latestResult = result;
})
.catch(err => {
taskState.latestResult = {
success: [],
failed: [{ url: "", error: err.message || "下载任务异常中断" }]
};
})
.finally(() => {
taskState.isRunning = false;
taskState.currentBatchNo = "";
broadcastStatus();
});
return {
code: 0,
msg: "下载任务已提交,后台处理中",
data: { isRunning: true }
};
}
function getStatus() {
return {
code: 0,
data: {
isRunning: taskState.isRunning,
currentBatchNo: taskState.currentBatchNo,
result: taskState.latestResult
}
};
}
/* ========== IPC 注册 ========== */
function registerDownloadIpc() {
ipcMain.on("download:submit", (event, params) => {
const result = submitTask(params);
event.sender.send("download:submit-reply", result);
});
ipcMain.on("download:getStatus", event => {
const result = getStatus();
event.sender.send("download:getStatus-reply", result);
});
}
module.exports = registerDownloadIpc;
const { ipcMain, BrowserWindow } = require("electron");
const path = require("path");
const { getHostApi } = require("@/server/utils/store");
const { batchDownloadByStr } = require("./utils/download-core");
/* ===================== 原有命名逻辑(完全保留) ===================== */
function formatTime() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const day = String(now.getDate()).padStart(2, "0");
const hour = String(now.getHours()).padStart(2, "0");
const minute = String(now.getMinutes()).padStart(2, "0");
const second = String(now.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day}_${hour}.${minute}.${second}`;
}
function customFileNameFormatter(urlStr) {
let cleanPath = urlStr;
try {
cleanPath = decodeURIComponent(urlStr);
} catch (e) {
cleanPath = urlStr;
}
cleanPath = cleanPath.replace(/\\/g, "/");
const originalFileName = path.basename(cleanPath);
const timePrefix = formatTime();
return originalFileName
? `${timePrefix} ${originalFileName}`
: `${timePrefix}.png`;
}
/**
* 原有纯函数调用方式(保留,兼容现有代码)
*/
async function batchDownloadUrls(urlStr, targetDir, options = {}) {
return batchDownloadByStr(urlStr, targetDir, {
baseUrl: getHostApi().fileApiUrl,
fileNameFormatter: customFileNameFormatter,
...options
});
}
/* ===================== 新增:IPC 任务管理模块(独立锁,与原素材隔离) ===================== */
const taskState = {
isRunning: false,
latestResult: { success: [], failed: [] }
};
/**
* 向所有窗口广播状态
*/
function broadcastStatus() {
const allWindows = BrowserWindow.getAllWindows();
allWindows.forEach(win => {
if (!win.isDestroyed()) {
win.webContents.send("download-typesetting:status", {
isRunning: taskState.isRunning,
result: taskState.latestResult
});
}
});
}
/**
* 提交下载任务(异步执行,立即返回)
*/
function submitTask(params) {
const { urlStr, targetPath } = params;
// 全局互斥:有任务在跑直接拒绝
if (taskState.isRunning) {
return {
code: 1,
msg: "当前正在下载手动排版素材,请等待完成后再操作",
data: { isRunning: true }
};
}
if (!urlStr || typeof urlStr !== "string") {
return { code: 1, msg: "下载链接为空或格式无效" };
}
// 加锁
taskState.isRunning = true;
taskState.latestResult = { success: [], failed: [] };
broadcastStatus();
// 后台异步执行下载,不阻塞 IPC 返回
batchDownloadUrls(urlStr, targetPath)
.then(result => {
taskState.latestResult = result;
})
.catch(err => {
taskState.latestResult = {
success: [],
failed: [{ url: "", error: err.message || "下载任务异常中断" }]
};
})
.finally(() => {
// 释放锁
taskState.isRunning = false;
broadcastStatus();
});
return {
code: 0,
msg: "手动排版素材下载任务已提交,后台处理中",
data: { isRunning: true }
};
}
/**
* 查询当前下载状态
*/
function getStatus() {
return {
code: 0,
data: {
isRunning: taskState.isRunning,
result: taskState.latestResult
}
};
}
/* ===================== 新增:IPC 事件注册 ===================== */
/**
* 注册手动排版下载 IPC 事件
* 在主进程入口调用一次即可
*/
function registerTypesettingDownloadIpc() {
// 提交下载任务
ipcMain.on("download-typesetting:submit", (event, params) => {
const result = submitTask(params);
event.sender.send("download-typesetting:submit-reply", result);
});
// 查询下载状态
ipcMain.on("download-typesetting:getStatus", event => {
const result = getStatus();
event.sender.send("download-typesetting:getStatus-reply", result);
});
}
/* ===================== 导出(兼容两种使用方式) ===================== */
module.exports = {
// 原有纯函数,可直接在主进程内调用
batchDownloadUrls,
// IPC 注册函数,主进程入口调用
registerTypesettingDownloadIpc
};
const { ipcRenderer } = window.require("electron");
// ========== 原素材下载 API(原有保留) ==========
/**
* 提交下载任务
* @param {Object} params { urls, targetPath, batchArrangeNum }
* @returns {Promise<Object>}
*/
export function submitDownload(params) {
return new Promise(resolve => {
ipcRenderer.once("download:submit-reply", (_, res) => resolve(res));
ipcRenderer.send("download:submit", params);
});
}
/**
* 获取当前下载状态
* @returns {Promise<Object>}
*/
export function getDownloadStatus() {
return new Promise(resolve => {
ipcRenderer.once("download:getStatus-reply", (_, res) => resolve(res));
ipcRenderer.send("download:getStatus");
});
}
/**
* 监听下载状态变更
* @param {Function} callback
* @returns {Function} 取消监听函数
*/
export function onDownloadStatusChange(callback) {
const handler = (_, data) => callback(data);
ipcRenderer.on("download:status", handler);
return () => ipcRenderer.removeListener("download:status", handler);
}
// ========== 新增:手动排版下载 API ==========
/**
* 提交手动排版下载任务
* @param {Object} params { urlStr: 逗号分隔URL字符串, targetPath: 保存目录 }
* @returns {Promise<Object>}
*/
export function submitTypesettingDownload(params) {
return new Promise(resolve => {
ipcRenderer.once("download-typesetting:submit-reply", (_, res) =>
resolve(res)
);
ipcRenderer.send("download-typesetting:submit", params);
});
}
/**
* 查询手动排版下载状态
* @returns {Promise<Object>}
*/
export function getTypesettingDownloadStatus() {
return new Promise(resolve => {
ipcRenderer.once("download-typesetting:getStatus-reply", (_, res) =>
resolve(res)
);
ipcRenderer.send("download-typesetting:getStatus");
});
}
/**
* 监听手动排版下载状态变更
* @param {Function} callback
* @returns {Function} 取消监听函数
*/
export function onTypesettingStatusChange(callback) {
const handler = (_, data) => callback(data);
ipcRenderer.on("download-typesetting:status", handler);
return () =>
ipcRenderer.removeListener("download-typesetting:status", handler);
}
......@@ -62,7 +62,7 @@ export const cutArea = (canvasEl, mousewheel) => {
boundaryLeft,
boundaryTop,
boundaryWidth,
boundaryHeight,
boundaryHeight
} = getRealBoundary(canvasEl, mousewheel);
//存储正方形边界
......@@ -70,7 +70,7 @@ export const cutArea = (canvasEl, mousewheel) => {
boundaryLeft,
boundaryTop,
boundaryWidth,
boundaryHeight,
boundaryHeight
});
cutCtx.clearRect(boundaryLeft, boundaryTop, boundaryWidth, boundaryHeight);
......@@ -92,7 +92,7 @@ export const cutArea = (canvasEl, mousewheel) => {
canvasEl.set({
cutWidth: width,
cutHeight: height,
cutHeight: height
});
//设置蒙版图片
......@@ -119,7 +119,7 @@ export const cutArea = (canvasEl, mousewheel) => {
canvasEl.maskDiv.appendChild(mask_img);
insertAfter(
canvasEl.maskDiv,
document.getElementById(canvasEl.cutCanvas.id),
document.getElementById(canvasEl.cutCanvas.id)
);
}
......@@ -177,7 +177,7 @@ const getRealBoundary = function(canvasEl, mousewheel) {
if (!canvasEl.oldCutWidth) {
canvasEl.set({
oldCutWidth: cutWidth,
oldCutHeight: cutHeight,
oldCutHeight: cutHeight
});
}
}
......@@ -218,7 +218,7 @@ const getRealBoundary = function(canvasEl, mousewheel) {
boundaryLeft,
boundaryTop,
boundaryWidth,
boundaryHeight,
boundaryHeight
};
};
......
......@@ -6,6 +6,17 @@ const { Menu } = remote;
const path = require("path");
const { pathMap } = require("@/config/index.js");
import DTFhead from "./components/head.vue";
import debounce from "lodash/debounce";
import {
submitDownload,
getDownloadStatus,
onDownloadStatusChange,
submitTypesettingDownload,
getTypesettingDownloadStatus,
onTypesettingStatusChange
} from "@/api/download.api";
export default {
name: "design-dtf",
components: { BaseTable, DTFhead },
......@@ -26,9 +37,12 @@ export default {
searchForm: {},
radio: "",
templateBatchArrangeNum: "",
templateId: "",
isDownloading: false,
resTypesettingisDownloading: false,
dtfSetting: getDTFSetting(),
isFetching: false,
removeStatusListener: null, // 保存取消监听函数
pageInfo: {
currentPage: 1,
pageSize: 10,
......@@ -106,11 +120,24 @@ export default {
}
};
},
mounted() {
async mounted() {
this.loadLocalConfig();
this.fetchBatchList();
this.removeStatusListener = onDownloadStatusChange(status => {
this.handleDownloadStatus("material", status);
});
this.removeListener = onTypesettingStatusChange(status => {
this.handleDownloadStatus("typesetting", status);
});
// 初始化同步状态
await this.syncStatus();
},
beforeDestroy() {
if (this.removeStatusListener) this.removeStatusListener();
if (this.removeListener) this.removeListener();
// 取消待执行的防抖任务,避免销毁后执行报错
this.downloadFile.cancel?.();
},
methods: {
async loadLocalConfig() {
try {
......@@ -154,11 +181,11 @@ export default {
handleSizeChange(size) {
this.pageInfo.pageSize = size;
this.pageInfo.currentPage = 1;
this.settingRes();
this.fetchBatchList(this.searchForm);
},
handleCurrentChange(page) {
this.pageInfo.currentPage = page;
this.loadData();
this.fetchBatchList(this.searchForm);
},
//右键选择器
......@@ -206,6 +233,7 @@ export default {
this.dialogVisible = true;
this.radio = "";
this.templateBatchArrangeNum = value.batchArrangeNum;
this.templateId = value.id;
} else {
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
......@@ -215,10 +243,15 @@ export default {
//提交手动排版
async submit() {
if (this.resTypesettingisDownloading) {
this.$message.warning("其他排版下载中,请等待完成后再操作");
return;
}
if (!this.radio) {
return this.$message.error("请选择排版宽度");
}
try {
this.resTypesettingisDownloading = true;
if (this.dtfSetting.widthStrategy == 3 && this.radio == 60) {
this.$confirm(
"由于排版设置中选择“按更大规格排版”仅适用于40+2,选60时,默认超60的规格不排版",
......@@ -232,21 +265,36 @@ export default {
batchArrangeNum: this.templateBatchArrangeNum,
templateWidth: this.radio
});
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
} else {
await this.$api.post(pathMap["psReComposingDesignImages"], {
batchArrangeNum: this.templateBatchArrangeNum,
templateWidth: this.radio
});
}
const { data } = await this.$api.post(
pathMap["podOrderBatchDownload"],
{
id: this.templateId
}
);
await submitTypesettingDownload({
urlStr: data.data.url,
targetPath: path.join(
getDTFSetting().downloadDir,
`批次号:${this.templateBatchArrangeNum}`,
"手动排版素材"
)
});
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
}
this.dialogVisible = false;
this.fetchBatchList(this.searchForm);
} catch (error) {
console.log(error);
this.resTypesettingisDownloading = false;
}
},
//跳转批次详情页
......@@ -258,30 +306,84 @@ export default {
}
});
},
downloadFile: debounce(
function(value) {
this._downloadFile(value);
},
300,
{
leading: true,
trailing: false
}
),
//下载批次原素材
async downloadFile(value) {
async _downloadFile(value) {
if (this.isDownloading) {
this.$message.warning("正在下载中,请等待完成后再操作");
return;
}
try {
this.isDownloading = true;
const { data } = await this.$api.post(pathMap["listMaterialsByBatch"], {
batchArrangeNum: value
});
const newUrls = data.flatMap(el => el.urls);
// console.log(311, newUrls);
// return;
const res = await this.$api.post("/downloadMaterial", {
if (newUrls.length === 0) {
this.$message.warning("该批次暂无素材可下载");
this.isDownloading = false;
return;
}
await submitDownload({
urls: newUrls,
targetPath: path.join(
getDTFSetting().downloadDir,
this.dtfSetting.downloadDir,
`批次号:${value}`,
"原素材"
)
),
batchArrangeNum: value
});
// console.log("listMaterialsByBatch-", data);
console.log("downloadMaterial", res);
this.$message("下载进行中,下载完成的素材将在文件夹原素材中显示");
// 提交成功后,锁由 onDownloadStatusChange 事件维护,不再手动修改
} catch (error) {
console.log(error);
console.error("下载提交失败", error);
this.$message.error("下载提交失败,请重试");
// 仅提交失败时释放锁
this.isDownloading = false;
}
},
/**
* 状态变更回调
*/
handleDownloadStatus(type, status) {
const statusKey =
type === "material" ? "isDownloading" : "resTypesettingisDownloading";
this[statusKey] = status.isRunning;
if (!status.isRunning && status.result) {
const { success, failed } = status.result;
console.log(
`下载完成:成功 ${success.length} 个,失败 ${failed.length} 个`
);
if (failed.length > 0) {
console.warn("下载失败明细:", failed);
}
}
},
/**
* 同步当前状态
*/
async syncStatus() {
try {
const res = await getDownloadStatus();
const resTypesetting = await getTypesettingDownloadStatus();
this.isDownloading = res.data.isRunning;
this.resTypesettingisDownloading = resTypesetting.data.isRunning;
} catch (err) {
console.error("同步下载状态失败", err);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment