Commit 495695bd by zhuzhequan

转为工厂端

parent a7b73f94
{
"apiApiHost":"https://factory.jomalls.com/api",
"fileApiUrl":"https://factory.jomalls.com/upload/factory",
"visionUrl":"https://console.jomalls.com"
}
"use strict";
import { ipcMain } from "electron";
import { app, protocol, BrowserWindow, screen, globalShortcut } from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import { createServer } from "@/server/index.js";
import { autoUpdater } from "electron-updater";
Object.defineProperty(app, "isPackaged", {
get() {
return true;
}
});
createServer();
const isDevelopment = process.env.NODE_ENV !== "production";
let win;
let newWindow;
protocol.registerSchemesAsPrivileged([
{ scheme: "app", privileges: { secure: true, standard: true } }
]);
const winURL =
process.env.NODE_ENV === "development"
? "http://localhost:8050"
: `file://${__dirname}/index.html`;
async function createWindow() {
win = new BrowserWindow({
width: 1500,
height: 1000,
icon: "./src/assets/logo.jpg",
webPreferences: {
webSecurity: false,
nodeIntegration: true
}
});
let newWindow = new BrowserWindow({
fullscreen: false,
width: 1000,
height: 1000,
webPreferences: {
nodeIntegration: true
//配置预加载脚本文件(preload),此处起名为preloadOther
//p.s.路径为绝对路径
// preload: path.join(__dirname, "./preloadOther.js")
}
});
console.log(winURL + "#" + `/design-detail`);
//指定副屏幕打开的网页
await newWindow.loadURL(winURL + "#" + `/design-detail`);
win.on("closed", () => {
//这一段放外面的话,如果你电脑没双屏会报错。
win = null;
});
ipcMain.on("allPrint", () => {
// 获取到打印机列表
const printers = win.webContents.getPrinters();
// 把获取的打印机列表发送给渲染进程
win.webContents.send("printName", printers);
});
ipcMain.on("win-subScreen", (data, v) => {
if (newWindow) newWindow.webContents.send("getProductionNoInfo", v);
});
if (process.env.WEBPACK_DEV_SERVER_URL) {
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
if (!process.env.IS_TEST) win.webContents.openDevTools();
} else {
createProtocol("app");
await win.loadURL("app://./index.html");
}
ipcMain.on("send-card", (event, obj) => {
win.webContents.send("sendWebsockt", obj);
});
win.on("closed", () => {
win.removeAllListeners();
win = null;
newWindow = null;
});
// 自动更新逻辑开始
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = false; // 应用退出后自动安装
autoUpdater.on("download-progress", progress => {
// 下载进度监听
if (win.isDestroyed()) return;
win.webContents.send("update", {
speed: Math.ceil(progress.bytesPerSecond / 1000), // 网速
percent: Math.ceil(progress.percent) // 百分比
});
});
autoUpdater.on("error", err => {
// 下载失败监听
if (win.isDestroyed()) return;
win.webContents.send("update-error",err);
});
autoUpdater.on("update-downloaded", info => {
// 下载完成监听
if (win.isDestroyed()) return;
console.log(info, "info");
win.webContents.send("downloaded", info);
});
ipcMain.on("install", () => {
// 退出安装
autoUpdater.quitAndInstall();
});
ipcMain.on("toUpdateApp", (data, item) => {
// 去手动下载更新
if (win.isDestroyed()) return;
autoUpdater.setFeedURL({
provider: "generic",
url: item.url
});
autoUpdater.checkForUpdates().then(res=>{
console.log(res);
autoUpdater.downloadUpdate()
})
});
}
app.on("activate", async () => {
if (win === null) {
await createWindow();
}
});
app.on("ready", async () => {
await createWindow();
globalShortcut.register("F5", () => {
return false;
});
globalShortcut.register("CommandOrControl+R", () => {
return false;
});
});
app.on("will-quit", () => {
globalShortcut.unregister("F5");
globalShortcut.unregister("CommandOrControl+R");
});
if (isDevelopment) {
if (process.platform === "win32") {
process.on("message", data => {
if (data === "graceful-exit") {
app.quit();
}
});
} else {
process.on("SIGTERM", () => {
app.quit();
});
}
}
"use strict";
import { ipcMain } from "electron";
import { app, protocol, BrowserWindow, screen, globalShortcut } from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import { createServer } from "@/server/index.js";
import { autoUpdater } from "electron-updater";
Object.defineProperty(app, "isPackaged", {
get() {
return true;
}
});
createServer();
const isDevelopment = process.env.NODE_ENV !== "production";
let win;
let newWindow;
protocol.registerSchemesAsPrivileged([
{ scheme: "app", privileges: { secure: true, standard: true } }
]);
const winURL =
process.env.NODE_ENV === "development"
? "http://localhost:8050"
: `file://${__dirname}/index.html`;
async function createWindow() {
win = new BrowserWindow({
width: 1500,
height: 1000,
icon: "./src/assets/logo.jpg",
webPreferences: {
webSecurity: false,
nodeIntegration: true
}
});
let newWindow = new BrowserWindow({
fullscreen: false,
width: 1000,
height: 1000,
webPreferences: {
nodeIntegration: true
//配置预加载脚本文件(preload),此处起名为preloadOther
//p.s.路径为绝对路径
// preload: path.join(__dirname, "./preloadOther.js")
}
});
console.log(winURL + "#" + `/design-detail`);
//指定副屏幕打开的网页
await newWindow.loadURL(winURL + "#" + `/design-detail`);
win.on("closed", () => {
//这一段放外面的话,如果你电脑没双屏会报错。
win = null;
});
ipcMain.on("allPrint", () => {
// 获取到打印机列表
const printers = win.webContents.getPrinters();
// 把获取的打印机列表发送给渲染进程
win.webContents.send("printName", printers);
});
ipcMain.on("win-subScreen", (data, v) => {
if (newWindow) newWindow.webContents.send("getProductionNoInfo", v);
});
if (process.env.WEBPACK_DEV_SERVER_URL) {
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
if (!process.env.IS_TEST) win.webContents.openDevTools();
} else {
createProtocol("app");
await win.loadURL("app://./index.html");
}
ipcMain.on("send-card", (event, obj) => {
win.webContents.send("sendWebsockt", obj);
});
win.on("closed", () => {
win && win.removeAllListeners();
win = null;
newWindow && newWindow.close()
newWindow = null;
});
// 自动更新逻辑开始
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = false; // 应用退出后自动安装
autoUpdater.on("download-progress", progress => {
// 下载进度监听
if (win.isDestroyed()) return;
win.webContents.send("update", {
speed: Math.ceil(progress.bytesPerSecond / 1000), // 网速
percent: Math.ceil(progress.percent) // 百分比
});
});
autoUpdater.on("error", err => {
// 下载失败监听
if (win.isDestroyed()) return;
win.webContents.send("update-error",err);
});
autoUpdater.on("update-downloaded", info => {
// 下载完成监听
if (win.isDestroyed()) return;
console.log(info, "info");
win.webContents.send("downloaded", info);
});
ipcMain.on("install", () => {
// 退出安装
autoUpdater.quitAndInstall();
});
ipcMain.on("toUpdateApp", (data, item) => {
// 去手动下载更新
if (win.isDestroyed()) return;
autoUpdater.setFeedURL({
provider: "generic",
url: item.url
});
autoUpdater.checkForUpdates().then(res=>{
console.log(res);
autoUpdater.downloadUpdate()
})
});
}
app.on("activate", async () => {
if (win === null) {
await createWindow();
}
});
app.on("ready", async () => {
await createWindow();
globalShortcut.register("F5", () => {
return false;
});
globalShortcut.register("CommandOrControl+R", () => {
return false;
});
});
app.on("will-quit", () => {
globalShortcut.unregister("F5");
globalShortcut.unregister("CommandOrControl+R");
});
if (isDevelopment) {
if (process.platform === "win32") {
process.on("message", data => {
if (data === "graceful-exit") {
app.quit();
}
});
} else {
process.on("SIGTERM", () => {
app.quit();
});
}
}
import { downloadImage, toSend, writeProfileXml } from "@/server/utils";
import axios from "axios";
import { returnLogFilePath } from "../utils/log";
var request = require("request");
const compressing = require("compressing");
const uuid = require("uuid");
const path = require("path");
const fs = require("fs");
const os = require("os");
import axios from "axios";
import { returnLogFilePath } from "../utils/log";
const { app } = require("electron");
let fileEnv, env, visionUrl;
axios.defaults.timeout = 12600000;
const multiparty = require("multiparty");
function readEnv() {
let exePath,configPath
if(process.env.NODE_ENV === "development") {
configPath = path.join(__dirname, "../config/env.json");
}else{
exePath = path.dirname(app.getPath("exe")).replace(/\\/g, "/");
configPath = `${exePath}/config/env.json`;
}
console.log(configPath,__dirname);
fs.readFile(configPath, "utf-8", (err, data) => {
if (err) {
console.error("读取配置文件失败:", err);
return;
}
const config = JSON.parse(data);
fileEnv = config.fileApiUrl;
env = config.apiApiHost;
visionUrl = config.visionUrl;
});
}
readEnv()
export default {
writePrintLog: async (req, res) => {
try {
......@@ -33,32 +56,24 @@ export default {
res.json({ code: 500, msg: e });
}
},
getPodProductionInfo: async (req, res) => {
downloadBySubOrderNumber: async (req, res) => {
const token = req.headers["jwt-token"];
const company = req.headers["company"];
const productionNo = req.body.productionNo;
try {
let { data } = await axios.post(
`https://${company}/api/podDesignCenter/getPodImageByProduction`,
{ productionNo },
{ headers: { "jwt-token": token } }
let {
data
} = await axios.get(
`${env}/factory/podJomallOrder/downloadBySubOrderNumber`,
{ params: req.body, headers: { "jwt-token": token } }
);
console.log(data);
if (data.code === 200 && data.data && data.data.length > 0) {
let f = data.data.find(el => !el.productionFile);
if (f) {
return res.json({ code: 500, msg: "存在地址错误的素材图" });
}
data.data.forEach(el => {
if (!el.productionFile.includes("http")) {
el.productionFile = el.productionFile.replace(
"/data/upload/erp/",
""
);
el.productionFile = `https://${company}/upload/erp${el.productionFile}`;
}
let files = [];
if (data.code === 200 && data.message) {
files = [data.message];
files = files.map(el => {
return { url: `${fileEnv}${el}` };
});
downloadImage(data.data)
console.log(files);
downloadImage(files)
.then(data => {
res.json({ code: 200, data });
})
......@@ -75,11 +90,10 @@ export default {
},
findByPodProductionNo: async (req, res) => {
const token = req.headers["jwt-token"];
const company = req.headers["company"];
const q = req.body;
try {
let { data } = await axios.get(
`https://${company}/api/pod/podProductionInfo/findByPodProductionNo`,
`${env}/factory/podJomallOrderProduct/getSubOrderBySubOrderNumber`,
{
params: q,
headers: { "jwt-token": token }
......@@ -101,34 +115,20 @@ export default {
res.json({ code: 500, msg: err });
}
},
commitApply: async (req, res) => {
const company = req.headers["company"];
const q = req.body;
try {
let { data } = await axios.post(
`https://${company}/api/sysDeviceInfo/commitApply`,
q
);
res.send(data);
} catch (err) {
console.log(err);
res.json({ code: 500, msg: err });
}
},
commitApply: async (req, res) => {},
completeDelivery: async (req, res) => {
const token = req.headers["jwt-token"];
const company = req.headers["company"];
const q = req.body;
try {
let { data } = await axios.post(
`https://${company}/api/pod/podProductionInfo/completeDelivery`,
q,
{
headers: { "jwt-token": token }
}
let {
data
} = await axios.post(
`${env}/factory/podJomallOrderProduct/completeDelivery`,
req.body,
{ headers: { "jwt-token": token } }
);
res.json(data);
res.send(data);
} catch (err) {
console.log(err);
res.json({ code: 500, msg: err });
}
},
......@@ -232,14 +232,9 @@ export default {
}
},
login: async (req, res) => {
const { loginName, company, password, deviceId } = req.body;
try {
let { data } = await axios.post(`https://${company}/api/sysLogin/login`, {
loginName,
password,
deviceId
});
console.log(`${env}/factory/login`);
let { data } = await axios.post(`${env}/factory/login`, req.body);
res.send(data);
} catch (err) {
console.log(err);
......@@ -282,8 +277,7 @@ export default {
let from = path.join(process.cwd(), "./resources/app/css.zip");
let dirName = path.join(process.cwd(), "./resources/app/");
let stream = fs.createWriteStream(from);
const company = req.headers["company"];
req.body.url = "https://" + company + req.body.url;
req.body.url = visionUrl + req.body.url;
console.log(req.body.url, "下载zip地址");
request(req.body.url)
.pipe(stream)
......
import express from "express";
import fn from "../entity/function.js";
let router = express.Router();
// 执行打印命令
router.post("/toPrint", fn.toPrint);
// 打印日志添加
router.post("/writePrintLog", fn.writePrintLog);
// 登录接口
router.post("/login", fn.login);
// 获取本地文件返回
router.post("/getPngImg", fn.getPngImg);
// 上传文件到本地
router.post("/uploadImage", fn.uploadImage);
// 获取公司列表
router.get("/getCompanyList", fn.getCompanyList);
// 提交授权申请
router.post("/commitApply", fn.commitApply);
// 下载素材到本地
router.post("/downloadByDesignId", fn.downloadByDesignId);
// 获取 生产单号返回素材地址
router.post("/getPodProductionInfo", fn.getPodProductionInfo);
// 提交生产完成
router.post("/completeDelivery", fn.completeDelivery);
// 根据生产单号查询详情
router.post("/findByPodProductionNo", fn.findByPodProductionNo);
// 查询版本更新
router.get("/checkUpdate", fn.checkUpdate);
// 增量更新
router.post("/incrementalUpdates", fn.incrementalUpdates);
export { router as default };
import express from "express";
import fn from "../entity/function.js";
let router = express.Router();
// 执行打印命令
router.post("/toPrint", fn.toPrint);
// 打印日志添加
router.post("/writePrintLog", fn.writePrintLog);
// 登录接口
router.post("/login", fn.login);
// 获取本地文件返回
router.post("/getPngImg", fn.getPngImg);
// 上传文件到本地
router.post("/uploadImage", fn.uploadImage);
// 获取公司列表
router.get("/getCompanyList", fn.getCompanyList);
// 提交授权申请
router.post("/commitApply", fn.commitApply);
// 下载素材到本地
router.post("/downloadByDesignId", fn.downloadByDesignId);
// 获取 生产单号返回素材地址
router.post("/downloadBySubOrderNumber", fn.downloadBySubOrderNumber);
// 提交生产完成
router.post("/completeDelivery", fn.completeDelivery);
// 根据生产单号查询详情
router.post("/findByPodProductionNo", fn.findByPodProductionNo);
// 查询版本更新
router.get("/checkUpdate", fn.checkUpdate);
// 增量更新
router.post("/incrementalUpdates", fn.incrementalUpdates);
export { router as default };
import { exec } from "child_process";
var fs = require("fs");
var path = require("path");
var request = require("request");
var uuid = require("uuid");
const compressing = require("compressing");
function zip(from, to) {
return new Promise((resolve, reject) => {
let dirName = path.join(to, uuid.v4());
console.log(dirName);
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
}
let arr = [];
compressing.zip
.uncompress(from, dirName, { zipFileNameEncoding: "gbk" })
.then(() => {
console.log("success");
let data = fs.readdirSync(dirName);
for (let i = 0; i < data.length; i++) {
let fileName = uuid.v4() + ".png";
let el = data[i];
let file_path = path.join(dirName, el);
console.log(file_path, to);
fs.renameSync(file_path, path.join(to, fileName));
arr.push({
fileName: fileName,
productionFile: path.join(to, fileName)
});
}
fs.unlinkSync(from); // 删除压缩包
fs.rmdirSync(dirName); // 删除目录文件
// console.log(arr);
resolve(arr);
})
.catch(err => {
console.log(err);
reject("压缩包解压失败");
});
});
}
// 下载素材
export const downloadImage = list => {
return new Promise((resolve, reject) => {
try {
let dirPath = path.join(process.cwd(), "./print/Input/");
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
let count = 0;
for (let i = 0; i < list.length; i++) {
if (list[i].productionFile && list[i].productionFile.includes("http")) {
let fileName = "";
let type = 2;
let flag =
[
".zip",
".gzip",
".tar",
".taz",
".rar",
".7z",
".gz",
".bz2"
].filter(el => list[i].productionFile.toLowerCase().includes(el))
.length > 0;
if (flag) {
fileName = list[i].productionFile.split("/")[
list[i].productionFile.split("/").length - 1
];
type = 1;
} else {
fileName = uuid.v4() + ".png";
type = 2;
}
list[i].fileName = fileName;
list[i].type = type;
let p = path.join(process.cwd(), "./print/Input/" + fileName);
let stream = fs.createWriteStream(p);
request(list[i].productionFile)
.pipe(stream)
.on("close", async function() {
if (type === 1) {
let res_data = await zip(p, dirPath);
res_data.forEach(item => {
item.designId = list[i].designId;
});
list[i].list = res_data;
if (count === list.length - 1) {
resolve(list);
}
}
if (count === list.length - 1) {
console.log(list);
resolve(list);
}
count++;
});
}
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
// 传递素材给前端
export const sendImg = (filename = "sample.png") => {
let filePath = path.join(process.cwd(), "./print/Input/" + filename);
if (!fs.existsSync(filePath)) {
return false;
}
let data = fs.readFileSync(filePath);
data = Buffer.from(data).toString("base64");
return "data:" + "png" + ";base64," + data;
};
export const toSend = body => {
return new Promise((resolve, reject) => {
exec(
body.cmd,
{ cwd: path.join(process.cwd(), "print"), shell: true },
(err, stdout, stderr) => {
console.log(stdout, 1);
console.log(stderr, 2);
console.log(err, 4);
if (!err) {
exec(
body.print_cmd,
{ cwd: path.join(process.cwd(), "print"), shell: true },
err2 => {
console.log(err2);
if (!err2) {
// 成功后删除 素材图,xml,output文件
// fs.unlinkSync(path.join(process.cwd(), 'print/Input/' + body.fileName))
fs.unlinkSync(
path.join(
process.cwd(),
"print/Profile/" +
body.fileName.replace(".png", "") +
".xml"
)
);
fs.unlinkSync(
path.join(
process.cwd(),
"print/Output/" +
body.fileName.replace(".png", "") +
".arxp"
)
);
resolve("操作成功");
} else {
reject("打印机参数错误");
}
}
);
} else {
reject("生成arxp文件失败");
}
}
);
});
};
export const writeProfileXml = b => {
try {
let p = path.join(process.cwd(), `./print/Profile/${b.byInk}.xml`);
let file = fs.readFileSync(p, { encoding: "utf8" });
file = file.replace(
/<uiCopies>(.*)<\/uiCopies>/i,
`<uiCopies>${b.printNum}</uiCopies>`
);
file = file.replace(
/<byPlatenSize>(.*)<\/byPlatenSize>/i,
`<byPlatenSize>${b.byPlatenSize}</byPlatenSize>`
);
file = file.replace(
/<bEcoMode>(.*)<\/bEcoMode>/i,
`<bEcoMode>${b.bEcoMode}</bEcoMode>`
);
file = file.replace(
/<bMaterialBlack>(.*)<\/bMaterialBlack>/i,
`<bMaterialBlack>${b.bMaterialBlack}</bMaterialBlack>`
);
file = file.replace(
/<byHighlight>(.*)<\/byHighlight>/i,
`<byHighlight>${b.byHighlight}</byHighlight>`
);
file = file.replace(
/<byMask>(.*)<\/byMask>/i,
`<byMask>${b.byMask}</byMask>`
);
file = file.replace(
/<bTransColor>(.*)<\/bTransColor>/i,
`<bTransColor>${b.bTransColor}</bTransColor>`
);
file = file.replace(
/<bPause>(.*)<\/bPause>/i,
`<bPause>${b.bPause}</bPause>`
);
file = file.replace(
/<bDivide>(.*)<\/bDivide>/i,
`<bDivide>${b.bDivide}</bDivide>`
);
file = file.replace(
/<byChoke>(.*)<\/byChoke>/i,
`<byChoke>${b.byChoke}</byChoke>`
);
file = file.replace(/<byInk>(.*)<\/byInk>/i, `<byInk>${b.byInk}</byInk>`);
file = file.replace(
/<bFastMode>(.*)<\/bFastMode>/i,
`<bFastMode>${b.bFastMode}</bFastMode>`
);
file = file.replace(
/<byResolution>(.*)<\/byResolution>/i,
`<byResolution>${1}</byResolution>`
);
file = file.replace(
/<byInkVolume>(.*)<\/byInkVolume>/i,
`<byInkVolume>${b.byInkVolume}</byInkVolume>`
);
file = file.replace(
/<byDoublePrint>(.*)<\/byDoublePrint>/i,
`<byDoublePrint>${b.byDoublePrint}</byDoublePrint>`
);
file = file.replace(
/<bMultiple>(.*)<\/bMultiple>/i,
`<bMultiple>${b.bMultiple}</bMultiple>`
);
file = file.replace(
/<bySaturation>(.*)<\/bySaturation>/i,
`<bySaturation>${b.bySaturation}</bySaturation>`
);
file = file.replace(
/<byBrightness>(.*)<\/byBrightness>/i,
`<byBrightness>${b.byBrightness}</byBrightness>`
);
file = file.replace(
/<byContrast>(.*)<\/byContrast>/i,
`<byContrast>${b.byContrast}</byContrast>`
);
file = file.replace(
/<iCyanBalance>(.*)<\/iCyanBalance>/i,
`<iCyanBalance>${b.iCyanBalance}</iCyanBalance>`
);
file = file.replace(
/<iMagentaBalance>(.*)<\/iMagentaBalance>/i,
`<iMagentaBalance>${b.iMagentaBalance}</iMagentaBalance>`
);
file = file.replace(
/<iYellowBalance>(.*)<\/iYellowBalance>/i,
`<iYellowBalance>${b.iYellowBalance}</iYellowBalance>`
);
file = file.replace(
/<iBlackBalance>(.*)<\/iBlackBalance>/i,
`<iBlackBalance>${b.iBlackBalance}</iBlackBalance>`
);
file = file.replace(
/<bUniPrint>(.*)<\/bUniPrint>/i,
`<bUniPrint>${b.bUniPrint}</bUniPrint>`
);
fs.writeFileSync(
path.join(
process.cwd(),
`./print/Profile/${b.fileName.replace(".png", "")}.xml`
),
file
);
} catch (err) {
console.log(err);
}
};
import { exec } from "child_process";
var fs = require("fs");
var path = require("path");
var request = require("request");
var uuid = require("uuid");
const compressing = require("compressing");
function zip(from, to) {
return new Promise((resolve, reject) => {
let dirName = path.join(to, uuid.v4());
console.log(dirName);
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
}
let arr = [];
compressing.zip
.uncompress(from, dirName, { zipFileNameEncoding: "gbk" })
.then(() => {
console.log("success");
let data = fs.readdirSync(dirName);
for (let i = 0; i < data.length; i++) {
let fileName = uuid.v4() + ".png";
let el = data[i];
let file_path = path.join(dirName, el);
console.log(file_path, to);
fs.renameSync(file_path, path.join(to, fileName));
arr.push({
fileName: fileName,
designId: data[i].split(".")[0],
productionFile: path.join(to, fileName)
});
}
fs.unlinkSync(from); // 删除压缩包
fs.rmdirSync(dirName); // 删除目录文件
// console.log(arr);
resolve(arr);
})
.catch(err => {
console.log(err);
reject("压缩包解压失败");
});
});
}
// 下载素材
export const downloadImage = list => {
return new Promise((resolve, reject) => {
try {
let dirPath = path.join(process.cwd(), "./print/Input/");
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
let count = 0;
for (let i = 0; i < list.length; i++) {
if (list[i].url && list[i].url.includes("http")) {
let fileName = "";
let type = 2;
let flag =
[
".zip",
".gzip",
".tar",
".taz",
".rar",
".7z",
".gz",
".bz2"
].filter(el => list[i].url.toLowerCase().includes(el))
.length > 0;
if (flag) {
fileName = list[i].url.split("/")[
list[i].url.split("/").length - 1
];
type = 1;
} else {
fileName = uuid.v4() + ".png";
type = 2;
}
let p = path.join(process.cwd(), "./print/Input/" + fileName);
let stream = fs.createWriteStream(p);
request(list[i].url)
.pipe(stream)
.on("close", async function() {
if (type === 1) {
list[i].list = await zip(p, dirPath);
if (count === list.length - 1) {
resolve(list);
}
}
if (count === list.length - 1) {
console.log(list);
resolve(list);
}
count++;
});
}
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
// 传递素材给前端
export const sendImg = (filename = "sample.png") => {
let filePath = path.join(process.cwd(), "./print/Input/" + filename);
if (!fs.existsSync(filePath)) {
return false;
}
let data = fs.readFileSync(filePath);
data = Buffer.from(data).toString("base64");
return "data:" + "png" + ";base64," + data;
};
export const toSend = body => {
return new Promise((resolve, reject) => {
exec(
body.cmd,
{ cwd: path.join(process.cwd(), "print"), shell: true },
(err, stdout, stderr) => {
console.log(stdout, 1);
console.log(stderr, 2);
console.log(err, 4);
if (!err) {
exec(
body.print_cmd,
{ cwd: path.join(process.cwd(), "print"), shell: true },
err2 => {
console.log(err2);
if (!err2) {
// 成功后删除 素材图,xml,output文件
// fs.unlinkSync(path.join(process.cwd(), 'print/Input/' + body.fileName))
fs.unlinkSync(
path.join(
process.cwd(),
"print/Profile/" +
body.fileName.replace(".png", "") +
".xml"
)
);
fs.unlinkSync(
path.join(
process.cwd(),
"print/Output/" +
body.fileName.replace(".png", "") +
".arxp"
)
);
resolve("操作成功");
} else {
reject("打印机参数错误");
}
}
);
} else {
reject("生成arxp文件失败");
}
}
);
});
};
export const writeProfileXml = b => {
try {
let p = path.join(process.cwd(), `./print/Profile/${b.byInk}.xml`);
let file = fs.readFileSync(p, { encoding: "utf8" });
file = file.replace(
/<uiCopies>(.*)<\/uiCopies>/i,
`<uiCopies>${b.printNum}</uiCopies>`
);
file = file.replace(
/<byPlatenSize>(.*)<\/byPlatenSize>/i,
`<byPlatenSize>${b.byPlatenSize}</byPlatenSize>`
);
file = file.replace(
/<bEcoMode>(.*)<\/bEcoMode>/i,
`<bEcoMode>${b.bEcoMode}</bEcoMode>`
);
file = file.replace(
/<bMaterialBlack>(.*)<\/bMaterialBlack>/i,
`<bMaterialBlack>${b.bMaterialBlack}</bMaterialBlack>`
);
file = file.replace(
/<byHighlight>(.*)<\/byHighlight>/i,
`<byHighlight>${b.byHighlight}</byHighlight>`
);
file = file.replace(
/<byMask>(.*)<\/byMask>/i,
`<byMask>${b.byMask}</byMask>`
);
file = file.replace(
/<bTransColor>(.*)<\/bTransColor>/i,
`<bTransColor>${b.bTransColor}</bTransColor>`
);
file = file.replace(
/<bPause>(.*)<\/bPause>/i,
`<bPause>${b.bPause}</bPause>`
);
file = file.replace(
/<bDivide>(.*)<\/bDivide>/i,
`<bDivide>${b.bDivide}</bDivide>`
);
file = file.replace(
/<byChoke>(.*)<\/byChoke>/i,
`<byChoke>${b.byChoke}</byChoke>`
);
file = file.replace(/<byInk>(.*)<\/byInk>/i, `<byInk>${b.byInk}</byInk>`);
file = file.replace(
/<bFastMode>(.*)<\/bFastMode>/i,
`<bFastMode>${b.bFastMode}</bFastMode>`
);
file = file.replace(
/<byResolution>(.*)<\/byResolution>/i,
`<byResolution>${1}</byResolution>`
);
file = file.replace(
/<byInkVolume>(.*)<\/byInkVolume>/i,
`<byInkVolume>${b.byInkVolume}</byInkVolume>`
);
file = file.replace(
/<byDoublePrint>(.*)<\/byDoublePrint>/i,
`<byDoublePrint>${b.byDoublePrint}</byDoublePrint>`
);
file = file.replace(
/<bMultiple>(.*)<\/bMultiple>/i,
`<bMultiple>${b.bMultiple}</bMultiple>`
);
file = file.replace(
/<bySaturation>(.*)<\/bySaturation>/i,
`<bySaturation>${b.bySaturation}</bySaturation>`
);
file = file.replace(
/<byBrightness>(.*)<\/byBrightness>/i,
`<byBrightness>${b.byBrightness}</byBrightness>`
);
file = file.replace(
/<byContrast>(.*)<\/byContrast>/i,
`<byContrast>${b.byContrast}</byContrast>`
);
file = file.replace(
/<iCyanBalance>(.*)<\/iCyanBalance>/i,
`<iCyanBalance>${b.iCyanBalance}</iCyanBalance>`
);
file = file.replace(
/<iMagentaBalance>(.*)<\/iMagentaBalance>/i,
`<iMagentaBalance>${b.iMagentaBalance}</iMagentaBalance>`
);
file = file.replace(
/<iYellowBalance>(.*)<\/iYellowBalance>/i,
`<iYellowBalance>${b.iYellowBalance}</iYellowBalance>`
);
file = file.replace(
/<iBlackBalance>(.*)<\/iBlackBalance>/i,
`<iBlackBalance>${b.iBlackBalance}</iBlackBalance>`
);
file = file.replace(
/<bUniPrint>(.*)<\/bUniPrint>/i,
`<bUniPrint>${b.bUniPrint}</bUniPrint>`
);
fs.writeFileSync(
path.join(
process.cwd(),
`./print/Profile/${b.fileName.replace(".png", "")}.xml`
),
file
);
} catch (err) {
console.log(err);
}
};
const log4js = require("log4js");
const moment = require("moment");
const fs = require("fs");
const path = require("path");
export function returnLogFilePath() {
const today = moment(new Date()).format("YYYY-MM-DD");
const low_path = process.cwd();
let log_dir = path.join(low_path, "logs")
if (!fs.existsSync(log_dir)) {
fs.mkdirSync(log_dir) // 创建日志文件夹
}
const dir = path.join(low_path, `/logs/${today}`);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
return path.join(dir, "api.log");
}
//日志对象
const logger = (name) => {
const logFilePath = returnLogFilePath();
log4js.configure({
appenders: {
out: { type: "console" }, //在控制台输出日志
cheese: {
type: "file",
filename: logFilePath,
maxLogSize: 1024 * 1000 * 10 //10M
}
},
categories: {
//需要在控制台输出日志时:appenders: ['cheese', 'out']
default: { appenders: ["cheese"], level: log4js.levels.DEBUG }
}
});
return log4js.getLogger(name);
};
//添加日志
const addFormatLog = function(req, res, data) {
const now = new Date();
const resTime = now - req._startTime;
const token = req.headers["jwt-token"];
const company = req.headers["company"];
const {
ip,
headers,
method,
url,
body,
httpVersion,
res: { statusCode, _headers }
} = req;
let logInfo = {
ip,
host: headers.host,
resTime,
method,
url,
token,
company,
body,
httpVersion,
statusCode,
contentLength: _headers["content-length"],
userAgent: headers["user-agent"],
data: data[0]
};
// ${JSON.stringify(logInfo)}
logger("log").info(`
时间:${moment(new Date()).format("YYYY-MM-DD HH:mm:ss")}
ip : ${logInfo.ip}
host : ${logInfo.host}
响应时间 : ${logInfo.resTime / 1000} s
method :${logInfo.method}
url :${logInfo.url}
客户 :${logInfo.company || ""}
token :${logInfo.token || ""}
body :${JSON.stringify(logInfo.body)}
状态码 :${logInfo.statusCode}
data :${JSON.stringify(logInfo.data)}
`
);
};
//日志中间件
export const logMiddleWare = () => {
return function(req, res, next) {
req._startTime = new Date();
const oldSend = res.send;
res.send = function() {
oldSend.apply(res, arguments);
if (typeof [...arguments][0] === "object") {
res.once("finish", () => addFormatLog(req, res, arguments));
}
};
return next();
};
};
const log4js = require("log4js");
const moment = require("moment");
const fs = require("fs");
const path = require("path");
export function returnLogFilePath() {
const today = moment(new Date()).format("YYYY-MM-DD");
const low_path = process.cwd();
let log_dir = path.join(low_path, "logs")
if (!fs.existsSync(log_dir)) {
fs.mkdirSync(log_dir) // 创建日志文件夹
}
const dir = path.join(low_path, `/logs/${today}`);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
return path.join(dir, "api.log");
}
//日志对象
const logger = (name) => {
const logFilePath = returnLogFilePath();
log4js.configure({
appenders: {
out: { type: "console" }, //在控制台输出日志
cheese: {
type: "file",
filename: logFilePath,
maxLogSize: 1024 * 1000 * 10 //10M
}
},
categories: {
//需要在控制台输出日志时:appenders: ['cheese', 'out']
default: { appenders: ["cheese"], level: log4js.levels.DEBUG }
}
});
return log4js.getLogger(name);
};
//添加日志
const addFormatLog = function(req, res, data) {
const now = new Date();
const resTime = now - req._startTime;
const token = req.headers["jwt-token"];
const {
ip,
headers,
method,
url,
body,
httpVersion,
res: { statusCode, _headers }
} = req;
let logInfo = {
ip,
host: headers.host,
resTime,
method,
url,
token,
body,
httpVersion,
statusCode,
contentLength: _headers["content-length"],
userAgent: headers["user-agent"],
data: data[0]
};
// ${JSON.stringify(logInfo)}
logger("log").info(`
时间:${moment(new Date()).format("YYYY-MM-DD HH:mm:ss")}
ip : ${logInfo.ip}
host : ${logInfo.host}
响应时间 : ${logInfo.resTime / 1000} s
method :${logInfo.method}
url :${logInfo.url}
token :${logInfo.token || ""}
body :${JSON.stringify(logInfo.body)}
状态码 :${logInfo.statusCode}
data :${JSON.stringify(logInfo.data)}
`
);
};
//日志中间件
export const logMiddleWare = () => {
return function(req, res, next) {
req._startTime = new Date();
const oldSend = res.send;
res.send = function() {
oldSend.apply(res, arguments);
if (typeof [...arguments][0] === "object") {
res.once("finish", () => addFormatLog(req, res, arguments));
}
};
return next();
};
};
import axios from "axios";
import Vue from "vue";
import { Loading } from "element-ui";
// create an axios instance
const service = axios.create({
baseURL: "http://localhost:3000", // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 50000000 // request timeout
});
let loading;
function startLoading() {
loading = Loading.service({
lock: true,
text: "拼命加载中...",
spinner: "el-icon-loading",
background: "rgba(0,0,0,.7)"
});
}
function endLoading() {
loading.close();
}
// Add a request interceptor
service.interceptors.request.use(
config => {
console.log(Vue.prototype.$dataStore);
const user = Vue.prototype.$dataStore.get("user");
const company = Vue.prototype.$dataStore.get("company");
if (user) {
config.headers["jwt-token"] = user.token;
config.headers["company"] = company.domain;
}
startLoading();
return config;
},
error => {
endLoading();
// do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
async response => {
// do something with response data
const res = response.data;
endLoading();
if (res.code) {
if (res.code !== 200) {
if (res.code === 411) {
return Promise.resolve(res);
}
if (res.code === 403) {
Vue.prototype.$dataStore.delete("user");
Vue.prototype.$message.error({
showClose: true,
message: res.msg || res.message || "Error"
});
setTimeout(() => {
location.reload();
}, 500);
return Promise.reject(new Error(res.msg || res.message || "Error"));
}
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// TODO: to re-login
}
Vue.prototype.$message.error({
showClose: true,
message: res.msg || res.message || "Error"
});
// reject
return Promise.reject(new Error(res.msg || res.message || "Error"));
} else {
return Promise.resolve(res);
}
}
return Promise.resolve(res);
},
error => {
endLoading();
// do something with response error
return Promise.reject(error);
}
);
export default service;
import axios from "axios";
import Vue from "vue";
import { Loading } from "element-ui";
// create an axios instance
const service = axios.create({
baseURL: "http://localhost:3000", // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 50000000 // request timeout
});
let loading;
function startLoading() {
loading = Loading.service({
lock: true,
text: "拼命加载中...",
spinner: "el-icon-loading",
background: "rgba(0,0,0,.7)"
});
}
function endLoading() {
loading.close();
}
// Add a request interceptor
service.interceptors.request.use(
config => {
console.log(Vue.prototype.$dataStore);
const user = Vue.prototype.$dataStore.get("user");
if (user) {
config.headers["jwt-token"] = user.token;
}
startLoading();
return config;
},
error => {
endLoading();
// do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
async response => {
// do something with response data
const res = response.data;
endLoading();
if (res.code) {
if (res.code !== 200) {
if (res.code === 411) {
return Promise.resolve(res);
}
if (res.code === 403) {
Vue.prototype.$dataStore.delete("user");
Vue.prototype.$message.error({
showClose: true,
message: res.msg || res.message || "Error"
});
setTimeout(() => {
location.reload();
}, 500);
return Promise.reject(new Error(res.msg || res.message || "Error"));
}
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// TODO: to re-login
}
Vue.prototype.$message.error({
showClose: true,
message: res.msg || res.message || "Error"
});
// reject
return Promise.reject(new Error(res.msg || res.message || "Error"));
} else {
return Promise.resolve(res);
}
}
return Promise.resolve(res);
},
error => {
endLoading();
// do something with response error
return Promise.reject(error);
}
);
export default service;
<script>
import {ipcRenderer} from "electron";
export default {
mounted() {
let that = this;
ipcRenderer.on('getProductionNoInfo', (event, data) => {
console.log(data, 99622)
that.trackcodeInput(data)
})
},
watch: {
},
data() {
return {
shipForm: {shipmentType: '1'},
logistics: [],
placeholderText: '',
sendNum: 0,
type: 1,
isDownloadImage: false,
isAutoSure: false,
currentStatus: 'IN_PRODUCTION',
detail: {
imgList: []
},
dialogVisible: false,
audios: {
weight_warning: require(`../../../assets/audio/weight_warning.mp3`),
weight_success: require(`../../../assets/audio/weight_success.mp3`),
weight_repeat: require(`../../../assets/audio/weight_repeat.mp3`),
weight_search_error: require(`../../../assets/audio/weight_search_error.mp3`),
weight_search_success: require(`../../../assets/audio/weight_search_success.mp3`)
},
productInfo: {},
TrackingNumber: ''
}
},
methods: {
changeStatus() {
if (!this.detail || Object.keys(this.detail).length <= 1) {
return this.$message.warning('请扫码生产单号')
}
this.$confirm(
`确定${this.type === 1 ? '生产完成' : '确定发货'}?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
this.setData()
})
},
async setData() {
if (this.detail && this.detail.id) {
let url =
this.currentStatus == 'IN_PRODUCTION'
? 'pod/podProductionInfo/completeDelivery'
: 'pod/podProductionInfo/completeShipment'
try {
let data =
this.currentStatus == 'IN_PRODUCTION'
? {
id: this.detail.id
}
: {
list: [this.detail],
...this.shipForm
}
if (data.list) {
data.list[0].note =
data.list[0].note && typeof data.list[0].note === 'object'
? JSON.stringify(data.list[0].note)
: null
}
await post(url, data)
if (this.type === 2) {
this.sendNum = this.sendNum + 1
}
this.playAudio('weight_success')
this.detail = {imgList: []}
} catch (e) {
console.error(e)
this.detail = {imgList: []}
this.playAudio('weight_search_error')
}
}
},
downloadAllWe(data, designId) {
if (!this.detail || Object.keys(this.detail).length <= 1) {
return this.$message.warning('请扫码生产单号')
}
let params = {
productionNo: this.detail.podProductionNo,
method: 'POST'
}
if (data === 1) {
params = {
...params,
...{
designId
}
}
} else if (data === 2) {
params = {
...params,
...{
negativeDesignId: designId
}
}
}
downloadFile('podDesignCenter/downloadByDesignId', params)
.then((res) => {
const {data, fileName} = res
let url = window.URL.createObjectURL(data)
// 生成一个a标签
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
// 生成时间戳
link.download = fileName
link.click()
window.URL.revokeObjectURL(url)
})
.catch((err) => {
console.log(err)
})
},
playAudio(key, message) {
let text = ''
switch (key) {
case 'weight_search_success':
text = ''
break
case 'weight_search_error':
text = '请录入生产单号'
break
case 'weight_success':
text = ''
break
case 'weight_repeat':
text = '称重复录入'
break
default:
text = '请录入跟踪号或重量'
break
}
if (message || text) this.$message.warning(message || text)
let audio = document.createElement('audio')
console.log(key)
audio.src = this.audios[key]
audio.play()
},
async trackcodeInput(data) {
// if (this.type === 1) {
// if (this.isAutoSure) {
// await this.setData()
// }
// } else {
// await this.setData()
// }
try {
let d = JSON.parse(JSON.stringify(data))
if (d.note) {
d.note = JSON.parse(d.note)
} else {
d.note = []
}
let arr = []
if (!d.imageAry) {
arr = [
{url: d.variantImage, title: '正面', id: d.designId},
{url: d.negativeImage, title: '反面', id: d.negativeDesignId}
].filter((el) => el.url)
} else {
arr =
typeof d.imageAry == 'string' ? JSON.parse(d.imageAry) : d.imageAry
arr = arr.concat([
{url: d.negativeImage, title: '反面', id: d.negativeDesignId}
])
}
const result = []
console.log(arr)
arr = arr.filter((el) => el.url)
arr = arr.map((el) => {
return {
...el,
...{
url: el.url.includes('http')
? el.url
: window.location.origin + '/upload/erp' + el.url
}
}
})
for (let i = 0; i < arr.length; i += 2) {
result.push(arr.slice(i, i + 2))
}
d.imgList = result
console.log(d.imgList, 'this.detail.imgList ')
this.detail = d
// 自动下载素材
// if (this.isDownloadImage) {
// this.downloadAllWe()
// }
this.playAudio('weight_search_success')
// this.$nextTick(() => {
// if (this.$refs.trackingNumberRef) {
// this.$refs.trackingNumberRef.focus()
// }
// })
} catch (e) {
console.error(e)
this.productInfo = {}
this.playAudio('weight_search_error')
this.$nextTick(() => {
if (this.$refs.trackingNumberRef) {
this.$refs.trackingNumberRef.focus()
}
})
}
}
}
}
</script>
<template>
<div class="page">
<div class="sure-btn" v-if="type=== 2">
<el-button @click="changeStatus" size="small" type="success">
{{ type === 1 ? '生产完成' : '确定发货' }}
</el-button>
</div>
<div class="detail-div">
<div class="detail-content">
<div class="left">
<div class="left-images">
<el-carousel
v-if="detail.imgList.length > 0"
style="height: 100%"
:autoplay="false"
indicator-position="none">
<el-carousel-item
style="height: 100%"
:key="index"
v-for="(item, index) in detail.imgList">
<el-row :gutter="10" style="width: 100%; height: 100%">
<el-col
style="height: 100%"
v-for="(it, i) in item"
:key="i"
:span="12">
<div class="left-image">
<b v-show="it.title && it.url">
{{ it.title }}
<span
style="
text-decoration: underline;
cursor: pointer;
color: blue;
"
@click="
downloadAllWe(
it.title && it.title === '正面' ? 1 : 2,
it.id
)
"
v-if="it.id">
(DID:{{ it.id }}
</span>
</b>
<img :src="it.url" alt=""/>
</div>
</el-col>
</el-row>
</el-carousel-item>
</el-carousel>
</div>
</div>
<div class="right">
<!-- <div-->
<!-- class="input"-->
<!-- v-if="!detailData || Object.keys(detailData).length === 0">-->
<!--&lt;!&ndash; <el-input&ndash;&gt;-->
<!--&lt;!&ndash; v-model="TrackingNumber"&ndash;&gt;-->
<!--&lt;!&ndash; :placeholder="placeholderText"&ndash;&gt;-->
<!--&lt;!&ndash; style="width: 660px; margin-right: 10px"&ndash;&gt;-->
<!--&lt;!&ndash; clearable&ndash;&gt;-->
<!--&lt;!&ndash; ref="trackingNumberRef"&ndash;&gt;-->
<!--&lt;!&ndash; size="medium"&ndash;&gt;-->
<!--&lt;!&ndash; @keyup.enter.native="trackcodeInput()"></el-input>&ndash;&gt;-->
<!-- <el-button type="primary" size="medium" @click="trackcodeInput()">-->
<!-- 查询-->
<!-- </el-button>-->
<!-- </div>-->
<div class="div-text">
<b>生产单信息</b>
<div class="div-content">
<div :title="detail.podProductionNo" class="div-item">
<span>生产单号</span>
<p>{{ detail.podProductionNo }}</p>
<p
style="margin-left: 5px"
v-if="detail.podProductionNo"
:style="{
color: detail.customizedQuantity > 1 ? 'red' : '#67C23A'
}">
{{ detail.customizedQuantity > 1 ? '多' : '单' }}
</p>
</div>
<div :title="detail.podProcessName" class="div-item">
<span>生产工艺</span>
<p>{{ detail.podProcessName }}</p>
</div>
<div :title="detail.baseSku" class="div-item">
<span>基版</span>
<p>{{ detail.baseSku }}</p>
</div>
<div :title="detail.supplierItemNo" class="div-item">
<span>货号</span>
<p>{{ detail.supplierItemNo }}</p>
</div>
<div :title="detail.variantSku" class="div-item">
<span>变体SKU</span>
<p>{{ detail.variantSku }}</p>
</div>
<div :title="detail.categoryName" class="div-item">
<span>类别</span>
<p>{{ detail.categoryName }}</p>
</div>
<div :title="detail.color" class="div-item">
<span>颜色</span>
<p>{{ detail.color }}</p>
</div>
<div :title="detail.size" class="div-item">
<span>尺寸</span>
<p>{{ detail.size }}</p>
</div>
<div :title="detail.material" class="div-item">
<span>材质</span>
<p>{{ detail.material }}</p>
</div>
<div :title="detail.batchNo" class="div-item">
<span>批次号</span>
<p>{{ detail.batchNo }}</p>
</div>
<div
:title="detail.supplyMerchantCode"
v-if="currentStatus !== 'TO_BE_ASSIGN'"
class="div-item">
<span>供应商编号</span>
<p>{{ detail.supplyMerchantCode }}</p>
</div>
<div :title="detail.shopNumber" class="div-item">
<span>店铺单号</span>
<p>{{ detail.shopNumber }}</p>
</div>
<div :title="detail.shopShortName" class="div-item">
<span>店铺简称</span>
<p>{{ detail.shopShortName }}</p>
</div>
<div :title="detail.expectDeliveryTime" class="div-item">
<span>期望交货时间</span>
<p>{{ detail.expectDeliveryTime }}</p>
</div>
<div :title="detail.purchaseUserName" class="div-item">
<span>采购员</span>
<p>{{ detail.purchaseUserName }}</p>
</div>
<div :title="detail.productionConfirmTime" class="div-item">
<span>生产确认时间</span>
<p>{{ detail.productionConfirmTime }}</p>
</div>
<div :title="detail.followerName" class="div-item">
<span>跟单员</span>
<p>{{ detail.followerName }}</p>
</div>
<div :title="detail.actualDeliveryTime" class="div-item">
<span>实际交货时间</span>
<p>{{ detail.actualDeliveryTime }}</p>
</div>
<div :title="detail.storedName" class="div-item">
<span>入库人</span>
<p>{{ detail.storedName }}</p>
</div>
<div :title="detail.storedTime" class="div-item">
<span>入库时间</span>
<p>{{ detail.storedTime }}</p>
</div>
<div :title="detail.replenishmentNumber" class="div-item">
<span>补胚数量</span>
<p>{{ detail.replenishmentNumber }}</p>
</div>
<div
:title="detail.shipmentType == 1 ? '送货上门' : '快递'"
class="div-item">
<span>发货方式</span>
<p v-if="detail.shipmentType">
{{ detail.shipmentType == 1 ? '送货上门' : '快递' }}
</p>
</div>
</div>
</div>
<div
class="form"
style="margin: 15px 0; background: #4168ff; border-radius: 5px"
v-if="type === 2">
<el-form
:model="shipForm"
ref="form"
label-width="80px"
:inline="false"
size="small">
<el-form-item style="margin-top: 10px" label="发货方式">
<el-select
style="width: 384px"
v-model="shipForm.shipmentType"
value-key=""
placeholder="请选择">
<el-option label="送货上门" value="1"></el-option>
<el-option label="快递" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="物流方式"
v-if="shipForm.shipmentType == '2'">
<el-select
v-model="shipForm.shipmentWay"
style="width: 384px"
placeholder="请选择">
<el-option
v-for="(item, index) in logistics"
:key="index"
:label="item.name"
:value="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="物流单号"
v-if="shipForm.shipmentType == '2'">
<el-input
style="width: 384px"
v-model="shipForm.shipmentNumber"
placeholder="请输入"></el-input>
</el-form-item>
<el-form-item
label="物流费用"
v-if="shipForm.shipmentType == '2'">
<el-input
style="width: 384px"
v-model="shipForm.shipmentFreight"
placeholder="请输入"></el-input>
</el-form-item>
</el-form>
</div>
<!-- <div-->
<!-- class="btn"-->
<!-- v-if="type !== 2">-->
<!-- <div class="btn-sure">-->
<!-- <el-button style="width: 100%; height: 100%; font-size: 18px" size="large" @click="changeStatus"-->
<!-- type="success">-->
<!-- {{ type === 1 ? '生产完成' : '确定发货' }}-->
<!-- </el-button>-->
<!-- &lt;!&ndash; <div class="check">&ndash;&gt;-->
<!-- &lt;!&ndash; <el-checkbox v-if="type===1" v-model="isAutoSure">自动完成上一单</el-checkbox>&ndash;&gt;-->
<!-- &lt;!&ndash; </div>&ndash;&gt;-->
<!-- </div>-->
<!-- &lt;!&ndash; <div class="btn-down">&ndash;&gt;-->
<!-- &lt;!&ndash; <div class="check">&ndash;&gt;-->
<!-- &lt;!&ndash; <el-checkbox size="large" v-model="isDownloadImage">扫码下载素材</el-checkbox>&ndash;&gt;-->
<!-- &lt;!&ndash; </div>&ndash;&gt;-->
<!-- &lt;!&ndash; <el-button&ndash;&gt;-->
<!-- &lt;!&ndash; size="medium"&ndash;&gt;-->
<!-- &lt;!&ndash; @click="downloadAllWe"&ndash;&gt;-->
<!-- &lt;!&ndash; style="width: 100%; height: 100%; font-size: 18px"&ndash;&gt;-->
<!-- &lt;!&ndash; type="primary">&ndash;&gt;-->
<!-- &lt;!&ndash; 下载素材&ndash;&gt;-->
<!-- &lt;!&ndash; </el-button>&ndash;&gt;-->
<!-- &lt;!&ndash; </div>&ndash;&gt;-->
<!-- </div>-->
<div
v-if="type !== 2"
class="div-text"
style="
flex: 1;
margin-top: 30px;
flex-shrink: 0;
display: flex;
flex-direction: column;
">
<div style="height: 100%" class="div-content" v-if="detail.note">
<b style="position: absolute; top: -12px">客户留言信息</b>
<div
v-for="(item, index) in detail.note"
:key="index"
class="div-item">
<span>{{ item.prop }}:</span>
<p>
{{ item.value }}
</p>
</div>
</div>
</div>
<div
v-if="type === 2"
class="div-text"
style="
flex: 1;
flex-shrink: 0;
display: flex;
flex-direction: column;
">
<div style="height: 100%" class="div-content">
<b style="position: absolute; top: -12px">本次发货数量</b>
<div
class="div-item"
style="
display: flex;
align-items: center;
width: 100%;
height: 100%;
font-size: 40px;
justify-content: center;
">
<h2 style="color: red; font-weight: bold">{{ sendNum }}</h2>
</div>
</div>
</div>
</div>
</div>
<div
class="detail-images"
v-if="detail && Object.keys(detail).length > 1">
<div class="scroll-list">
<div class="img-title">
<b>商品信息</b>
<div class="id">
<img src="@/assets/id.png" alt=""/>
<span>{{ detail.variantSku.split('_')[0] }}</span>
</div>
</div>
<div class="scroll-content">
<div
class="scroll-item"
v-for="(it, i) in detail.colorImageList"
:key="i">
<el-image
style="width: 100%; height: 100%"
:src="it"
:preview-src-list="[it]"></el-image>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
::v-deep {
.el-dialog__body {
box-sizing: border-box;
flex: 1;
flex-shrink: 0;
overflow: hidden;
}
.el-dialog {
display: flex;
height: calc(100% - 50px);
margin-top: 50px;
flex-direction: column;
}
.el-carousel__container {
height: 100%;
}
.el-form-item__label {
font-weight: bold;
color: white;
}
.el-dialog__title {
font-weight: bold;
font-size: 37px;
color: black;
position: relative;
left: 47%;
top: 13px;
}
}
.sure-btn {
position: absolute;
right: 62px;
top: 14px;
}
.detail-div {
display: flex;
height: 100%;
flex-direction: column;
justify-content: space-between;
.detail-images {
.scroll-list {
background: #ececec;
display: flex;
height: 100px;
width: 100%;
padding: 5px;
.scroll-content {
margin-left: 10px;
overflow-x: auto;
overflow-y: hidden;
flex: 1;
display: flex;
flex-wrap: nowrap;
flex-shrink: 0;
.scroll-item {
height: 100%;
min-width: 100px;
background: white;
width: 80px;
margin-right: 5px;
}
}
.img-title {
display: flex;
flex-direction: column;
justify-content: center;
background: white;
padding: 10px;
b {
text-align: center;
color: black;
font-weight: bold;
font-size: 16px;
margin-bottom: 15px;
}
.id {
display: flex;
align-items: center;
padding: 3px 5px;
background: #ececec;
justify-content: center;
img {
width: 15px;
margin-right: 8px;
}
}
}
}
}
.detail-content {
display: flex;
width: 100%;
flex: 1;
margin-bottom: 10px;
flex-shrink: 0;
justify-content: space-between;
}
.right {
width: 710px;
height: 100%;
display: flex;
flex-direction: column;
.btn {
margin: 20px 0;
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
width: 100%;
}
.div-text {
.div-content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start;
padding: 15px 10px;
box-sizing: border-box;
position: relative;
border: 1px solid #ececec;
.div-item {
width: 50%;
margin-bottom: 10px;
font-size: 15px;
display: flex;
align-items: center;
p {
font-weight: 400;
color: black;
}
span {
display: inline-block;
text-align: right;
width: 100px;
&::after {
content: ':';
margin: 0 3px;
}
}
}
}
b {
position: relative;
background: white;
top: 9px;
left: 13px;
padding: 0 10px;
font-size: 18px;
color: black;
z-index: 3;
}
}
.input {
display: flex;
align-items: center;
margin: 30px 0;
}
}
.left {
flex: 1;
flex-shrink: 0;
margin-right: 20px;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.left-image {
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
img {
height: auto;
width: 100%;
max-height: 90%;
}
b {
color: black;
font-size: 18px;
margin-bottom: 15px;
}
}
.left-images {
display: flex;
width: 95%;
height: 100%;
flex-direction: column;
b {
color: black;
text-align: center;
margin-bottom: 15px;
}
}
}
}
.detail-div .right .btn .btn-sure, .detail-div .right .btn .btn-down {
width: 100%;
position: relative;
}
.detail-div .right .btn .btn-sure .check, .detail-div .right .btn .btn-down .check {
position: absolute;
width: 144px;
height: 100%;
background: transparent;
display: flex;
align-items: center;
justify-content: center;
right: 0;
top: 1px;
}
.btn {
position: relative;
.check {
::v-deep {
.el-checkbox__inner {
background-color: transparent !important;
border-color: white !important;
width: 12px;
height: 12px;
&::after {
left: 3px;
}
}
.el-checkbox__label {
padding-left: 5px;
font-size: 12px;
color: white !important;
}
}
}
}
.page {
width: 100%;
height: 100%;
}
p {
margin: 0;
}
</style>
<script>
import { ipcRenderer } from "electron";
export default {
mounted() {
let that = this;
ipcRenderer.on("getProductionNoInfo", (event, data) => {
console.log(data, 99622);
that.trackcodeInput(data);
});
},
watch: {},
data() {
return {
shipForm: { shipmentType: "1" },
logistics: [],
placeholderText: "",
sendNum: 0,
type: 1,
isDownloadImage: false,
isAutoSure: false,
currentStatus: "IN_PRODUCTION",
detail: {
imgList: []
},
dialogVisible: false,
audios: {
weight_warning: require(`../../../assets/audio/weight_warning.mp3`),
weight_success: require(`../../../assets/audio/weight_success.mp3`),
weight_repeat: require(`../../../assets/audio/weight_repeat.mp3`),
weight_search_error: require(`../../../assets/audio/weight_search_error.mp3`),
weight_search_success: require(`../../../assets/audio/weight_search_success.mp3`)
},
productInfo: {},
TrackingNumber: ""
};
},
methods: {
changeStatus() {
if (!this.detail || Object.keys(this.detail).length <= 1) {
return this.$message.warning("请扫码生产单号");
}
this.$confirm(
`确定${this.type === 1 ? "生产完成" : "确定发货"}?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(() => {
this.setData();
});
},
async setData() {
if (this.detail && this.detail.id) {
let url =
this.currentStatus == "IN_PRODUCTION"
? "pod/podProductionInfo/completeDelivery"
: "pod/podProductionInfo/completeShipment";
try {
let data =
this.currentStatus == "IN_PRODUCTION"
? {
id: this.detail.id
}
: {
list: [this.detail],
...this.shipForm
};
if (data.list) {
data.list[0].note =
data.list[0].note && typeof data.list[0].note === "object"
? JSON.stringify(data.list[0].note)
: null;
}
await post(url, data);
if (this.type === 2) {
this.sendNum = this.sendNum + 1;
}
this.playAudio("weight_success");
this.detail = { imgList: [] };
} catch (e) {
console.error(e);
this.detail = { imgList: [] };
this.playAudio("weight_search_error");
}
}
},
downloadAllWe(data, designId) {
if (!this.detail || Object.keys(this.detail).length <= 1) {
return this.$message.warning("请扫码生产单号");
}
let params = {
productionNo: this.detail.podProductionNo,
method: "POST"
};
if (data === 1) {
params = {
...params,
...{
designId
}
};
} else if (data === 2) {
params = {
...params,
...{
negativeDesignId: designId
}
};
}
downloadFile("podDesignCenter/downloadByDesignId", params)
.then(res => {
const { data, fileName } = res;
let url = window.URL.createObjectURL(data);
// 生成一个a标签
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// 生成时间戳
link.download = fileName;
link.click();
window.URL.revokeObjectURL(url);
})
.catch(err => {
console.log(err);
});
},
playAudio(key, message) {
let text = "";
switch (key) {
case "weight_search_success":
text = "";
break;
case "weight_search_error":
text = "请录入生产单号";
break;
case "weight_success":
text = "";
break;
case "weight_repeat":
text = "称重复录入";
break;
default:
text = "请录入跟踪号或重量";
break;
}
if (message || text) this.$message.warning(message || text);
let audio = document.createElement("audio");
console.log(key);
audio.src = this.audios[key];
audio.play();
},
async trackcodeInput(data) {
// if (this.type === 1) {
// if (this.isAutoSure) {
// await this.setData()
// }
// } else {
// await this.setData()
// }
try {
let d = JSON.parse(JSON.stringify(data));
if (d.note) {
d.note = JSON.parse(d.note);
} else {
d.note = [];
}
let arr = [];
if (!d.imageAry) {
arr = [
{ url: d.variantImage, title: "正面", id: d.designId },
{ url: d.negativeImage, title: "反面", id: d.negativeDesignId }
].filter(el => el.url);
} else {
arr =
typeof d.imageAry == "string" ? JSON.parse(d.imageAry) : d.imageAry;
arr = arr.concat([
{ url: d.negativeImage, title: "反面", id: d.negativeDesignId }
]);
}
const result = [];
console.log(arr);
arr = arr.filter(el => el.url);
arr = arr.map(el => {
return {
...el,
...{
url: el.url.includes("http")
? el.url
: window.location.origin + "/upload/erp" + el.url
}
};
});
for (let i = 0; i < arr.length; i += 2) {
result.push(arr.slice(i, i + 2));
}
d.imgList = result;
console.log(d.imgList, "this.detail.imgList ");
this.detail = d;
// 自动下载素材
// if (this.isDownloadImage) {
// this.downloadAllWe()
// }
this.playAudio("weight_search_success");
// this.$nextTick(() => {
// if (this.$refs.trackingNumberRef) {
// this.$refs.trackingNumberRef.focus()
// }
// })
} catch (e) {
console.error(e);
this.productInfo = {};
this.playAudio("weight_search_error");
this.$nextTick(() => {
if (this.$refs.trackingNumberRef) {
this.$refs.trackingNumberRef.focus();
}
});
}
}
}
};
</script>
<template>
<div class="page">
<div class="sure-btn" v-if="type === 2">
<el-button @click="changeStatus" size="small" type="success">
{{ type === 1 ? "生产完成" : "确定发货" }}
</el-button>
</div>
<div class="detail-div">
<div class="detail-content">
<div class="left">
<div class="left-images">
<el-carousel
v-if="detail.imgList.length > 0"
style="height: 100%"
:autoplay="false"
indicator-position="none"
>
<el-carousel-item
style="height: 100%"
:key="index"
v-for="(item, index) in detail.imgList"
>
<el-row :gutter="10" style="width: 100%; height: 100%">
<el-col
style="height: 100%"
v-for="(it, i) in item"
:key="i"
:span="12"
>
<div class="left-image">
<b v-show="it.title && it.url">
{{ it.title }}
<span
style="
text-decoration: underline;
cursor: pointer;
color: blue;
"
@click="
downloadAllWe(
it.title && it.title === '正面' ? 1 : 2,
it.id
)
"
v-if="it.id"
>
(DID:{{ it.id }}
</span>
</b>
<img :src="it.url" alt="" />
</div>
</el-col>
</el-row>
</el-carousel-item>
</el-carousel>
</div>
</div>
<div class="right">
<!-- <div-->
<!-- class="input"-->
<!-- v-if="!detailData || Object.keys(detailData).length === 0">-->
<!--&lt;!&ndash; <el-input&ndash;&gt;-->
<!--&lt;!&ndash; v-model="TrackingNumber"&ndash;&gt;-->
<!--&lt;!&ndash; :placeholder="placeholderText"&ndash;&gt;-->
<!--&lt;!&ndash; style="width: 660px; margin-right: 10px"&ndash;&gt;-->
<!--&lt;!&ndash; clearable&ndash;&gt;-->
<!--&lt;!&ndash; ref="trackingNumberRef"&ndash;&gt;-->
<!--&lt;!&ndash; size="medium"&ndash;&gt;-->
<!--&lt;!&ndash; @keyup.enter.native="trackcodeInput()"></el-input>&ndash;&gt;-->
<!-- <el-button type="primary" size="medium" @click="trackcodeInput()">-->
<!-- 查询-->
<!-- </el-button>-->
<!-- </div>-->
<div class="div-text">
<div class="div-content">
<div :title="String(detail?.userMark)" class="div-item">
<span style="font-size: 18px">客户</span>
<p style="color: red; font-size: 30px">
{{ detail?.userMark }}
</p>
</div>
<div
:title="String(detail?.factoryOrderNumber)"
class="div-item"
>
<span style="font-size: 18px">订单号</span>
<p style="color: red; font-size: 22px">
{{ detail?.factoryOrderNumber }}
</p>
</div>
</div>
</div>
<div class="div-text">
<b>生产单信息</b>
<div class="div-content">
<div :title="detail.podProductionNo" class="div-item">
<span>生产单号</span>
<p>{{ detail.factorySubOrderNumber }}</p>
<p
style="margin-left: 5px"
v-if="detail.podProductionNo"
:style="{
color: detail.customizedQuantity > 1 ? 'red' : '#67C23A'
}"
>
{{ detail.customizedQuantity > 1 ? "多" : "单" }}
</p>
</div>
<div :title="detail.process" class="div-item">
<span>生产工艺</span>
<p>{{ detail.process }}</p>
</div>
<div :title="detail.baseSku" class="div-item">
<span>基版</span>
<p>{{ detail.baseSku }}</p>
</div>
<div :title="detail.supplierItemNo" class="div-item">
<span>货号</span>
<p>{{ detail.supplierItemNo }}</p>
</div>
<div :title="detail.variantSku" class="div-item">
<span>变体SKU</span>
<p>{{ detail.variantSku }}</p>
</div>
<div :title="detail.num" class="div-item">
<span>数量</span>
<p>{{ detail.num }}</p>
</div>
<div :title="detail.color" class="div-item">
<span>颜色</span>
<p>{{ detail.baseSku?detail.baseSku.split("_")[1]:null }}</p>
</div>
<div :title="detail.size" class="div-item">
<span>尺寸</span>
<p>{{ detail.size }}</p>
</div>
<div :title="detail.shopNumber" class="div-item">
<span>店铺单号</span>
<p>{{ detail.shopNumber }}</p>
</div>
<div :title="detail.expectDeliveryTime" class="div-item">
<span>期望交货时间</span>
<p>{{ detail.expectDeliveryTime }}</p>
</div>
<div :title="detail.productionConfirmTime" class="div-item">
<span>生产确认时间</span>
<p>{{ detail.startStockingTime }}</p>
</div>
</div>
</div>
<div
class="form"
style="margin: 15px 0; background: #4168ff; border-radius: 5px"
v-if="type === 2"
>
<el-form
:model="shipForm"
ref="form"
label-width="80px"
:inline="false"
size="small"
>
<el-form-item style="margin-top: 10px" label="发货方式">
<el-select
style="width: 384px"
v-model="shipForm.shipmentType"
value-key=""
placeholder="请选择"
>
<el-option label="送货上门" value="1"></el-option>
<el-option label="快递" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="物流方式"
v-if="shipForm.shipmentType == '2'"
>
<el-select
v-model="shipForm.shipmentWay"
style="width: 384px"
placeholder="请选择"
>
<el-option
v-for="(item, index) in logistics"
:key="index"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label="物流单号"
v-if="shipForm.shipmentType == '2'"
>
<el-input
style="width: 384px"
v-model="shipForm.shipmentNumber"
placeholder="请输入"
></el-input>
</el-form-item>
<el-form-item
label="物流费用"
v-if="shipForm.shipmentType == '2'"
>
<el-input
style="width: 384px"
v-model="shipForm.shipmentFreight"
placeholder="请输入"
></el-input>
</el-form-item>
</el-form>
</div>
<div
v-if="type !== 2"
class="div-text"
style="
flex: 1;
margin-top: 30px;
flex-shrink: 0;
display: flex;
flex-direction: column;
"
>
<div style="height: 100%" class="div-content" v-if="detail.note">
<b style="position: absolute; top: -12px">客户留言信息</b>
<div
v-for="(item, index) in detail.note"
:key="index"
class="div-item"
>
<span>{{ item.prop }}:</span>
<p>
{{ item.value }}
</p>
</div>
</div>
</div>
<div
v-if="type === 2"
class="div-text"
style="
flex: 1;
flex-shrink: 0;
display: flex;
flex-direction: column;
"
>
<div style="height: 100%" class="div-content">
<b style="position: absolute; top: -12px">本次发货数量</b>
<div
class="div-item"
style="
display: flex;
align-items: center;
width: 100%;
height: 100%;
font-size: 40px;
justify-content: center;
"
>
<h2 style="color: red; font-weight: bold">{{ sendNum }}</h2>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
::v-deep {
.el-dialog__body {
box-sizing: border-box;
flex: 1;
flex-shrink: 0;
overflow: hidden;
}
.el-dialog {
display: flex;
height: calc(100% - 50px);
margin-top: 50px;
flex-direction: column;
}
.el-carousel__container {
height: 100%;
}
.el-form-item__label {
font-weight: bold;
color: white;
}
.el-dialog__title {
font-weight: bold;
font-size: 37px;
color: black;
position: relative;
left: 47%;
top: 13px;
}
}
.sure-btn {
position: absolute;
right: 62px;
top: 14px;
}
.detail-div {
display: flex;
height: 100%;
flex-direction: column;
justify-content: space-between;
.detail-images {
.scroll-list {
background: #ececec;
display: flex;
height: 100px;
width: 100%;
padding: 5px;
.scroll-content {
margin-left: 10px;
overflow-x: auto;
overflow-y: hidden;
flex: 1;
display: flex;
flex-wrap: nowrap;
flex-shrink: 0;
.scroll-item {
height: 100%;
min-width: 100px;
background: white;
width: 80px;
margin-right: 5px;
}
}
.img-title {
display: flex;
flex-direction: column;
justify-content: center;
background: white;
padding: 10px;
b {
text-align: center;
color: black;
font-weight: bold;
font-size: 16px;
margin-bottom: 15px;
}
.id {
display: flex;
align-items: center;
padding: 3px 5px;
background: #ececec;
justify-content: center;
img {
width: 15px;
margin-right: 8px;
}
}
}
}
}
.detail-content {
display: flex;
width: 100%;
flex: 1;
margin-bottom: 10px;
flex-shrink: 0;
justify-content: space-between;
}
.right {
width: 710px;
height: 100%;
display: flex;
flex-direction: column;
.btn {
margin: 20px 0;
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
width: 100%;
}
.div-text {
.div-content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start;
padding: 15px 10px;
box-sizing: border-box;
position: relative;
border: 1px solid #ececec;
.div-item {
width: 50%;
margin-bottom: 10px;
font-size: 15px;
display: flex;
align-items: center;
p {
font-weight: 400;
color: black;
}
span {
display: inline-block;
text-align: right;
width: 100px;
&::after {
content: ":";
margin: 0 3px;
}
}
}
}
b {
position: relative;
background: white;
top: 9px;
left: 13px;
padding: 0 10px;
font-size: 18px;
color: black;
z-index: 3;
}
}
.input {
display: flex;
align-items: center;
margin: 30px 0;
}
}
.left {
flex: 1;
flex-shrink: 0;
margin-right: 20px;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.left-image {
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
img {
height: auto;
width: 100%;
max-height: 90%;
}
b {
color: black;
font-size: 18px;
margin-bottom: 15px;
}
}
.left-images {
display: flex;
width: 95%;
height: 100%;
flex-direction: column;
b {
color: black;
text-align: center;
margin-bottom: 15px;
}
}
}
}
.detail-div .right .btn .btn-sure,
.detail-div .right .btn .btn-down {
width: 100%;
position: relative;
}
.detail-div .right .btn .btn-sure .check,
.detail-div .right .btn .btn-down .check {
position: absolute;
width: 144px;
height: 100%;
background: transparent;
display: flex;
align-items: center;
justify-content: center;
right: 0;
top: 1px;
}
.btn {
position: relative;
.check {
::v-deep {
.el-checkbox__inner {
background-color: transparent !important;
border-color: white !important;
width: 12px;
height: 12px;
&::after {
left: 3px;
}
}
.el-checkbox__label {
padding-left: 5px;
font-size: 12px;
color: white !important;
}
}
}
}
.page {
width: 100%;
height: 100%;
}
p {
margin: 0;
}
</style>
<script>
import bus from "@/bus";
import PrintDialog from "./printDialog.vue";
import { ipcRenderer } from "electron";
import { grid } from "../data";
import pkg from "../../../../package.json";
import UpdateDialog from "@/views/design/updateDialog.vue";
export default {
components: { PrintDialog, UpdateDialog },
props: {
user: {
default: {
avatar: ""
},
type: Object
},
company: {
default: {},
type: Object
}
},
data() {
return {
checkList: [],
cacheList: [
{
label: "清除当前登录信息",
value: "token"
},
{
label: "登录记录",
value: "userList"
},{
label: "公司信息",
value: "company"
}, {
label: "打印预设",
value: "print-setting"
}, {
label: "系统授权信息",
value: "deviceId"
}, {
label: "系统设置",
value: "setting"
}
],
selectGridIndex: 0,
pkg,
actionIndex: -1,
isAutoFinish: false,
cacheVisible: false,
showPrintDialog: false,
productionNo: "",
setting: {
gridShow: 1,
gridValue: 0,
unit: "mm",
language: "cn",
autoPrint: false,
gridSpacing: 10
},
imgList: [],
detail: null,
selectBgColor: "#ececec",
predefineColors: [
"#ff4500",
"#ff8c00",
"#ffd700",
"#90ee90",
"#00ced1",
"#1e90ff",
"#c71585",
"rgba(255, 69, 0, 0.68)",
"rgb(255, 120, 0)",
"hsv(51, 100, 98)",
"hsva(120, 40, 94, 0.5)",
"hsl(181, 100%, 37%)",
"hsla(209, 100%, 56%, 0.73)",
"#c7158577"
],
grid
};
},
computed: {
avatar() {
if (this.user && this.user.avatar && this.company.domain) {
console.log(this.user, 9);
console.log(this.company, 8);
let host = this.company.domain;
if (host.includes("console")) {
host = host.replace(".jomalls.com", ".joshine.cn");
}
let avatar = this.user.avatar.includes("http")
? this.user.avatar
: `https://${host}/erpimg/${this.user.avatar}`;
console.log(avatar);
return avatar;
}
return "";
},
actionList() {
return this.$store.getters.getActionList;
}
},
mounted() {
console.log(pkg, "pkg");
this.$nextTick(() => {
this.$refs.searchRef.focus();
});
},
created() {
if (this.$dataStore.get("setting")) {
this.setting = this.$dataStore.get("setting");
} else {
this.$dataStore.set("setting", this.setting);
}
},
watch: {
setting: {
handler() {
this.$dataStore.set("setting", this.setting);
bus.$emit("busEmit", { type: "updateSystemSetting" });
},
deep: true
}
},
methods: {
checkUpdate() {
this.$refs.updateDialog.checkUpdate().then(data => {
if (data) {
// 有新版本更新
this.$refs.updateDialog.open(data);
} else {
this.$message.warning("已是最新版本");
}
});
},
dropdownCommand(v) {
switch (v) {
case "logout":
this.$confirm("是否退出登录?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$dataStore.delete("user");
this.$router.push("/");
})
.catch(() => {
});
break;
case "company":
this.$confirm("是否切换系统?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$dataStore.delete("company");
this.$dataStore.delete("user");
this.$router.push("/");
})
.catch(() => {
});
break;
case "cache":
this.checkList = [];
this.cacheVisible = true;
break;
}
},
async setData(data) {
if (!data) return this.$message.warning("请扫描生产单号");
await this.$api.post("/completeDelivery", { id: data.id }).then(() => {
});
this.$message.success("成功生产完成");
},
async sureData() {
if (!this.detail || Object.keys(this.detail).length <= 1) {
return this.$message.warning("请扫描生产单号");
}
this.$confirm(`确定生产完成?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
await this.setData(this.detail);
});
},
clearCache() {
if (this.checkList.length === 0) {
return this.$message.warning("请选择要清除的数据");
}
this.$confirm("是否确定清除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
for (let k of this.checkList) {
if (k === "print-setting" || k === "deviceId") {
let list = Object.keys(this.$dataStore.store).filter(el => el.includes(k));
list.forEach(el => {
this.$dataStore.delete(el);
});
}else if (k === "token" ) {
this.$dataStore.delete('token');
this.$dataStore.delete('user');
} else {
if (this.$dataStore.get(k)) {
this.$dataStore.delete(k);
}
}
}
window.location.reload();
})
.catch(() => {
});
},
async downloadImage() {
if (!this.detail || Object.keys(this.detail).length === 0)
return this.$message.warning("请扫描生产单号");
let params = {
productionNo: this.detail.podProductionNo,
imgList: this.imgList
};
let res = await this.$api.post("/downloadByDesignId", params);
this.$message.success(res.msg);
},
async getDataInfo() {
if (
this.detail &&
Object.keys(this.detail).length > 0 &&
this.isAutoFinish
) {
await this.setData(this.detail);
}
if (this.productionNo === "")
return this.$message.warning("请录入生产单号");
try {
//查找生产单号信息传给第二个显示器
const findByPodProductionNo = await this.$api.post(
"/findByPodProductionNo",
{
podProductionNo: this.productionNo,
status: "IN_PRODUCTION"
}
);
this.detail = findByPodProductionNo.data;
ipcRenderer.send("win-subScreen", findByPodProductionNo.data);
// 根据生产单号查找 素材图片 下载到本地 然后返回本地地址去显示
let res = await this.$api.post("/getPodProductionInfo", {
productionNo: this.productionNo
});
this.$dataStore.set('production_no',this.productionNo)
if (res.data.length === 0)
return this.$message.warning("未找到素材图!");
let arr = [];
res.data.forEach(el => {
arr.push(el);
if (el.list) {
el.list.forEach(it => {
arr.push({
...it,
...{
designId: el.designId
}
});
});
}
});
console.log(arr, "arr");
res.data = arr.filter(el => el.type !== 1);
bus.$emit("busEmit", { type: "sendFile", value: res.data });
this.productionNo = "";
this.$refs.searchRef.focus();
} catch (err) {
this.productionNo = "";
this.$refs.searchRef.focus();
}
},
changeActionIndex(t) {
let index = this.actionIndex;
if (t === "+") {
if (index === this.$store.state.actionList.length - 1) return;
this.actionIndex = this.actionIndex + 1;
} else {
if (index === 0) return;
this.actionIndex = this.actionIndex - 1;
}
console.log(this.actionIndex, 88);
bus.$emit("busEmit", { type: "index", value: this.actionIndex });
this.$store.commit("changeActionIndex", this.actionIndex);
},
setDefaultSetting() {
this.$store.commit("setDefaultSetting");
this.setting = {
gridShow: 1,
gridValue: 0,
unit: "mm",
language: "cn",
autoPrint: false,
gridSpacing: 10
};
this.$message.success("重置应用程序设置成功");
},
settingChange(field, value) {
if (value === "inch") {
this.setting.gridSpacing = 1;
} else if (value === "mm") {
this.setting.gridSpacing = 20;
}
this.$store.commit("updateSystemSetting", { field, value });
},
setBg() {
bus.$emit("busEmit", { type: "bg", value: this.selectBgColor });
},
async uploadImage(f) {
let formData = new FormData();
formData.append("file", f);
let { data } = await this.$api.post("/uploadImage", formData, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
bus.$emit("busEmit", { type: "uploadImage", value: data });
return false;
},
command(i) {
this.selectGridIndex = i;
this.setting.gridValue = i;
this.$store.commit("updateSystemSetting", {
field: "gridValue",
value: this.grid[i]
});
bus.$emit("busEmit", { type: "grid", value: this.grid[i] });
}
}
};
</script>
<style scoped>
.page-header {
background-color: #ececec;
display: flex;
justify-content: space-between;
height: 40px;
padding: 5px;
}
.left-btn {
display: flex;
}
</style>
<template>
<div>
<div class="page-header">
<div class="left-btn">
<!-- <el-tooltip content="文件">-->
<!-- <el-button style="margin-right: 8px" size="small">文件</el-button>-->
<!-- </el-tooltip>-->
<el-dropdown trigger="click" @command="command" :hide-on-click="false">
<el-button style="height: 100%;margin-right: 0px" size="small">{{
grid[selectGridIndex].label
}}
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="i" v-for="(it, i) in grid" :key="i">
{{ it.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- <el-tooltip content="字体">-->
<!-- <el-button size="small">-->
<!-- <img style="width: 13px;height: 13px" src="@/static/icon/ziti.png" alt="">-->
<!-- </el-button>-->
<!-- </el-tooltip>-->
<el-tooltip content="图片">
<el-upload
accept=".png"
action=""
:show-file-list="false"
multiple
:before-upload="uploadImage"
>
<el-button style="height: 100%;margin:0 8px" size="small">
<i class="el-icon-picture" style="font-size: 15px;"></i>
</el-button>
</el-upload>
</el-tooltip>
<!-- <el-tooltip content="撤销">-->
<!-- <el-button @click="changeActionIndex('+')"-->
<!-- :disabled="actionList.length===0 || actionIndex<-1 || actionIndex===actionList.length-1 " icon=""-->
<!-- size="small">-->
<!-- <img style="width: 14px;height: 14px" src="@/static/icon/chehuizuo.png" alt="">-->
<!-- </el-button>-->
<!-- </el-tooltip>-->
<!-- <el-tooltip content="恢复">-->
<!-- <el-button @click="changeActionIndex('-')"-->
<!-- :disabled="actionList.length===0 || actionIndex<=-1" icon=""-->
<!-- size="small">-->
<!-- <img style="width: 14px;height: 14px" src="@/static/icon/chehuiyou.png" alt="">-->
<!-- </el-button>-->
<!-- </el-tooltip>-->
<el-tooltip content="背景色">
<el-color-picker
style="margin-right: 3px"
v-model="selectBgColor"
@change="setBg"
color-format="hex"
:predefine="predefineColors"
>
</el-color-picker>
</el-tooltip>
<el-popover
width="320"
:offset="-120"
trigger="click"
placement="bottom"
>
<div class="setting-form">
<el-form
:model="setting"
label-position="left"
label-width="80px"
size="small"
>
<el-form-item prop="setting" label="网格显示">
<el-select
@change="e => settingChange('gridShow', e)"
clearable
v-model="setting.gridShow"
>
<el-option :value="1" label="未缩放的网格"></el-option>
<el-option :value="0" label="无"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="gridSpacing" label="单位">
<el-select
@change="e => settingChange('unit', e)"
clearable
v-model="setting.unit"
>
<el-option value="mm" label="mm"></el-option>
<el-option value="inch" label="inch"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="gridSpacing" label="网格间隔">
<el-select
@change="e => settingChange('gridSpacing', e)"
clearable
v-model="setting.gridSpacing"
>
<el-option
v-if="setting.unit === 'mm'"
:value="20"
:label="`20 ${setting.unit}`"
></el-option>
<el-option
v-if="setting.unit === 'mm'"
:value="10"
:label="`10 ${setting.unit}`"
></el-option>
<el-option
v-if="setting.unit === 'inch'"
:value="1"
:label="`1 ${setting.unit}`"
></el-option>
<el-option
v-if="setting.unit === 'inch'"
:value="0.5"
:label="`0.5 ${setting.unit}`"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="language" label="语言设置">
<el-select
@change="e => settingChange('language', e)"
clearable
v-model="setting.language"
>
<el-option value="cn" label="中文"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="language" label="版本号">
<b>{{ pkg.version || "" }}</b>
<el-button @click="checkUpdate" style="margin-left: 15px" type="text">检查更新</el-button>
</el-form-item>
<!-- <el-form-item label="自动打印模式">-->
<!-- <el-switch @change="(e)=>settingChange('autoPrint',e)" v-model="setting.autoPrint"></el-switch>-->
<!-- </el-form-item>-->
</el-form>
<!-- <div class="form-block">-->
<!-- <div @click="setDefaultSetting" class="block-item">重置应用程序设置</div>-->
<!-- </div>-->
<!-- <div class="form-block">-->
<!-- <div class="block-item">隐私政策</div>-->
<!-- <div class="block-item">版本信息</div>-->
<!-- </div>-->
</div>
<el-tooltip slot="reference" content="设置">
<el-button style="margin-right: 8px" size="small">
<img
style="width: 15px;height: 15px"
src="@/static/icon/shezhi.png"
alt=""
/>
</el-button>
</el-tooltip>
</el-popover>
<!-- <el-tooltip content="打印">-->
<!-- <el-button @click="showPrintDialog=true" size="small" type="primary">打印</el-button>-->
<!-- </el-tooltip>-->
<!-- <el-tooltip content="添加模板">-->
<!-- <el-button size="small">添加模板</el-button>-->
<!-- </el-tooltip>-->
</div>
<div class="center-input">
<el-input
@keyup.enter.native="getDataInfo"
style="width: 40%;"
size="medium"
placeholder="请扫描生产单号"
ref="searchRef"
v-model="productionNo"
></el-input>
<el-button
@click="getDataInfo"
size="medium"
style="margin-left: 10px"
type="primary"
>查询
</el-button
>
<div class="sure-btn">
<el-button
@click="sureData"
size="medium"
style="margin-left: 10px;width: 100%;"
type="success"
>生产完成
</el-button>
<div class="check">
<el-checkbox v-model="isAutoFinish">自动完成上一单</el-checkbox>
</div>
</div>
<el-button
@click="downloadImage"
size="medium"
style="margin-left: 15px"
type="primary"
>下载素材
</el-button>
</div>
<div class="right-user">
<p>{{ company.companyName }}</p>
<el-avatar :src="avatar"></el-avatar>
<el-dropdown @command="dropdownCommand">
<b style="cursor:pointer;">{{ user.employeeName }}</b>
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item command="clear">清除缓存</el-dropdown-item>-->
<el-dropdown-item command="company">切换系统</el-dropdown-item>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
<el-dropdown-item command="cache">清除缓存</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<update-dialog ref="updateDialog" />
<el-dialog :visible.sync="cacheVisible" title="清除缓存" width="700px">
<el-checkbox-group style="display: flex;flex-direction: column" v-model="checkList">
<el-checkbox style="margin-bottom: 10px" :label="item.value" v-for="(item,i) in cacheList"
:key="i">{{item.label}}</el-checkbox>
</el-checkbox-group>
<template #footer>
<el-button @click="cacheVisible =false">取消</el-button>
<el-button @click="clearCache" type="primary">清除</el-button>
</template>
</el-dialog>
</div>
</template>
<style lang="less" scoped>
.right-user {
display: flex;
align-items: center;
b {
margin: 0 10px;
display: inline-block;
color: black;
font-size: 15px;
font-weight: bold;
}
p {
margin: 0 10px;
font-weight: bold;
display: inline-block;
font-size: 15px;
color: #e6a23c;
}
}
.setting-form {
.el-form {
padding: 10px;
box-sizing: border-box;
}
}
.form-block {
padding: 15px 0;
border-top: 1px solid #ececec;
&:nth-last-of-type(1) {
border-bottom: 1px solid #ececec;
}
}
.block-item {
width: 100%;
text-align: left;
cursor: pointer;
font-size: 14px;
padding: 10px 10px;
&:hover {
background-color: #ececec;
}
}
.center-input {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
flex-shrink: 0;
overflow: hidden;
padding-left: 100px;
}
.sure-btn {
width: 300px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
::v-deep {
.el-button {
span {
position: relative;
left: -40px;
}
}
}
}
.check {
position: absolute;
right: 10px;
width: fit-content;
line-height: 36px;
height: 100%;
z-index: 2;
color: white;
}
</style>
<script>
import bus from "@/bus";
import PrintDialog from "./printDialog.vue";
import { ipcRenderer } from "electron";
import { grid } from "../data";
import pkg from "../../../../package.json";
import UpdateDialog from "@/views/design/updateDialog.vue";
export default {
components: { PrintDialog, UpdateDialog },
props: {
user: {
default: {
avatar: "",
factory: {}
},
type: Object
}
},
data() {
return {
checkList: [],
cacheList: [
{
label: "清除当前登录信息",
value: "token"
},
{
label: "登录记录",
value: "userList"
},
{
label: "打印预设",
value: "print-setting"
},
{
label: "系统设置",
value: "setting"
}
],
selectGridIndex: 0,
pkg,
actionIndex: -1,
isAutoFinish: false,
cacheVisible: false,
showPrintDialog: false,
productionNo: "",
setting: {
gridShow: 1,
gridValue: 0,
unit: "mm",
language: "cn",
autoPrint: false,
gridSpacing: 10
},
imgList: [],
detail: null,
selectBgColor: "#ececec",
predefineColors: [
"#ff4500",
"#ff8c00",
"#ffd700",
"#90ee90",
"#00ced1",
"#1e90ff",
"#c71585",
"rgba(255, 69, 0, 0.68)",
"rgb(255, 120, 0)",
"hsv(51, 100, 98)",
"hsva(120, 40, 94, 0.5)",
"hsl(181, 100%, 37%)",
"hsla(209, 100%, 56%, 0.73)",
"#c7158577"
],
grid
};
},
computed: {
actionList() {
return this.$store.getters.getActionList;
}
},
mounted() {
console.log(pkg, "pkg");
this.$nextTick(() => {
this.$refs.searchRef.focus();
});
},
created() {
if (this.$dataStore.get("setting")) {
this.setting = this.$dataStore.get("setting");
} else {
this.$dataStore.set("setting", this.setting);
}
},
watch: {
setting: {
handler() {
this.$dataStore.set("setting", this.setting);
bus.$emit("busEmit", { type: "updateSystemSetting" });
},
deep: true
}
},
methods: {
checkUpdate() {
this.$refs.updateDialog.checkUpdate().then(data => {
if (data) {
// 有新版本更新
this.$refs.updateDialog.open(data);
} else {
this.$message.warning("已是最新版本");
}
});
},
dropdownCommand(v) {
switch (v) {
case "logout":
this.$confirm("是否退出登录?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$dataStore.delete("user");
this.$router.push("/");
})
.catch(() => {});
break;
case "cache":
this.checkList = [];
this.cacheVisible = true;
break;
}
},
async setData(data) {
if (!data) return this.$message.warning("请扫描生产单号");
await this.$api.post("/completeDelivery", { id: data.id }).then(() => {});
this.$message.success("操作成功");
},
async sureData() {
if (!this.detail || Object.keys(this.detail).length <= 1) {
return this.$message.warning("请扫描生产单号");
}
this.$confirm(`确定生产完成?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
await this.setData(this.detail);
});
},
clearCache() {
if (this.checkList.length === 0) {
return this.$message.warning("请选择要清除的数据");
}
this.$confirm("是否确定清除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
for (let k of this.checkList) {
if (k === "print-setting" || k === "deviceId") {
let list = Object.keys(this.$dataStore.store).filter(el =>
el.includes(k)
);
list.forEach(el => {
this.$dataStore.delete(el);
});
} else if (k === "token") {
this.$dataStore.delete("token");
this.$dataStore.delete("user");
} else {
if (this.$dataStore.get(k)) {
this.$dataStore.delete(k);
}
}
}
window.location.reload();
})
.catch(() => {});
},
async downloadImage() {
if (!this.detail || Object.keys(this.detail).length === 0)
return this.$message.warning("请扫描生产单号");
let params = {
productionNo: this.detail.factorySubOrderNumber,
imgList: this.imgList
};
let res = await this.$api.post("/downloadByDesignId", params);
this.$message.success(res.msg);
},
async getDataInfo() {
if (
this.detail &&
Object.keys(this.detail).length > 0 &&
this.isAutoFinish
) {
await this.setData(this.detail);
}
if (this.productionNo === "")
return this.$message.warning("请录入生产单号");
try {
//查找生产单号信息传给第二个显示器
const findByPodProductionNo = await this.$api.post(
"/findByPodProductionNo",
{
factorySubOrderNumber: this.productionNo
}
);
this.detail = findByPodProductionNo.data;
console.log(findByPodProductionNo.data, "findByPodProductionNo.data");
ipcRenderer.send("win-subScreen", findByPodProductionNo.data);
// 根据生产单号查找 素材图片 下载到本地 然后返回本地地址去显示
let res = await this.$api.post("/downloadBySubOrderNumber", {
subOrderNumber: this.productionNo
});
this.imgList = [];
res.data.forEach(el => {
this.imgList = this.imgList.concat(el.list || []);
});
this.$dataStore.set("production_no", this.productionNo);
if (res.data.length === 0)
return this.$message.warning("未找到素材图!");
let arr = [];
res.data.forEach(el => {
if (el.list) {
el.list.forEach(it => {
arr.push(it);
});
}
});
console.log(arr, "arr");
res.data = arr.filter(el => el.type !== 1);
bus.$emit("busEmit", { type: "sendFile", value: res.data });
this.productionNo = "";
this.$refs.searchRef.focus();
} catch (err) {
this.productionNo = "";
this.$refs.searchRef.focus();
}
},
changeActionIndex(t) {
let index = this.actionIndex;
if (t === "+") {
if (index === this.$store.state.actionList.length - 1) return;
this.actionIndex = this.actionIndex + 1;
} else {
if (index === 0) return;
this.actionIndex = this.actionIndex - 1;
}
console.log(this.actionIndex, 88);
bus.$emit("busEmit", { type: "index", value: this.actionIndex });
this.$store.commit("changeActionIndex", this.actionIndex);
},
setDefaultSetting() {
this.$store.commit("setDefaultSetting");
this.setting = {
gridShow: 1,
gridValue: 0,
unit: "mm",
language: "cn",
autoPrint: false,
gridSpacing: 10
};
this.$message.success("重置应用程序设置成功");
},
settingChange(field, value) {
if (value === "inch") {
this.setting.gridSpacing = 1;
} else if (value === "mm") {
this.setting.gridSpacing = 20;
}
this.$store.commit("updateSystemSetting", { field, value });
},
setBg() {
bus.$emit("busEmit", { type: "bg", value: this.selectBgColor });
},
async uploadImage(f) {
let formData = new FormData();
formData.append("file", f);
let { data } = await this.$api.post("/uploadImage", formData, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
bus.$emit("busEmit", { type: "uploadImage", value: data });
return false;
},
command(i) {
this.selectGridIndex = i;
this.setting.gridValue = i;
this.$store.commit("updateSystemSetting", {
field: "gridValue",
value: this.grid[i]
});
bus.$emit("busEmit", { type: "grid", value: this.grid[i] });
}
}
};
</script>
<style scoped>
.page-header {
background-color: #ececec;
display: flex;
justify-content: space-between;
height: 40px;
padding: 5px;
}
.left-btn {
display: flex;
}
</style>
<template>
<div>
<div class="page-header">
<div class="left-btn">
<!-- <el-tooltip content="文件">-->
<!-- <el-button style="margin-right: 8px" size="small">文件</el-button>-->
<!-- </el-tooltip>-->
<el-dropdown trigger="click" @command="command" :hide-on-click="false">
<el-button style="height: 100%;margin-right: 0px" size="small"
>{{ grid[selectGridIndex].label }}
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="i" v-for="(it, i) in grid" :key="i">
{{ it.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- <el-tooltip content="字体">-->
<!-- <el-button size="small">-->
<!-- <img style="width: 13px;height: 13px" src="@/static/icon/ziti.png" alt="">-->
<!-- </el-button>-->
<!-- </el-tooltip>-->
<el-tooltip content="图片">
<el-upload
accept=".png"
action=""
:show-file-list="false"
multiple
:before-upload="uploadImage"
>
<el-button style="height: 100%;margin:0 8px" size="small">
<i class="el-icon-picture" style="font-size: 15px;"></i>
</el-button>
</el-upload>
</el-tooltip>
<!-- <el-tooltip content="撤销">-->
<!-- <el-button @click="changeActionIndex('+')"-->
<!-- :disabled="actionList.length===0 || actionIndex<-1 || actionIndex===actionList.length-1 " icon=""-->
<!-- size="small">-->
<!-- <img style="width: 14px;height: 14px" src="@/static/icon/chehuizuo.png" alt="">-->
<!-- </el-button>-->
<!-- </el-tooltip>-->
<!-- <el-tooltip content="恢复">-->
<!-- <el-button @click="changeActionIndex('-')"-->
<!-- :disabled="actionList.length===0 || actionIndex<=-1" icon=""-->
<!-- size="small">-->
<!-- <img style="width: 14px;height: 14px" src="@/static/icon/chehuiyou.png" alt="">-->
<!-- </el-button>-->
<!-- </el-tooltip>-->
<el-tooltip content="背景色">
<el-color-picker
style="margin-right: 3px"
v-model="selectBgColor"
@change="setBg"
color-format="hex"
:predefine="predefineColors"
>
</el-color-picker>
</el-tooltip>
<el-popover
width="320"
:offset="-120"
trigger="click"
placement="bottom"
>
<div class="setting-form">
<el-form
:model="setting"
label-position="left"
label-width="80px"
size="small"
>
<el-form-item prop="setting" label="网格显示">
<el-select
@change="e => settingChange('gridShow', e)"
clearable
v-model="setting.gridShow"
>
<el-option :value="1" label="未缩放的网格"></el-option>
<el-option :value="0" label="无"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="gridSpacing" label="单位">
<el-select
@change="e => settingChange('unit', e)"
clearable
v-model="setting.unit"
>
<el-option value="mm" label="mm"></el-option>
<el-option value="inch" label="inch"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="gridSpacing" label="网格间隔">
<el-select
@change="e => settingChange('gridSpacing', e)"
clearable
v-model="setting.gridSpacing"
>
<el-option
v-if="setting.unit === 'mm'"
:value="20"
:label="`20 ${setting.unit}`"
></el-option>
<el-option
v-if="setting.unit === 'mm'"
:value="10"
:label="`10 ${setting.unit}`"
></el-option>
<el-option
v-if="setting.unit === 'inch'"
:value="1"
:label="`1 ${setting.unit}`"
></el-option>
<el-option
v-if="setting.unit === 'inch'"
:value="0.5"
:label="`0.5 ${setting.unit}`"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="language" label="语言设置">
<el-select
@change="e => settingChange('language', e)"
clearable
v-model="setting.language"
>
<el-option value="cn" label="中文"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="language" label="版本号">
<b>{{ pkg.version || "" }}</b>
<el-button
@click="checkUpdate"
style="margin-left: 15px"
type="text"
>检查更新</el-button
>
</el-form-item>
<!-- <el-form-item label="自动打印模式">-->
<!-- <el-switch @change="(e)=>settingChange('autoPrint',e)" v-model="setting.autoPrint"></el-switch>-->
<!-- </el-form-item>-->
</el-form>
<!-- <div class="form-block">-->
<!-- <div @click="setDefaultSetting" class="block-item">重置应用程序设置</div>-->
<!-- </div>-->
<!-- <div class="form-block">-->
<!-- <div class="block-item">隐私政策</div>-->
<!-- <div class="block-item">版本信息</div>-->
<!-- </div>-->
</div>
<el-tooltip slot="reference" content="设置">
<el-button style="margin-right: 8px" size="small">
<img
style="width: 18px;height: 18px"
src="@/static/icon/shezhi.png"
alt=""
/>
</el-button>
</el-tooltip>
</el-popover>
<!-- <el-tooltip content="打印">-->
<!-- <el-button @click="showPrintDialog=true" size="small" type="primary">打印</el-button>-->
<!-- </el-tooltip>-->
<!-- <el-tooltip content="添加模板">-->
<!-- <el-button size="small">添加模板</el-button>-->
<!-- </el-tooltip>-->
</div>
<div class="center-input">
<el-input
@keyup.enter.native="getDataInfo"
style="width: 40%;"
size="medium"
placeholder="请扫描生产单号"
ref="searchRef"
v-model="productionNo"
></el-input>
<el-button
@click="getDataInfo"
size="medium"
style="margin-left: 10px"
type="primary"
>查询
</el-button>
<div class="sure-btn">
<el-button
@click="sureData"
size="medium"
style="margin-left: 10px;width: 100%;"
type="success"
>生产完成
</el-button>
<div class="check">
<el-checkbox v-model="isAutoFinish">自动完成上一单</el-checkbox>
</div>
</div>
<el-button
@click="downloadImage"
size="medium"
style="margin-left: 15px"
type="primary"
>下载素材
</el-button>
</div>
<div class="right-user">
<p v-if="user && user.factory">{{ user.factory.title }}</p>
<el-dropdown @command="dropdownCommand">
<div style="margin-right: 20px">
<b style="cursor:pointer;">{{ user.account }}</b>
<i class="el-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
<el-dropdown-item command="cache">清除缓存</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<update-dialog ref="updateDialog" />
<el-dialog :visible.sync="cacheVisible" title="清除缓存" width="700px">
<el-checkbox-group
style="display: flex;flex-direction: column"
v-model="checkList"
>
<el-checkbox
style="margin-bottom: 10px"
:label="item.value"
v-for="(item, i) in cacheList"
:key="i"
>{{ item.label }}</el-checkbox
>
</el-checkbox-group>
<template #footer>
<el-button @click="cacheVisible = false">取消</el-button>
<el-button @click="clearCache" type="primary">清除</el-button>
</template>
</el-dialog>
</div>
</template>
<style lang="less" scoped>
.right-user {
display: flex;
align-items: center;
b {
margin: 0 3px;
display: inline-block;
color: black;
font-size: 15px;
font-weight: bold;
}
p {
margin: 0 10px;
font-weight: bold;
display: inline-block;
font-size: 15px;
color: #e6a23c;
}
}
.setting-form {
.el-form {
padding: 10px;
box-sizing: border-box;
}
}
.form-block {
padding: 15px 0;
border-top: 1px solid #ececec;
&:nth-last-of-type(1) {
border-bottom: 1px solid #ececec;
}
}
.block-item {
width: 100%;
text-align: left;
cursor: pointer;
font-size: 14px;
padding: 10px 10px;
&:hover {
background-color: #ececec;
}
}
.center-input {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
flex-shrink: 0;
overflow: hidden;
padding-left: 100px;
}
.sure-btn {
width: 300px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
::v-deep {
.el-button {
span {
position: relative;
left: -40px;
}
}
}
}
.check {
position: absolute;
right: 10px;
width: fit-content;
line-height: 36px;
height: 100%;
z-index: 2;
color: white;
}
::v-deep .el-color-picker__trigger{
background: white;
width: 41px;
}
::v-deep .el-color-picker__color{
border: none !important;
}
</style>
<script>
import fieldDescription from "./fieldDescription";
import { ipcRenderer } from "electron";
import axios from "axios";
import html2canvas from "html2canvas";
import moment from "moment";
import pkg from "../../../../package.json";
export default {
data() {
return {
dialogShow: true,
pkg,
axios,
fieldDescription,
printerList: [],
printSettingList: [],
printSettingVal: 0,
description: "",
printSettingSelectLabel: "default",
printer: "",
settingName: "",
printInkList: [
{
label: "仅彩色油墨"
},
{
label: "仅白色油墨"
},
{
label: "彩色 + 白色油墨"
},
{
label: "仅黑色油墨"
}
],
detailShow: false,
showPopover: false,
printSetting: {
printer: "",
xy: "",
byInk: 2,
byInkVolume: 1,
byDoublePrint: 3,
bEcoMode: false,
bMaterialBlack: false,
byHighlight: 5,
printNum: 1,
bFastMode: false,
bUniPrint: false,
bDivide: false,
bPause: false,
byMask: 3,
bTransColor: false,
byChoke: 2,
minWhiteInkType: 0,
bySaturation: 5,
byBrightness: 5,
byContrast: 5,
iCyanBalance: 0,
iMagentaBalance: 0,
iBlackBalance: 0,
iYellowBalance: 0,
byMinWhite: 1,
bMultiple: false
}
};
},
props: {
visible: {
default: false,
type: Boolean
},
byPlatenSize: {
default: 0,
type: Number
},
imgList: {
default: () => [],
type: Array
}
},
mounted() {
this.$dataStore.set("default-print-setting", this.printSetting);
this.getPrintSettingList(() => {
let select = this.$dataStore.get("print-setting-select");
console.log(this.$dataStore, "select");
if (select) {
this.printSettingSelectLabel = select;
let index = this.printSettingList.findIndex(el => el.label === select);
if (index >= 0) {
this.printSettingVal = index;
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[index].value)
);
} else {
this.printSettingVal = 0;
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[0].value)
);
}
} else {
this.printSettingVal = 0;
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[0].value)
);
}
});
},
computed: {
inkNum() {
return 200 + Number(this.printSetting.byHighlight) * 50 - 50;
},
defaultTime() {
if ([6, 7].includes(Number(this.printSetting.byHighlight))) {
return "1.25";
} else if (this.printSetting.byHighlight < 6) {
return "1.00";
} else {
return "1.5";
}
}
},
watch: {
printSetting: {
handler() {
this.$dataStore.set("print-setting", this.printSetting);
},
deep: true,
immediate: true
},
visible() {
this.dialogShow = this.visible;
}
},
created() {
this.getPrinter();
},
methods: {
delSetting() {
this.$confirm(`确定删除该预设?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$dataStore.delete(
this.printSettingList[this.printSettingVal].label + "-print-setting"
);
this.getPrintSettingList();
this.printSettingVal = 0;
});
},
getPrintSettingList(callback) {
let arr = [];
for (let k in this.$dataStore.store) {
if (k.includes("-print-setting")) {
arr.push({
label: k.replace("-print-setting", ""),
value: this.$dataStore.get(k)
});
}
}
this.printSettingList = arr;
callback && callback();
},
printSettingChange(v) {
let label = this.printSettingList[v].label;
this.$dataStore.set("print-setting-select", label);
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[v].value)
);
},
saveSetting() {
if (this.settingName.trim() === "") {
return this.$message.warning("预设名称不能为空");
}
if (this.printSettingList.find(el => el.label === this.settingName)) {
return this.$message.warning("预设名称不能重复");
}
this.$dataStore.set(
`${this.settingName}-print-setting`,
this.printSetting
);
this.showPopover = false;
this.printSettingVal = this.printSettingList.length;
this.getPrintSettingList();
},
openPopover() {
this.showPopover = true;
this.settingName = "";
},
singleStr(str) {
if (Number(str) >= 0) {
str = str.toString().replace(".", "");
if (str.length >= 4) {
str = str.slice(0, 5);
} else if (str.length === 3) {
str = "0" + str;
} else if (str.length === 2) {
str = "00" + str;
} else if (str.length === 1) {
str = "000" + str;
}
} else {
str = str
.toString()
.replace(".", "")
.replace("-", "");
if (str.length >= 4) {
str = str.slice(0, 5);
} else if (str.length === 3) {
str = "0" + str;
} else if (str.length === 2) {
str = "00" + str;
} else if (str.length === 1) {
str = "000" + str;
}
str = "-" + str;
}
// 不足四位前面用0补齐
console.log(str);
return str;
},
dataURLtoBlob(dataurl) {
var arr = dataurl.split(",");
//注意base64的最后面中括号和引号是不转译的
var _arr = arr[1].substring(0, arr[1].length - 2);
var mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(_arr),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime
});
},
moreImageCmd(arr) {
var canvas1 = document.createElement("canvas");
let _canvas = document.getElementsByClassName("sucaitu")[0]; //目标块
var bodyW = parseInt(window.getComputedStyle(_canvas).width);
var bodyH = parseInt(window.getComputedStyle(_canvas).height);
canvas1.width = bodyW;
canvas1.height = bodyH;
canvas1.style.width = bodyW + "px";
canvas1.style.height = bodyH + "px";
canvas1.style.background = "transparent";
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
var context = canvas1.getContext("2d");
// context.scale(2, 2);
let that = this;
html2canvas(_canvas, {
canvas: canvas1,
backgroundColor: null,
useCORS: true,
allowTaint: true
}).then(async function(canvas) {
let dataURL = canvas.toDataURL("image/png");
let pageBlob = that.dataURLtoBlob(dataURL);
let params = new FormData();
let fileOfBlob = new File([pageBlob], new Date().getTime() + ".jpg");
params.append("file", fileOfBlob);
let { data } = await that.$api.post("/uploadImage", params, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
let w_mm = Number((canvas1.width * 0.84183).toFixed(1));
let h_mm = Number((canvas1.height * 0.84183).toFixed(1));
let size = `${that.singleStr(Number(w_mm).toFixed(1))}${that.singleStr(
Number(h_mm).toFixed(1)
)}`;
await that.sendCmd(data.fileName, size, "00000000", 0);
//canvas转换成url,然后利用a标签的download属性,直接下载,绕过上传服务器再下载
// document.querySelector(".down").setAttribute('href', canvas.toDataURL());
});
},
async getPrintCmd() {
if (this.imgList.length === 0)
return this.$message.warning("素材不能为空");
if (this.imgList.length > 1) {
let dom = document.getElementsByClassName("drr");
for (let i = 0; i < dom.length; i++) {
dom[i].classList.remove("active");
dom[i].classList.add("inactive");
}
setTimeout(() => {
this.moreImageCmd(this.imgList);
}, 500);
return;
}
let { x, y, r, w, h } = this.imgList[0];
y = Number(y) - Number(h) / 2;
x = Number(x) - Number(w) / 2;
let x_mm = Number((x * 0.84183).toFixed(1));
let w_mm = Number((w * 0.84183).toFixed(1));
let h_mm = Number((h * 0.84183).toFixed(1));
let y_mm = Number((y * 0.84183).toFixed(1));
console.log(x_mm, y_mm);
r = Number(r).toFixed(0);
const imgFileName = this.imgList[0].fileName;
let position = ""; // 位置
let size = ""; // 图像大小
if (Number(x_mm) < 0 || Number(y_mm) < 0) {
position = `"${this.singleStr(
Number(x_mm).toFixed(1)
)},${this.singleStr(Number(y_mm).toFixed(1))}"`;
} else {
position = `${this.singleStr(x_mm.toFixed(1))}${this.singleStr(
y_mm.toFixed(1)
)}`;
}
size = `${this.singleStr(Number(w_mm).toFixed(1))}${this.singleStr(
Number(h_mm).toFixed(1)
)}`;
const bigNum = "0031131"; // 图像放大倍数 -R
await this.sendCmd(imgFileName, size, position, r);
},
async sendCmd(imgFileName, size, position, r) {
const whitePrint = [1, 2].includes(this.printSetting.byInk) ? 1 : 0; // 白色打印
let cmd = `GTXproCMD.exe print -X "${`Profile\\${imgFileName.replace(
".png",
""
)}.xml`}" -I "${"Input\\" +
imgFileName}" -A "Output\\${imgFileName.replace(
".png",
""
)}.arxp" -S ${size} -L ${position} -D ${r} -W ${whitePrint}`;
let print_cmd = `GTXproCMD.exe send -A "Output\\${imgFileName.replace(
".png",
""
)}.arxp" -P "${this.printer}`;
let data = {
...this.printSetting,
...{
byPlatenSize: this.byPlatenSize,
cmd,
fileName: imgFileName,
print_cmd
}
};
await this.toWritePrintLog(data);
let res = await this.$api.post("/toPrint", data);
this.$message.success(res.msg);
},
async toWritePrintLog(send_api_data) {
let head_setting = this.$dataStore.get("setting");
let position_before_px = this.$dataStore.get("position_before_px"); // 图片的位置信息 px
let position_after_px = this.$dataStore.get("position_after_px");// 图片根据单位转换后的px
let position_unit = this.$dataStore.get("position_unit"); // 图片根据单位转换后的px
let print_time = moment(new Date()).format("YYYY-MM-DD HH:mm:ss"); // 打印的时间
let production_no = this.$dataStore.get("production_no"); // 打印的单号
let print_setting = JSON.parse(JSON.stringify(this.printSetting)); // 打印的设置
let version = this.pkg.version
let data = {
head_setting,
version,
print_setting,
production_no,
print_time,
position_unit,
position_after_px,
position_before_px,
send_api_data
};
await this.$api.post("/writePrintLog", data);
},
async getPrinter() {
ipcRenderer.send("allPrint");
ipcRenderer.once("printName", (event, data) => {
console.log(data, 996); // data就是返回的打印机数据列表
this.printerList = data;
if (this.printerList.length > 0) {
this.printer = this.printerList[0].name;
}
});
},
setDetailShow() {
this.detailShow = !this.detailShow;
}
}
};
</script>
<template>
<div class="print-div">
<div :class="dialogShow ? 'open-expand' : 'close-expand'">
<slot></slot>
</div>
<div v-show="dialogShow" class="print-content">
<el-form
label-width="170px"
label-position="left"
size="mini"
:model="printSetting"
>
<el-form-item label-width="55px" label="打印机">
<div class="flex-row">
<el-select v-model="printer" clearable>
<el-option
v-for="(it, i) in printerList"
:key="i"
:label="it.name"
:value="it.name"
></el-option>
</el-select>
<el-button
title="刷新"
@click="getPrinter"
style="margin-left: 10px"
icon="el-icon-refresh"
></el-button>
</div>
</el-form-item>
<el-form-item label-width="50px" label="预设">
<div class="flex-row">
<el-select
@change="printSettingChange"
filterable
v-model="printSettingVal"
clearable
>
<el-option
v-for="(it, i) in printSettingList"
:key="i"
:value="i"
:label="it.label"
></el-option>
</el-select>
<div style="margin-left: 15px;display: flex" class="save-btn">
<el-popover
placement="bottom"
width="200"
v-model="showPopover"
trigger="manual"
>
<el-button
style="margin-right: 10px"
@click="openPopover"
slot="reference"
type="primary"
>保存预设
</el-button>
<div class="save-setting">
<el-input
size="large"
maxlength="10"
v-model="settingName"
placeholder="预设名称:"
></el-input>
<div class="save-footer">
<el-button size="medium" @click="showPopover = false"
>取消
</el-button>
<el-button
@click="saveSetting"
:disabled="settingName === ''"
size="medium"
type="primary"
>保存
</el-button>
</div>
</div>
</el-popover>
<el-button
:disabled="printSettingVal === 0"
@click="delSetting"
type="danger"
>删除
</el-button>
</div>
</div>
</el-form-item>
<div class="detail-setting">
<div class="setting-left">
<div class="left-block-item">
<b class="setting-title">基本设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byInk'] || ''"></div>
</template>
<el-form-item label="油墨选择">
<el-select v-model="printSetting.byInk" clearable>
<el-option
:label="it.label"
:value="i"
:key="i"
v-for="(it, i) in printInkList"
></el-option>
</el-select>
</el-form-item>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bEcoMode'] || ''"></div>
</template>
<el-form-item v-if="printSetting.byInk === 2" label="模式">
<el-select v-model="printSetting.bEcoMode" clearable>
<el-option label="通常" :value="false"></el-option>
<el-option label="白色油墨削减" :value="true"></el-option>
</el-select>
</el-form-item>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bMaterialBlack'] || ''"></div>
</template>
<div v-if="printSetting.byInk === 2">
<el-form-item label="利用底材的黑色">
<el-switch
v-model="printSetting.bMaterialBlack"
></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bMultiple'] || ''"></div>
</template>
<div v-if="printSetting.byInk !== 1">
<el-form-item label="彩色的复合路径打印">
<el-switch v-model="printSetting.bMultiple"></el-switch>
</el-form-item>
</div>
</el-tooltip>
</div>
<div
class="left-block-item"
v-if="[0, 3].includes(printSetting.byInk)"
>
<b class="setting-title">彩色油墨设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byInkVolume'] || ''"></div>
</template>
<div>
<el-form-item label="油墨量">
<div class="flex-row">
<el-slider
:step="1"
:min="1"
:max="10"
v-model="printSetting.byInkVolume"
></el-slider>
<span>{{ printSetting.byInkVolume }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byDoublePrint'] || ''"></div>
</template>
<div>
<el-form-item label="2次打印">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="3"
v-model="printSetting.byDoublePrint"
></el-slider>
<span>{{ printSetting.byDoublePrint }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
</div>
<div
class="left-block-item"
v-if="[1, 2].includes(printSetting.byInk)"
>
<b class="setting-title">白色油墨设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byHighlight'] || ''"></div>
</template>
<div>
<el-form-item label="高光">
<div class="flex-row">
<el-slider
:step="1"
:min="1"
:max="9"
v-model="printSetting.byHighlight"
></el-slider>
<span>{{ printSetting.byHighlight }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byMask'] || ''"></div>
</template>
<div>
<el-form-item label="遮光">
<div class="flex-row">
<el-slider
:step="1"
:min="1"
:max="5"
v-model="printSetting.byMask"
></el-slider>
<span>{{ printSetting.byMask }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bFastMode'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="白色高速打印">
<el-switch v-model="printSetting.bFastMode"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bDivide'] || ''"></div>
</template>
<div>
<el-form-item label="白色分次打印">
<el-switch v-model="printSetting.bDivide"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bPause'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="白色/彩色个别打印">
<el-switch v-model="printSetting.bPause"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bTransColor'] || ''"></div>
</template>
<div>
<el-form-item label="透明色">
<el-switch v-model="printSetting.bTransColor"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byChoke'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="白色油墨的削减范围">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="10"
v-model="printSetting.byChoke"
></el-slider>
<span>{{ printSetting.byChoke }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byMinWhite'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="最小白色油墨量">
<div class="flex-column">
<el-select v-model="printSetting.minWhiteInkType">
<el-option label="通常" :value="0"></el-option>
<el-option label="特殊" :value="1"></el-option>
</el-select>
<div class="slider flex-row">
<el-slider
:step="1"
:min="1"
:max="printSetting.minWhiteInkType === 1 ? 6 : 3"
v-model="printSetting.byMinWhite"
></el-slider>
<span>{{ printSetting.byMinWhite }}</span>
</div>
</div>
</el-form-item>
</div>
</el-tooltip>
</div>
<div v-show="detailShow" class="left-block-item">
<b class="setting-title">画质设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bySaturation'] || ''"></div>
</template>
<div>
<el-form-item label="饱和度">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="40"
v-model="printSetting.bySaturation"
></el-slider>
<span>{{ printSetting.bySaturation }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byBrightness'] || ''"></div>
</template>
<div>
<el-form-item label="亮度">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="40"
v-model="printSetting.byBrightness"
></el-slider>
<span>{{ printSetting.byBrightness }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byContrast'] || ''"></div>
</template>
<div>
<el-form-item label="对比度">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="40"
v-model="printSetting.byContrast"
></el-slider>
<span>{{ printSetting.byContrast }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bUniPrint'] || ''"></div>
</template>
<div v-if="[1].includes(printSetting.byInk)">
<el-form-item label="单向打印">
<el-switch v-model="printSetting.bUniPrint"></el-switch>
</el-form-item>
</div>
</el-tooltip>
</div>
<div
v-if="detailShow && ![1].includes(printSetting.byInk)"
class="left-block-item"
>
<b class="setting-title">彩色平衡</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iCyanBalance'] || ''"></div>
</template>
<div v-if="![3].includes(printSetting.byInk)">
<el-form-item label="青色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iCyanBalance"
></el-slider>
<span>{{ printSetting.iCyanBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iMagentaBalance'] || ''"></div>
</template>
<div v-if="![3].includes(printSetting.byInk)">
<el-form-item label="红色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iMagentaBalance"
></el-slider>
<span>{{ printSetting.iMagentaBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iYellowBalance'] || ''"></div>
</template>
<div v-if="![3].includes(printSetting.byInk)">
<el-form-item label="黄色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iYellowBalance"
></el-slider>
<span>{{ printSetting.iYellowBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iBlackBalance'] || ''"></div>
</template>
<div>
<el-form-item label="黑色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iBlackBalance"
></el-slider>
<span>{{ printSetting.iBlackBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bUniPrint'] || ''"></div>
</template>
<div>
<el-form-item label="单向打印">
<el-switch v-model="printSetting.bUniPrint"></el-switch>
</el-form-item>
</div>
</el-tooltip>
</div>
<el-button size="small" @click="setDetailShow"
>{{ detailShow ? "关闭详细设置" : "打开详细设置" }}...
</el-button>
</div>
</div>
</el-form>
<div class="bottom-info flex-row">
<div class="info">
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['printTime'] || ''"></div>
</template>
<div class="info-item">
<span>打印时间</span>
<b>×{{ defaultTime }}</b>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['whiteInk'] || ''"></div>
</template>
<div class="info-item">
<span>白色油墨量</span>
<b>{{ inkNum }}%</b>
</div>
</el-tooltip>
</div>
<div class="btn">
<el-input
size="small"
style="width: 100px;"
oninput="value=value.replace(/[^\-?\d]/g,'')"
v-model="printSetting.printNum"
></el-input>
<span></span>
</div>
</div>
<el-button
@click="getPrintCmd"
type="primary"
style="width: 100%;height: 50px"
>打印
</el-button>
</div>
</div>
</template>
<style lang="less" scoped>
.flex-row {
display: flex;
align-items: center;
display: flex;
align-items: center;
span {
margin-left: 10px;
}
.el-slider {
flex: 1;
flex-shrink: 0;
margin: 0 10px;
}
}
.el-form {
height: 84%;
display: flex;
flex-direction: column;
padding-top: 15px;
border-top: 1px solid #ececec;
}
.detail-setting {
border-top: 2px solid transparent;
display: flex;
background-color: #ececec;
align-items: flex-start;
flex: 1;
flex-shrink: 0;
overflow: auto;
}
.left-block-item {
.setting-title {
font-weight: bold;
font-size: 20px;
color: #409eff;
position: relative;
margin-bottom: 30px;
margin-top: 30px;
display: inline-block;
left: -15px;
}
}
.setting-right {
box-sizing: border-box;
padding: 20px;
width: 50%;
height: 100%;
color: #333;
}
.setting-left {
width: 100%;
box-sizing: border-box;
padding: 15px 30px;
background-color: white;
}
.fixed-top {
position: absolute;
word-break: break-all;
max-width: 44%;
}
.bottom-info {
padding: 15px 0;
margin-top: 20px;
font-size: 14px;
justify-content: space-between;
border-top: 1px solid #ececec;
}
.info {
width: 62%;
display: flex;
justify-content: space-between;
}
.info-item {
span {
margin-right: 5px;
}
}
.save-setting {
display: flex;
flex-direction: column;
}
.save-footer {
display: flex;
justify-content: space-between;
margin-top: 15px;
}
.print-div {
position: fixed;
box-sizing: border-box;
right: 0;
z-index: 4;
bottom: 0;
height: calc(100% - 51px);
.print-content {
background: #ececec;
border-left: 1px solid gray;
height: 100%;
padding: 10px;
display: flex;
width: 430px;
flex-direction: column;
}
}
.close-expand {
position: fixed;
right: 0;
cursor: pointer;
top: 50%;
width: 20px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
height: 40px;
display: flex;
align-items: center;
background-color: blueviolet;
color: white;
justify-content: center;
i {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
.open-expand {
position: absolute;
left: -20px;
cursor: pointer;
top: 50%;
width: 20px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
height: 40px;
display: flex;
align-items: center;
background-color: blueviolet;
color: white;
justify-content: center;
i {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
<style>
.my-popper {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>
<script>
import fieldDescription from "./fieldDescription";
import { ipcRenderer } from "electron";
import axios from "axios";
import html2canvas from "html2canvas";
import moment from "moment";
import pkg from "../../../../package.json";
export default {
data() {
return {
dialogShow: true,
pkg,
axios,
fieldDescription,
printerList: [],
printSettingList: [],
printSettingVal: 0,
description: "",
printSettingSelectLabel: "default",
printer: "",
settingName: "",
printInkList: [
{
label: "仅彩色油墨"
},
{
label: "仅白色油墨"
},
{
label: "彩色 + 白色油墨"
},
{
label: "仅黑色油墨"
}
],
detailShow: false,
showPopover: false,
printSetting: {
printer: "",
xy: "",
byInk: 2,
byInkVolume: 1,
byDoublePrint: 3,
bEcoMode: false,
bMaterialBlack: false,
byHighlight: 5,
printNum: 1,
bFastMode: false,
bUniPrint: false,
bDivide: false,
bPause: false,
byMask: 3,
bTransColor: false,
byChoke: 2,
minWhiteInkType: 0,
bySaturation: 5,
byBrightness: 5,
byContrast: 5,
iCyanBalance: 0,
iMagentaBalance: 0,
iBlackBalance: 0,
iYellowBalance: 0,
byMinWhite: 1,
bMultiple: false
}
};
},
props: {
visible: {
default: false,
type: Boolean
},
byPlatenSize: {
default: 0,
type: Number
},
imgList: {
default: () => [],
type: Array
}
},
mounted() {
this.$dataStore.set("default-print-setting", this.printSetting);
this.getPrintSettingList(() => {
let select = this.$dataStore.get("print-setting-select");
console.log(this.$dataStore, "select");
if (select) {
this.printSettingSelectLabel = select;
let index = this.printSettingList.findIndex(el => el.label === select);
if (index >= 0) {
this.printSettingVal = index;
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[index].value)
);
} else {
this.printSettingVal = 0;
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[0].value)
);
}
} else {
this.printSettingVal = 0;
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[0].value)
);
}
});
},
computed: {
inkNum() {
return 200 + Number(this.printSetting.byHighlight) * 50 - 50;
},
defaultTime() {
if ([6, 7].includes(Number(this.printSetting.byHighlight))) {
return "1.25";
} else if (this.printSetting.byHighlight < 6) {
return "1.00";
} else {
return "1.5";
}
}
},
watch: {
printSetting: {
handler() {
this.$dataStore.set("print-setting", this.printSetting);
},
deep: true,
immediate: true
},
visible() {
this.dialogShow = this.visible;
}
},
created() {
this.getPrinter();
},
methods: {
delSetting() {
this.$confirm(`确定删除该预设?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$dataStore.delete(
this.printSettingList[this.printSettingVal].label + "-print-setting"
);
this.getPrintSettingList();
this.printSettingVal = 0;
});
},
getPrintSettingList(callback) {
let arr = [];
for (let k in this.$dataStore.store) {
if (k.includes("-print-setting")) {
arr.push({
label: k.replace("-print-setting", ""),
value: this.$dataStore.get(k)
});
}
}
this.printSettingList = arr;
callback && callback();
},
printSettingChange(v) {
let label = this.printSettingList[v].label;
this.$dataStore.set("print-setting-select", label);
this.printSetting = JSON.parse(
JSON.stringify(this.printSettingList[v].value)
);
},
saveSetting() {
if (this.settingName.trim() === "") {
return this.$message.warning("预设名称不能为空");
}
if (this.printSettingList.find(el => el.label === this.settingName)) {
return this.$message.warning("预设名称不能重复");
}
this.$dataStore.set(
`${this.settingName}-print-setting`,
this.printSetting
);
this.showPopover = false;
this.printSettingVal = this.printSettingList.length;
this.getPrintSettingList();
},
openPopover() {
this.showPopover = true;
this.settingName = "";
},
singleStr(str) {
if (Number(str) >= 0) {
str = str.toString().replace(".", "");
if (str.length >= 4) {
str = str.slice(0, 5);
} else if (str.length === 3) {
str = "0" + str;
} else if (str.length === 2) {
str = "00" + str;
} else if (str.length === 1) {
str = "000" + str;
}
} else {
str = str
.toString()
.replace(".", "")
.replace("-", "");
if (str.length >= 4) {
str = str.slice(0, 5);
} else if (str.length === 3) {
str = "0" + str;
} else if (str.length === 2) {
str = "00" + str;
} else if (str.length === 1) {
str = "000" + str;
}
str = "-" + str;
}
// 不足四位前面用0补齐
console.log(str);
return str;
},
dataURLtoBlob(dataurl) {
var arr = dataurl.split(",");
//注意base64的最后面中括号和引号是不转译的
var _arr = arr[1].substring(0, arr[1].length - 2);
var mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(_arr),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime
});
},
moreImageCmd(arr) {
var canvas1 = document.createElement("canvas");
let _canvas = document.getElementsByClassName("sucaitu")[0]; //目标块
var bodyW = parseInt(window.getComputedStyle(_canvas).width);
var bodyH = parseInt(window.getComputedStyle(_canvas).height);
canvas1.width = bodyW;
canvas1.height = bodyH;
canvas1.style.width = bodyW + "px";
canvas1.style.height = bodyH + "px";
canvas1.style.background = "transparent";
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
var context = canvas1.getContext("2d");
// context.scale(2, 2);
let that = this;
html2canvas(_canvas, {
canvas: canvas1,
backgroundColor: null,
useCORS: true,
allowTaint: true
}).then(async function(canvas) {
let dataURL = canvas.toDataURL("image/png");
let pageBlob = that.dataURLtoBlob(dataURL);
let params = new FormData();
let fileOfBlob = new File([pageBlob], new Date().getTime() + ".jpg");
params.append("file", fileOfBlob);
let { data } = await that.$api.post("/uploadImage", params, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
let w_mm = Number((canvas1.width * 0.84183).toFixed(1));
let h_mm = Number((canvas1.height * 0.84183).toFixed(1));
let size = `${that.singleStr(Number(w_mm).toFixed(1))}${that.singleStr(
Number(h_mm).toFixed(1)
)}`;
await that.sendCmd(data.fileName, size, "00000000", 0);
//canvas转换成url,然后利用a标签的download属性,直接下载,绕过上传服务器再下载
// document.querySelector(".down").setAttribute('href', canvas.toDataURL());
});
},
async getPrintCmd() {
if (this.imgList.length === 0)
return this.$message.warning("素材不能为空");
if (this.imgList.length > 1) {
let dom = document.getElementsByClassName("drr");
for (let i = 0; i < dom.length; i++) {
dom[i].classList.remove("active");
dom[i].classList.add("inactive");
}
setTimeout(() => {
this.moreImageCmd(this.imgList);
}, 500);
return;
}
let { x, y, r, w, h } = this.imgList[0];
y = Number(y) - Number(h) / 2;
x = Number(x) - Number(w) / 2;
let x_mm = Number((x * 0.84183).toFixed(1));
let w_mm = Number((w * 0.84183).toFixed(1));
let h_mm = Number((h * 0.84183).toFixed(1));
let y_mm = Number((y * 0.84183).toFixed(1));
console.log(x_mm, y_mm);
r = Number(r).toFixed(0);
const imgFileName = this.imgList[0].fileName;
let position = ""; // 位置
let size = ""; // 图像大小
if (Number(x_mm) < 0 || Number(y_mm) < 0) {
position = `"${this.singleStr(
Number(x_mm).toFixed(1)
)},${this.singleStr(Number(y_mm).toFixed(1))}"`;
} else {
position = `${this.singleStr(x_mm.toFixed(1))}${this.singleStr(
y_mm.toFixed(1)
)}`;
}
size = `${this.singleStr(Number(w_mm).toFixed(1))}${this.singleStr(
Number(h_mm).toFixed(1)
)}`;
const bigNum = "0031131"; // 图像放大倍数 -R
await this.sendCmd(imgFileName, size, position, r);
},
async sendCmd(imgFileName, size, position, r) {
const whitePrint = [1, 2].includes(this.printSetting.byInk) ? 1 : 0; // 白色打印
let cmd = `GTXproCMD.exe print -X "${`Profile\\${imgFileName.replace(
".png",
""
)}.xml`}" -I "${"Input\\" +
imgFileName}" -A "Output\\${imgFileName.replace(
".png",
""
)}.arxp" -S ${size} -L ${position} -D ${r} -W ${whitePrint}`;
let print_cmd = `GTXproCMD.exe send -A "Output\\${imgFileName.replace(
".png",
""
)}.arxp" -P "${this.printer}`;
let data = {
...this.printSetting,
...{
byPlatenSize: this.byPlatenSize,
cmd,
fileName: imgFileName,
print_cmd
}
};
await this.toWritePrintLog(data);
let res = await this.$api.post("/toPrint", data);
this.$message.success(res.msg);
},
async toWritePrintLog(send_api_data) {
let head_setting = this.$dataStore.get("setting");
let position_before_px = this.$dataStore.get("position_before_px"); // 图片的位置信息 px
let position_after_px = this.$dataStore.get("position_after_px");// 图片根据单位转换后的px
let position_unit = this.$dataStore.get("position_unit"); // 图片根据单位转换后的px
let print_time = moment(new Date()).format("YYYY-MM-DD HH:mm:ss"); // 打印的时间
let production_no = this.$dataStore.get("production_no"); // 打印的单号
let print_setting = JSON.parse(JSON.stringify(this.printSetting)); // 打印的设置
let version = this.pkg.version
let data = {
head_setting,
version,
print_setting,
production_no,
print_time,
position_unit,
position_after_px,
position_before_px,
send_api_data
};
await this.$api.post("/writePrintLog", data);
},
async getPrinter() {
ipcRenderer.send("allPrint");
ipcRenderer.once("printName", (event, data) => {
console.log(data, 996); // data就是返回的打印机数据列表
this.printerList = data;
if (this.printerList.length > 0) {
this.printer = this.printerList[0].name;
}
});
},
setDetailShow() {
this.detailShow = !this.detailShow;
}
}
};
</script>
<template>
<div class="print-div">
<div :class="dialogShow ? 'open-expand' : 'close-expand'">
<slot></slot>
</div>
<div v-show="dialogShow" class="print-content">
<el-form
label-width="170px"
label-position="left"
size="mini"
:model="printSetting"
>
<el-form-item label-width="55px" label="打印机">
<div class="flex-row">
<el-select v-model="printer" clearable>
<el-option
v-for="(it, i) in printerList"
:key="i"
:label="it.name"
:value="it.name"
></el-option>
</el-select>
<el-button
title="刷新"
@click="getPrinter"
style="margin-left: 10px"
icon="el-icon-refresh"
></el-button>
</div>
</el-form-item>
<el-form-item label-width="50px" label="预设">
<div class="flex-row">
<el-select
@change="printSettingChange"
filterable
v-model="printSettingVal"
clearable
>
<el-option
v-for="(it, i) in printSettingList"
:key="i"
:value="i"
:label="it.label"
></el-option>
</el-select>
<div style="margin-left: 15px;display: flex" class="save-btn">
<el-popover
placement="bottom"
width="200"
v-model="showPopover"
trigger="manual"
>
<el-button
style="margin-right: 10px"
@click="openPopover"
slot="reference"
type="primary"
>保存预设
</el-button>
<div class="save-setting">
<el-input
size="large"
maxlength="10"
v-model="settingName"
placeholder="预设名称:"
></el-input>
<div class="save-footer">
<el-button size="medium" @click="showPopover = false"
>取消
</el-button>
<el-button
@click="saveSetting"
:disabled="settingName === ''"
size="medium"
type="primary"
>保存
</el-button>
</div>
</div>
</el-popover>
<el-button
:disabled="printSettingVal === 0"
@click="delSetting"
type="danger"
>删除
</el-button>
</div>
</div>
</el-form-item>
<div class="detail-setting">
<div class="setting-left">
<div class="left-block-item">
<b class="setting-title">基本设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byInk'] || ''"></div>
</template>
<el-form-item label="油墨选择">
<el-select v-model="printSetting.byInk" clearable>
<el-option
:label="it.label"
:value="i"
:key="i"
v-for="(it, i) in printInkList"
></el-option>
</el-select>
</el-form-item>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bEcoMode'] || ''"></div>
</template>
<el-form-item v-if="printSetting.byInk === 2" label="模式">
<el-select v-model="printSetting.bEcoMode" clearable>
<el-option label="通常" :value="false"></el-option>
<el-option label="白色油墨削减" :value="true"></el-option>
</el-select>
</el-form-item>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bMaterialBlack'] || ''"></div>
</template>
<div v-if="printSetting.byInk === 2">
<el-form-item label="利用底材的黑色">
<el-switch
v-model="printSetting.bMaterialBlack"
></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bMultiple'] || ''"></div>
</template>
<div v-if="printSetting.byInk !== 1">
<el-form-item label="彩色的复合路径打印">
<el-switch v-model="printSetting.bMultiple"></el-switch>
</el-form-item>
</div>
</el-tooltip>
</div>
<div
class="left-block-item"
v-if="[0, 3].includes(printSetting.byInk)"
>
<b class="setting-title">彩色油墨设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byInkVolume'] || ''"></div>
</template>
<div>
<el-form-item label="油墨量">
<div class="flex-row">
<el-slider
:step="1"
:min="1"
:max="10"
v-model="printSetting.byInkVolume"
></el-slider>
<span>{{ printSetting.byInkVolume }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byDoublePrint'] || ''"></div>
</template>
<div>
<el-form-item label="2次打印">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="3"
v-model="printSetting.byDoublePrint"
></el-slider>
<span>{{ printSetting.byDoublePrint }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
</div>
<div
class="left-block-item"
v-if="[1, 2].includes(printSetting.byInk)"
>
<b class="setting-title">白色油墨设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byHighlight'] || ''"></div>
</template>
<div>
<el-form-item label="高光">
<div class="flex-row">
<el-slider
:step="1"
:min="1"
:max="9"
v-model="printSetting.byHighlight"
></el-slider>
<span>{{ printSetting.byHighlight }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byMask'] || ''"></div>
</template>
<div>
<el-form-item label="遮光">
<div class="flex-row">
<el-slider
:step="1"
:min="1"
:max="5"
v-model="printSetting.byMask"
></el-slider>
<span>{{ printSetting.byMask }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bFastMode'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="白色高速打印">
<el-switch v-model="printSetting.bFastMode"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bDivide'] || ''"></div>
</template>
<div>
<el-form-item label="白色分次打印">
<el-switch v-model="printSetting.bDivide"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bPause'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="白色/彩色个别打印">
<el-switch v-model="printSetting.bPause"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bTransColor'] || ''"></div>
</template>
<div>
<el-form-item label="透明色">
<el-switch v-model="printSetting.bTransColor"></el-switch>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byChoke'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="白色油墨的削减范围">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="10"
v-model="printSetting.byChoke"
></el-slider>
<span>{{ printSetting.byChoke }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byMinWhite'] || ''"></div>
</template>
<div v-if="[2].includes(printSetting.byInk)">
<el-form-item label="最小白色油墨量">
<div class="flex-column">
<el-select v-model="printSetting.minWhiteInkType">
<el-option label="通常" :value="0"></el-option>
<el-option label="特殊" :value="1"></el-option>
</el-select>
<div class="slider flex-row">
<el-slider
:step="1"
:min="1"
:max="printSetting.minWhiteInkType === 1 ? 6 : 3"
v-model="printSetting.byMinWhite"
></el-slider>
<span>{{ printSetting.byMinWhite }}</span>
</div>
</div>
</el-form-item>
</div>
</el-tooltip>
</div>
<div v-show="detailShow" class="left-block-item">
<b class="setting-title">画质设置</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bySaturation'] || ''"></div>
</template>
<div>
<el-form-item label="饱和度">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="40"
v-model="printSetting.bySaturation"
></el-slider>
<span>{{ printSetting.bySaturation }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byBrightness'] || ''"></div>
</template>
<div>
<el-form-item label="亮度">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="40"
v-model="printSetting.byBrightness"
></el-slider>
<span>{{ printSetting.byBrightness }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['byContrast'] || ''"></div>
</template>
<div>
<el-form-item label="对比度">
<div class="flex-row">
<el-slider
:step="1"
:min="0"
:max="40"
v-model="printSetting.byContrast"
></el-slider>
<span>{{ printSetting.byContrast }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bUniPrint'] || ''"></div>
</template>
<div v-if="[1].includes(printSetting.byInk)">
<el-form-item label="单向打印">
<el-switch v-model="printSetting.bUniPrint"></el-switch>
</el-form-item>
</div>
</el-tooltip>
</div>
<div
v-if="detailShow && ![1].includes(printSetting.byInk)"
class="left-block-item"
>
<b class="setting-title">彩色平衡</b>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iCyanBalance'] || ''"></div>
</template>
<div v-if="![3].includes(printSetting.byInk)">
<el-form-item label="青色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iCyanBalance"
></el-slider>
<span>{{ printSetting.iCyanBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iMagentaBalance'] || ''"></div>
</template>
<div v-if="![3].includes(printSetting.byInk)">
<el-form-item label="红色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iMagentaBalance"
></el-slider>
<span>{{ printSetting.iMagentaBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iYellowBalance'] || ''"></div>
</template>
<div v-if="![3].includes(printSetting.byInk)">
<el-form-item label="黄色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iYellowBalance"
></el-slider>
<span>{{ printSetting.iYellowBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['iBlackBalance'] || ''"></div>
</template>
<div>
<el-form-item label="黑色">
<div class="flex-row">
<el-slider
:step="1"
:min="-5"
:max="5"
v-model="printSetting.iBlackBalance"
></el-slider>
<span>{{ printSetting.iBlackBalance }}</span>
</div>
</el-form-item>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['bUniPrint'] || ''"></div>
</template>
<div>
<el-form-item label="单向打印">
<el-switch v-model="printSetting.bUniPrint"></el-switch>
</el-form-item>
</div>
</el-tooltip>
</div>
<el-button size="small" @click="setDetailShow"
>{{ detailShow ? "关闭详细设置" : "打开详细设置" }}...
</el-button>
</div>
</div>
</el-form>
<div class="bottom-info flex-row">
<div class="info">
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['printTime'] || ''"></div>
</template>
<div class="info-item">
<span>打印时间</span>
<b>×{{ defaultTime }}</b>
</div>
</el-tooltip>
<el-tooltip placement="left" popper-class="my-popper">
<template slot="content">
<div v-html="fieldDescription['whiteInk'] || ''"></div>
</template>
<div class="info-item">
<span>白色油墨量</span>
<b>{{ inkNum }}%</b>
</div>
</el-tooltip>
</div>
<div class="btn">
<el-input
size="small"
style="width: 100px;"
oninput="value=value.replace(/[^\-?\d]/g,'')"
v-model="printSetting.printNum"
></el-input>
<span></span>
</div>
</div>
<el-button
@click="getPrintCmd"
type="primary"
style="width: 98%;height: 50px"
>打印
</el-button>
</div>
</div>
</template>
<style lang="less" scoped>
.flex-row {
display: flex;
align-items: center;
display: flex;
align-items: center;
span {
margin-left: 10px;
}
.el-slider {
flex: 1;
flex-shrink: 0;
margin: 0 10px;
}
}
.el-form {
height: 87%;
display: flex;
flex-direction: column;
padding-top: 0;
border-top: 1px solid #ececec;
}
.detail-setting {
border-top: 2px solid transparent;
display: flex;
background-color: #ececec;
align-items: flex-start;
flex: 1;
flex-shrink: 0;
overflow: auto;
}
.left-block-item {
.setting-title {
font-weight: bold;
font-size: 20px;
color: #409eff;
position: relative;
margin :15px 0;
display: inline-block;
left: -15px;
}
}
.setting-right {
box-sizing: border-box;
padding: 20px;
width: 50%;
height: 100%;
color: #333;
}
.setting-left {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 15px 30px;
background-color: white;
}
.fixed-top {
position: absolute;
word-break: break-all;
max-width: 44%;
}
.bottom-info {
padding: 5px 0;
margin-top: 10px;
font-size: 14px;
justify-content: space-between;
border-top: 1px solid #ececec;
}
.info {
width: 62%;
display: flex;
justify-content: space-between;
}
.info-item {
span {
margin-right: 5px;
}
}
.save-setting {
display: flex;
flex-direction: column;
}
.save-footer {
display: flex;
justify-content: space-between;
margin-top: 15px;
}
.print-div {
position: fixed;
box-sizing: border-box;
right: 0;
z-index: 4;
bottom: 0;
height: calc(100% - 51px);
.print-content {
background: #ececec;
border-left: 1px solid gray;
height: 100%;
padding: 10px;
display: flex;
width: 430px;
flex-direction: column;
}
}
.close-expand {
position: fixed;
right: 0;
cursor: pointer;
top: 50%;
width: 20px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
height: 40px;
display: flex;
align-items: center;
background-color: blueviolet;
color: white;
justify-content: center;
i {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
.open-expand {
position: absolute;
left: -20px;
cursor: pointer;
top: 50%;
width: 20px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
height: 40px;
display: flex;
align-items: center;
background-color: blueviolet;
color: white;
justify-content: center;
i {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
::v-deep .el-form-item{
margin-bottom: 9px;
}
</style>
<style>
.my-popper {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>
<script>
import PHead from "./head/index.vue";
import PMain from "./main/index.vue";
import UpdateDialog from "@/views/design/updateDialog.vue";
export default {
components: { PHead, PMain, UpdateDialog },
data() {
return {
user: {},
company: {}
};
},
mounted() {
this.user = this.$dataStore.get("user");
this.company = this.$dataStore.get("company");
this.$refs.updateDialog.checkUpdate().then(data => {
if (data) {
// 有新版本更新
this.$refs.updateDialog.open(data);
}
});
}
};
</script>
<template>
<div class="page">
<p-head :company="company" :user="user" />
<p-main />
<update-dialog ref="updateDialog" />
</div>
</template>
<style scoped>
.page {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
</style>
\ No newline at end of file
<script>
import PHead from "./head/index.vue";
import PMain from "./main/index.vue";
import UpdateDialog from "@/views/design/updateDialog.vue";
export default {
components: { PHead, PMain, UpdateDialog },
data() {
return {
user: {},
};
},
mounted() {
this.user = this.$dataStore.get("user");
this.$refs.updateDialog.checkUpdate().then(data => {
if (data) {
// 有新版本更新
this.$refs.updateDialog.open(data);
}
});
}
};
</script>
<template>
<div class="page">
<p-head :user="user" />
<p-main />
<update-dialog ref="updateDialog" />
</div>
</template>
<style scoped>
.page {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
</style>
<script>
export default {
data() {
return {
drawerShow: false,
form: {
x: 0,
rate: 0,
sx: 0,
zIndex: 0,
sh: 0,
sw: 0,
sy: 0,
y: 0,
w: 0,
h: 0,
r: 0
}
};
},
props: {
visible: {
type: Boolean,
default: false
},
item: {
type: Object,
default: () => {
}
}
},
watch: {
visible: {
handler() {
this.drawerShow = this.visible;
},
immediate: true
},
item: {
handler() {
if (this.item) {
let setting = this.$dataStore.get("setting");
this.item.y = (this.item.y - this.item.h / 2);
this.item.x = (this.item.x - this.item.w / 2);
this.$dataStore.set("position_before_px", JSON.parse(JSON.stringify(this.item)));
console.log(
"setting",
setting
)
let x_mm, w_mm, h_mm, y_mm;
if (setting.unit === "mm") {
x_mm = Number((this.item.x * 0.84183).toFixed(2));
w_mm = Number((this.item.w * 0.84183).toFixed(2));
h_mm = Number((this.item.h * 0.84183).toFixed(2));
y_mm = Number((this.item.y * 0.84183).toFixed(2));
} else if (setting.unit === "inch") {
x_mm = Number((this.item.x * 0.84183) / 25.4).toFixed(2);
w_mm = Number((this.item.w * 0.84183) / 25.4).toFixed(2);
h_mm = Number((this.item.h * 0.84183) / 25.4).toFixed(2);
y_mm = Number((this.item.y * 0.84183) / 25.4).toFixed(2);
}
// return
this.form.x = x_mm;
this.form.rate = this.item.rate;
this.form.y = y_mm;
this.form.w = w_mm;
this.form.h = h_mm;
this.form.zIndex = this.item.zIndex;
this.form.r = this.item.r;
this.$dataStore.set(`position_after_px`, JSON.parse(JSON.stringify(this.form)));
}
},
immediate: true,
deep: true
}
},
methods: {
formChange(t) {
if (t && t === "w") {
this.form.h = this.form.w * this.form.rate;
}
if (t && t === "h") {
this.form.w = this.form.h * this.form.rate;
}
let f = JSON.parse(JSON.stringify(this.form));
f.y = (Number(f.y) + Number(f.h) / 2);
f.x = (Number(f.x) + Number(f.w) / 2);
let setting = this.$dataStore.get("setting");
if (setting.unit === "mm") {
f.x = Number((f.x / 0.84183).toFixed(2));
f.y = Number((f.y / 0.84183).toFixed(2));
f.w = Number((f.w / 0.84183).toFixed(2));
f.h = Number((f.h / 0.84183).toFixed(2));
} else if (setting.unit === "inch") {
f.x = (Number((f.x / 0.84183) * 25.4).toFixed(2));
f.y = (Number((f.y / 0.84183) * 25.4).toFixed(2));
f.w = (Number((f.w / 0.84183) * 25.4).toFixed(2));
f.h = (Number((f.h / 0.84183) * 25.4).toFixed(2));
}
f.zIndex = Number((f.zIndex));
for (let k in f) {
f[k] = Number(f[k]);
}
this.$emit("change", f);
this.$dataStore.set("position_unit", JSON.parse(JSON.stringify(f)));
},
addValue(f) {
if (!this.form[f]) this.$set(this.form, f, 0);
let nw = Number(this.form[f]) + 1;
this.$set(this.form, f, nw);
if (f && f === "w") {
this.form.h = this.form.w * this.form.rate;
}
if (f && f === "h") {
this.form.w = this.form.h * this.form.rate;
}
this.formChange();
},
reduceValue(f) {
if (!this.form[f]) this.$set(this.form, f, 0);
let nw = Number(this.form[f]) - 1;
this.$set(this.form, f, nw);
if (f && f === "w") {
this.form.h = this.form.w * this.form.rate;
}
if (f && f === "h") {
this.form.w = this.form.h * this.form.rate;
}
this.formChange();
}
}
};
</script>
<template>
<div class="drawer" :style="{animation:`ltr-drawer-in .3s 1ms`}" v-show="visible">
<div class="title">
图片编辑
</div>
<div class="img-form">
<el-form size="small" style="" :model="form" label-position="left" label-width="30px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="x:" prop="x">
<div class="form-content">
<el-input @blur="formChange" v-model="form.x"></el-input>
<div class="set-value">
<i @click="addValue('x')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('x')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="y:">
<div class="form-content">
<el-input @blur="formChange" v-model="form.y"></el-input>
<div class="set-value">
<i @click="addValue('y')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('y')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="w:">
<div class="form-content">
<el-input @blur="formChange('w')" v-model="form.w"></el-input>
<div class="set-value">
<i @click="addValue('w')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('w')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="h:">
<div class="form-content">
<el-input @blur="formChange('h')" v-model="form.h"></el-input>
<div class="set-value">
<i @click="addValue('h')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('h')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="r:">
<div class="form-content">
<el-input maxlength="3" @blur="formChange" v-model="form.r">
</el-input>
<div class="set-value">
<i @click="addValue('r')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('r')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="z:">
<div class="form-content">
<el-input @blur="formChange" v-model="form.zIndex">
</el-input>
<div class="set-value">
<i @click="addValue('zIndex')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('zIndex')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-tooltip content="居中">
<el-button @click="$emit('ev','center')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/juzhong-01.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="垂直居中">
<el-button @click="$emit('ev','y_center')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/vertical.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="水平居中">
<el-button @click="$emit('ev','x_center')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/shuipingjuzhong.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="上移一层">
<el-button @click="$emit('ev','add_index')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/shangyi.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="下移一层">
<el-button @click="$emit('ev','reduce_index')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/xiayi.png" alt="">
</el-button>
</el-tooltip>
</el-col>
</el-row>
</el-form>
</div>
</div>
</template>
<style lang="less" scoped>
.img-form {
padding: 10px;
}
::v-deep {
.el-drawer__header {
border-bottom: 1px solid #ececec;
padding-bottom: 10px;
margin-bottom: 20px;
}
}
.form-content {
display: flex;
align-items: center;
}
.set-value {
height: 100%;
margin-left: 6px;
i {
width: 20px;
height: 12px;
display: block;
text-align: center;
line-height: 12px;
cursor: pointer;
border: 1px solid transparent;
&:hover {
border-color: #ececec;
}
}
}
.drawer {
width: 300px;
bottom: 0;
top: 50px;
padding: 10px;
z-index: 99;
background: white;
box-shadow: 0 8px 10px -5px rgba(0, 0, 0, .2), 0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12);
left: 0;
position: fixed;
border-right: 1px solid #ececec;
height: calc(100vh - 50px);
//animation: ltr-drawer-in .3s 1ms;
.title {
padding-bottom: 10px;
border-bottom: 1px solid #ececec;
}
}
@keyframes ltr-drawer-in {
0% {
transform: translate(-100%);
}
100% {
transform: translate(0);
}
}
@keyframes ltr-drawer-in {
0% {
transform: translate(-100%);
}
100% {
transform: translate(0);
}
}
@keyframes ltr-drawer-out {
0% {
transform: translate(0);
}
100% {
transform: translate(-100%);
}
}
</style>
\ No newline at end of file
<script>
export default {
data() {
return {
drawerShow: false,
form: {
x: 0,
rate: 0,
sx: 0,
zIndex: 0,
sh: 0,
sw: 0,
sy: 0,
y: 0,
w: 0,
h: 0,
r: 0
}
};
},
props: {
visible: {
type: Boolean,
default: false
},
item: {
type: Object,
default: () => {
}
}
},
watch: {
visible: {
handler() {
this.drawerShow = this.visible;
},
immediate: true
},
item: {
handler() {
if (this.item) {
let setting = this.$dataStore.get("setting");
this.item.y = (this.item.y - this.item.h / 2);
this.item.x = (this.item.x - this.item.w / 2);
this.$dataStore.set("position_before_px", JSON.parse(JSON.stringify(this.item)));
console.log(
"setting",
setting
)
let x_mm, w_mm, h_mm, y_mm;
if (setting.unit === "mm") {
x_mm = Number((this.item.x * 0.84183).toFixed(2));
w_mm = Number((this.item.w * 0.84183).toFixed(2));
h_mm = Number((this.item.h * 0.84183).toFixed(2));
y_mm = Number((this.item.y * 0.84183).toFixed(2));
} else if (setting.unit === "inch") {
x_mm = Number((this.item.x * 0.84183) / 25.4).toFixed(2);
w_mm = Number((this.item.w * 0.84183) / 25.4).toFixed(2);
h_mm = Number((this.item.h * 0.84183) / 25.4).toFixed(2);
y_mm = Number((this.item.y * 0.84183) / 25.4).toFixed(2);
}
// return
this.form.x = x_mm;
this.form.rate = this.item.rate;
this.form.y = y_mm;
this.form.w = w_mm;
this.form.h = h_mm;
this.form.zIndex = this.item.zIndex;
this.form.r = this.item.r;
this.$dataStore.set(`position_after_px`, JSON.parse(JSON.stringify(this.form)));
}
},
immediate: true,
deep: true
}
},
methods: {
formChange(t) {
if (t && t === "w") {
this.form.h = this.form.w * this.form.rate;
}
if (t && t === "h") {
this.form.w = this.form.h * this.form.rate;
}
let f = JSON.parse(JSON.stringify(this.form));
f.y = (Number(f.y) + Number(f.h) / 2);
f.x = (Number(f.x) + Number(f.w) / 2);
let setting = this.$dataStore.get("setting");
if (setting.unit === "mm") {
f.x = Number((f.x / 0.84183).toFixed(2));
f.y = Number((f.y / 0.84183).toFixed(2));
f.w = Number((f.w / 0.84183).toFixed(2));
f.h = Number((f.h / 0.84183).toFixed(2));
} else if (setting.unit === "inch") {
f.x = (Number((f.x / 0.84183) * 25.4).toFixed(2));
f.y = (Number((f.y / 0.84183) * 25.4).toFixed(2));
f.w = (Number((f.w / 0.84183) * 25.4).toFixed(2));
f.h = (Number((f.h / 0.84183) * 25.4).toFixed(2));
}
f.zIndex = Number((f.zIndex));
for (let k in f) {
f[k] = Number(f[k]);
}
this.$emit("change", f);
this.$dataStore.set("position_unit", JSON.parse(JSON.stringify(f)));
},
addValue(f) {
if (!this.form[f]) this.$set(this.form, f, 0);
let nw = Number(this.form[f]) + 1;
this.$set(this.form, f, nw);
if (f && f === "w") {
this.form.h = this.form.w * this.form.rate;
}
if (f && f === "h") {
this.form.w = this.form.h * this.form.rate;
}
this.formChange();
},
reduceValue(f) {
if (!this.form[f]) this.$set(this.form, f, 0);
let nw = Number(this.form[f]) - 1;
this.$set(this.form, f, nw);
if (f && f === "w") {
this.form.h = this.form.w * this.form.rate;
}
if (f && f === "h") {
this.form.w = this.form.h * this.form.rate;
}
this.formChange();
}
}
};
</script>
<template>
<div class="drawer" :style="{animation:`ltr-drawer-in .3s 1ms`}">
<div class="title">
图片编辑
</div>
<div class="img-form">
<el-form size="small" style="" :model="form" label-position="left" label-width="30px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="x:" prop="x">
<div class="form-content">
<el-input @blur="formChange" v-model="form.x"></el-input>
<div class="set-value">
<i @click="addValue('x')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('x')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="y:">
<div class="form-content">
<el-input @blur="formChange" v-model="form.y"></el-input>
<div class="set-value">
<i @click="addValue('y')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('y')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="w:">
<div class="form-content">
<el-input @blur="formChange('w')" v-model="form.w"></el-input>
<div class="set-value">
<i @click="addValue('w')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('w')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="h:">
<div class="form-content">
<el-input @blur="formChange('h')" v-model="form.h"></el-input>
<div class="set-value">
<i @click="addValue('h')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('h')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="r:">
<div class="form-content">
<el-input maxlength="3" @blur="formChange" v-model="form.r">
</el-input>
<div class="set-value">
<i @click="addValue('r')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('r')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="z:">
<div class="form-content">
<el-input @blur="formChange" v-model="form.zIndex">
</el-input>
<div class="set-value">
<i @click="addValue('zIndex')" class="el-icon-arrow-up"></i>
<i @click="reduceValue('zIndex')" class="el-icon-arrow-down"></i>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-tooltip content="居中">
<el-button @click="$emit('ev','center')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/juzhong-01.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="垂直居中">
<el-button @click="$emit('ev','y_center')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/vertical.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="水平居中">
<el-button @click="$emit('ev','x_center')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/shuipingjuzhong.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="上移一层">
<el-button @click="$emit('ev','add_index')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/shangyi.png" alt="">
</el-button>
</el-tooltip>
<el-tooltip content="下移一层">
<el-button @click="$emit('ev','reduce_index')" size="mini">
<img style="width: 13px;height: 13px" src="@/static/icon/xiayi.png" alt="">
</el-button>
</el-tooltip>
</el-col>
</el-row>
</el-form>
</div>
<slot></slot>
</div>
</template>
<style lang="less" scoped>
.img-form {
padding: 10px;
}
::v-deep {
.el-drawer__header {
border-bottom: 1px solid #ececec;
padding-bottom: 10px;
margin-bottom: 20px;
}
}
.form-content {
display: flex;
align-items: center;
}
.set-value {
height: 100%;
margin-left: 6px;
i {
width: 20px;
height: 12px;
display: block;
text-align: center;
line-height: 12px;
cursor: pointer;
border: 1px solid transparent;
&:hover {
border-color: #ececec;
}
}
}
.drawer {
width: 300px;
bottom: 0;
top: 50px;
padding: 10px;
z-index: 99;
background: white;
box-shadow: 0 8px 10px -5px rgba(0, 0, 0, .2), 0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12);
left: 0;
position: fixed;
border-right: 1px solid #ececec;
height: calc(100vh - 50px);
display: flex;
flex-direction: column;
//animation: ltr-drawer-in .3s 1ms;
.title {
padding-bottom: 10px;
border-bottom: 1px solid #ececec;
}
}
@keyframes ltr-drawer-in {
0% {
transform: translate(-100%);
}
100% {
transform: translate(0);
}
}
@keyframes ltr-drawer-in {
0% {
transform: translate(-100%);
}
100% {
transform: translate(0);
}
}
@keyframes ltr-drawer-out {
0% {
transform: translate(0);
}
100% {
transform: translate(-100%);
}
}
</style>
<script>
import VueDragResizeRotate from "@minogin/vue-drag-resize-rotate";
import { grid } from "../data";
import ImgSetting from "./imgSetting.vue";
import bus from "@/bus";
import PrintDialog from "@/views/design/head/printDialog.vue";
const img = require("../../../assets/bg_tshirt_shadow.png");
export default {
components: {
PrintDialog,
VueDragResizeRotate,
ImgSetting
},
destroyed() {
document.removeEventListener("keyup", this.keyup);
document.removeEventListener("dragover", this.dragover);
document.removeEventListener("drop", this.drop);
},
computed: {
gridWH() {
if (
!this.systemSetting ||
!this.grid ||
!this.grid[this.systemSetting.gridValue]
)
return { w: 0, h: 0, v: 1 };
return {
w: this.grid[this.systemSetting.gridValue].w,
v: this.grid[this.systemSetting.gridValue].value,
h: this.grid[this.systemSetting.gridValue].h
};
},
gridSpacing() {
if (!this.systemSetting) return { w: 0, h: 0 };
if (this.systemSetting.unit === "mm") {
return {
w: this.systemSetting.gridSpacing + "px",
h: this.systemSetting.gridSpacing + "px"
};
} else if (this.systemSetting.unit === "inch") {
console.log(this.systemSetting.gridValue);
let w = this.grid[this.systemSetting.gridValue].w;
let row = this.grid[this.systemSetting.gridValue].row;
let col = this.grid[this.systemSetting.gridValue].col;
let h = this.grid[this.systemSetting.gridValue].h;
return {
w: this.systemSetting.gridSpacing * ((w - row + 1) / row) + "px",
h: this.systemSetting.gridSpacing * (h / col) + "px"
};
}
},
computedGridSize() {
const getter = this.systemSetting;
const num = getter.gridSpacing.slice(0, 2);
return 10 + "px";
},
returnItem() {
if (this.selectIndex < 0) {
this.showImgSetting = false;
return null;
}
let item = this.imgList[this.selectIndex];
if (item) {
item = JSON.parse(JSON.stringify(item));
item.x = Number(item.x) - Number(item.w);
item.y = Number(item.y) + Number(item.h) / 2;
return JSON.parse(JSON.stringify(this.imgList[this.selectIndex]));
}
this.showImgSetting = false;
return null;
}
},
data() {
return {
actionList: [],
parentWidth: 0,
systemSetting: {},
imgHeight: 0,
selectImgList: [],
bus: 0,
grid,
showImgSetting: false,
printDialogShow: true,
parentHeight: 0,
width: 0,
selectIndex: -1,
height: 0,
x: 0,
y: 0,
imgList: [],
selectImgIndexList: [],
imgHistoryList: [[]],
imgHistoryIndex: 0,
row: 8,
img,
col: 7
};
},
watch: {
imgList: {
handler() {
if (this.imgList.length > 0) {
this.$nextTick(() => {
let dom = document.getElementsByClassName("drr");
this.imgList.forEach((el, i) => {
let dom_i = document.getElementsByClassName("drr")[i];
dom_i.style.zIndex =
dom_i.style.zIndex === "" || !dom_i.style.zIndex
? 0
: dom_i.style.zIndex;
dom[i].addEventListener("click", e => {
this.selectIndex = i;
this.selectItem(i);
});
});
});
}
this.$store.commit("changeImgList", this.imgList);
},
deep: true,
immediate: true
},
selectIndex() {
if (this.selectIndex >= 0) {
if (!this.showImgSetting) {
this.showImgSetting = true;
}
} else {
this.showImgSetting = false;
}
}
},
methods: {
changePrintDialogShow() {
this.printDialogShow = !this.printDialogShow;
},
async drop(e) {
let that = this;
e.stopPropagation();
//阻止浏览器默认打开文件的操作
e.preventDefault();
console.log(e);
const files = e.dataTransfer.files;
if (files.length === 0) return;
for (let i = 0; i < files.length; i++) {
if (files[i].type !== "image/png") {
return that.$message.warning("只能上传png格式文件");
}
let formData = new FormData();
formData.append("file", files[i]);
let { data } = await that.$api.post("/uploadImage", formData, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
that.selectImgIndex = 0;
that.addFile(data, file => {
that.imgHistoryList.push(JSON.parse(JSON.stringify(that.imgList)));
});
}
},
dragover(e) {
e.stopPropagation();
//阻止浏览器默认打开文件的操作
e.preventDefault();
e.dataTransfer.dropEffect = "copy";
},
keyup(e) {
console.log(e);
if (e.keyCode == 90 && e.ctrlKey) {
let i = this.imgHistoryList.length - (2 + this.imgHistoryIndex);
if (this.imgHistoryList[i]) {
this.imgList = JSON.parse(JSON.stringify(this.imgHistoryList[i]));
this.imgHistoryIndex = this.imgHistoryIndex + 1;
}
}
if (this.selectIndex >= 0) {
if (e.keyCode === 38) {
//上
this.$set(
this.imgList[this.selectIndex],
"y",
Number(this.imgList[this.selectIndex].y) - 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
if (e.keyCode === 40) {
//下
this.$set(
this.imgList[this.selectIndex],
"y",
Number(this.imgList[this.selectIndex].y) + 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
if (e.keyCode === 37) {
//左
this.$set(
this.imgList[this.selectIndex],
"x",
Number(this.imgList[this.selectIndex].x) - 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
if (e.keyCode === 39) {
//右
this.$set(
this.imgList[this.selectIndex],
"x",
Number(this.imgList[this.selectIndex].x) + 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
}
if (e.keyCode === 8) {
if (this.selectIndex >= 0) {
this.imgList.splice(this.selectIndex, 1);
if (this.imgList.length > 0) {
this.selectIndex = 0;
} else {
this.selectIndex = -1;
}
}
}
},
indexChange(v) {
console.log(v);
if (this.imgList.length === 0) return;
let index = !this.imgList[this.selectIndex] ? 0 : this.selectIndex;
let item = this.$store.state.actionList[v];
if (!item) return;
if (item.t === "drag") {
this.$set(this.imgList[index], "x", item.x);
this.$set(this.imgList[index], "y", item.y);
} else if (item.t === "resize") {
this.$set(this.imgList[index], "x", item.x);
this.$set(this.imgList[index], "y", item.y);
this.$set(this.imgList[index], "w", item.w);
this.$set(this.imgList[index], "h", item.h);
}
console.log();
},
getOneMmsPx() {
// 创建一个1mm宽的元素插入到页面,然后坐等出结果
let div = document.createElement("div");
div.id = "mm";
div.style.width = "1mm";
document.querySelector("body").appendChild(div);
// 原生方法获取浏览器对元素的计算值
let mm1 = document.getElementById("mm").getBoundingClientRect();
return mm1.width;
},
selectImg(it, i) {
// this.selectImgIndexList.push(i)
// this.selectImgIndexList = Array.from(new Set(this.selectImgIndexList))
this.getBackFile([it], file => {
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
});
},
ev(type) {
if (this.selectIndex < 0) return;
// if (this.selectIndex === -1) this.selectIndex = 0
if (!this.imgList[this.selectIndex]) return;
let w = document.getElementById("line").clientWidth / 2;
let h = document.getElementById("line").clientHeight / 2;
let dom = document.getElementsByClassName("drr")[this.selectIndex];
let z_index =
dom.style.zIndex === "" || !dom.style.zIndex ? 0 : dom.style.zIndex;
switch (type) {
case "center":
this.$set(this.imgList[this.selectIndex], "x", Number(w));
this.$set(this.imgList[this.selectIndex], "y", Number(h));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "x_center":
this.$set(this.imgList[this.selectIndex], "x", Number(w));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "y_center":
this.$set(this.imgList[this.selectIndex], "y", Number(h));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "add_index":
dom.style.zIndex = Number(z_index) + 1;
console.log(dom.style.zIndex);
this.$set(
this.imgList[this.selectIndex],
"zIndex",
this.imgList[this.selectIndex].zIndex + 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "reduce_index":
dom.style.zIndex = Number(z_index) - 1;
console.log(dom.style.zIndex);
this.$set(
this.imgList[this.selectIndex],
"zIndex",
this.imgList[this.selectIndex].zIndex - 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
default:
break;
}
},
formChange(form) {
// if (this.selectIndex === -1) this.selectIndex = 0
if (!this.imgList[this.selectIndex]) return;
let f = JSON.parse(JSON.stringify(form));
let x_mm = f.x;
let w_mm = f.w;
let h_mm = f.h;
let y_mm = f.y;
this.$set(this.imgList[this.selectIndex], "x", x_mm);
this.$set(this.imgList[this.selectIndex], "y", y_mm);
this.$set(this.imgList[this.selectIndex], "w", w_mm);
this.$set(this.imgList[this.selectIndex], "h", h_mm);
this.$set(this.imgList[this.selectIndex], "r", f.r);
this.$set(this.imgList[this.selectIndex], "zIndex", f.zIndex);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
close() {
this.showImgSetting = false;
},
onDragDebounce(left, top, item, index) {},
dragStop(data, item) {
this.$set(item, "y", data.y);
this.$set(item, "x", data.x);
// console.log(left, top)
// if (!this.imgList[this.selectIndex]) return
// this.$set(this.imgList[this.selectIndex], 'x', left)
// this.$set(this.imgList[this.selectIndex], 'y', top)
// this.selectIndex = -1
// this.actionList.unshift({
// t: 'drag',
// x: left,
// y: top
// })
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
// this.$store.commit('changeActionList', this.actionList)
},
resizeStop(data, item) {
// if (this.selectIndex === -1) this.selectIndex = 0
console.log("drag", this.selectIndex);
if (this.selectIndex < 0) return;
this.$set(item, "y", data.y);
this.$set(item, "w", data.w);
this.$set(item, "h", data.h);
this.$set(item, "x", data.x);
// console.log(this.selectIndex,'resize',x, y, w, h)
// this.actionList.unshift({
// t: 'resize',
// x,
// y,
// w,
// h
// })
// this.$store.commit('changeActionList', this.actionList)
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
resizing(index) {},
rotating(data, item) {
console.log(data);
this.$set(item, "r", data.angle.toFixed(2));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
outsideClick(e) {
if (
!(
e.target.className.includes("drr") ||
e.target.className.includes("sucaitu-img")
)
) {
this.selectIndex = -1;
this.close();
}
},
selectItem(index) {
let dom = document.getElementsByClassName("drr");
for (let i = 0; i < dom.length; i++) {
if (index !== i) {
dom[i].classList.remove("active");
dom[i].classList.add("inactive");
}
}
this.selectIndex = index;
},
deSelect(index) {
console.log(index, 222222222);
this.close();
this.selectIndex = -1;
},
delImg(index) {
console.log(index, "index");
this.imgList.splice(index, 1);
if (this.imgList.length > 0) {
this.selectIndex = 0;
this.showImgSetting = true;
} else {
this.selectIndex = -1;
}
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
fileToBase64(file) {
return new Promise((resolve, reject) => {
// 创建一个新的 FileReader 对象
const reader = new FileReader();
// 读取 File 对象
reader.readAsDataURL(file);
// 加载完成后
reader.onload = function() {
// 将读取的数据转换为 base64 编码的字符串
const base64String = reader.result;
// 解析为 Promise 对象,并返回 base64 编码的字符串
resolve(base64String);
};
// 加载失败时
reader.onerror = function() {
reject(new Error("Failed to load file"));
};
});
},
getBackFile(files, callback) {
console.log(files);
let that = this;
let bw = document.getElementById("line").clientWidth;
let bh = document.getElementById("line").clientHeight;
for (let i = 0; i < files.length; i++) {
files[i].url = files[i].productionFile;
that.$nextTick(() => {
that.getImageSize(files[i].url).then(data => {
let w = document.getElementById("line").clientWidth / 2;
let rate = data.height / data.width;
that.imgList.push({
url: files[i].url,
fileName: files[i].fileName,
rate,
w: bw * (2 / 3),
zIndex: that.imgList.length,
x: w,
y: (bw * (2 / 3) * rate) / 2,
h: bw * (2 / 3) * rate,
r: 0
});
that.selectIndex = that.imgList.length - 1;
that.showImgSetting = true;
if (i === files.length - 1) {
callback && callback();
}
});
});
}
},
addFile(file, callback) {
let that = this;
let bw = document.getElementById("line").clientWidth;
let bh = document.getElementById("line").clientHeight;
console.log(bw, bh);
that.$nextTick(() => {
that.getImageSize(file.url).then(data => {
let w = document.getElementById("line").clientWidth / 2;
let rate = data.height / data.width;
that.imgList.push({
url: file.url,
w: bw * (2 / 3),
rate,
fileName: file.fileName,
zIndex: that.imgList.length,
x: w,
y: (bw * (2 / 3) * rate) / 2,
h: bw * (2 / 3) * rate,
r: 0
});
console.log(that.imgList);
that.selectIndex = that.imgList.length - 1;
that.showImgSetting = true;
callback && callback(file);
});
});
},
listenUpload() {
let that = this;
document.getElementById("img").onmousedown = function(e) {
e.preventDefault();
};
that.parentWidth = document.getElementById("img").clientWidth;
that.parentHeight = document.getElementById("img").clientHeight;
let dp = document.getElementsByClassName("container")[0];
dp.addEventListener("dragover", this.dragover);
dp.addEventListener("drop", this.drop);
},
getImageSize(url) {
return new Promise(function(resolve, reject) {
let image = new Image();
image.onload = function() {
resolve({
width: image.width,
height: image.height
});
};
image.onerror = function() {
reject(new Error("error"));
};
image.src = url;
});
},
/**
* 根据主题颜色修改图片颜色
* @param {[type]} imgUrl 图片url
* @param {[type]} color 主题颜色
* @param {Function} callback 返回值 返回base64
*/
changeImageColor(color = "#00ff7f", callback) {
let threshold = 114; //默认颜色阀值 为 114 ->和默认图相关
let img = new Image();
img.src = require("../../../assets/bg_tshirt_shadow.png");
let newR = parseInt("0x" + color.substr(1, 2));
let newG = parseInt("0x" + color.substr(3, 2));
let newB = parseInt("0x" + color.substr(5, 2));
//图片加载后进行处理
img.onload = function() {
let width = img.width,
height = img.height,
canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
// 将源图片复制到画布上
ctx.drawImage(img, 0, 0, width, height);
// 获取画布的像素信息
let imageData = ctx.getImageData(0, 0, width, height),
data = imageData.data;
// 对像素集合中的单个像素进行循环,每个像素是由4个通道组成,所以要注意
let i = 0;
while (i < data.length) {
let r = data[i++],
g = data[i++],
b = data[i++],
a = data[i++];
//计算透明度
let alp = (255 - r) / (255 - threshold);
//判断是否透明
let isTransparent = r == 255 && g == 255 && b == 255 && a == 255;
if (isTransparent) {
data[i - 1] = 0;
} else {
data[i - 4] = newR;
data[i - 3] = newG;
data[i - 2] = newB;
data[i - 1] = a !== 255 ? 255 - a : alp * 255; //处理透明的图片和不透明的图片
}
}
// 将修改后的代码复制回画布中
ctx.putImageData(imageData, 0, 0);
// 图片导出为 png 格式
let imgType = "png";
let imgData = canvas.toDataURL(imgType);
callback && callback(imgData);
};
return img;
}
},
mounted() {
this.imgHeight = window.screen.height + "px";
this.systemSetting = this.$dataStore.get("setting");
bus.$on("busEmit", v => {
let { type, value } = v;
switch (type) {
case "grid":
this.row = value.row;
this.col = value.col;
break;
case "index":
this.indexChange(value);
break;
case "bg":
this.changeImageColor(value, res => {
this.img = res;
});
break;
case "updateSystemSetting":
console.log(this.$dataStore);
this.systemSetting = this.$dataStore.get("setting");
break;
case "uploadImage":
this.addFile(value, file => {
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
// this.selectImgList.push(file)
// this.selectImgIndex = this.selectImgList.length - 1
});
break;
case "sendFile":
this.imgList = [];
this.selectIndex = -1;
if (value.length > 0) {
console.log(value);
this.selectImgList = value;
this.selectImgIndex = 0;
this.getBackFile([value[0]], file => {
this.imgHistoryList.push(
JSON.parse(JSON.stringify(this.imgList))
);
});
// this.addFile([value[0].file])
}
break;
default:
break;
}
});
document.addEventListener("keyup", this.keyup);
this.$nextTick(() => {
this.listenUpload();
});
}
};
</script>
<template>
<div class="page-main">
<div @click="outsideClick" class="main-bg">
<div class="container">
<div class="select-img" v-if="selectImgList.length > 1">
<div
@click="selectImg(it, i)"
v-for="(it, i) in selectImgList"
:key="i"
class="img-item"
>
<img style="width: 100px;height: auto;" :src="it.productionFile" />
<span>{{ it.designId }}</span>
</div>
</div>
<div :style="{ height: imgHeight }" id="img">
<div id="line">
<div
class="sucaitu"
:style="{ width: gridWH.w + 'px', height: gridWH.h + 'px' }"
>
<vue-drag-resize-rotate
:w="item.w"
class-name="my-drag-resize-rotate"
:prevent-deactivation="false"
:h="item.h"
:x="item.x"
:z="item.zIndex"
:aspectRatio="true"
:isActive="index === selectIndex"
:y="item.y"
v-for="(item, index) in imgList"
:key="index"
:draggable="true"
:resizable="true"
:rotatable="true"
@dragstop="a => dragStop(a, item)"
@resizestop="a => resizeStop(a, item)"
@rotatestop="a => rotating(a, item)"
:angle="item.r"
>
<div
ref="sucaitu-img"
:class="{ active: index === selectIndex }"
:style="{ zIndex: item.zIndex }"
class="sucaitu-img img element"
>
<img
crossOrigin="anonymous"
:src="item.url"
alt=""
class="sucaitu-img"
/>
<i
@click="delImg(index)"
v-if="index === selectIndex"
class=" close el-icon-close"
></i>
<div
v-if="index === selectIndex"
class="control-point control-rotator"
></div>
</div>
</vue-drag-resize-rotate>
</div>
<div
v-if="systemSetting.gridShow === 1"
:style="{ width: gridWH.w + 'px', height: gridWH.h + 'px' }"
class="grid"
>
<div
:style="{ height: gridSpacing.h, lineHeight: gridSpacing.h }"
class="grid-row"
v-for="it in 100"
:key="it"
>
<div
:style="{ width: gridSpacing.w, height: gridSpacing.h }"
class="grid-col"
v-for="it in 100"
:key="it"
></div>
</div>
</div>
</div>
<img class="template-img" draggable="false" :src="img" alt="" />
</div>
<print-dialog
:visible="printDialogShow"
:imgList="imgList"
:byPlatenSize="gridWH.v"
>
<i
@click="changePrintDialogShow"
:class="
!printDialogShow ? 'el-icon-arrow-left' : 'el-icon-arrow-right'
"
></i>
</print-dialog>
</div>
</div>
<img-setting
@ev="ev"
@change="formChange"
:item="returnItem"
@close="close"
:visible="showImgSetting"
>
</img-setting>
</div>
</template>
<style lang="less" scoped>
.page-main {
flex: 1;
flex-shrink: 0;
overflow: hidden;
box-sizing: border-box;
}
.main-bg {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#line {
position: absolute;
z-index: 2;
}
.grid {
border: 1px solid gray;
overflow: hidden;
.grid-row {
.grid-col {
display: inline-block;
border: 1px solid gray;
border-right: none;
border-bottom: none;
}
}
}
.grid-row {
width: 100%;
overflow: hidden;
height: 10px;
line-height: 10px;
white-space: nowrap;
&:nth-of-type(1) {
.grid-col {
border-top: none !important;
}
}
&:nth-last-of-type(1) {
.grid-col {
border-bottom: none !important;
}
}
.grid-col {
&:nth-of-type(1) {
border-left: none !important;
}
}
}
#img {
position: absolute;
z-index: 1;
left: 130px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
width: auto;
img {
pointer-events: none;
width: auto;
height: 100%;
}
}
.container {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
position: relative;
}
.sucaitu {
position: absolute;
z-index: 0;
width: 100%;
//display: flex;
//justify-content: center;
//align-items: center;
height: 100%;
img {
width: 100%;
height: 100%;
}
.close {
position: absolute;
top: -11px;
right: -12px;
color: white;
z-index: 1000;
width: 20px;
cursor: pointer;
height: 20px;
background: red;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.img {
height: fit-content;
width: 100%;
height: 100%;
cursor: move;
border: 1px dashed transparent;
}
}
.select-img {
border-color: #409eff;
width: 120px;
z-index: 5;
overflow: auto;
background-color: gray;
height: calc(100% - 72px);
padding: 10px;
position: fixed;
box-sizing: border-box;
left: 0;
bottom: 0;
border-right: 1px solid #ececec;
}
img {
user-select: none;
user-drag: none;
}
::v-deep .active,
.active {
border-color: #66b1ff !important;
}
.select-img-index {
box-sizing: border-box;
border-color: #409eff !important;
}
.img-item {
padding: 5px;
display: flex;
cursor: pointer;
margin-bottom: 20px;
border: 2px dashed transparent;
flex-direction: column;
align-items: center;
justify-content: center;
span {
margin: 5px 0;
color: white;
}
}
.sucaitu-img {
position: relative;
}
</style>
<style>
.el-upload {
height: 100%;
}
.drr-stick {
z-index: 9999;
}
.drr-stick-tr {
z-index: -1 !important;
}
.my-drag-resize-rotate {
border-color: transparent;
}
.handle-rot::before,
.handle-rot::after {
display: none;
}
</style>
<script>
import VueDragResizeRotate from "@minogin/vue-drag-resize-rotate";
import { grid } from "../data";
import ImgSetting from "./imgSetting.vue";
import bus from "@/bus";
import PrintDialog from "@/views/design/head/printDialog.vue";
const img = require("../../../assets/bg_tshirt_shadow.png");
export default {
components: {
PrintDialog,
VueDragResizeRotate,
ImgSetting
},
destroyed() {
document.removeEventListener("keyup", this.keyup);
document.removeEventListener("dragover", this.dragover);
document.removeEventListener("drop", this.drop);
},
computed: {
gridWH() {
if (
!this.systemSetting ||
!this.grid ||
!this.grid[this.systemSetting.gridValue]
)
return { w: 0, h: 0, v: 1 };
return {
w: this.grid[this.systemSetting.gridValue].w,
v: this.grid[this.systemSetting.gridValue].value,
h: this.grid[this.systemSetting.gridValue].h
};
},
gridSpacing() {
if (!this.systemSetting) return { w: 0, h: 0 };
if (this.systemSetting.unit === "mm") {
return {
w: this.systemSetting.gridSpacing + "px",
h: this.systemSetting.gridSpacing + "px"
};
} else if (this.systemSetting.unit === "inch") {
console.log(this.systemSetting.gridValue);
let w = this.grid[this.systemSetting.gridValue].w;
let row = this.grid[this.systemSetting.gridValue].row;
let col = this.grid[this.systemSetting.gridValue].col;
let h = this.grid[this.systemSetting.gridValue].h;
return {
w: this.systemSetting.gridSpacing * ((w - row + 1) / row) + "px",
h: this.systemSetting.gridSpacing * (h / col) + "px"
};
}
},
computedGridSize() {
const getter = this.systemSetting;
const num = getter.gridSpacing.slice(0, 2);
return 10 + "px";
},
returnItem() {
if (this.selectIndex < 0) {
this.showImgSetting = false;
return null;
}
let item = this.imgList[this.selectIndex];
if (item) {
item = JSON.parse(JSON.stringify(item));
item.x = Number(item.x) - Number(item.w);
item.y = Number(item.y) + Number(item.h) / 2;
return JSON.parse(JSON.stringify(this.imgList[this.selectIndex]));
}
this.showImgSetting = false;
return null;
}
},
data() {
return {
actionList: [],
parentWidth: 0,
systemSetting: {},
imgHeight: 0,
selectImgList: [],
bus: 0,
grid,
showImgSetting: true,
printDialogShow: true,
parentHeight: 0,
width: 0,
selectIndex: -1,
height: 0,
x: 0,
y: 0,
imgList: [],
selectImgIndexList: [],
imgHistoryList: [[]],
imgHistoryIndex: 0,
row: 8,
img,
col: 7
};
},
watch: {
imgList: {
handler() {
if (this.imgList.length > 0) {
this.$nextTick(() => {
let dom = document.getElementsByClassName("drr");
this.imgList.forEach((el, i) => {
let dom_i = document.getElementsByClassName("drr")[i];
dom_i.style.zIndex =
dom_i.style.zIndex === "" || !dom_i.style.zIndex
? 0
: dom_i.style.zIndex;
dom[i].addEventListener("click", e => {
this.selectIndex = i;
this.selectItem(i);
});
});
});
}
this.$store.commit("changeImgList", this.imgList);
},
deep: true,
immediate: true
},
selectIndex() {
if (this.selectIndex >= 0) {
if (!this.showImgSetting) {
this.showImgSetting = true;
}
} else {
this.showImgSetting = false;
}
}
},
methods: {
changePrintDialogShow() {
this.printDialogShow = !this.printDialogShow;
},
async drop(e) {
let that = this;
e.stopPropagation();
//阻止浏览器默认打开文件的操作
e.preventDefault();
console.log(e);
const files = e.dataTransfer.files;
if (files.length === 0) return;
for (let i = 0; i < files.length; i++) {
if (files[i].type !== "image/png") {
return that.$message.warning("只能上传png格式文件");
}
let formData = new FormData();
formData.append("file", files[i]);
let { data } = await that.$api.post("/uploadImage", formData, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
that.selectImgIndex = 0;
that.addFile(data, file => {
that.imgHistoryList.push(JSON.parse(JSON.stringify(that.imgList)));
});
}
},
dragover(e) {
e.stopPropagation();
//阻止浏览器默认打开文件的操作
e.preventDefault();
e.dataTransfer.dropEffect = "copy";
},
keyup(e) {
console.log(e);
if (e.keyCode == 90 && e.ctrlKey) {
let i = this.imgHistoryList.length - (2 + this.imgHistoryIndex);
if (this.imgHistoryList[i]) {
this.imgList = JSON.parse(JSON.stringify(this.imgHistoryList[i]));
this.imgHistoryIndex = this.imgHistoryIndex + 1;
}
}
if (this.selectIndex >= 0) {
if (e.keyCode === 38) {
//上
this.$set(
this.imgList[this.selectIndex],
"y",
Number(this.imgList[this.selectIndex].y) - 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
if (e.keyCode === 40) {
//下
this.$set(
this.imgList[this.selectIndex],
"y",
Number(this.imgList[this.selectIndex].y) + 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
if (e.keyCode === 37) {
//左
this.$set(
this.imgList[this.selectIndex],
"x",
Number(this.imgList[this.selectIndex].x) - 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
if (e.keyCode === 39) {
//右
this.$set(
this.imgList[this.selectIndex],
"x",
Number(this.imgList[this.selectIndex].x) + 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}
}
if (e.keyCode === 8) {
if (this.selectIndex >= 0) {
this.imgList.splice(this.selectIndex, 1);
if (this.imgList.length > 0) {
this.selectIndex = 0;
} else {
this.selectIndex = -1;
}
}
}
},
indexChange(v) {
console.log(v);
if (this.imgList.length === 0) return;
let index = !this.imgList[this.selectIndex] ? 0 : this.selectIndex;
let item = this.$store.state.actionList[v];
if (!item) return;
if (item.t === "drag") {
this.$set(this.imgList[index], "x", item.x);
this.$set(this.imgList[index], "y", item.y);
} else if (item.t === "resize") {
this.$set(this.imgList[index], "x", item.x);
this.$set(this.imgList[index], "y", item.y);
this.$set(this.imgList[index], "w", item.w);
this.$set(this.imgList[index], "h", item.h);
}
console.log();
},
getOneMmsPx() {
// 创建一个1mm宽的元素插入到页面,然后坐等出结果
let div = document.createElement("div");
div.id = "mm";
div.style.width = "1mm";
document.querySelector("body").appendChild(div);
// 原生方法获取浏览器对元素的计算值
let mm1 = document.getElementById("mm").getBoundingClientRect();
return mm1.width;
},
selectImg(it, i) {
// this.selectImgIndexList.push(i)
let item = this.imgList.find(img=>img.fileName===it.fileName)
if(item) return
// this.selectImgIndexList = Array.from(new Set(this.selectImgIndexList))
this.getBackFile([it], file => {
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
});
},
ev(type) {
if (this.selectIndex < 0) return;
// if (this.selectIndex === -1) this.selectIndex = 0
if (!this.imgList[this.selectIndex]) return;
let w = document.getElementById("line").clientWidth / 2;
let h = document.getElementById("line").clientHeight / 2;
let dom = document.getElementsByClassName("drr")[this.selectIndex];
let z_index =
dom.style.zIndex === "" || !dom.style.zIndex ? 0 : dom.style.zIndex;
switch (type) {
case "center":
this.$set(this.imgList[this.selectIndex], "x", Number(w));
this.$set(this.imgList[this.selectIndex], "y", Number(h));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "x_center":
this.$set(this.imgList[this.selectIndex], "x", Number(w));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "y_center":
this.$set(this.imgList[this.selectIndex], "y", Number(h));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "add_index":
dom.style.zIndex = Number(z_index) + 1;
console.log(dom.style.zIndex);
this.$set(
this.imgList[this.selectIndex],
"zIndex",
this.imgList[this.selectIndex].zIndex + 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "reduce_index":
dom.style.zIndex = Number(z_index) - 1;
console.log(dom.style.zIndex);
this.$set(
this.imgList[this.selectIndex],
"zIndex",
this.imgList[this.selectIndex].zIndex - 1
);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
default:
break;
}
},
formChange(form) {
// if (this.selectIndex === -1) this.selectIndex = 0
if (!this.imgList[this.selectIndex]) return;
let f = JSON.parse(JSON.stringify(form));
let x_mm = f.x;
let w_mm = f.w;
let h_mm = f.h;
let y_mm = f.y;
this.$set(this.imgList[this.selectIndex], "x", x_mm);
this.$set(this.imgList[this.selectIndex], "y", y_mm);
this.$set(this.imgList[this.selectIndex], "w", w_mm);
this.$set(this.imgList[this.selectIndex], "h", h_mm);
this.$set(this.imgList[this.selectIndex], "r", f.r);
this.$set(this.imgList[this.selectIndex], "zIndex", f.zIndex);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
close() {
this.showImgSetting = false;
},
onDragDebounce(left, top, item, index) {},
dragStop(data, item) {
this.$set(item, "y", data.y);
this.$set(item, "x", data.x);
// console.log(left, top)
// if (!this.imgList[this.selectIndex]) return
// this.$set(this.imgList[this.selectIndex], 'x', left)
// this.$set(this.imgList[this.selectIndex], 'y', top)
// this.selectIndex = -1
// this.actionList.unshift({
// t: 'drag',
// x: left,
// y: top
// })
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
// this.$store.commit('changeActionList', this.actionList)
},
resizeStop(data, item) {
// if (this.selectIndex === -1) this.selectIndex = 0
console.log("drag", this.selectIndex);
if (this.selectIndex < 0) return;
this.$set(item, "y", data.y);
this.$set(item, "w", data.w);
this.$set(item, "h", data.h);
this.$set(item, "x", data.x);
// console.log(this.selectIndex,'resize',x, y, w, h)
// this.actionList.unshift({
// t: 'resize',
// x,
// y,
// w,
// h
// })
// this.$store.commit('changeActionList', this.actionList)
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
resizing(index) {},
rotating(data, item) {
console.log(data);
this.$set(item, "r", data.angle.toFixed(2));
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
outsideClick(e) {
if (
!(
e.target.className.includes("drr") ||
e.target.className.includes("sucaitu-img")
)
) {
this.selectIndex = -1;
this.close();
}
},
selectItem(index) {
let dom = document.getElementsByClassName("drr");
for (let i = 0; i < dom.length; i++) {
if (index !== i) {
dom[i].classList.remove("active");
dom[i].classList.add("inactive");
}
}
this.selectIndex = index;
},
deSelect(index) {
console.log(index, 222222222);
this.close();
this.selectIndex = -1;
},
delImg(index) {
console.log(index, "index");
this.imgList.splice(index, 1);
if (this.imgList.length > 0) {
this.selectIndex = 0;
this.showImgSetting = true;
} else {
this.selectIndex = -1;
}
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
},
fileToBase64(file) {
return new Promise((resolve, reject) => {
// 创建一个新的 FileReader 对象
const reader = new FileReader();
// 读取 File 对象
reader.readAsDataURL(file);
// 加载完成后
reader.onload = function() {
// 将读取的数据转换为 base64 编码的字符串
const base64String = reader.result;
// 解析为 Promise 对象,并返回 base64 编码的字符串
resolve(base64String);
};
// 加载失败时
reader.onerror = function() {
reject(new Error("Failed to load file"));
};
});
},
getBackFile(files, callback) {
console.log(files);
let that = this;
let bw = document.getElementById("line").clientWidth;
let bh = document.getElementById("line").clientHeight;
for (let i = 0; i < files.length; i++) {
files[i].url = files[i].productionFile;
that.$nextTick(() => {
that.getImageSize(files[i].url).then(data => {
let w = document.getElementById("line").clientWidth / 2;
let rate = data.height / data.width;
that.imgList.push({
url: files[i].url,
fileName: files[i].fileName,
rate,
w: bw * (2 / 3),
zIndex: that.imgList.length,
x: w,
y: (bw * (2 / 3) * rate) / 2,
h: bw * (2 / 3) * rate,
r: 0
});
that.selectIndex = that.imgList.length - 1;
that.showImgSetting = true;
if (i === files.length - 1) {
callback && callback();
}
});
});
}
},
addFile(file, callback) {
let that = this;
let bw = document.getElementById("line").clientWidth;
let bh = document.getElementById("line").clientHeight;
console.log(bw, bh);
that.$nextTick(() => {
that.getImageSize(file.url).then(data => {
let w = document.getElementById("line").clientWidth / 2;
let rate = data.height / data.width;
that.imgList.push({
url: file.url,
w: bw * (2 / 3),
rate,
fileName: file.fileName,
zIndex: that.imgList.length,
x: w,
y: (bw * (2 / 3) * rate) / 2,
h: bw * (2 / 3) * rate,
r: 0
});
console.log(that.imgList);
that.selectIndex = that.imgList.length - 1;
that.showImgSetting = true;
callback && callback(file);
});
});
},
listenUpload() {
let that = this;
document.getElementById("img").onmousedown = function(e) {
e.preventDefault();
};
that.parentWidth = document.getElementById("img").clientWidth;
that.parentHeight = document.getElementById("img").clientHeight;
let dp = document.getElementsByClassName("container")[0];
dp.addEventListener("dragover", this.dragover);
dp.addEventListener("drop", this.drop);
},
getImageSize(url) {
return new Promise(function(resolve, reject) {
let image = new Image();
image.onload = function() {
resolve({
width: image.width,
height: image.height
});
};
image.onerror = function() {
reject(new Error("error"));
};
image.src = url;
});
},
/**
* 根据主题颜色修改图片颜色
* @param {[type]} imgUrl 图片url
* @param {[type]} color 主题颜色
* @param {Function} callback 返回值 返回base64
*/
changeImageColor(color = "#00ff7f", callback) {
let threshold = 114; //默认颜色阀值 为 114 ->和默认图相关
let img = new Image();
img.src = require("../../../assets/bg_tshirt_shadow.png");
let newR = parseInt("0x" + color.substr(1, 2));
let newG = parseInt("0x" + color.substr(3, 2));
let newB = parseInt("0x" + color.substr(5, 2));
//图片加载后进行处理
img.onload = function() {
let width = img.width,
height = img.height,
canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
// 将源图片复制到画布上
ctx.drawImage(img, 0, 0, width, height);
// 获取画布的像素信息
let imageData = ctx.getImageData(0, 0, width, height),
data = imageData.data;
// 对像素集合中的单个像素进行循环,每个像素是由4个通道组成,所以要注意
let i = 0;
while (i < data.length) {
let r = data[i++],
g = data[i++],
b = data[i++],
a = data[i++];
//计算透明度
let alp = (255 - r) / (255 - threshold);
//判断是否透明
let isTransparent = r == 255 && g == 255 && b == 255 && a == 255;
if (isTransparent) {
data[i - 1] = 0;
} else {
data[i - 4] = newR;
data[i - 3] = newG;
data[i - 2] = newB;
data[i - 1] = a !== 255 ? 255 - a : alp * 255; //处理透明的图片和不透明的图片
}
}
// 将修改后的代码复制回画布中
ctx.putImageData(imageData, 0, 0);
// 图片导出为 png 格式
let imgType = "png";
let imgData = canvas.toDataURL(imgType);
callback && callback(imgData);
};
return img;
}
},
mounted() {
this.imgHeight = window.screen.height + "px";
this.systemSetting = this.$dataStore.get("setting");
bus.$on("busEmit", v => {
let { type, value } = v;
switch (type) {
case "grid":
this.row = value.row;
this.col = value.col;
break;
case "index":
this.indexChange(value);
break;
case "bg":
this.changeImageColor(value, res => {
this.img = res;
});
break;
case "updateSystemSetting":
console.log(this.$dataStore);
this.systemSetting = this.$dataStore.get("setting");
break;
case "uploadImage":
this.addFile(value, file => {
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
// this.selectImgList.push(file)
// this.selectImgIndex = this.selectImgList.length - 1
});
break;
case "sendFile":
this.imgList = [];
this.selectIndex = -1;
if (value.length > 0) {
console.log(value);
this.selectImgList = value;
this.selectImgIndex = 0;
this.getBackFile([value[0]], file => {
this.imgHistoryList.push(
JSON.parse(JSON.stringify(this.imgList))
);
});
// this.addFile([value[0].file])
}
break;
default:
break;
}
});
document.addEventListener("keyup", this.keyup);
this.$nextTick(() => {
this.listenUpload();
});
}
};
</script>
<template>
<div class="page-main">
<div @click="outsideClick" class="main-bg">
<div class="container">
<div :style="{ height: imgHeight }" id="img">
<div id="line">
<div
class="sucaitu"
:style="{ width: gridWH.w + 'px', height: gridWH.h + 'px' }"
>
<vue-drag-resize-rotate
:w="item.w"
class-name="my-drag-resize-rotate"
:prevent-deactivation="false"
:h="item.h"
:x="item.x"
:z="item.zIndex"
:aspectRatio="true"
:isActive="index === selectIndex"
:y="item.y"
v-for="(item, index) in imgList"
:key="index"
:draggable="true"
:resizable="true"
:rotatable="true"
@dragstop="a => dragStop(a, item)"
@resizestop="a => resizeStop(a, item)"
@rotatestop="a => rotating(a, item)"
:angle="item.r"
>
<div
ref="sucaitu-img"
:class="{ active: index === selectIndex }"
:style="{ zIndex: item.zIndex }"
class="sucaitu-img img element"
>
<img
crossOrigin="anonymous"
:src="item.url"
alt=""
class="sucaitu-img"
/>
<i
@click="delImg(index)"
v-if="index === selectIndex"
class=" close el-icon-close"
></i>
<div
v-if="index === selectIndex"
class="control-point control-rotator"
></div>
</div>
</vue-drag-resize-rotate>
</div>
<div
v-if="systemSetting.gridShow === 1"
:style="{ width: gridWH.w + 'px', height: gridWH.h + 'px' }"
class="grid"
>
<div
:style="{ height: gridSpacing.h, lineHeight: gridSpacing.h }"
class="grid-row"
v-for="it in 100"
:key="it"
>
<div
:style="{ width: gridSpacing.w, height: gridSpacing.h }"
class="grid-col"
v-for="it in 100"
:key="it"
></div>
</div>
</div>
</div>
<img class="template-img" draggable="false" :src="img" alt="" />
</div>
<print-dialog
:visible="printDialogShow"
:imgList="imgList"
:byPlatenSize="gridWH.v"
>
<i
@click="changePrintDialogShow"
:class="
!printDialogShow ? 'el-icon-arrow-left' : 'el-icon-arrow-right'
"
></i>
</print-dialog>
</div>
</div>
<img-setting
@ev="ev"
@change="formChange"
:item="returnItem"
@close="close"
>
<div class="select-img" v-if="selectImgList.length">
<div
@click="selectImg(it, i)"
v-for="(it, i) in selectImgList"
:key="i"
class="img-item"
>
<img style="width: 140px;height: auto;" :src="it.productionFile" />
<span>{{ it.designId }}</span>
</div>
</div>
</img-setting>
</div>
</template>
<style lang="less" scoped>
.page-main {
flex: 1;
flex-shrink: 0;
overflow: hidden;
box-sizing: border-box;
}
.main-bg {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#line {
position: absolute;
z-index: 2;
}
.grid {
border: 1px solid gray;
overflow: hidden;
.grid-row {
.grid-col {
display: inline-block;
border: 1px solid gray;
border-right: none;
border-bottom: none;
}
}
}
.grid-row {
width: 100%;
overflow: hidden;
height: 10px;
line-height: 10px;
white-space: nowrap;
&:nth-of-type(1) {
.grid-col {
border-top: none !important;
}
}
&:nth-last-of-type(1) {
.grid-col {
border-bottom: none !important;
}
}
.grid-col {
&:nth-of-type(1) {
border-left: none !important;
}
}
}
#img {
position: absolute;
z-index: 1;
left: 130px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
width: auto;
img {
pointer-events: none;
width: auto;
height: 100%;
}
}
.container {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
position: relative;
}
.sucaitu {
position: absolute;
z-index: 0;
width: 100%;
//display: flex;
//justify-content: center;
//align-items: center;
height: 100%;
img {
width: 100%;
height: 100%;
}
.close {
position: absolute;
top: -11px;
right: -12px;
color: white;
z-index: 1000;
width: 20px;
cursor: pointer;
height: 20px;
background: red;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.img {
height: fit-content;
width: 100%;
height: 100%;
cursor: move;
border: 1px dashed transparent;
}
}
.select-img {
border: 1px solid #ececec;
width: 100%;
overflow: auto;
height: calc(100% - 251px);
padding: 10px;
box-sizing: border-box;
}
img {
user-select: none;
user-drag: none;
}
::v-deep .active,
.active {
border-color: #66b1ff !important;
}
.select-img-index {
box-sizing: border-box;
border-color: #409eff !important;
}
.img-item {
padding: 5px;
display: flex;
cursor: pointer;
margin-bottom: 20px;
border: 2px dashed transparent;
flex-direction: column;
align-items: center;
justify-content: center;
span {
font-size: 14px;
margin: 5px 0;
color: black;
}
}
.sucaitu-img {
position: relative;
}
</style>
<style>
.el-upload {
height: 100%;
}
.drr-stick {
z-index: 9999;
}
.drr-stick-tr {
z-index: -1 !important;
}
.my-drag-resize-rotate {
border-color: transparent;
}
.handle-rot::before,
.handle-rot::after {
display: none;
}
</style>
<script>
import { ipcRenderer } from "electron";
import pkg from "../../../package.json";
import axios from "@/utils/axios";
export default {
data() {
return {
visible: false,
version: pkg.version,
downloaded: false,
percent: 0,
loading: false,
speed: 0,
item: {}
};
},
created() {
let that = this;
ipcRenderer.on("update", (event, data) => {
console.log("下載進度", data);
if (!that.loading) that.loading = true;
that.percent = data.percent;
that.speed = data.speed;
});
ipcRenderer.on("update-error", (event, data) => {
console.log(data);
that.$message.error(`安装包下载失败`);
that.loading = false;
});
ipcRenderer.on("downloaded", () => {
that.loading = false;
that.download();
});
},
methods: {
async checkUpdate() {
return new Promise((resolve, reject) => {
try {
axios
.get(`/checkUpdate?version=${this.version}`)
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err);
});
} catch (err) {
reject(err);
}
});
},
download() {
this.$confirm("新版本已下载,是否立即安装?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
showCancelButton: this.item.forcedUpdate === 0,
showClose: this.item.forcedUpdate === 0,
type: "success"
})
.then(() => {
ipcRenderer.send("install");
this.visible = false;
})
.catch(() => {});
},
incrementalUpdates() {
this.$confirm("新版本已下载,是否刷新页面", "提示", {
confirmButtonText: "确定",
showCancelButton: this.item.forcedUpdate === 0,
showClose: this.item.forcedUpdate === 0,
cancelButtonText: "取消",
type: "success"
})
.then(() => {
window.location.reload();
})
.catch(() => {});
},
async toUpdate(type) {
if (type === 1) {
this.visible = false;
if (this.loading) return;
} else {
this.loading = true;
}
if (!this.item.fileList || this.item.fileList.length === 0) {
return this.$message.warning("缺少更新文件");
}
console.log("开始下载");
if (this.item.fullUpdate) {
// 全量更新
const domain = "https://" + this.$dataStore.get("company").domain;
this.item.url =
domain + this.item.fileList[0].versionPath.replace("/data", "");
console.log(this.item.url);
ipcRenderer.send("toUpdateApp", this.item);
} else {
try {
this.loading = false;
await this.$api.post("/incrementalUpdates", {
url: this.item.fileList[0].fileUrl.replace("/data", "")
});
this.incrementalUpdates();
} catch (e) {
// this.$message.warning("更新失败");
}
}
},
open(data) {
this.item = data;
this.visible = true;
}
}
};
</script>
<template>
<el-dialog
:show-close="item.forcedUpdate === 0"
destroy-on-close
:close-on-press-escape="false"
:close-on-click-modal="false"
width="500px"
:title="item.title"
:visible.sync="visible"
>
<pre>{{ item.content }}</pre>
<!-- <el-progress :text-inside="true" :stroke-width="26" :percentage="percent"></el-progress>-->
<template slot="footer">
<el-button
@click="visible = false"
v-if="item.forcedUpdate === 0"
size="small"
>关闭
</el-button>
<!-- <el-button @click="toUpdate(1)" size="small" type="warning"-->
<!-- >后台更新-->
<!-- </el-button-->
<!-- >-->
<el-button
@click="toUpdate(2)"
size="small"
type="primary"
:loading="loading"
>
{{ loading ? `正在下载中(${percent}%)` : "确定更新" }}
</el-button>
</template>
</el-dialog>
</template>
<style scoped lang="less"></style>
<script>
import { ipcRenderer } from "electron";
import pkg from "../../../package.json";
import axios from "@/utils/axios";
export default {
data() {
return {
visible: false,
version: pkg.version,
downloaded: false,
percent: 0,
loading: false,
speed: 0,
item: {}
};
},
created() {
let that = this;
ipcRenderer.on("update", (event, data) => {
console.log("下載進度", data);
if (!that.loading) that.loading = true;
that.percent = data.percent;
that.speed = data.speed;
});
ipcRenderer.on("update-error", (event, data) => {
console.log(data);
that.$message.error(`安装包下载失败`);
that.loading = false;
});
ipcRenderer.on("downloaded", () => {
that.loading = false;
that.download();
});
},
methods: {
async checkUpdate() {
return new Promise((resolve, reject) => {
try {
axios
.get(`/checkUpdate?version=${this.version}`)
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err);
});
} catch (err) {
reject(err);
}
});
},
download() {
this.$confirm("新版本已下载,是否立即安装?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
showCancelButton: this.item.forcedUpdate === 0,
showClose: this.item.forcedUpdate === 0,
type: "success"
})
.then(() => {
ipcRenderer.send("install");
this.visible = false;
})
.catch(() => {});
},
incrementalUpdates() {
this.$confirm("新版本已下载,是否刷新页面", "提示", {
confirmButtonText: "确定",
showCancelButton: this.item.forcedUpdate === 0,
showClose: this.item.forcedUpdate === 0,
cancelButtonText: "取消",
type: "success"
})
.then(() => {
window.location.reload();
})
.catch(() => {});
},
async toUpdate(type) {
if (type === 1) {
this.visible = false;
if (this.loading) return;
} else {
this.loading = true;
}
if (!this.item.fileList || this.item.fileList.length === 0) {
return this.$message.warning("缺少更新文件");
}
console.log("开始下载");
if (this.item.fullUpdate) {
// 全量更新
const domain = "https://console.jomalls.com";
this.item.url =
domain + this.item.fileList[0].versionPath.replace("/data", "");
console.log(this.item.url);
ipcRenderer.send("toUpdateApp", this.item);
} else {
try {
this.loading = false;
await this.$api.post("/incrementalUpdates", {
url: this.item.fileList[0].fileUrl.replace("/data", "")
});
this.incrementalUpdates();
} catch (e) {
// this.$message.warning("更新失败");
}
}
},
open(data) {
this.item = data;
this.visible = true;
}
}
};
</script>
<template>
<el-dialog
:show-close="item.forcedUpdate === 0"
destroy-on-close
:close-on-press-escape="false"
:close-on-click-modal="false"
width="500px"
:title="item.title"
:visible.sync="visible"
>
<pre>{{ item.content }}</pre>
<!-- <el-progress :text-inside="true" :stroke-width="26" :percentage="percent"></el-progress>-->
<template slot="footer">
<el-button
@click="visible = false"
v-if="item.forcedUpdate === 0"
size="small"
>关闭
</el-button>
<!-- <el-button @click="toUpdate(1)" size="small" type="warning"-->
<!-- >后台更新-->
<!-- </el-button-->
<!-- >-->
<el-button
@click="toUpdate(2)"
size="small"
type="primary"
:loading="loading"
>
{{ loading ? `正在下载中(${percent}%)` : "确定更新" }}
</el-button>
</template>
</el-dialog>
</template>
<style scoped lang="less"></style>
<script>
export default {
data() {
return {
rules: {
company: [
{ validator:this.validatePass, message: "请检查客户名称", required: true, trigger: "blur" },
],
loginName: [
{ message: "请输入用户名", required: true, trigger: "blur" },
],
password: [{ message: "请输入密码", required: true, trigger: "blur" }],
},
companyList: [],
userList: [],
company: null,
authorityVisible: false,
remember: true,
authorityForm: {},
form: {
loginName: "",
user: "",
company: "",
password: "",
},
};
},
created() {
// this.len = Object.keys(this.$dataStore.store).length
console.log(this.$dataStore, "this.$dataStore");
// this.$dataStore.set('console_deviceId_Zhe Wang','920d79c4748c2a3c4111fb878ffe44a2')
this.company = this.$dataStore.get("company");
this.userList = this.$dataStore.get("userList") || [];
if (this.company) {
this.form.company = this.company.domain.replace('.jomalls.com','');
}
// if (user) {
// return this.$router.push('/design')
// }
this.getCompanyList();
},
mounted() {
document.addEventListener("keyup", this.keyUp);
},
beforeDestroy() {
document.removeEventListener("keyup", this.keyUp);
},
methods: {
keyUp(e) {
console.log(e);
if (e.keyCode === 13) {
this.login();
}
},
submitAuthority() {
this.$refs.authorityForm.validate((v) => {
if (v) {
this.$api
.post(
"/commitApply",
{
...this.authorityForm,
...this.form,
},
{
headers: {
company: this.form.company +'.jomalls.com',
},
}
)
.then((res) => {
if (res.code === 200) {
this.authorityVisible = false;
this.$message.success("申请提交成功");
this.$dataStore.set(
this.form.company + "_deviceId_" + this.form.loginName,
res.data.id
);
}
});
}
});
},
validatePass(rule, value, callback) {
if (!value || value === "") {
return callback(new Error("请输入客户(例如demo)"));
}
let item = this.companyList.find(
(item) => item.domain.replace(".jomalls.com", "") === value
);
if (item) {
return callback();
} else {
return callback(new Error("未查找到该客户"));
}
},
async login() {
// if (this.form.auth) {
// this.$dataStore.set(this.form.auth.split(",")[0], this.form.auth.split(",")[1]);
// console.log("存储成功");
// console.log(this.$dataStore.store);
//
// }
this.$refs.formRef.validate(async (valid) => {
if (valid) {
let f = JSON.parse(JSON.stringify(this.form));
if (!f.deviceId) {
f.deviceId = this.$dataStore.get(
f.company + "_deviceId_" + this.form.loginName
);
}
if(f.company){
f.company = f.company.includes('.jomalls.com')?f.company:f.company+'.jomalls.com'
}
if (!f.deviceId) delete f.deviceId;
let { data, code, message } = await this.$api.post("/login", f);
if (code === 411) {
this.authorityVisible = true;
this.authorityForm = {};
return this.$message.error(message);
}
data = {
...data.sysUser,
...{
token: data.token,
},
};
delete data.sysMenus;
delete data.sysUser;
let item = this.companyList.find((item) => item.domain === f.company);
console.log(item, 111222);
this.$dataStore.set("user", data);
this.$dataStore.set("company", item);
console.log( this.$dataStore);
if (this.remember) {
let userList = this.$dataStore.get("userList");
if (userList) {
if (
!userList.find(
(el) =>
el.loginName === f.loginName && el.company === f.company
)
) {
userList.push(f);
}
} else {
userList = [f];
}
this.$dataStore.set("userList", userList);
}
await this.$router.push("/design");
}
});
},
userChange(v) {
if (v === "") {
this.form.deviceId = "";
return;
}
console.log(this.userList, v);
this.form.company = this.userList[v].company.replace('.jomalls.com','');
this.form.loginName = this.userList[v].loginName;
this.form.password = this.userList[v].password;
this.form.deviceId = this.userList[v].deviceId;
},
async getCompanyList() {
let { data } = await this.$api.get("/getCompanyList");
this.companyList = data.records;
},
},
};
</script>
<template>
<div class="login">
<div class="form-content">
<el-form ref="formRef" :rules="rules" size="small" :model="form">
<el-form-item v-if="userList.length > 0">
<el-select
@change="userChange"
filterable
style="width: 100%"
placeholder="登录记录"
v-model="form.user"
clearable
>
<template slot="prefix">
<i class="el-icon-monitor"></i>
</template>
<el-option
v-for="(it, i) in userList"
:key="i"
:label="`${it.loginName}(${it.company.split('.')[0]})`"
:value="i"
></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="!company" prop="company">
<!-- <el-select prefix-icon="el-icon-monitor" v-model="form.company">-->
<!-- <el-option v-for="(it,i) in companyList" :key="i" :label="it.companyName" :value="it.domain.replace('.jomalls.com','')"></el-option>-->
<!-- </el-select>-->
<el-input placeholder="客户(例如demo)" prefix-icon="el-icon-monitor" v-model="form.company"
clearable>
<template #append>
.jomalls.com
</template>
</el-input>
<!-- <el-select-->
<!-- filterable-->
<!-- style="width: 100%"-->
<!-- placeholder="系统"-->
<!-- v-model="form.company"-->
<!-- clearable-->
<!-- >-->
<!-- <template slot="prefix">-->
<!-- <i class="el-icon-monitor"></i>-->
<!-- </template>-->
<!-- <el-option-->
<!-- v-for="(it, i) in companyList"-->
<!-- :key="i"-->
<!-- :label="it.companyName"-->
<!-- :value="it.domain"-->
<!-- ></el-option>-->
<!-- </el-select>-->
</el-form-item>
<el-form-item prop="loginName">
<el-input
placeholder="用户名"
prefix-icon="el-icon-user"
v-model="form.loginName"
clearable
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
placeholder="密码"
show-password
prefix-icon="el-icon-lock"
type="password"
v-model="form.password"
clearable
></el-input>
</el-form-item>
<!-- <el-form-item v-if="len===0" prop="授权信息">-->
<!-- <el-input placeholder="授权信息" prefix-icon="el-icon-lock" v-model="form.auth"-->
<!-- clearable></el-input>-->
<!-- </el-form-item>-->
<div class="check">
<el-checkbox v-model="remember">记住账号</el-checkbox>
</div>
<el-form-item>
<div style="display: flex; justify-content: center">
<el-button
@keyup.enter.native="login"
@click="login"
type="primary"
style="width: 60%"
>登录</el-button
>
</div>
</el-form-item>
</el-form>
</div>
<el-dialog
:close-on-click-modal="false"
title="权限申请"
:visible.sync="authorityVisible"
top="15%"
width="400px"
>
<el-form
:model="authorityForm"
size="mini"
ref="authorityForm"
label-width="80px"
>
<el-form-item label="设备名称" prop="deviceName" required>
<el-input v-model="authorityForm.deviceName"></el-input>
</el-form-item>
<el-form-item label="授权类型" prop="authType" required>
<el-radio v-model="authorityForm.authType" label="1">
一次授权
</el-radio>
<el-radio v-model="authorityForm.authType" label="2">
永久授权
</el-radio>
</el-form-item>
</el-form>
<span slot="footer">
<el-button size="mini" @click="authorityVisible = false">
取 消
</el-button>
<el-button size="mini" type="primary" @click="submitAuthority">
提交
</el-button>
</span>
</el-dialog>
</div>
</template>
<style lang="less" scoped>
.check {
display: flex;
justify-content: flex-end;
margin-bottom: 15px;
}
.login {
width: 100%;
height: 100%;
background-image: url("../../assets/logo-bg.jpg");
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
.form-content {
width: 300px;
padding-top: 50px;
}
.el-icon-monitor {
position: relative;
left: 6px;
}
</style>
\ No newline at end of file
<script>
export default {
data() {
return {
rules: {
factoryCode: [
{ message: "请输入工厂编码", required: true, trigger: "blur" }
],
account: [{ message: "请输入账号", required: true, trigger: "blur" }],
password: [{ message: "请输入密码", required: true, trigger: "blur" }]
},
userList: [],
authorityVisible: false,
remember: true,
authorityForm: {},
form: {
factoryCode: "",
account: "",
password: ""
}
};
},
created() {
this.userList = this.$dataStore.get('userList') || []
},
mounted() {
document.addEventListener("keyup", this.keyUp);
},
beforeDestroy() {
document.removeEventListener("keyup", this.keyUp);
},
methods: {
keyUp(e) {
if (e.keyCode === 13) {
this.login();
}
},
async login() {
this.$refs.formRef.validate(async valid => {
if (valid) {
let f = JSON.parse(JSON.stringify(this.form));
let { data } = await this.$api.post("/login", f);
this.$dataStore.set("user", { ...data.sysUser,...{token:data.token} });
console.log(this.$dataStore);
if (this.remember) {
let userList = this.$dataStore.get("userList");
if (userList) {
if (
!userList.find(
el =>
el.account === f.account && el.factoryCode === f.factoryCode
)
) {
userList.push(f);
}
} else {
userList = [f];
}
this.$dataStore.set("userList", userList);
}
await this.$router.push("/design");
}
});
},
userChange(v) {
this.form.account = this.userList[v].account;
this.form.factoryCode = this.userList[v].factoryCode;
this.form.password = this.userList[v].password;
}
}
};
</script>
<template>
<div class="login">
<div class="form-content">
<el-form ref="formRef" :rules="rules" size="small" :model="form">
<el-form-item v-if="userList.length > 0">
<el-select
@change="userChange"
filterable
style="width: 100%"
placeholder="登录记录"
v-model="form.user"
clearable
>
<template slot="prefix">
<i class="el-icon-monitor"></i>
</template>
<el-option
v-for="(it, i) in userList"
:key="i"
:label="`${it.account}(${it.factoryCode})`"
:value="i"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="factoryCode">
<el-input
placeholder="工厂编码"
prefix-icon="el-icon-s-shop"
v-model="form.factoryCode"
clearable
></el-input>
</el-form-item>
<el-form-item prop="account">
<el-input
placeholder="账号"
prefix-icon="el-icon-user"
v-model="form.account"
clearable
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
placeholder="密码"
show-password
prefix-icon="el-icon-lock"
type="password"
v-model="form.password"
clearable
></el-input>
</el-form-item>
<div class="check">
<el-checkbox v-model="remember">记住账号</el-checkbox>
</div>
<el-form-item>
<div style="display: flex; justify-content: center">
<el-button
@keyup.enter.native="login"
@click="login"
type="primary"
style="width: 60%"
>登录</el-button
>
</div>
</el-form-item>
</el-form>
</div>
</div>
</template>
<style lang="less" scoped>
.check {
display: flex;
justify-content: flex-end;
margin-bottom: 15px;
}
.login {
width: 100%;
height: 100%;
background-image: url("../../assets/logo-bg.jpg");
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
.form-content {
width: 300px;
padding-top: 50px;
}
.el-icon-monitor {
position: relative;
left: 6px;
}
</style>
const path = require("path");
module.exports = {
// 基本路径
publicPath: process.env.NODE_ENV === "production" ? "" : "/",
// 输出文件目录
outputDir: process.env.NODE_ENV === "production" ? "dist" : "devdist",
// eslint-loader 是否在保存的时候检查
lintOnSave: false,
/** vue3.0内置了webpack所有东西,
* webpack配置,see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
**/
chainWebpack: config => {
const svgRule = config.module.rule("svg");
svgRule.uses.clear();
svgRule
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]",
include: ["./src/icons"]
});
config.module
.rule("pug")
.test(/\.pug$/)
.use("pug-html-loader")
.loader("pug-html-loader")
.end();
},
configureWebpack: config => {
config.resolve = {
// 配置解析别名
extensions: [".js", ".json", ".vue"], // 自动添加文件名后缀
alias: {
vue: "vue/dist/vue.js",
"@": path.resolve(__dirname, "./src"),
"@c": path.resolve(__dirname, "./src/components")
}
};
},
// 生产环境是否生成 sourceMap 文件
productionSourceMap: false,
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {
sass: {
prependData: `@import "./src/styles/main.css";`
}
},
// 启用 CSS modules for all css / pre-processor files.
requireModuleExtension: true // 是否开启支持‘foo.module.css’样式
},
// use thread-loader for babel & TS in production build
// enabled by default if the machine has more than 1 cores
parallel: require("os").cpus().length > 1,
/**
* PWA 插件相关配置,see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
*/
pwa: {},
// webpack-dev-server 相关配置
devServer: {
open: false, // 编译完成是否打开网页
host: "0.0.0.0", // 指定使用地址,默认localhost,0.0.0.0代表可以被外界访问
port: 8050, // 访问端口
https: false, // 编译失败时刷新页面
hot: true, // 开启热加载
hotOnly: false,
proxy: {
// 配置跨域
"/devApi": {
//要访问的跨域的api的域名
target: "http://localhost:3000",
ws: true,
changOrigin: true,
pathRewrite: {
"^/devApi": ""
}
}
},
overlay: {
// 全屏模式下是否显示脚本错误
warnings: true,
errors: true
},
before: app => {}
},
/**
* 第三方插件配置
*/
pluginOptions: {
electronBuilder: {
builderOptions: {
asar: false,
extraResources: [
{
from: "./print/",
to: "../print"
},
{
from: "./logs/",
to: "../logs"
}
]
}
}
}
};
const path = require("path");
module.exports = {
// 基本路径
publicPath: process.env.NODE_ENV === "production" ? "" : "/",
// 输出文件目录
outputDir: process.env.NODE_ENV === "production" ? "dist" : "devdist",
// eslint-loader 是否在保存的时候检查
lintOnSave: false,
/** vue3.0内置了webpack所有东西,
* webpack配置,see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
**/
chainWebpack: config => {
const svgRule = config.module.rule("svg");
svgRule.uses.clear();
svgRule
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]",
include: ["./src/icons"]
});
config.module
.rule("pug")
.test(/\.pug$/)
.use("pug-html-loader")
.loader("pug-html-loader")
.end();
},
configureWebpack: config => {
config.resolve = {
// 配置解析别名
extensions: [".js", ".json", ".vue"], // 自动添加文件名后缀
alias: {
vue: "vue/dist/vue.js",
"@": path.resolve(__dirname, "./src"),
"@c": path.resolve(__dirname, "./src/components")
}
};
},
// 生产环境是否生成 sourceMap 文件
productionSourceMap: false,
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {
sass: {
prependData: `@import "./src/styles/main.css";`
}
},
// 启用 CSS modules for all css / pre-processor files.
requireModuleExtension: true // 是否开启支持‘foo.module.css’样式
},
// use thread-loader for babel & TS in production build
// enabled by default if the machine has more than 1 cores
parallel: require("os").cpus().length > 1,
/**
* PWA 插件相关配置,see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
*/
pwa: {},
// webpack-dev-server 相关配置
devServer: {
open: false, // 编译完成是否打开网页
host: "0.0.0.0", // 指定使用地址,默认localhost,0.0.0.0代表可以被外界访问
port: 8050, // 访问端口
https: false, // 编译失败时刷新页面
hot: true, // 开启热加载
hotOnly: false,
proxy: {
// 配置跨域
"/devApi": {
//要访问的跨域的api的域名
target: "http://localhost:3000",
ws: true,
changOrigin: true,
pathRewrite: {
"^/devApi": ""
}
}
},
overlay: {
// 全屏模式下是否显示脚本错误
warnings: true,
errors: true
},
before: app => {}
},
/**
* 第三方插件配置
*/
pluginOptions: {
electronBuilder: {
builderOptions: {
asar: false,
extraResources: [
{
from: "./print/",
to: "../print"
},
{
from: "./logs/",
to: "../logs"
},
{
from: "./config/",
to: "../config"
}
]
}
}
}
};
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