Commit 587836ed by linjinhong

feat:添加列表轮询功能

parent a65d4912
......@@ -4,7 +4,8 @@ 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 axios = require("axios");
const createDownloadQueue = require("@/utils/download-queue");
const fs = require("fs");
import path from "path"; // 引入 path 模块
......@@ -29,6 +30,27 @@ const winURL =
? "http://localhost:8050"
: `file://${__dirname}/index.html`;
// 全局唯一下载队列,服务启动时初始化一次
const downloadQueue = createDownloadQueue({
concurrency: 2,
retryTimes: 2,
// 根目录:系统下载目录/排版素材,可自行修改为固定盘符
basePath: path.join(app.getPath("downloads"), "自动排版素材"),
// 文件名规则,可自定义
fileNameRule: task => `${task.batchArrangeNum}_自动排版素材.zip`,
onSuccess: task => {
console.log(`批次 ${task.batchArrangeNum} 下载完成`);
win.webContents.send("download:success", task.batchArrangeNum);
},
onError: (task, err) => {
console.error(`批次 ${task.batchArrangeNum} 下载失败:`, err.message);
win.webContents.send("download:error", {
batchArrangeNum: task.batchArrangeNum,
msg: err.message
});
}
});
async function createWindow() {
win = new BrowserWindow({
width: 1500,
......@@ -391,26 +413,16 @@ async function createWindow() {
ipcMain.on("open-folder-only", async (event, dirPath) => {
console.log(938, dirPath);
const result = shell.showItemInFolder(dirPath);
const result = shell.openItem(dirPath);
return result;
});
win.on("closed", () => {
// win && win.removeAllListeners();
// win = null;
// newWindow && newWindow.close();
// newWindow = null;
// 确保窗口还未销毁,才执行清理操作
if (win && !win.isDestroyed()) {
win.removeAllListeners();
win = null;
}
// // 确保 newWindow 还未销毁,才执行关闭操作
// if (newWindow && !newWindow.isDestroyed()) {
// newWindow.close();
// newWindow = null;
// }
});
// 自动更新逻辑开始
......@@ -492,6 +504,33 @@ async function createWindow() {
const { width, height } = win.getBounds();
win.webContents.send("window-size", { width, height });
});
// 1. 批量添加下载任务
ipcMain.on("download:addTasks", (event, tasks) => {
const BASE_URL = "";
// 给每个任务挂载获取下载地址的方法
const taskList = tasks.map(item => ({
...item,
fetchUrl: async () => {
const params = {};
const res = await axios({
method: "get",
url: `${BASE_URL}/material/getDownloadUrl`,
params
})({
batchArrangeNum: item.batchArrangeNum
});
return res.data.downloadUrl;
}
}));
downloadQueue.addTasks(taskList);
event.returnValue = { code: 200, msg: "已加入队列" };
});
// 2. 查询队列运行状态
ipcMain.on("download:getStatus", event => {
event.returnValue = { isRunning: downloadQueue.isRunning };
});
}
app.on("activate", async () => {
......@@ -524,6 +563,9 @@ app.on("will-quit", () => {
globalShortcut.unregister("F5");
globalShortcut.unregister("CommandOrControl+R");
});
app.on("before-quit", () => {
downloadQueue.destroy();
});
if (isDevelopment) {
if (process.platform === "win32") {
......
......@@ -12,7 +12,7 @@
<el-table-column
v-if="hasSelection"
type="selection"
width="50"
width="55"
align="center"
/>
<!-- 序号列 -->
......@@ -219,6 +219,9 @@ export default {
*/
handleCurrentChange(page) {
this.$emit("page-current-change", page);
},
toggleAllSelection(value) {
this.$refs.tableRef.toggleAllSelection(value);
}
},
mounted() {
......
<template>
<div class="log-list">
<div v-for="l in logList" :key="l.id" class="log-item flex">
<div class="log-item-icon">
<el-icon name="a-2labadianji3x" />
</div>
<div class="log-item-time">
<span>{{ l.local && `${l.local}:` }}{{ l.createTime }}</span>
</div>
<div v-if="l.employeeName" class="log-item-name">
<span>{{ l.employeeName }}</span>
</div>
<div class="log-item-content" :title="l.description">
<span>{{ l.description }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
export default {
props: {
logList: {
default: () => [],
type: Array
}
}
};
</script>
<style lang="scss" scoped>
.log-list {
height: 500px;
overflow: auto;
font-size: 14px;
}
.log-item {
line-height: 26px;
white-space: pre-wrap;
word-break: break-all;
}
.log-item div:not(:last-child) {
margin-right: 6px;
}
.log-item-time {
// width: 220px;
}
.log-item-name {
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.log-item-content {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
// white-space: nowrap;
}
</style>
<template>
<el-dialog
:visible.sync="visible"
width="92%"
top="5vh"
:before-close="handleClose"
:show-close="true"
>
<div class="order-detail-container" style="display: flex; gap: 32px;">
<!-- 左侧图片区域 -->
<div class="left-img" style="width: 36%; text-align: center;">
<p style="font-size: 22px; font-weight: bold; margin: 0 0 10px;">B</p>
<div style="background-color: #f9f7ee; padding: 45px 20px;">
<img :src="imgUrl" alt="成衣图片" style="width: 85%;" />
</div>
</div>
<!-- 右侧信息区域 -->
<div class="right-info" style="flex: 1;">
<!-- 客户+订单号栏 -->
<div
class="customer-order-row"
style="display: flex; justify-content: space-between; border: 1px solid #e4e7ed; padding: 15px 20px; margin-bottom: 18px;"
>
<div>
<span style="color: #606266;">客户:</span>
<span style="color: #f56c6c; font-size: 18px; font-weight: bold;">{{
info.customer
}}</span>
</div>
<div>
<span style="color: #606266;">订单号:</span>
<span style="color: #f56c6c; font-size: 18px; font-weight: bold;">{{
info.orderNo
}}</span>
</div>
</div>
<!-- 操作单信息区块 -->
<div
class="op-info-box"
style="border: 1px solid #e4e7ed; padding: 18px 22px; margin-bottom: 26px;"
>
<h4 style="margin: 0 0 18px; font-size: 16px;">操作单信息</h4>
<div
style="display: grid; grid-template-columns: 1fr 1fr; row-gap: 14px;"
>
<div>
<span style="color: #909399;">操作单号:</span>{{ info.opNo }}
</div>
<div>
<span style="color: #909399;">生产工艺:</span>{{ info.tech }}
</div>
<div>
<span style="color: #909399;">基版:</span>{{ info.basePlate }}
</div>
<div>
<span style="color: #909399;">变体SKU:</span>{{ info.sku }}
</div>
<div><span style="color: #909399;">数量:</span>{{ info.num }}</div>
<div>
<span style="color: #909399;">尺寸:</span>{{ info.size }}
</div>
<div>
<span style="color: #909399;">店铺单号:</span>{{ info.shopNo }}
</div>
<div>
<span style="color: #909399;">创建时间:</span
>{{ info.createTime }}
</div>
</div>
</div>
<!-- 底部按钮 -->
<div style="text-align: right;">
<el-button type="primary" size="medium">下载素材</el-button>
<el-checkbox
v-model="scanDownloadCheck"
label="扫码下载素材"
style="margin-left: 10px;"
/>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: "OrderDetailDialog",
props: {
// 弹窗显示控制
show: {
type: Boolean,
default: false
},
// 图片地址
imgUrl: {
type: String,
default: ""
},
// 订单详情数据
info: {
type: Object,
default: () => ({
customer: "",
orderNo: "",
opNo: "",
tech: "",
basePlate: "",
sku: "",
num: "",
size: "",
shopNo: "",
createTime: ""
})
}
},
computed: {
visible: {
get() {
return this.show;
},
set(val) {
this.$emit("update:show", val);
}
}
},
data() {
return {
scanDownloadCheck: true
};
},
methods: {
handleClose() {
this.$emit("update:show", false);
}
}
};
</script>
......@@ -3,8 +3,10 @@ import {
downloadOtherImage,
toSend,
writeProfileXml,
copySingleImage
copySingleImage,
createBatchFolder
} from "@/server/utils";
const {
cropImageTransparentEdges,
cropTransparentEdges,
......@@ -653,13 +655,24 @@ export default {
res.json({ code: 500, msg: error });
}
},
getFileList: async (req, res) => {
createBatchFolder: async (req, res) => {
try {
const { downloadDir, isArray, basePath } = req.body;
const fn = isArray ? createBatchFolder : createBatchFolder;
const data = await fn(basePath, downloadDir);
res.send(data);
} catch (error) {
console.log("createBatchFolder", error);
res.json({ code: 500, msg: error });
}
},
downloadMaterial: async (req, res) => {
try {
const { downloadDir } = req.body;
const { downloadDir, isArray, basePath } = req.body;
res.send();
} catch (error) {
console.log("getFileList", error);
console.log("downloadMaterial", error);
res.json({ code: 500, msg: error });
}
}
......
......@@ -52,7 +52,10 @@ router.post("/getAllCountry", fn.getAllCountry);
//根据图片地址保存文件到本地
router.post("/saveImgByUrl", fn.saveImgByUrl);
//获取目标路径文件夹下所以文件
router.post("/getFileList", fn.getFileList);
router.post("/createBatchFolder", fn.createBatchFolder);
//获下载原素材
router.post("/downloadMaterial", fn.downloadMaterial);
//复制文件夹下文件
router.post("/copySingleImageFn", fn.copySingleImageFn);
......
......@@ -564,3 +564,79 @@ export async function copySingleImage(sourceImagePath, targetDir) {
throw err;
}
}
/**
* 创建批次目录:基础路径/批次号:xxx/三个素材子目录
* @param {string} basePath 父目录基础路径
* @param {string} batchNo 批次编号
*/
export function createBatchFolder(basePath, batchNo) {
try {
// 拼接外层批次文件夹名称
const batchDirName = `批次号:${batchNo}`;
const batchPath = path.join(basePath, batchDirName);
// 固定子文件夹列表
const subDirList = ["原素材", "自动排版素材", "手动排版素材"];
// 1. 判断批次目录是否已存在
if (fs.existsSync(batchPath)) {
return { data: batchPath, message: "success" };
}
// 2. 创建外层批次目录,recursive自动补全上级目录
fs.mkdirSync(batchPath, { recursive: true });
// 3. 批量创建内部三个子目录,存在自动跳过
subDirList.forEach(subName => {
const subPath = path.join(batchPath, subName);
fs.mkdirSync(subPath, { recursive: true });
});
// 目录为本次新建
return { data: batchPath, message: "success" };
} catch (error) {
return { message: error.message };
}
}
export async function createBatchList(basePath, batchNoList) {
const fs = require("fs").promises;
const path = require("path");
const subFolders = ["原素材", "自动排版素材", "手动排版素材"];
let successCount = 0;
let skipCount = 0;
for (const batchNo of batchNoList) {
const str = `批次号:${batchNo}`;
const batchPath = path.join(basePath, str);
try {
// 已存在就跳过
try {
await fs.access(batchPath);
skipCount++;
continue;
} catch {
// 不存在,继续创建
}
// 创建批次文件夹
await fs.mkdir(batchPath, { recursive: true });
// 创建三个子文件夹
await Promise.all(
subFolders.map(name =>
fs.mkdir(path.join(batchPath, name), { recursive: true })
)
);
successCount++;
} catch (e) {
console.error(`批次 ${batchNo} 创建失败:`, e);
}
}
console.error(`创建完成:成功 ${successCount} 个,跳过 ${skipCount} 个`);
return true;
}
const fs = require("fs");
const path = require("path");
const https = require("https");
function createDownloadQueue(options = {}) {
// 配置项
const config = Object.assign(
{
concurrency: 2,
retryTimes: 2,
basePath: "", // 根目录,外部传入
fileNameRule: task => `${task.batchArrangeNum}_素材.zip`, // 默认文件名规则:批次号_素材.zip
onSuccess: () => {},
onError: () => {},
onIdle: () => {}
},
options
);
// 内部状态
let pendingQueue = [];
let runningCount = 0;
const successSet = new Set();
const runningSet = new Set();
let isDestroyed = false;
// 工具方法
const hasFile = targetPath => fs.existsSync(targetPath);
const cleanFile = targetPath =>
hasFile(targetPath) && fs.unlinkSync(targetPath);
// 流式下载核心
const streamDownload = (url, targetPath) =>
new Promise((resolve, reject) => {
const ws = fs.createWriteStream(targetPath);
const req = https.get(url, res => {
// 处理重定向
if ([301, 302, 307, 308].includes(res.statusCode)) {
ws.close();
streamDownload(res.headers.location, targetPath)
.then(resolve)
.catch(reject);
return;
}
if (res.statusCode !== 200) {
ws.close();
cleanFile(targetPath);
reject(new Error(`状态码 ${res.statusCode}`));
return;
}
res.pipe(ws);
});
ws.on("finish", () => {
ws.close();
resolve();
});
ws.on("error", err => {
ws.close();
cleanFile(targetPath);
reject(err);
});
req.on("error", err => {
ws.close();
cleanFile(targetPath);
reject(err);
});
req.setTimeout(30000, () => {
req.destroy();
ws.close();
cleanFile(targetPath);
reject(new Error("下载超时"));
});
});
// 队列消费
const consume = () => {
if (isDestroyed) return;
if (runningCount >= config.concurrency || pendingQueue.length === 0) {
runningCount === 0 && config.onIdle();
return;
}
const task = pendingQueue.shift();
runningCount++;
(async () => {
try {
// 自动创建当前批次的目录(仅创建需要下载的批次目录,不批量预创建)
const targetDir = path.dirname(task.targetPath);
if (!hasFile(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
// 获取下载地址
const url =
typeof task.fetchUrl === "function"
? await task.fetchUrl(task)
: task.downloadUrl;
await streamDownload(url, task.targetPath);
successSet.add(task.targetPath);
config.onSuccess(task);
} catch (err) {
if (task.remainRetry > 0) {
task.remainRetry--;
pendingQueue.unshift(task);
} else {
config.onError(task, err);
}
} finally {
runningCount--;
runningSet.delete(task.targetPath);
consume();
}
})();
};
// 对外方法
return {
addTasks(tasks = []) {
if (isDestroyed) return;
const validTasks = tasks
.map(row => {
// 按规则拼接完整路径:根目录 / 批次号:xxx / 自动排版素材 / 文件名
const dir = path.join(
config.basePath,
`批次号:${row.batchArrangeNum}`,
"自动排版素材"
);
const fileName = config.fileNameRule(row);
const targetPath = path.join(dir, fileName);
return { ...row, targetPath, remainRetry: config.retryTimes };
})
// 三重过滤:本地已存在、已下载成功、正在队列中
.filter(
task =>
!hasFile(task.targetPath) &&
!successSet.has(task.targetPath) &&
!runningSet.has(task.targetPath)
);
if (validTasks.length === 0) return;
validTasks.forEach(t => {
runningSet.add(t.targetPath);
pendingQueue.push(t);
});
consume();
},
get isRunning() {
return runningCount > 0 || pendingQueue.length > 0;
},
destroy() {
isDestroyed = true;
pendingQueue = [];
runningCount = 0;
successSet.clear();
runningSet.clear();
}
};
}
module.exports = createDownloadQueue;
......@@ -26,7 +26,8 @@ export default {
});
const routerName = this.$router.currentRoute.name;
const routerMap = { DTG: "design-dtf", DTF: "design-dtf" };
const routerMap = { DTG: "design-dtg", DTF: "design-dtf" };
if (routerName !== routerMap[getProductType()]) {
if (getProductType() === "DTG") {
this.$router.push({ name: "design-dtg" });
......
<script>
import { mapState } from "vuex";
const { getDesktopDevice } = require("@/server/utils/store");
const { getDesktopDevice, getDTFSetting } = require("@/server/utils/store");
const { ipcRenderer } = require("electron");
export default {
props: {
user: {
......@@ -13,7 +15,11 @@ export default {
factoryType: { type: String, default: "CN" }
},
data() {
return {};
return {
dialogVisible: false,
dtfSetting: getDTFSetting(),
radio: ""
};
},
computed: {
...mapState([
......@@ -96,6 +102,48 @@ export default {
})
.then(() => {})
.catch(() => {});
},
changeTypesetting() {
this.dialogVisible = true;
},
submit() {
console.log(this.radio);
if (!this.radio) {
return this.$message.error("请选择排版宽度");
}
if (this.dtfSetting.overWidthMode === "biggerSize" && this.radio == 60) {
this.$confirm(
"由于排版设置中选择“按更大规格排版”仅适用于40+2,选60时,默认超60的规格不排版",
"提示",
{
confirmButtonText: "确定",
type: "warning"
}
).then(() => {
this.dialogVisible = false;
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
});
} else {
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
}
},
async goFliePage(value, type) {
console.log(value);
let { data } = await this.$api.post("/createBatchFolder", {
basePath: this.dtfSetting.downloadDir,
downloadDir: value.batchNo,
isArray: false
});
console.log("goFliePage", data);
if (type == "check") {
ipcRenderer.send("open-folder-only", data);
}
}
}
};
......@@ -110,7 +158,6 @@ export default {
icon="el-icon-arrow-left"
@click="goBack"
style="margin-right:12px;"
type="text"
>返回</el-button
></el-form-item
>
......@@ -133,12 +180,12 @@ export default {
</el-button></el-form-item
>
<el-form-item>
<el-button @click="goSetting" type="success"
<el-button @click="changeTypesetting" type="success"
>排版
</el-button></el-form-item
>
<el-form-item>
<el-button @click="() => {}" type="success"
<el-button @click="goFliePage" type="success"
>查看排版文件
</el-button></el-form-item
>
......@@ -170,6 +217,16 @@ export default {
</el-dropdown>
</div>
</div>
<el-dialog title="排版宽度" :visible.sync="dialogVisible" width="25%">
<el-radio-group v-model="radio">
<el-radio :label="40">40+2cm</el-radio>
<el-radio :label="60">60cm</el-radio>
</el-radio-group>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</el-dialog>
</div>
</template>
......
<script>
import BaseCard from "../../components/BaseCard.vue";
import BaseCard from "@/components/BaseCard.vue";
import DTFhead from "./components/detailHead.vue";
import DetailDialog from "@/components/detailDialog.vue";
const { remote } = require("electron");
const { Menu } = remote;
import dayjs from "dayjs";
export default {
name: "dtf-batch-detail",
components: { BaseCard, DTFhead },
components: { BaseCard, DTFhead, DetailDialog },
props: {
user: {
default: () => ({
......@@ -26,11 +26,27 @@ export default {
},
data() {
return {
logVisible: false,
detailVisible: false,
logList: [],
pageInfo: {
pageNum: 1,
pageSize: 10,
total: 2
},
cardList: Array.from({ length: 10 }, (_, index) => {
const isDtg = index % 2 === 0;
return {
id: index + 1,
batchNo: index + 1,
status: index % 3 === 0 ? 0 : 1,
img: isDtg ? "/static/dtg.jpg" : "/static/dtf.jpg",
subOrderNumber: index % 4 !== 0,
num: isDtg ? 120 + index * 2 : 86 + index,
failedReason: "",
active: false
};
}),
detailRow: {
name: { label: "批次号", value: 111 },
name1: { label: "操作单数量", value: 111 },
......@@ -40,11 +56,12 @@ export default {
name4: { label: "创建时间", value: 111 },
name5: { label: "排版状态", value: 111 },
name7: { label: "操作单状态", value: 111 }
},
item: {}
}
};
},
mounted() {},
mounted() {
console.log(this.cardList);
},
methods: {
loadData() {
// 请求列表接口
......@@ -78,17 +95,41 @@ export default {
openMenu(e) {
e.preventDefault();
const template = [
{ label: "全部选择", click: () => console.log("全部选择") },
{ label: "取消选择", click: () => console.log("取消选择") }
{
label: "全部选择",
click: () => {
this.cardList.forEach(el => {
el.active = true;
});
}
},
{
label: "取消选择",
click: () => {
this.cardList.forEach(el => {
el.active = false;
});
}
}
];
const menu = Menu.buildFromTemplate(template);
menu.popup({ x: e.clientX, y: e.clientY });
},
getItemTags(tagsId) {},
handleViewDetail(tagsId) {},
setProductMark(tagsId) {},
parseImageAry(tagsId) {},
openLogDialog(tagsId) {}
openLogDialog(tagsId) {},
changeActive(item) {
item.active = !item.active;
},
handleViewDetail(item) {
try {
this.detailVisible = true;
} catch (e) {
console.error(e);
}
}
}
};
</script>
......@@ -110,11 +151,16 @@ export default {
</div>
<div class="card-content">
<div class="card-grid">
<div class="card-grid-item" v-for="value in 20" :key="value">
<div
class="card-grid-item"
v-for="(item, index) in cardList"
:key="index"
@click.stop="changeActive(item)"
>
<BaseCard
style="cursor: pointer;"
:card-item="item"
:active="true"
:active="item.active"
:show-sku="false"
:show-product-info="false"
:image-field="'variantImage'"
......@@ -350,6 +396,20 @@ export default {
/>
</div>
</div>
<el-dialog
v-model="logVisible"
title="操作日志"
width="1000px"
:close-on-click-modal="false"
>
<LogList :log-list="logList" />
<div v-if="!logList.length" class="empty-content">暂无数据</div>
</el-dialog>
<DetailDialog
:show.sync="detailVisible"
:img-url="''"
:info="''"
></DetailDialog>
</div>
</template>
......
......@@ -118,6 +118,7 @@ export default {
>DTF排版设置
</el-button></el-form-item
>
<el-form-item>
<el-button @click="goSetting1" type="success"
>详情页
......
<script>
import BaseTable from "../../components/BaseTable.vue";
const { remote, ipcRenderer } = require("electron");
const { getDTFSetting } = require("@/server/utils/store");
const { Menu } = remote;
import DTFhead from "./components/head.vue";
export default {
......@@ -17,6 +20,10 @@ export default {
},
data() {
return {
dialogVisible: false,
selectionList: [],
radio: "",
dtfSetting: getDTFSetting(),
pageInfo: {
pageNum: 1,
pageSize: 10,
......@@ -26,72 +33,62 @@ export default {
const isDtg = index % 2 === 0;
return {
id: index + 1,
name: index + 1,
batchArrangeNum: index + 1,
status: index % 3 === 0 ? 0 : 1,
img: isDtg ? "/static/dtg.jpg" : "/static/dtf.jpg",
open: index % 4 !== 0,
price: isDtg ? 120 + index * 2 : 86 + index,
remark: ""
subOrderNumber: index % 4 !== 0,
num: isDtg ? 120 + index * 2 : 86 + index,
failedReason: ""
};
}),
tableConfig: [
{
prop: "name",
prop: "batchArrangeNum",
label: "批次号",
width: 100
width: 100,
slotName: "batchNo"
},
{
prop: "price",
prop: "operationNum",
label: "操作单数量",
width: 100,
// 自定义渲染函数
render: row => ${row.price}.00`
width: 100
},
{
prop: "status",
prop: "materialNum",
label: "素材数量",
width: 100,
type: "tag",
// 动态标签文字
getTagText: row => (row.status === 1 ? "启用" : "停用"),
// 动态标签颜色
getTagType: row => (row.status === 1 ? "success" : "danger")
width: 100
},
{
prop: "img",
prop: "craftType",
label: "工艺类型",
width: 100,
type: "image"
slotName: "craftType"
},
{
prop: "open",
prop: "standardDesignImage",
label: "规范素材",
width: 100,
type: "switch",
onSwitchChange: row => {
console.log("切换上架状态", row);
}
slotName: "standardDesignImage"
},
{
label: "创建时间",
slotName: "remark" // 绑定外部自定义插槽
prop: "createTime"
},
{
label: "排版状态",
width: 140,
slotName: "remark" // 绑定外部自定义插槽
prop: "status"
},
{
prop: "failReason",
label: "失败原因",
width: 300,
slotName: "remark" // 绑定外部自定义插槽
slotName: "failReason"
},
{
label: "排版参数",
width: 300,
slotName: "remark" // 绑定外部自定义插槽
prop: "layoutParameters",
width: 300
},
{
label: "操作",
......@@ -108,6 +105,7 @@ export default {
},
handleSelect(rows) {
console.log("选中行", rows);
this.selectionList = rows;
},
handleSizeChange(size) {
this.pageInfo.pageSize = size;
......@@ -118,19 +116,91 @@ export default {
this.pageInfo.pageNum = page;
this.loadData();
},
goFliePage() {
openMenu(e) {
e.preventDefault();
const template = [
{
label: "全部选择",
click: () => {
this.$refs.tableRefs?.toggleAllSelection(true);
}
},
{
label: "取消选择",
click: () => this.$refs.tableRefs?.toggleAllSelection(false)
}
];
const menu = Menu.buildFromTemplate(template);
menu.popup({ x: e.clientX, y: e.clientY });
},
async goFliePage(value, type) {
console.log(value);
let { data } = await this.$api.post("/createBatchFolder", {
basePath: this.dtfSetting.downloadDir,
downloadDir: value.batchNo,
isArray: false
});
console.log("goFliePage", data);
if (type == "check") {
ipcRenderer.send("open-folder-only", data);
}
},
changeTypesetting() {
if (this.dtfSetting.autoLayoutType == "none") {
this.dialogVisible = true;
} else {
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
}
},
submit() {
console.log(this.radio);
if (!this.radio) {
return this.$message.error("请选择排版宽度");
}
if (this.dtfSetting.overWidthMode === "biggerSize" && this.radio == 60) {
this.$confirm(
"由于排版设置中选择“按更大规格排版”仅适用于40+2,选60时,默认超60的规格不排版",
"提示",
{
confirmButtonText: "确定",
type: "warning"
}
).then(() => {
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
});
} else {
this.$message(
"排版进行中,请查看处理状态,排版完成的素材至文件夹排版素材查看"
);
}
},
toDetail(value) {
this.$router.push({
name: "dtf-file-download"
name: "dtf-batch-detail",
params: {
batchNo: value
}
});
},
downloadFile() {
this.$message("下载进行中,下载完成的素材将在文件夹原素材中显示");
}
}
};
</script>
<template>
<div class="page">
<div class="page" @contextmenu.prevent="openMenu">
<DTFhead :user="user" :factoryType="factoryType"></DTFhead>
<BaseTable
v-if="tableList.length"
ref="tableRefs"
:table-data="tableList"
:table-config="tableConfig"
:has-selection="true"
......@@ -145,27 +215,68 @@ export default {
size="mini"
>
<!-- 自定义插槽示例 -->
<template #remark="scope">
<el-input v-model="scope.row.remark" size="mini" />
<template #batchNo="scope">
<a href="javascript:;" @click="toDetail(scope.row.batchNo)">{{
scope.row.batchNo
}}</a>
</template>
<template #failReason="scope">
<div style="white-space: pre-line">
<span v-html="scope.row?.failReason"></span>
</div>
</template>
<template #operation>
<template #operation="scope">
<div class="flex" style="justify-content: space-between;">
<el-button type="text" class="btn flex btnBox">
<el-button
type="text"
class="btn flex btnBox"
@click="downloadFile(scope.row)"
>
<img src="../../assets/download.png" width="30" height="30" />
<div>下载素材</div></el-button
>
<el-button type="text" class="btn flex btnBox"
><img src="../../assets/typesetting.png" width="30" height="30" />
<el-button
type="text"
disabled
class="btn flex btnBox"
@click="changeTypesetting(scope.row)"
><img
src="../../assets/typesetting.png"
width="30"
height="30"
:class="{ disabled: false }"
/>
<div>排版</div>
</el-button>
<el-button type="text" class="btn flex btnBox" @click="goFliePage">
<el-button
type="text"
class="btn flex btnBox"
@click="goFliePage(scope.row, 'check')"
>
<img src="../../assets/file.png" width="30" height="30" />
<div>查看排版文件</div>
</el-button>
</div>
</template>
</BaseTable>
<!-- <BaseCard></BaseCard> -->
<el-empty
style="height: 100%; "
v-else
:image-size="500"
:image="require('@/assets/JOMALL.png')"
description="好像什么都没有"
></el-empty>
<el-dialog title="排版宽度" :visible.sync="dialogVisible" width="25%">
<el-radio-group v-model="radio">
<el-radio :label="40">40+2cm</el-radio>
<el-radio :label="60">60cm</el-radio>
</el-radio-group>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submit">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
......@@ -183,4 +294,21 @@ export default {
.btn {
padding: 0;
}
::v-deep .el-empty__image img {
filter: grayscale(100%);
opacity: 0.3;
}
::v-deep.el-empty__description p {
font-size: 50px;
}
.el-button {
div {
margin-top: 5px;
font-size: 12px;
}
}
::v-deep.disabled {
filter: grayscale(100%);
opacity: 0.3;
}
</style>
......@@ -3,7 +3,7 @@
<div class="dtf-setting-page">
<!-- 返回按钮 -->
<div class="page-top">
<el-button icon="el-icon-arrow-left" text @click="goBack">
<el-button icon="el-icon-arrow-left" @click="goBack">
返回
</el-button>
</div>
......@@ -121,7 +121,23 @@ export default {
},
// 保存配置到本地文件
saveConfig() {
this.$message.success("排版设置保存成功!");
if (
this.form.autoLayoutType == "60" &&
this.form.overWidthMode === "biggerSize"
) {
this.$confirm(
"由于排版设置中选择“按更大规格排版”仅适用于40+2,选60时,默认超60的规格不排版",
"提示",
{
confirmButtonText: "确定",
type: "warning"
}
).then(() => {
this.$message.success("排版设置保存成功!");
});
} else {
this.$message.success("排版设置保存成功!");
}
setDTFSetting({ ...this.form });
},
tabClick(tab) {
......
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