Commit 0508c0d0 by linjinhong

fix:添加自动排版本地下载标记

parent 530e2bc6
...@@ -193,15 +193,29 @@ async function createWindow() { ...@@ -193,15 +193,29 @@ async function createWindow() {
} }
try { try {
let configObj = JSON.parse(data); let configObj = JSON.parse(data);
configObj.apiApiHost = `https://${newDomain}/api`; const isTest = process.env.VUE_APP_ENV === "test";
configObj.fileApiUrl = `https://${newDomain}/upload/factory`; console.log("isTest", isTest);
configObj.configPath = configPath; console.log("configObj", configObj);
const newData = JSON.stringify(configObj); // 使用2个空格缩进
const config = isTest ? configObj.test : configObj.prod;
config.apiApiHost = isTest
? `http://${newDomain}/api`
: `https://${newDomain}/api`;
config.fileApiUrl = isTest
? `http://${newDomain}/upload/factory`
: `https://${newDomain}/upload/factory`;
config.configPath = configPath;
// const newData = JSON.stringify(config); // 使用2个空格缩进
// console.log("修改后的数据:", newData); // console.log("修改后的数据:", newData);
configObj[isTest ? "test" : "prod"] = config;
const newConfigObj = JSON.stringify(configObj);
// 4. 写回文件 // 4. 写回文件
fs.writeFile(configPath, newData, "utf-8", writeErr => { fs.writeFile(
configPath,
newConfigObj,
"utf-8",
writeErr => {
if (writeErr) { if (writeErr) {
console.error("写入配置文件失败:", writeErr); console.error("写入配置文件失败:", writeErr);
this.$message.error( this.$message.error(
...@@ -210,10 +224,11 @@ async function createWindow() { ...@@ -210,10 +224,11 @@ async function createWindow() {
return; return;
} }
console.log("配置文件更新成功", configObj); console.log("配置文件更新成功", config);
setApi(configObj); setApi(config);
}); }
);
} catch (parseError) { } catch (parseError) {
console.error("解析 JSON 失败:", parseError); console.error("解析 JSON 失败:", parseError);
this.$message.error( this.$message.error(
...@@ -494,19 +509,17 @@ async function createWindow() { ...@@ -494,19 +509,17 @@ async function createWindow() {
}); });
ipcMain.on("get-install-path", event => { ipcMain.on("get-install-path", event => {
// 固定桌面路径,不再区分开发环境
const desktopPath = app.getPath("desktop"); const desktopPath = app.getPath("desktop");
const dtfDir = path.join(desktopPath, "JomallProductionAssistant-DTF"); const dtfDir = path.join(desktopPath, "JomallProductionAssistant-DTF");
let resPath = desktopPath;
try { try {
// 递归创建文件夹,不存在自动生成,存在不报错
fs.mkdirSync(dtfDir, { recursive: true }); fs.mkdirSync(dtfDir, { recursive: true });
event.returnValue = dtfDir; resPath = dtfDir;
} catch (err) { } catch (err) {
console.error("创建 DTF 桌面文件夹失败:", err); console.error("创建文件夹失败", err);
// 兜底返回桌面,防止空值
event.returnValue = desktopPath;
} }
event.reply("get-install-path-res", resPath);
}); });
// ========== 新增3:窗口关闭时停止定时任务 ========== // ========== 新增3:窗口关闭时停止定时任务 ==========
...@@ -515,6 +528,22 @@ async function createWindow() { ...@@ -515,6 +528,22 @@ async function createWindow() {
}); });
} }
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
} else {
app.on("second-instance", () => {
// 第二次双击时,唤起已有的窗口
const allWindows = BrowserWindow.getAllWindows();
const mainWin = allWindows[0];
if (mainWin) {
if (mainWin.isMinimized()) mainWin.restore();
mainWin.show();
mainWin.focus();
}
});
}
app.on("activate", async () => { app.on("activate", async () => {
if (win === null) { if (win === null) {
await createWindow(); await createWindow();
......
...@@ -52,7 +52,7 @@ export const pathMap = { ...@@ -52,7 +52,7 @@ export const pathMap = {
listOperationByBatch: "factory/podOrderBatchDownload/listOperationByBatch", listOperationByBatch: "factory/podOrderBatchDownload/listOperationByBatch",
//排版 //排版
replenishmentComposingDesignImages: replenishmentComposingDesignImages:
"factory/podOrderOperation/replenishmentComposingDesignImages", "factory/podOrderOperation/softwareProduction-replenishmentComposingDesignImages",
//获取单个批次号信息 //获取单个批次号信息
podOrderBatchDownload: "factory/podOrderBatchDownload/get", podOrderBatchDownload: "factory/podOrderBatchDownload/get",
//操作日志 //操作日志
......
...@@ -29,7 +29,7 @@ export const createServer = () => { ...@@ -29,7 +29,7 @@ export const createServer = () => {
res.status(err.status || 500); res.status(err.status || 500);
res.json({ res.json({
message: err.message, message: err.message,
error: err, error: err
}); });
}); });
......
...@@ -7,7 +7,6 @@ const MAX_LIMIT_RECORD_KEY = "originalIdMaxLimitRecord"; // 永久上限标记 ...@@ -7,7 +7,6 @@ const MAX_LIMIT_RECORD_KEY = "originalIdMaxLimitRecord"; // 永久上限标记
// ===== 2. 核心内存缓存 ===== // ===== 2. 核心内存缓存 =====
let orderCacheMap = new Map(); // key格式:前缀-数字(如AAAF...-1),value:原始订单对象 let orderCacheMap = new Map(); // key格式:前缀-数字(如AAAF...-1),value:原始订单对象
// ===== 3. 永久上限标记方法(保留你的原有核心逻辑,无改动) ===== // ===== 3. 永久上限标记方法(保留你的原有核心逻辑,无改动) =====
/** /**
* 获取已达永久上限的原始newId Map * 获取已达永久上限的原始newId Map
...@@ -197,6 +196,7 @@ module.exports = { ...@@ -197,6 +196,7 @@ module.exports = {
store.set("desktoBoard", version); store.set("desktoBoard", version);
}, },
getBoard: () => store.get("desktoBoard") || 3, getBoard: () => store.get("desktoBoard") || 3,
setIsOver: value => { setIsOver: value => {
store.set("isOver", value); store.set("isOver", value);
}, },
...@@ -213,10 +213,9 @@ module.exports = { ...@@ -213,10 +213,9 @@ module.exports = {
store.set("productType", value); store.set("productType", value);
}, },
getProductType: () => store.get("productType") || "DTG", getProductType: () => store.get("productType") || "DTG",
//DTF生产设置 //DTF生产设置
setDTFSetting: value => { setDTFSetting: value => {
console.log("DTFSetting", value);
store.set("DTFSetting", value); store.set("DTFSetting", value);
}, },
getDTFSetting: () => getDTFSetting: () =>
...@@ -232,6 +231,12 @@ module.exports = { ...@@ -232,6 +231,12 @@ module.exports = {
downloadDir: "" downloadDir: ""
}, },
//本地储存 文件批次号
setBatchNumbers: value => {
store.set("batchNumbers", value);
},
getBatchNumbers: () => store.get("batchNumbers") || [],
setLocation: (version, locationKey) => { setLocation: (version, locationKey) => {
if (!locationKey) return; if (!locationKey) return;
store.set(locationKey, version); store.set(locationKey, version);
......
...@@ -3,7 +3,7 @@ const fs = require("fs"); ...@@ -3,7 +3,7 @@ const fs = require("fs");
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const url = require("url"); const url = require("url");
const { setBatchNumbers, getBatchNumbers } = require("@/server/utils/store");
/* ===================== 基础工具函数 ===================== */ /* ===================== 基础工具函数 ===================== */
/** /**
...@@ -206,12 +206,28 @@ async function batchDownloadByList(urlList, targetDir, options = {}) { ...@@ -206,12 +206,28 @@ async function batchDownloadByList(urlList, targetDir, options = {}) {
retryTimes = 0, retryTimes = 0,
baseUrl = "", baseUrl = "",
skipExists = true, skipExists = true,
fileNameFormatter = null // 新增:自定义文件名回调, fileNameFormatter = null, // 新增:自定义文件名回调,
isCheck = false,
batchId = "" // 新增:批次唯一标识,isCheck 模式下使用
} = options; } = options;
const success = []; const success = [];
const failed = []; const failed = [];
if (isCheck) {
// 批次已处理过则直接跳过整个批次,不执行后续任何下载逻辑
const batchNumbers = getBatchNumbers() || [];
if (batchNumbers.includes(batchId)) {
console.log(`该批次已执行过,直接跳过 | 批次号: ${batchId}`);
return {
success: [],
failed: [],
skipped: true,
batchId
};
}
}
// 1. 创建目标目录 // 1. 创建目标目录
try { try {
await ensureDir(targetDir); await ensureDir(targetDir);
...@@ -260,6 +276,11 @@ async function batchDownloadByList(urlList, targetDir, options = {}) { ...@@ -260,6 +276,11 @@ async function batchDownloadByList(urlList, targetDir, options = {}) {
}) })
); );
if (isCheck && batchId) {
setBatchNumbers([...getBatchNumbers(), batchId]);
console.log(`批量下载 批次标记已标记批次为已处理 | 批次号: ${batchId}`);
}
await Promise.all(tasks); await Promise.all(tasks);
console.log(`批量下载完成,成功: ${success.length},失败: ${failed.length}`); console.log(`批量下载完成,成功: ${success.length},失败: ${failed.length}`);
return { success, failed }; return { success, failed };
......
...@@ -30,7 +30,7 @@ const { pLimit } = require("./download-core"); ...@@ -30,7 +30,7 @@ const { pLimit } = require("./download-core");
/* ========== 业务逻辑 ========== */ /* ========== 业务逻辑 ========== */
async function processBatchItem(item) { async function processBatchItem(item) {
const { batchArrangeNum, url: urlStr } = item; const { batchArrangeNum, spUrl: urlStr } = item;
if (!batchArrangeNum) { if (!batchArrangeNum) {
logDownloadError( logDownloadError(
...@@ -70,7 +70,9 @@ async function processBatchItem(item) { ...@@ -70,7 +70,9 @@ async function processBatchItem(item) {
await batchDownloadByStr(urlStr, saveDir, { await batchDownloadByStr(urlStr, saveDir, {
concurrency: taskState.maxImageConcurrency, concurrency: taskState.maxImageConcurrency,
timeout: 30000, timeout: 30000,
baseUrl: getHostApi().fileApiUrl baseUrl: getHostApi().fileApiUrl,
isCheck: true,
batchId: batchArrangeNum
}); });
} }
...@@ -105,7 +107,7 @@ async function runTask() { ...@@ -105,7 +107,7 @@ async function runTask() {
console.log("当前页无数据,本轮任务结束"); console.log("当前页无数据,本轮任务结束");
return; return;
} }
console.log(layoutRes);
// 多批次并行下载 // 多批次并行下载
const batchLimit = pLimit(taskState.maxBatchConcurrency); const batchLimit = pLimit(taskState.maxBatchConcurrency);
const batchPromises = list.map(item => const batchPromises = list.map(item =>
......
...@@ -90,12 +90,13 @@ export default { ...@@ -90,12 +90,13 @@ export default {
<el-option label="部分成功" :value="5"> </el-option> <el-option label="部分成功" :value="5"> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="创建时间"> <el-form-item label="时间范围">
<el-date-picker <el-date-picker
style="width: 380px;"
clearable clearable
v-model="searchForm.startTime" v-model="searchForm.timeRange"
type="datetime" type="datetimerange"
placeholder="选择创建时间" placeholder="选择时间"
format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
> >
......
...@@ -140,12 +140,12 @@ export default { ...@@ -140,12 +140,12 @@ export default {
}, },
methods: { methods: {
async loadLocalConfig() { async loadLocalConfig() {
console.log(getDTFSetting());
setDTFSetting({ downloadDir: "" });
try { try {
if (!getDTFSetting().downloadDir) { if (!getDTFSetting().downloadDir) {
const path = ipcRenderer.sendSync("get-install-path"); ipcRenderer.send("get-install-path");
setDTFSetting({ downloadDir: path }); ipcRenderer.once("get-install-path-res", (_, defaultPath) => {
setDTFSetting({ downloadDir: defaultPath });
});
} }
} catch (error) { } catch (error) {
console.log(error); console.log(error);
...@@ -274,7 +274,7 @@ export default { ...@@ -274,7 +274,7 @@ export default {
); );
const res = await submitTypesettingDownload({ const res = await submitTypesettingDownload({
urlStr: data.data.url, urlStr: data.data.spUrl,
targetPath: path.join( targetPath: path.join(
getDTFSetting().downloadDir, getDTFSetting().downloadDir,
`批次号:${this.templateBatchArrangeNum}`, `批次号:${this.templateBatchArrangeNum}`,
...@@ -394,6 +394,17 @@ export default { ...@@ -394,6 +394,17 @@ export default {
} catch (err) { } catch (err) {
console.error("同步下载状态失败", err); console.error("同步下载状态失败", err);
} }
},
searchFn(value) {
this.searchForm = value;
if (value.timeRange?.length) {
this.searchForm.startTime = value.timeRange[0];
this.searchForm.endTime = value.timeRange[1];
} else {
this.searchForm.startTime = "";
this.searchForm.endTime = "";
}
this.fetchBatchList(this.searchForm);
} }
} }
}; };
...@@ -404,12 +415,7 @@ export default { ...@@ -404,12 +415,7 @@ export default {
<DTFhead <DTFhead
:user="user" :user="user"
:factoryType="factoryType" :factoryType="factoryType"
@search=" @search="searchFn"
value => {
searchForm = value;
this.fetchBatchList(searchForm);
}
"
></DTFhead> ></DTFhead>
<BaseTable <BaseTable
v-if="tableList.length" v-if="tableList.length"
......
...@@ -120,11 +120,7 @@ export default { ...@@ -120,11 +120,7 @@ export default {
try { try {
const { data } = await this.$api.post(pathMap["productionConfig"]); const { data } = await this.$api.post(pathMap["productionConfig"]);
this.form = { ...getDTFSetting(), ...data }; this.form = { ...getDTFSetting(), ...data };
console.log(94, this.form);
// if (!this.form.downloadDir) {
// const path = ipcRenderer.sendSync("get-install-path");
// this.form.downloadDir = path;
// }
setDTFSetting({ ...this.form }); setDTFSetting({ ...this.form });
this.$nextTick(() => (this.isInitLoad = false)); this.$nextTick(() => (this.isInitLoad = false));
......
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