Commit 98eefb15 by linjinhong

feat:对接详情页排版和下载素材

parent 67b322c3
...@@ -390,12 +390,13 @@ async function createWindow() { ...@@ -390,12 +390,13 @@ async function createWindow() {
if (newWindow) newWindow.webContents.send("getProductionNoInfo", v); if (newWindow) newWindow.webContents.send("getProductionNoInfo", v);
}); });
ipcMain.on("request-select-folder", event => { ipcMain.on("request-select-folder", (event, currentPath) => {
// 打开文件夹选择对话框(Electron 6.x 回调写法,更稳定) // 打开文件夹选择对话框(Electron 6.x 回调写法,更稳定)
dialog.showOpenDialog( dialog.showOpenDialog(
{ {
properties: ["openDirectory"], // 仅允许选择文件夹 properties: ["openDirectory"], // 仅允许选择文件夹
title: "选择下载保存位置" title: "选择下载保存位置",
defaultPath: currentPath || ""
}, },
result => { result => {
// 处理结果并返回给渲染进程 // 处理结果并返回给渲染进程
...@@ -513,12 +514,34 @@ async function createWindow() { ...@@ -513,12 +514,34 @@ async function createWindow() {
const { width, height } = win.getBounds(); const { width, height } = win.getBounds();
win.webContents.send("window-size", { width, height }); win.webContents.send("window-size", { width, height });
}); });
// IPC 通信 // IPC 通信
ipcMain.on("download:submit-batch-list", (event, list) => { ipcMain.on("download:submit-batch-list", (event, list) => {
downloadQueue.addBatchList(list); downloadQueue.addBatchList(list);
event.returnValue = { code: 200, msg: "已处理" }; event.returnValue = { code: 200, msg: "已处理" };
}); });
ipcMain.on("get-install-path", event => {
let psScriptPath;
if (process.env.NODE_ENV === "development") {
psScriptPath = __dirname;
} else {
psScriptPath = path.dirname(app.getPath("exe"));
}
const dtfDir = path.join(psScriptPath, "DTF");
try {
// 2. 确保目录存在:不存在则递归创建,已存在则直接跳过,不会报错
fs.mkdirSync(dtfDir, { recursive: true });
// 3. 返回 DTF 目录路径
event.returnValue = dtfDir;
} catch (err) {
console.error("创建 DTF 文件夹失败:", err);
// 创建失败时兜底返回安装根目录,避免渲染进程拿不到值报错
event.returnValue = psScriptPath;
}
});
ipcMain.on("download:get-status", event => { ipcMain.on("download:get-status", event => {
try { try {
// 无论正常异常都保证回复,避免前端挂起 // 无论正常异常都保证回复,避免前端挂起
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
<slot name="time"></slot> <slot name="time"></slot>
<!-- 名称和价格 --> <!-- 名称和价格 -->
<div <!-- <div
v-if="cardItem?.productName" v-if="cardItem?.productName"
class="commodity-card-name-price flex flex-justify-space-between" class="commodity-card-name-price flex flex-justify-space-between"
> >
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<span>{{ cardItem?.productName }}</span> <span>{{ cardItem?.productName }}</span>
</slot> </slot>
<slot name="price"></slot> <slot name="price"></slot>
</div> </div> -->
<!-- SKU信息 --> <!-- SKU信息 -->
<div <div
...@@ -124,7 +124,23 @@ export default { ...@@ -124,7 +124,23 @@ export default {
return true; return true;
}, },
mainImageSrc() { mainImageSrc() {
return "https://tcustom.jomalls.com/shengchengtu/xiaoguotu/20260603/1780453208357TTp79stDPWRzooRZ.jpg"; const item = this.cardItem;
// 使用索引访问避免联合类型的属性访问问题
if (
this.imageField === "variantImage" &&
typeof item[this.imageField] === "string"
) {
return item[this.imageField];
}
if (
this.imageField === "mainImage" &&
typeof item[this.imageField] === "string"
) {
return item[this.imageField];
}
// 默认返回空字符串
return "";
} }
}, },
methods: {} methods: {}
......
...@@ -213,8 +213,8 @@ export default { ...@@ -213,8 +213,8 @@ export default {
} }
}, },
mounted() { mounted() {
console.log("tableConfig", this.tableConfig); // console.log("tableConfig", this.tableConfig);
console.log("tableData", this.tableData); // console.log("tableData", this.tableData);
} }
}; };
</script> </script>
......
...@@ -6,13 +6,37 @@ ...@@ -6,13 +6,37 @@
:before-close="handleClose" :before-close="handleClose"
:show-close="true" :show-close="true"
> >
<div class="order-detail-container" style="display: flex; gap: 32px;"> <div class="order-detail-container" style="display: flex;height: 800px;">
<!-- 左侧图片区域 --> <!-- 左侧图片区域 -->
<div class="left-img" style="width: 36%; text-align: center;"> <div class="left-images" style="width: 50%; text-align: center;">
<p style="font-size: 22px; font-weight: bold; margin: 0 0 10px;">B</p> <el-carousel
<div style="background-color: #f9f7ee; padding: 45px 20px;"> v-if="parseImageAry(info.imageAry).length > 0"
<img :src="imgUrl" alt="成衣图片" style="width: 85%;" /> style="height: 100%"
</div> :autoplay="false"
>
<el-carousel-item
v-for="(item, index) in parseImageAry(info.imageAry)"
:key="index"
style="height: 100%"
>
<div class="left-image">
<b v-show="item?.title && item?.url">
{{ item.title }}
<span
v-if="item?.id"
style="
text-decoration: underline;
cursor: pointer;
color: blue;
"
>
(DID:{{ item.id }}
</span>
</b>
<img :src="item.url" alt="" />
</div>
</el-carousel-item>
</el-carousel>
</div> </div>
<!-- 右侧信息区域 --> <!-- 右侧信息区域 -->
...@@ -22,51 +46,42 @@ ...@@ -22,51 +46,42 @@
class="customer-order-row" class="customer-order-row"
style="display: flex; justify-content: space-between; border: 1px solid #e4e7ed; padding: 15px 20px; margin-bottom: 18px;" style="display: flex; justify-content: space-between; border: 1px solid #e4e7ed; padding: 15px 20px; margin-bottom: 18px;"
> >
<div> <div class="text-label">
<span style="color: #606266;">客户:</span> <span>客户:</span>
<span style="color: #f56c6c; font-size: 18px; font-weight: bold;">{{ <span style="color: #f56c6c;">{{ info.customer }}</span>
info.customer
}}</span>
</div> </div>
<div> <div class="text-label">
<span style="color: #606266;">订单号:</span> <span>订单号:</span>
<span style="color: #f56c6c; font-size: 18px; font-weight: bold;">{{ <span style="color: #f56c6c;">{{ info.orderNo }}</span>
info.orderNo
}}</span>
</div> </div>
</div> </div>
<!-- 操作单信息区块 --> <!-- 操作单信息区块 -->
<div class="div-text"><b>操作单信息</b></div>
<div <div
class="op-info-box" class="info-box"
style="border: 1px solid #e4e7ed; padding: 18px 22px; margin-bottom: 26px;" style="border: 1px solid #e4e7ed; padding: 18px 22px; margin-bottom: 26px;"
> >
<h4 style="margin: 0 0 18px; font-size: 16px;">操作单信息</h4>
<div <div
style="display: grid; grid-template-columns: 1fr 1fr; row-gap: 14px;" style="display: grid; grid-template-columns: 1fr 1fr; row-gap: 14px;"
> >
<div> <div class="text-label">
<span style="color: #909399;">操作单号:</span>{{ info.opNo }} <span>操作单号:</span>{{ info.operationNo }}
</div>
<div>
<span style="color: #909399;">生产工艺:</span>{{ info.tech }}
</div> </div>
<div> <div class="text-label">
<span style="color: #909399;">基版:</span>{{ info.basePlate }} <span>生产工艺:</span>{{ info.craftName }}
</div> </div>
<div> <div class="text-label"><span>基版:</span>{{ info.baseSku }}</div>
<span style="color: #909399;">变体SKU:</span>{{ info.sku }} <div class="text-label">
<span>变体SKU:</span>{{ info.variantSku }}
</div> </div>
<div><span style="color: #909399;">数量:</span>{{ info.num }}</div> <div class="text-label"><span>数量:</span>{{ info.quantity }}</div>
<div> <div class="text-label"><span>尺寸:</span>{{ info.size }}</div>
<span style="color: #909399;">尺寸:</span>{{ info.size }} <div class="text-label">
<span>店铺单号:</span>{{ info.shopNumber }}
</div> </div>
<div> <div class="text-label">
<span style="color: #909399;">店铺单号:</span>{{ info.shopNo }} <span>创建时间:</span>{{ info.createTime }}
</div>
<div>
<span style="color: #909399;">创建时间:</span
>{{ info.createTime }}
</div> </div>
</div> </div>
</div> </div>
...@@ -74,11 +89,6 @@ ...@@ -74,11 +89,6 @@
<!-- 底部按钮 --> <!-- 底部按钮 -->
<div style="text-align: right;"> <div style="text-align: right;">
<el-button type="primary" size="medium">下载素材</el-button> <el-button type="primary" size="medium">下载素材</el-button>
<el-checkbox
v-model="scanDownloadCheck"
label="扫码下载素材"
style="margin-left: 10px;"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -94,26 +104,10 @@ export default { ...@@ -94,26 +104,10 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
// 图片地址
imgUrl: {
type: String,
default: ""
},
// 订单详情数据 // 订单详情数据
info: { info: {
type: Object, type: Object,
default: () => ({ default: () => ({})
customer: "",
orderNo: "",
opNo: "",
tech: "",
basePlate: "",
sku: "",
num: "",
size: "",
shopNo: "",
createTime: ""
})
} }
}, },
computed: { computed: {
...@@ -134,7 +128,92 @@ export default { ...@@ -134,7 +128,92 @@ export default {
methods: { methods: {
handleClose() { handleClose() {
this.$emit("update:show", false); this.$emit("update:show", false);
},
parseImageAry(imageAry) {
if (typeof imageAry !== "string" || !imageAry.trim()) return [];
const trimmed = imageAry.trim();
if (trimmed.startsWith("http")) {
return trimmed
.split(",")
.map(url => ({ url: url.trim() }))
.filter(item => item.url);
}
try {
const parsed = JSON.parse(trimmed);
if (!Array.isArray(parsed)) return [{ url: trimmed }];
const result = [];
for (const item of parsed) {
if (typeof item === "string" && item) {
result.push({ url: item });
} else if (item && typeof item === "object" && "url" in item) {
const url = item.url;
if (url) {
result.push({
url,
title: item.title
});
}
}
}
return result;
} catch {
return [{ url: trimmed }];
}
} }
} }
}; };
</script> </script>
<style scoped lang="less">
.left-images {
display: flex;
width: 95%;
height: 100%;
flex-direction: column;
b {
color: black;
text-align: center;
margin-bottom: 15px;
}
.left-image {
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
img {
height: auto;
width: 100%;
max-height: 90%;
object-fit: contain;
}
b {
color: black;
font-size: 18px;
margin-bottom: 15px;
}
}
}
.div-text {
b {
position: relative;
background: white;
top: 9px;
left: 13px;
padding: 0 10px;
font-size: 22px;
color: black;
z-index: 3;
}
}
.text-label {
flex: 50%;
font-size: 16px;
}
::v-deep.el-carousel {
.el-carousel__container {
height: 100% !important;
}
}
</style>
...@@ -21,7 +21,8 @@ export const pathMap = { ...@@ -21,7 +21,8 @@ export const pathMap = {
CN: "factory/podJomallOrderProductCn/completeDelivery", CN: "factory/podJomallOrderProductCn/completeDelivery",
US: "factory/podJomallOrderProductUs/completeDelivery", US: "factory/podJomallOrderProductUs/completeDelivery",
GC: "factory/podJomallOrderProduct/completeDelivery", GC: "factory/podJomallOrderProduct/completeDelivery",
OP: "factory/podOrderOperation/printerCompleteDelivery" OP: "factory/podOrderOperation/printerCompleteDelivery",
DTF: "factory/podOrderOperation/completeDelivery"
}, },
//惠立彩素材下载接口 //惠立彩素材下载接口
processTransparentBackground: { processTransparentBackground: {
...@@ -48,7 +49,10 @@ export const pathMap = { ...@@ -48,7 +49,10 @@ export const pathMap = {
psReComposingDesignImages: psReComposingDesignImages:
"factory/podOrderBatchDownload/psReComposingDesignImages", "factory/podOrderBatchDownload/psReComposingDesignImages",
//根据批次分页查询操作单 //根据批次分页查询操作单
listOperationByBatch: "factory/podOrderBatchDownload/listOperationByBatch" listOperationByBatch: "factory/podOrderBatchDownload/listOperationByBatch",
//排版
replenishmentComposingDesignImages:
"factory/podOrderOperation/replenishmentComposingDesignImages"
}; };
// 操作单状态枚举 // 操作单状态枚举
export const statusMap = { export const statusMap = {
......
...@@ -4,7 +4,8 @@ import { ...@@ -4,7 +4,8 @@ import {
toSend, toSend,
writeProfileXml, writeProfileXml,
copySingleImage, copySingleImage,
createBatchFolder createBatchFolder,
downloadDTFFiles
} from "@/server/utils"; } from "@/server/utils";
const { downloadPngList } = require("@/utils/download-queue"); const { downloadPngList } = require("@/utils/download-queue");
const { const {
...@@ -155,6 +156,7 @@ export default { ...@@ -155,6 +156,7 @@ export default {
env = getHostApi().apiApiHost; env = getHostApi().apiApiHost;
fileEnv = getHostApi().fileApiUrl; fileEnv = getHostApi().fileApiUrl;
const params = req.body; const params = req.body;
const targetDir = params.targetDir || "";
const token = req.headers["jwt-token"]; const token = req.headers["jwt-token"];
const forceProduction = params.forceProduction || false; const forceProduction = params.forceProduction || false;
const downloadBySubOrderNumber = pathMap["downloadBySubOrderNumber"]; const downloadBySubOrderNumber = pathMap["downloadBySubOrderNumber"];
...@@ -196,20 +198,23 @@ export default { ...@@ -196,20 +198,23 @@ export default {
let files = [path]; let files = [path];
files = files.map(el => ({ url: `${fileEnv}${el}` })); files = files.map(el => ({ url: `${fileEnv}${el}` }));
let result;
const downloadFunc = if (params.device === 4) {
params.device === 2 ? downloadOtherImage : downloadImage; result = await downloadDTFFiles(files[0].url, targetDir);
const result = await downloadFunc(files, { } else {
processDesignA, const downloadFunc =
processDesignB params.device === 2 ? downloadOtherImage : downloadImage;
}); result = await downloadFunc(files, {
processDesignA,
processDesignB
});
}
console.log("result200", result); console.log("result200", result);
res.json({ code: 200, data: result }); res.json({ code: 200, data: result });
} catch (err) { } catch (err) {
console.error("Download error:", err); console.error("Download error:", err);
res.status(500).json({ code: 500, msg: err }); res.status(500).json({ code: 500, msg: err.message });
} }
}, },
findByPodProductionNo: async (req, res) => { findByPodProductionNo: async (req, res) => {
...@@ -267,7 +272,8 @@ export default { ...@@ -267,7 +272,8 @@ export default {
podJomallOrderUsId: params.podJomallOrderUsId || "" podJomallOrderUsId: params.podJomallOrderUsId || ""
}, },
GC: { id: params.id }, GC: { id: params.id },
OP: { ...params.data } OP: { ...params.data },
DTF: params.ids
}; };
let url = pathMap["completeDelivery"][params.orderType]; let url = pathMap["completeDelivery"][params.orderType];
...@@ -778,5 +784,37 @@ export default { ...@@ -778,5 +784,37 @@ export default {
console.log("checkInventory", error); console.log("checkInventory", error);
res.json({ code: 500, msg: error }); res.json({ code: 500, msg: error });
} }
},
replenishmentComposingDesignImages: async (req, res) => {
env = getHostApi().apiApiHost;
const token = req.headers["jwt-token"];
const { ids, type, templateWidth, targetDir } = req.body;
let url = pathMap["replenishmentComposingDesignImages"];
try {
let { data } = await axios.post(
`${env}/${url}?type=${type}&templateWidth=${templateWidth}`,
ids,
{
headers: { "jwt-token": token }
}
);
if (data.code !== 200) {
return res.json(data);
}
console.log("data", data);
let path = data.message;
// 转义中文
if (path) {
path = encodeURIComponent(path);
}
let files = [path];
files = files.map(el => ({ url: `${fileEnv}${el}` }));
const result = await downloadDTFFiles(files[0].url, targetDir);
res.json({ code: 200, data: result });
} catch (error) {
console.log("checkInventory", error);
res.json({ code: 500, msg: error });
}
} }
}; };
...@@ -74,6 +74,12 @@ autoRegisterRouter( ...@@ -74,6 +74,12 @@ autoRegisterRouter(
"psReComposingDesignImages", "psReComposingDesignImages",
fn.psReComposingDesignImages fn.psReComposingDesignImages
); );
//重新合成排版
autoRegisterRouter(
router,
"replenishmentComposingDesignImages",
fn.replenishmentComposingDesignImages
);
//根据批次分页查询操作单 //根据批次分页查询操作单
autoRegisterRouter(router, "listOperationByBatch", fn.listOperationByBatch); autoRegisterRouter(router, "listOperationByBatch", fn.listOperationByBatch);
......
import { exec } from "child_process"; import { exec } from "child_process";
var fs = require("fs"); var fs = require("fs");
const https = require("https");
const http = require("http");
var path = require("path"); var path = require("path");
var request = require("request"); var request = require("request");
var uuid = require("uuid"); var uuid = require("uuid");
...@@ -84,9 +85,6 @@ export const downloadImage = (list, isForcedProduction) => { ...@@ -84,9 +85,6 @@ export const downloadImage = (list, isForcedProduction) => {
if (downloadItems.length === 0) { if (downloadItems.length === 0) {
return resolve(list); return resolve(list);
} }
console.log("list1111", list);
console.log("downloadItems", downloadItems);
// 并行处理所有下载 // 并行处理所有下载
const downloadPromises = downloadItems.map(item => { const downloadPromises = downloadItems.map(item => {
return new Promise(async itemResolve => { return new Promise(async itemResolve => {
...@@ -494,19 +492,10 @@ export const writeProfileXml = b => { ...@@ -494,19 +492,10 @@ export const writeProfileXml = b => {
const fsPromises = fs.promises; // 明确获取 promises 异步 API const fsPromises = fs.promises; // 明确获取 promises 异步 API
export async function copySingleImage(sourceImagePath, targetDir) { export async function copySingleImage(sourceImagePath, targetDir) {
// 先打印传入的原始路径(方便验证是否和预期一致)
// console.log(`传入参数验证:
// 源图片路径:${sourceImagePath}
// 目标文件夹路径:${targetDir}`);
try { try {
// 步骤1:路径规范化(修正潜在的分隔符/隐形字符问题) // 步骤1:路径规范化(修正潜在的分隔符/隐形字符问题)
const normalizedSourcePath = path.resolve(sourceImagePath); const normalizedSourcePath = path.resolve(sourceImagePath);
const normalizedTargetDir = path.resolve(targetDir); const normalizedTargetDir = path.resolve(targetDir);
// console.log(`路径规范化后:
// 源图片路径:${normalizedSourcePath}
// 目标文件夹路径:${normalizedTargetDir}`);
// 步骤2:校验源文件是否为有效图片文件 // 步骤2:校验源文件是否为有效图片文件
let fileStat; let fileStat;
try { try {
...@@ -521,8 +510,6 @@ export async function copySingleImage(sourceImagePath, targetDir) { ...@@ -521,8 +510,6 @@ export async function copySingleImage(sourceImagePath, targetDir) {
if (!fileStat.isFile()) { if (!fileStat.isFile()) {
throw new Error(`源路径不是有效文件,是文件夹:${normalizedSourcePath}`); throw new Error(`源路径不是有效文件,是文件夹:${normalizedSourcePath}`);
} }
// console.log("校验通过:源路径是有效文件");
// 2.2 校验是否为图片格式(可选,过滤非图片文件) // 2.2 校验是否为图片格式(可选,过滤非图片文件)
const validImageExts = [".jpg", ".jpeg", ".png", ".gif", ".bmp"]; const validImageExts = [".jpg", ".jpeg", ".png", ".gif", ".bmp"];
const fileExt = path.extname(normalizedSourcePath).toLowerCase(); const fileExt = path.extname(normalizedSourcePath).toLowerCase();
...@@ -533,8 +520,6 @@ export async function copySingleImage(sourceImagePath, targetDir) { ...@@ -533,8 +520,6 @@ export async function copySingleImage(sourceImagePath, targetDir) {
)})` )})`
); );
} }
// console.log(`校验通过:源文件是图片格式(${fileExt})`);
// 步骤3:获取文件名 + 拼接目标图片完整路径 // 步骤3:获取文件名 + 拼接目标图片完整路径
const imageFileName = path.basename(normalizedSourcePath); const imageFileName = path.basename(normalizedSourcePath);
const targetImagePath = path.join(normalizedTargetDir, imageFileName); const targetImagePath = path.join(normalizedTargetDir, imageFileName);
...@@ -640,3 +625,160 @@ export async function createBatchList(basePath, batchNoList) { ...@@ -640,3 +625,160 @@ export async function createBatchList(basePath, batchNoList) {
console.error(`创建完成:成功 ${successCount} 个,跳过 ${skipCount} 个`); console.error(`创建完成:成功 ${successCount} 个,跳过 ${skipCount} 个`);
return true; return true;
} }
/**
* 格式化当前时间为 YYYY-MM-DD HH-mm-ss
* @returns {string}
*/
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}`;
}
/**
* 下载文件(图片/zip)到指定目录,zip格式自动解压
* @param {string} fileUrl - 文件链接(支持png/jpg/zip等)
* @param {string} targetDir - 目标文件夹绝对路径
* @param {object} options - 可选配置
* @param {boolean} options.deleteZipAfterUnzip - 解压后是否删除原zip文件,默认false
* @param {boolean} options.unzipToSubdir - zip是否解压到同名子文件夹,默认false(直接散列到目标目录)
* @returns {Promise<{success: boolean, type: string, filePath: string, fileName: string, unzipDir?: string}>}
*/
export function downloadDTFFiles(fileUrl, targetDir, options = {}) {
const { deleteZipAfterUnzip = true, unzipToSubdir = false } = options;
console.log("downloadDTFFiles---------", fileUrl, targetDir);
return new Promise((resolve, reject) => {
try {
// 1. 解析URL,判断协议
const urlObj = new URL(fileUrl);
const requestLib = urlObj.protocol === "https:" ? https : http;
// 2. 递归创建目标目录
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
// 3. 提取文件名(去除参数/哈希,无后缀默认补.jpg)
let cleanPath = urlObj.pathname;
try {
// 先解码URL编码字符,还原 / 和 \
cleanPath = decodeURIComponent(urlObj.pathname);
} catch (e) {
// 解码失败则使用原始路径兜底
cleanPath = urlObj.pathname;
}
// 统一所有反斜杠为正斜杠,兼容Windows路径格式
cleanPath = cleanPath.replace(/\\/g, "/");
// 提取最后一段:纯文件名(含后缀)
const originalFileName = path.basename(cleanPath);
// 最终命名:时间 + 原文件名,兜底空文件名
const fileName = originalFileName
? `${formatTime()} ${originalFileName}`
: `${formatTime()}.png`;
const savePath = path.join(targetDir, fileName);
// 4. 发起网络请求
const request = requestLib.get(fileUrl, response => {
// 处理301/302重定向
if ([301, 302, 307, 308].includes(response.statusCode)) {
const redirectUrl = response.headers.location;
const finalRedirectUrl = redirectUrl.startsWith("http")
? redirectUrl
: new URL(redirectUrl, fileUrl).href;
downloadDTFFiles(finalRedirectUrl, targetDir, options)
.then(resolve)
.catch(reject);
response.resume();
return;
}
if (response.statusCode !== 200) {
reject(new Error(`下载失败,HTTP状态码:${response.statusCode}`));
return;
}
// 5. 流式写入文件
const writeStream = fs.createWriteStream(savePath);
response.pipe(writeStream);
// 写入完成:判断格式,zip自动解压
writeStream.on("finish", () => {
writeStream.close(async () => {
const fileExt = path.extname(fileName).toLowerCase();
// 非zip文件:直接返回
if (fileExt !== ".zip") {
resolve({
success: true,
type: "image",
filePath: savePath,
fileName: fileName
});
return;
}
// zip文件:执行解压
try {
// 解压目标目录:直接解压到目标目录 / 或解压到同名子文件夹
let unzipTargetDir = targetDir;
if (unzipToSubdir) {
const dirName = path.basename(fileName, ".zip");
unzipTargetDir = path.join(targetDir, dirName);
if (!fs.existsSync(unzipTargetDir)) {
fs.mkdirSync(unzipTargetDir, { recursive: true });
}
}
// 执行解压
await compressing.zip.uncompress(savePath, unzipTargetDir);
// 可选:解压完成后删除原zip文件
if (deleteZipAfterUnzip) {
fs.unlinkSync(savePath);
}
resolve({
success: true,
type: "zip",
filePath: savePath,
fileName: fileName,
unzipDir: unzipTargetDir
});
} catch (unzipErr) {
reject(new Error(`ZIP解压失败:${unzipErr.message}`));
}
});
});
// 写入异常:删除残留文件
writeStream.on("error", err => {
if (fs.existsSync(savePath)) {
fs.unlink(savePath, () => {});
}
reject(new Error(`文件写入失败:${err.message}`));
});
});
// 网络请求异常
request.on("error", err => {
reject(new Error(`网络请求失败:${err.message}`));
});
// 超时控制
request.setTimeout(15000, () => {
request.destroy();
reject(new Error("下载超时,请检查网络或链接有效性"));
});
} catch (err) {
reject(new Error(`参数校验失败:${err.message}`));
}
});
}
...@@ -202,6 +202,12 @@ module.exports = { ...@@ -202,6 +202,12 @@ module.exports = {
}, },
getIsOver: () => store.get("isOver") || false, getIsOver: () => store.get("isOver") || false,
//储存用户信息
setUser: value => {
store.set("userData", value);
},
getUser: () => store.get("userData"),
//本地储存 DTG、DTF生产类型 //本地储存 DTG、DTF生产类型
setProductType: value => { setProductType: value => {
store.set("productType", value); store.set("productType", value);
......
...@@ -26,6 +26,7 @@ function endLoading() { ...@@ -26,6 +26,7 @@ function endLoading() {
service.interceptors.request.use( service.interceptors.request.use(
config => { config => {
const user = Vue.prototype.$dataStore.get("user"); const user = Vue.prototype.$dataStore.get("user");
if (user) { if (user) {
config.headers["jwt-token"] = user.token; config.headers["jwt-token"] = user.token;
} }
...@@ -82,8 +83,26 @@ service.interceptors.response.use( ...@@ -82,8 +83,26 @@ service.interceptors.response.use(
}, },
error => { error => {
endLoading(); endLoading();
// do something with response error let errMsg = "请求失败,请稍后重试";
return Promise.reject(error);
// 1. 有服务端响应:提取后端返回的 msg
if (error.response && error.response.data) {
const data = error.response.data;
// 优先取后端返回的 msg(适配你后端 {code:500, msg:'xxx'} 的格式)
errMsg =
data.msg || data.message || `请求错误(${error.response.status})`;
}
// 2. 无响应:网络层面错误
else if (error.message) {
if (error.message.includes("timeout")) {
errMsg = "请求超时,请检查网络";
} else if (error.message.includes("Network Error")) {
errMsg = "网络连接异常,请检查网络";
} else {
errMsg = error.message;
}
}
return Promise.reject(new Error(errMsg));
} }
); );
......
<script> <script>
import PHead from "./head/index.vue"; import PHead from "./head/index.vue";
import PMain from "./main/index.vue"; import PMain from "./main/index.vue";
const { getUser } = require("@/server/utils/store");
export default { export default {
name: "design-dtg", name: "design-dtg",
components: { PHead, PMain }, components: { PHead, PMain },
data() { data() {
return { return {
user: {}, user: {},
factoryType: "CN" factoryType: "CN",
userData: getUser()
}; };
}, },
mounted() {}, mounted() {},
...@@ -17,7 +20,7 @@ export default { ...@@ -17,7 +20,7 @@ export default {
<template> <template>
<div class="page"> <div class="page">
<p-head :user="user" :factoryType="factoryType" /> <p-head :user="userData.user" :factoryType="userData.factoryType" />
<p-main :factoryType="factoryType" /> <p-main :factoryType="factoryType" />
</div> </div>
</template> </template>
......
<script> <script>
import UpdateDialog from "@/views/design/updateDialog.vue"; import UpdateDialog from "@/views/design/updateDialog.vue";
import { Loading } from "element-ui"; import { Loading } from "element-ui";
const { getProductType, setProductType } = require("@/server/utils/store"); const {
getProductType,
setProductType,
setUser
} = require("@/server/utils/store");
export default { export default {
components: { UpdateDialog }, components: { UpdateDialog },
...@@ -24,7 +28,7 @@ export default { ...@@ -24,7 +28,7 @@ export default {
this.$refs.updateDialog?.open(data); this.$refs.updateDialog?.open(data);
} }
}); });
setUser({ user: this.user, factoryType: this.factoryType });
const routerName = this.$router.currentRoute.name; const routerName = this.$router.currentRoute.name;
const routerMap = { DTG: "design-dtg", DTF: "design-dtf" }; const routerMap = { DTG: "design-dtg", DTF: "design-dtf" };
......
...@@ -2,28 +2,31 @@ ...@@ -2,28 +2,31 @@
const { getDTFSetting } = require("@/server/utils/store"); const { getDTFSetting } = require("@/server/utils/store");
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
const { statusMap } = require("@/config/index.js"); const { statusMap } = require("@/config/index.js");
const { pathMap } = require("@/config/index.js");
const { getUser } = require("@/server/utils/store");
var path = require("path");
export default { export default {
props: { props: {
user: { selection: { type: Array, default: () => [] },
default: () => ({ podOrderProductIds: { type: Array, default: () => [] }
avatar: "",
factory: {}
}),
type: Object
},
factoryType: { type: String, default: "CN" }
}, },
data() { data() {
return { return {
dialogVisible: false, dialogVisible: false,
dtfSetting: getDTFSetting(), dtfSetting: getDTFSetting(),
radio: "", radio: "",
curBatchArrangeNum: "",
searchForm: {}, searchForm: {},
statusMap: statusMap statusMap: statusMap,
userData: getUser()
}; };
}, },
computed: {},
mounted() {}, mounted() {
const params = this.$route.params;
this.curBatchArrangeNum = params.batchArrangeNum;
},
created() {}, created() {},
methods: { methods: {
...@@ -61,65 +64,111 @@ export default { ...@@ -61,65 +64,111 @@ export default {
goBack() { goBack() {
this.$router.push({ name: "design-dtf" }); this.$router.push({ name: "design-dtf" });
}, },
goSetting() {}, async goSetting() {
if (!this.podOrderProductIds.length) {
return this.$message.warning("请选择操作单");
}
try {
let res = await this.$api.post(
pathMap["downloadBySubOrderNumber"]["OP"],
{
ids: this.podOrderProductIds,
device: 4,
orderType: "OP",
targetDir: path.join(
getDTFSetting().downloadDir,
`批次号:${this.curBatchArrangeNum}`,
"原素材"
)
}
);
console.log(77, res);
} catch (error) {
this.$message.error(error);
}
},
getDataInfo() { getDataInfo() {
this.$emit("search", this.searchForm); this.$emit("search", this.searchForm);
}, },
productionCompleted() { productionCompleted() {
this.$confirm("确认完成生产?", "提示", { if (!this.selection.length) {
return this.$message.warning("请选择操作单");
}
this.$confirm(`确定生产完成?`, "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}) }).then(async () => {
.then(() => {}) await this.$api.post(pathMap.completeDelivery["DTF"], {
.catch(() => {}); orderType: "DTF",
ids: this.selection
});
});
}, },
changeTypesetting() { changeTypesetting() {
if (!this.selection.length) {
return this.$message.warning("请选择操作单");
}
this.dialogVisible = true; this.dialogVisible = true;
this.radio = "";
}, },
async submit() { async submit() {
if (!this.radio) { try {
return this.$message.error("请选择排版宽度"); if (!this.radio) {
} return this.$message.error("请选择排版宽度");
}
const payload = {
ids: this.selection,
type: "png",
templateWidth: this.radio,
targetDir: path.join(
getDTFSetting().downloadDir,
`批次号:${this.curBatchArrangeNum}`,
"手动排版素材"
)
};
if (this.dtfSetting.widthStrategy == 3 && this.radio == 60) {
this.$confirm(
"由于排版设置中选择“按更大规格排版”仅适用于40+2,选60时,默认超60的规格不排版",
"提示",
{
confirmButtonText: "确定",
type: "warning"
}
);
const { data } = await this.$api.post(
pathMap["replenishmentComposingDesignImages"],
payload
);
console.log("submit", data);
if (this.dtfSetting.widthStrategy == 3 && this.radio == 60) { this.$message.success("DTF排版成功,请到手动排版素材中查看");
this.$confirm( } else {
"由于排版设置中选择“按更大规格排版”仅适用于40+2,选60时,默认超60的规格不排版", const { data } = await this.$api.post(
"提示", pathMap["replenishmentComposingDesignImages"],
{ payload
confirmButtonText: "确定", );
type: "warning" console.log("submit", data);
}
); this.$message.success("DTF排版成功,请到手动排版素材中查看");
await this.$api.post("/psReComposingDesignImages", { }
batchArrangeNum: this.templateBatchArrangeNum, this.dialogVisible = false;
templateWidth: this.radio this.getDataInfo();
}); } catch (error) {
this.$message( console.log("submit", error);
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
} else {
await this.$api.post("/psReComposingDesignImages", {
batchArrangeNum: this.templateBatchArrangeNum,
templateWidth: this.radio
});
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
} }
}, },
async goFliePage(value, type) { async goFliePage() {
console.log(value);
let { data } = await this.$api.post("/createBatchFolder", { let { data } = await this.$api.post("/createBatchFolder", {
basePath: this.dtfSetting.downloadDir, basePath: this.dtfSetting.downloadDir,
downloadDir: value.batchNo, downloadDir: this.curBatchArrangeNum,
isArray: false isArray: false
}); });
console.log("goFliePage", data); if (!data) {
if (type == "check") { return this.$message.error("下载文件目录未配置或者目录错误");
ipcRenderer.send("open-folder-only", data);
} }
ipcRenderer.send("open-folder-only", data);
} }
} }
}; };
...@@ -141,6 +190,7 @@ export default { ...@@ -141,6 +190,7 @@ export default {
<el-input <el-input
placeholder="请扫描操作单" placeholder="请扫描操作单"
v-model="searchForm.operationNo" v-model="searchForm.operationNo"
clearable
></el-input ></el-input
></el-form-item> ></el-form-item>
<el-form-item label="操作单状态"> <el-form-item label="操作单状态">
...@@ -153,9 +203,9 @@ export default { ...@@ -153,9 +203,9 @@ export default {
></el-option> </el-select ></el-option> </el-select
></el-form-item> ></el-form-item>
<el-form-item label="操作单排版状态"> <el-form-item label="操作单排版状态">
<el-select v-model="searchForm.layout" placeholder="请选择"> <el-select v-model="searchForm.layout" placeholder="请选择" clearable>
<el-option label="" :value="true"></el-option> <el-option label="排版成功" :value="true"></el-option>
<el-option label="" :value="false"> </el-option> </el-select <el-option label="排版失败" :value="false"> </el-option> </el-select
></el-form-item> ></el-form-item>
<el-form-item> <el-form-item>
...@@ -187,21 +237,23 @@ export default { ...@@ -187,21 +237,23 @@ export default {
<div class="right-user"> <div class="right-user">
<div <div
v-if="user && user.factory" v-if="userData && userData.factory"
style="font-weight: 700;margin-left: 8px;" style="font-weight: 700;margin-left: 8px;"
> >
{{ {{
user.factory.countryCode userData.user.countryCode
? `${user.factory.countryCode}${getCountryName( ? `${userData.user.countryCode}${getCountryName(
user.factory.countryCode userData.user.countryCode
)}` )}`
: "CN(中国)" : "CN(中国)"
}} }}
</div> </div>
<p v-if="user && user.factory">{{ user.factory.title }}</p> <p v-if="userData.user && userData.user.factory">
{{ userData.user.factory.title }}
</p>
<el-dropdown @command="dropdownCommand"> <el-dropdown @command="dropdownCommand">
<div style="margin-right: 20px"> <div style="margin-right: 20px">
<b style="cursor:pointer;">{{ user.account }}</b> <b style="cursor:pointer;">{{ userData.user.account }}</b>
<i class="el-icon-arrow-down"></i> <i class="el-icon-arrow-down"></i>
</div> </div>
...@@ -213,7 +265,7 @@ export default { ...@@ -213,7 +265,7 @@ export default {
</div> </div>
<el-dialog title="排版宽度" :visible.sync="dialogVisible" width="25%"> <el-dialog title="排版宽度" :visible.sync="dialogVisible" width="25%">
<el-radio-group v-model="radio"> <el-radio-group v-model="radio">
<el-radio :label="40">40+2cm</el-radio> <el-radio :label="42">40+2cm</el-radio>
<el-radio :label="60">60cm</el-radio> <el-radio :label="60">60cm</el-radio>
</el-radio-group> </el-radio-group>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
......
...@@ -26,42 +26,55 @@ export default { ...@@ -26,42 +26,55 @@ export default {
return { return {
logVisible: false, logVisible: false,
detailVisible: false, detailVisible: false,
curData: {},
logList: [], logList: [],
selection: [],
podOrderProductIds: [],
pageInfo: { pageInfo: {
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
total: 2 total: 2
}, },
cardList: [], cardList: [],
curBatchArrangeNum: "",
detailRow: { detailRow: {
batchArrangeNum: { label: "批次号", value: 111 }, batchArrangeNum: { label: "批次号", value: "" },
operationNum: { label: "操作单数量", value: 111 }, operationNum: { label: "操作单数量", value: "" },
materialNum: { label: "素材数量", value: 111 }, materialNum: { label: "素材数量", value: "" },
craftType: { label: "工艺类型", value: 111 }, craftType: { label: "工艺类型", value: "" },
standardDesignImage: { label: "规范素材", value: 111 }, standardDesignImage: { label: "规范素材", value: "" },
createTime: { label: "创建时间", value: 111 }, createTime: { label: "创建时间", value: "" },
layoutStatus: { label: "排版状态", value: 111 }, layoutStatus: { label: "排版状态", value: "" },
status: { label: "操作单状态", value: 111 } status: { label: "操作单状态", value: "" }
}, },
platformJson: platformJson platformJson: platformJson,
layoutStatus: {
1: { label: "待排版", type: "warning" },
2: { label: "排版中", type: "info" },
3: { label: "排版成功", type: "success" },
4: { label: "排版失败", type: "danger" },
5: { label: "部分成功", type: "success" }
}
}; };
}, },
mounted() { mounted() {
this.loadRowData(); this.loadRowData();
this.curData = {};
this.selection = [];
this.podOrderProductIds = [];
}, },
methods: { methods: {
async loadRowData() { async loadRowData() {
try { try {
const params = this.$route.params; const params = this.$route.params;
console.log("params", params); this.curBatchArrangeNum = params.batchArrangeNum;
Object.keys(this.detailRow).forEach(key => { Object.keys(this.detailRow).forEach(key => {
// 路由里有对应值就赋值,没有则保留默认值 // 路由里有对应值就赋值,没有则保留默认值
if (params[key] !== undefined) { if (params[key] !== undefined) {
this.detailRow[key].value = params[key]; this.detailRow[key].value = params[key];
} }
}); });
await this.getCardList({ batchArrangeNumber: params.batchArrangeNum }); await this.getCardList();
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
...@@ -69,7 +82,8 @@ export default { ...@@ -69,7 +82,8 @@ export default {
async getCardList(value) { async getCardList(value) {
let params = { let params = {
currentPage: this.pageInfo.currentPage, currentPage: this.pageInfo.currentPage,
pageSize: this.pageInfo.pageSize pageSize: this.pageInfo.pageSize,
batchArrangeNumber: this.curBatchArrangeNum
}; };
if (value) { if (value) {
params = { ...params, ...value }; params = { ...params, ...value };
...@@ -80,6 +94,7 @@ export default { ...@@ -80,6 +94,7 @@ export default {
params params
); );
this.cardList = data.records; this.cardList = data.records;
this.pageInfo.total = data.total;
console.log("listOperationByBatch", data); console.log("listOperationByBatch", data);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
...@@ -119,26 +134,34 @@ export default { ...@@ -119,26 +134,34 @@ export default {
{ {
label: "全部选择", label: "全部选择",
click: () => { click: () => {
this.cardList.forEach(el => { const cardIds = this.cardList.map(el => el.id);
el.active = true; const cardProIds = this.cardList.map(el => el.podOrderProductId);
}); this.podOrderProductIds = Array.from(
new Set([...this.podOrderProductIds, ...cardProIds])
);
this.selection = Array.from(
new Set([...this.selection, ...cardIds])
);
} }
}, },
{ {
label: "取消选择", label: "取消选择",
click: () => { click: () => {
this.cardList.forEach(el => { const cardIdSet = new Set(this.cardList.map(el => el.id));
el.active = false; const cardProIdsSet = new Set(
}); this.cardList.map(el => el.podOrderProductId)
);
this.selection = this.selection.filter(id => !cardIdSet.has(id));
this.podOrderProductIds = this.selection.filter(
id => !cardProIdsSet.has(id)
);
} }
} }
]; ];
const menu = Menu.buildFromTemplate(template); const menu = Menu.buildFromTemplate(template);
menu.popup({ x: e.clientX, y: e.clientY }); menu.popup({ x: e.clientX, y: e.clientY });
}, },
getItemTags(tagsId) {},
setProductMark(tagsId) {},
parseImageAry(imageAry) { parseImageAry(imageAry) {
if (typeof imageAry !== "string" || !imageAry.trim()) return []; if (typeof imageAry !== "string" || !imageAry.trim()) return [];
const trimmed = imageAry.trim(); const trimmed = imageAry.trim();
...@@ -170,17 +193,30 @@ export default { ...@@ -170,17 +193,30 @@ export default {
return [{ url: trimmed }]; return [{ url: trimmed }];
} }
}, },
openLogDialog(tagsId) { openLogDialog() {
console.log(999);
this.logVisible = true; this.logVisible = true;
}, },
changeActive(item) { changeActive(item) {
item.active = !item.active; const index = this.selection.indexOf(item.id);
const podIndex = this.podOrderProductIds.indexOf(item.podOrderProductId);
if (podIndex > -1) {
this.podOrderProductIds.splice(podIndex, 1);
} else {
this.podOrderProductIds.push(item.podOrderProductId);
}
if (index > -1) {
this.selection.splice(index, 1);
} else {
this.selection.push(item.id);
}
},
isSelected(item) {
return this.selection.includes(item.id);
}, },
handleViewDetail(item) { handleViewDetail(item) {
try { try {
this.detailVisible = true; this.detailVisible = true;
this.curData = item;
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
...@@ -192,7 +228,7 @@ export default { ...@@ -192,7 +228,7 @@ export default {
); );
if (item) { if (item) {
console.log(item.icon); // console.log(item.icon);
return item.icon.split("/").pop(); return item.icon.split("/").pop();
} }
...@@ -205,7 +241,13 @@ export default { ...@@ -205,7 +241,13 @@ export default {
<template> <template>
<div style="height:100%" @contextmenu.prevent="openMenu"> <div style="height:100%" @contextmenu.prevent="openMenu">
<div class="page"> <div class="page">
<DTFhead :user="user" :factoryType="factoryType"></DTFhead> <DTFhead
:user="user"
:factoryType="factoryType"
@search="getCardList"
:selection="selection"
:podOrderProductIds="podOrderProductIds"
></DTFhead>
<div class="rowBox"> <div class="rowBox">
<div class="rowItem" v-for="(item, index) in detailRow" :key="index"> <div class="rowItem" v-for="(item, index) in detailRow" :key="index">
<div <div
...@@ -213,7 +255,14 @@ export default { ...@@ -213,7 +255,14 @@ export default {
flex-direction: column; align-items: center;" flex-direction: column; align-items: center;"
> >
<div style="min-height: 22px;">{{ item.label }}</div> <div style="min-height: 22px;">{{ item.label }}</div>
<div style="min-height: 22px;">{{ item.value }}</div> <div style="min-height: 22px;" v-if="item.label == '排版状态'">
<el-tag :type="layoutStatus[item.value]?.type">{{
layoutStatus[item.value]?.label
}}</el-tag>
</div>
<div v-else style="min-height: 22px;">
{{ item.value }}
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -223,12 +272,12 @@ export default { ...@@ -223,12 +272,12 @@ export default {
class="card-grid-item" class="card-grid-item"
v-for="(item, index) in cardList" v-for="(item, index) in cardList"
:key="index" :key="index"
@click.stop="changeActive(item)" @click="changeActive(item)"
> >
<BaseCard <BaseCard
style="cursor: pointer;" style="cursor: pointer;"
:card-item="item" :card-item="item"
:active="item.active" :active="isSelected(item)"
:show-sku="false" :show-sku="false"
:show-product-info="false" :show-product-info="false"
:image-field="'variantImage'" :image-field="'variantImage'"
...@@ -238,7 +287,7 @@ export default { ...@@ -238,7 +287,7 @@ export default {
<span <span
class="operation-number" class="operation-number"
:title="`操作单号:${item.operationNo}`" :title="`操作单号:${item.operationNo}`"
@click.stop="() => {}" @click.stop="copyText(item.operationNo || '')"
> >
{{ item.operationNo }} {{ item.operationNo }}
</span> </span>
...@@ -345,9 +394,9 @@ export default { ...@@ -345,9 +394,9 @@ export default {
<div class="card-info-row full"> <div class="card-info-row full">
<span <span
class="info-value ellipsis" class="info-value ellipsis"
:title="item.operationNo || ''" :title="item.productName || ''"
> >
{{ item.operationNo }} {{ item.productName }}
</span> </span>
</div> </div>
<div class="card-info-row"> <div class="card-info-row">
...@@ -433,7 +482,7 @@ export default { ...@@ -433,7 +482,7 @@ export default {
small small
@size-change="handleSizeChange" @size-change="handleSizeChange"
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
:current-page="pageInfo.pageNum" :current-page="pageInfo.currentPage"
:page-sizes="[10, 20, 50, 100]" :page-sizes="[10, 20, 50, 100]"
:page-size="pageInfo.pageSize" :page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
...@@ -450,11 +499,7 @@ export default { ...@@ -450,11 +499,7 @@ export default {
<LogList v-if="logList.length" :log-list="logList" /> <LogList v-if="logList.length" :log-list="logList" />
<div v-else class="empty-content">暂无数据</div> <div v-else class="empty-content">暂无数据</div>
</el-dialog> </el-dialog>
<DetailDialog <DetailDialog :show.sync="detailVisible" :info="curData"></DetailDialog>
:show.sync="detailVisible"
:img-url="''"
:info="{}"
></DetailDialog>
</div> </div>
</template> </template>
......
<script> <script>
const { getUser } = require("@/server/utils/store");
export default { export default {
props: {
user: {
default: () => ({
avatar: "",
factory: {}
}),
type: Object
},
factoryType: { type: String, default: "CN" }
},
data() { data() {
return { return {
searchForm: { batchArrangeNumber: "", layoutStatus: "", startTime: "" } searchForm: { batchArrangeNumber: "", layoutStatus: "", startTime: "" },
userData: getUser()
}; };
}, },
computed: {}, computed: {},
...@@ -81,12 +74,14 @@ export default { ...@@ -81,12 +74,14 @@ export default {
<el-input <el-input
v-model="searchForm.batchArrangeNumber" v-model="searchForm.batchArrangeNumber"
placeholder="请输入批次号" placeholder="请输入批次号"
clearable
></el-input ></el-input
></el-form-item> ></el-form-item>
<el-form-item label="排版状态"> <el-form-item label="排版状态">
<el-select <el-select
v-model="searchForm.layoutStatus" v-model="searchForm.layoutStatus"
placeholder="请选择排版状态" placeholder="请选择排版状态"
clearable
> >
<el-option label="待排版" :value="1"></el-option> <el-option label="待排版" :value="1"></el-option>
<el-option label="排版中" :value="2"> </el-option> <el-option label="排版中" :value="2"> </el-option>
...@@ -97,6 +92,7 @@ export default { ...@@ -97,6 +92,7 @@ export default {
</el-form-item> </el-form-item>
<el-form-item label="创建时间"> <el-form-item label="创建时间">
<el-date-picker <el-date-picker
clearable
v-model="searchForm.startTime" v-model="searchForm.startTime"
type="datetime" type="datetime"
placeholder="选择创建时间" placeholder="选择创建时间"
...@@ -119,21 +115,23 @@ export default { ...@@ -119,21 +115,23 @@ export default {
<div class="right-user"> <div class="right-user">
<div <div
v-if="user && user.factory" v-if="userData.user && userData.user.factory"
style="font-weight: 700;margin-left: 8px;" style="font-weight: 700;margin-left: 8px;"
> >
{{ {{
user.factory.countryCode userData.user.countryCode
? `${user.factory.countryCode}${getCountryName( ? `${userData.user.countryCode}${getCountryName(
user.factory.countryCode userData.user.countryCode
)}` )}`
: "CN(中国)" : "CN(中国)"
}} }}
</div> </div>
<p v-if="user && user.factory">{{ user.factory.title }}</p> <p v-if="userData.user && userData.user.factory">
{{ userData.user.factory.title }}
</p>
<el-dropdown @command="dropdownCommand"> <el-dropdown @command="dropdownCommand">
<div style="margin-right: 20px"> <div style="margin-right: 20px">
<b style="cursor:pointer;">{{ user.account }}</b> <b style="cursor:pointer;">{{ userData.user.account }}</b>
<i class="el-icon-arrow-down"></i> <i class="el-icon-arrow-down"></i>
</div> </div>
......
...@@ -23,6 +23,7 @@ export default { ...@@ -23,6 +23,7 @@ export default {
return { return {
dialogVisible: false, dialogVisible: false,
selectionList: [], selectionList: [],
searchForm: {},
radio: "", radio: "",
templateBatchArrangeNum: "", templateBatchArrangeNum: "",
pollTimer: null, pollTimer: null,
...@@ -107,7 +108,7 @@ export default { ...@@ -107,7 +108,7 @@ export default {
}, },
mounted() { mounted() {
this.fetchBatchList(); this.fetchBatchList();
// this.pollTimer = setInterval(() => this.fetchBatchList(), 300000); this.pollTimer = setInterval(() => this.fetchBatchList(), 300000);
// 单文件下载成功 // 单文件下载成功
ipcRenderer.on("download:file-success", (_, data) => { ipcRenderer.on("download:file-success", (_, data) => {
...@@ -154,13 +155,13 @@ export default { ...@@ -154,13 +155,13 @@ export default {
//定时任务 //定时任务
async fetchBatchList(value) { async fetchBatchList(value) {
// 先判断:有下载任务在跑,本轮直接跳过 // 先判断:有下载任务在跑,本轮直接跳过
console.log("this.isFetching", this.isFetching); // console.log("this.isFetching", this.isFetching);
if (this.isFetching) return; if (this.isFetching) return;
this.isFetching = true; this.isFetching = true;
try { try {
const status = await this.getDownloadStatus(); const status = await this.getDownloadStatus();
console.log("status", status); // console.log("status", status);
if (status.isRunning) return; if (status.isRunning) return;
let params = { let params = {
...@@ -176,7 +177,6 @@ export default { ...@@ -176,7 +177,6 @@ export default {
if (res.code === 200) { if (res.code === 200) {
this.tableList = res.data.records || []; this.tableList = res.data.records || [];
console.log(this.tableList);
this.pageInfo.total = res.data.total; this.pageInfo.total = res.data.total;
ipcRenderer.sendSync("download:submit-batch-list", this.tableList); ipcRenderer.sendSync("download:submit-batch-list", this.tableList);
...@@ -230,7 +230,9 @@ export default { ...@@ -230,7 +230,9 @@ export default {
downloadDir: value.batchArrangeNum, downloadDir: value.batchArrangeNum,
isArray: false isArray: false
}); });
console.log("goFliePage", data); if (!data) {
return this.$message.error("下载文件目录未配置或者目录错误");
}
if (type == "check") { if (type == "check") {
ipcRenderer.send("open-folder-only", data); ipcRenderer.send("open-folder-only", data);
} }
...@@ -238,9 +240,12 @@ export default { ...@@ -238,9 +240,12 @@ export default {
//打开手动排版弹窗 //打开手动排版弹窗
changeTypesetting(value) { changeTypesetting(value) {
if (this.dtfSetting.autoLayoutStrategy == 3) { if (
this.dtfSetting.autoLayoutStrategy == 3 ||
[3, 5].includes(value.layoutStatus)
) {
this.dialogVisible = true; this.dialogVisible = true;
this.templateBatchArrangeNum = value; this.templateBatchArrangeNum = value.batchArrangeNum;
} else { } else {
this.$message( this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看" "排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
...@@ -279,6 +284,9 @@ export default { ...@@ -279,6 +284,9 @@ export default {
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看" "排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
); );
} }
this.dialogVisible = false;
this.fetchBatchList(this.searchForm);
}, },
//跳转批次详情页 //跳转批次详情页
...@@ -322,7 +330,12 @@ export default { ...@@ -322,7 +330,12 @@ export default {
<DTFhead <DTFhead
:user="user" :user="user"
:factoryType="factoryType" :factoryType="factoryType"
@search="fetchBatchList" @search="
value => {
searchForm = value;
this.fetchBatchList(searchForm);
}
"
></DTFhead> ></DTFhead>
<BaseTable <BaseTable
v-if="tableList.length" v-if="tableList.length"
...@@ -371,7 +384,7 @@ export default { ...@@ -371,7 +384,7 @@ export default {
type="text" type="text"
:disabled="scope.row.layoutStatus == 2" :disabled="scope.row.layoutStatus == 2"
class="btn flex btnBox" class="btn flex btnBox"
@click="changeTypesetting(scope.row.batchArrangeNum)" @click="changeTypesetting(scope.row)"
><img ><img
src="../../assets/typesetting.png" src="../../assets/typesetting.png"
width="30" width="30"
......
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
<script> <script>
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
const { setDTFSetting, getDTFSetting } = require("@/server/utils/store"); const { setDTFSetting, getDTFSetting } = require("@/server/utils/store");
const { pathMap } = require("@/config/index.js");
export default { export default {
name: "dtf-setting", name: "dtf-setting",
...@@ -98,8 +99,13 @@ export default { ...@@ -98,8 +99,13 @@ export default {
// 读取本地配置 // 读取本地配置
async loadLocalConfig() { async loadLocalConfig() {
try { try {
const { data } = await this.$api.post("/productionConfig"); const { data } = await this.$api.post(pathMap["productionConfig"]);
this.form = { ...data }; this.form = { ...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 });
} catch (error) { } catch (error) {
console.log(error); console.log(error);
...@@ -107,10 +113,11 @@ export default { ...@@ -107,10 +113,11 @@ export default {
}, },
// 选择文件夹弹窗 // 选择文件夹弹窗
selectFolder() { selectFolder() {
ipcRenderer.send("request-select-folder"); ipcRenderer.send("request-select-folder", this.form.downloadDir);
ipcRenderer.once("select-folder-result", (_, path) => { ipcRenderer.once("select-folder-result", (_, path) => {
if (path) this.form.downloadDir = path; if (path) this.form.downloadDir = path;
}); });
console.log("selectFolder", this.form);
}, },
// 保存配置到本地文件 // 保存配置到本地文件
async saveConfig() { async saveConfig() {
...@@ -124,7 +131,7 @@ export default { ...@@ -124,7 +131,7 @@ export default {
} }
); );
} }
await this.$api.post("/productionConfigUpdate", this.form); await this.$api.post(pathMap["productionConfigUpdate"], this.form);
setDTFSetting({ ...this.form }); setDTFSetting({ ...this.form });
this.$message.success("排版设置保存成功!"); this.$message.success("排版设置保存成功!");
} }
......
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