Commit b28530b1 by 朱哲铨

项目初始化

parents
> 1%
last 2 versions
module.exports = {
root: true,
env: {
node: true
},
extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
parserOptions: {
parser: "babel-eslint"
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
}
};
.DS_Store
node_modules
/dist
/dist_electron
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
#Electron-builder output
/dist_electron
\ No newline at end of file
This diff is collapsed. Click to expand it.
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
};
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "vue-exectron-express-lowdb",
"productName": "Jomall Graphics Lab",
"description": "",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"electron:build": "vue-cli-service electron:build",
"electron:serve": "nodemon --watch src/backend --exec vue-cli-service electron:serve",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps"
},
"main": "background.js",
"dependencies": {
"@gausszhou/vue-drag-resize-rotate": "^2.0.15",
"@vue/composition-api": "^0.3.4",
"axios": "^0.19.2",
"core-js": "^3.6.4",
"electron-store": "^4.0.0",
"element-ui": "^2.13.0",
"express": "^4.17.1",
"lodash-id": "^0.14.0",
"lowdb": "^1.0.0",
"morgan": "^1.10.0",
"multiparty": "^4.2.3",
"node-cmd": "^5.0.0",
"node-printer": "^1.0.4",
"nodemon": "^3.1.4",
"normalize.css": "^8.0.1",
"printer": "^0.4.0",
"shelljs": "^0.8.5",
"vue": "^2.6.11",
"vue-draggable-resizable": "^3.0.0",
"vue-i18n": "^8.16.0",
"vue-moveable": "^2.0.0-beta.75",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-eslint": "^4.2.0",
"@vue/cli-plugin-router": "^4.2.0",
"@vue/cli-plugin-vuex": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.0.3",
"electron": "^6.0.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^6.1.2",
"prettier": "^1.19.1",
"pug": "^2.0.4",
"pug-html-loader": "^1.1.5",
"pug-plain-loader": "^1.0.0",
"vue-cli-plugin-electron-builder": "^1.4.6",
"vue-template-compiler": "^2.6.11"
}
}
{
"name": "vue-node-lowdb",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"electron:build": "vue-cli-service electron:build",
"electron:serve": "vue-cli-service electron:serve",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps"
},
"main": "background_simple.js",
"dependencies": {
"@vue/composition-api": "^0.3.4",
"axios": "^0.19.2",
"core-js": "^3.6.4",
"element-ui": "^2.13.0",
"express": "^4.17.1",
"lodash-id": "^0.14.0",
"lowdb": "^1.0.0",
"morgan": "^1.10.0",
"normalize.css": "^8.0.1",
"vue": "^2.6.11",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-eslint": "^4.2.0",
"@vue/cli-plugin-router": "^4.2.0",
"@vue/cli-plugin-vuex": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.0.3",
"electron": "^6.0.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^6.1.2",
"node-sass": "^4.13.1",
"prettier": "^1.19.1",
"pug": "^2.0.4",
"pug-html-loader": "^1.1.5",
"pug-plain-loader": "^1.0.0",
"sass-loader": "^8.0.2",
"vue-cli-plugin-electron-builder": "^1.4.6",
"vue-template-compiler": "^2.6.11"
}
}
<?xml version="1.0" encoding="utf-8"?>
<GTOPTION xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<szFileName />
<uiCopies>1</uiCopies>
<byPlatenSize>1</byPlatenSize>
<bMultiple>1</bMultiple>
<byResolution>1</byResolution>
<byInk>1</byInk>
<byInkVolume>1</byInkVolume>
<byDoublePrint>1</byDoublePrint>
<bySaturation>1</bySaturation>
<byBrightness>1</byBrightness>
<byContrast>1</byContrast>
<iCyanBalance>1</iCyanBalance>
<iMagentaBalance>1</iMagentaBalance>
<iYellowBalance>1</iYellowBalance>
<iBlackBalance>1</iBlackBalance>
<bUniPrint>1</bUniPrint>
</GTOPTION>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<GTOPTION xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<szFileName />
<uiCopies>1</uiCopies>
<byPlatenSize>1</byPlatenSize>
<byHighlight>1</byHighlight>
<byMask>1</byMask>
<bDivide>1</bDivide>
<bTransColor>1</bTransColor>
<bySaturation>1</bySaturation>
<byBrightness>1</byBrightness>
<byContrast>1</byContrast>
<bUniPrint>1</bUniPrint>
<byResolution>1</byResolution>
<byInk>1</byInk>
</GTOPTION>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<GTOPTION xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<szFileName />
<uiCopies>1</uiCopies>
<byPlatenSize>1</byPlatenSize>
<bEcoMode>1</bEcoMode>
<byInk>1</byInk>
<bMaterialBlack>1</bMaterialBlack>
<bMultiple>1</bMultiple>
<byHighlight>1</byHighlight>
<byMask>1</byMask>
<bFastMode>1</bFastMode>
<bDivide>1</bDivide>
<bPause>1</bPause>
<bTransColor>1</bTransColor>
<byChoke>1</byChoke>
<byMinWhite>1</byMinWhite>
<bySaturation>1</bySaturation>
<byBrightness>1</byBrightness>
<byContrast>1</byContrast>
<iCyanBalance>1</iCyanBalance>
<bUniPrint>1</bUniPrint>
<iMagentaBalance>1</iMagentaBalance>
<iYellowBalance>1</iYellowBalance>
<iBlackBalance>1</iBlackBalance>
<byResolution>1</byResolution>
</GTOPTION>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<GTOPTION xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<szFileName />
<uiCopies>1</uiCopies>
<byPlatenSize>1</byPlatenSize>
<byResolution>1</byResolution>
<byInk>1</byInk>
<bMultiple>1</bMultiple>
<byInkVolume>1</byInkVolume>
<byDoublePrint>1</byDoublePrint>
<bySaturation>1</bySaturation>
<byBrightness>1</byBrightness>
<byContrast>1</byContrast>
<iBlackBalance>1</iBlackBalance>
<bUniPrint>1</bUniPrint>
</GTOPTION>
\ No newline at end of file
GTXproCMD.exe print -X "Profile\CO12.xml" -I "Input\sample.png" -A "Output\pO12.arxp" -S 01000200 -L 02540254
echo %errorlevel%
\ No newline at end of file
GTXproCMD.exe send -A "D:\sample\Output\pO12.arxp" -P "Brother GTX pro" -D 1
echo %errorlevel%
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {}
}
</script>
<style>
body {
margin: 0;
height: 100vh;
}
#app {
height: 100vh;
display: flex;
overflow: hidden;
width: 100vw;
flex-direction: column;
}
</style>
import express from "express";
import router from "./routes/be_routes.js";
const PORT = 3000;
const webApp = express();
//webApp.use(logger("./logs"));
webApp.use(express.json());
webApp.use(express.urlencoded({ extended: false }));
webApp.use("/", router);
// catch 404
webApp.use((req, res, next) => {
res.status(404).send("Sorry! 404 Error.");
});
// error handler, 4个参数
webApp.use((err, req, res, next) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
res.json({
message: err.message,
error: err
});
});
webApp.set("port", PORT);
webApp.listen(PORT, () => console.log(`App listening on port ${PORT}`));
export { webApp as default };
import {downloadImage, toSend, writeProfileXml} from "@/backend/webserver/utils";
var uuid = require("uuid");
const path = require('path');
const fs = require('fs');
const os = require('os');
import axios from "axios";
var multiparty = require("multiparty");
let fn = new Object();
fn.getPodProductionInfo = 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}})
if (data.code === 200 && data.data && data.data.length > 0) {
downloadImage(data.data, company, data => {
res.json({code: 200, data})
}, (err) => {
res.json({code: 500, msg: '素材图下载失败'})
})
} else {
res.json({code: 200, msg: '未找到素材图', data: []})
}
} catch (err) {
console.log(err)
res.json({code: 500, msg: '接口调用失败'})
}
}
fn.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`, {
params: q,
headers: {'jwt-token': token}
})
res.json(data)
} catch (err) {
res.json({code: 500, msg: err})
}
}
fn.getCompanyList = async (req, res) => {
try {
let {data} = await axios.get('https://platform.jomalls.com/api/tools/getCompanyList')
res.send(data)
} catch (err) {
console.log(err)
res.json({code: 500, msg: err})
}
}
fn.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})
}
}
fn.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}
})
res.json(data)
} catch (err) {
res.json({code: 500, msg: err})
}
}
fn.downloadByDesignId = async (req, res) => {
const token = req.headers["jwt-token"]
const company = req.headers["company"]
try {
let downloadByDesignId = await axios.post(`https://${company}/api/podDesignCenter/downloadByDesignId`, req.body, {
headers: {'jwt-token': token, responseType: 'blob',}
})
console.log(downloadByDesignId.headers)
const dispositionStr = downloadByDesignId.headers['content-disposition']
if (dispositionStr == null || dispositionStr === '') {
return res.json({code: 500, msg: '下载失败'})
}
let dispositionArr = dispositionStr.split(';')[1].split('filename=')[1]
let fileName = decodeURIComponent(dispositionArr)
let dir = path.join(os.homedir(), '/Desktop/' + fileName)
console.log(dir,'dir')
let ws=fs.createWriteStream(dir );
ws.write(downloadByDesignId.data);
ws.on('drain',function () {
console.log("内存干了");
});
ws.on('error',function (err) {
res.json({code: 500, msg: '文件下载失败'})
});
ws.on('close',function (err) {
});
ws.end()
res.json({code: 200, msg: fileName + '已下载到桌面'})
} catch (err) {
console.log(err)
res.json({code: 500, msg: err})
}
}
fn.uploadImage = async (req, res) => {
try {
const p = path.join(process.cwd(), './print/Input/')
let fileName = uuid.v4() + ".png";
console.log(fileName)
const form = new multiparty.Form({uploadDir: p});
form.parse(req, function (err, fields, files) {
console.log(fields, files, err)
if (err) {
res.send({code: 500, err})
} else {
fs.renameSync(files.file[0].path, path.join(p, fileName))
res.json({code: 200, data: {fileName, url: path.join(process.cwd(), './print/Input/' + fileName)}})
}
});
} catch (err) {
console.log(err)
res.json({code: 500, msg: err})
}
}
fn.getPngImg = async (req, res) => {
try {
const filePath = path.join(process.cwd(), `./print/Input/${req.body.fileName}`);
console.log(filePath)
// 给客户端返回一个文件流 type类型
res.set('content-type', {"png": "image/png", "jpg": "image/jpeg"});//设置返回类型
let stream = fs.createReadStream(filePath);
let responseData = [];//存储文件流
if (stream) {//判断状态
stream.on('data', function (chunk) {
responseData.push(chunk);
});
stream.on('end', function () {
const finalData = Buffer.concat(responseData);
res.write(finalData);
res.end();
});
}
} catch (err) {
res.send({code: 500, msg: err})
}
}
fn.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})
res.send(data)
} catch (err) {
console.log(err)
res.json({code: 500, msg: err})
}
}
fn.toPrint = (req, res) => {
let body = req.body;
writeProfileXml(body) // 写入xml文件
// GTXproCMD.exe print -X "Profile\\CO12.xml" -I "Input\\sample.png" -A "Output\\pO12.arxp" -S 03000400 -L 02540254
toSend(body).then(r => {
res.send({code: 200, msg: '操作成功'})
}).catch(err => {
res.send({code: 500, msg: err})
})
};
export {fn as default};
import express from "express";
import fn from "../entity/function.js";
import {getPodProductionInfo, sendImg} from "@/backend/webserver/utils";
let router = express.Router();
router.post("/toPrint", fn.toPrint);
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);
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");
// 下载素材
export const downloadImage = (list, company, callback, errorBack = null) => {
try {
let dirPath = path.join(process.cwd(), "./print/Input/");
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
for (let i = 0; i < list.length; i++) {
if (!list[i].productionFile) return
if (!list[i].productionFile.includes('http')) return;
let fileName = uuid.v4() + ".png";
let p = path.join(process.cwd(), './print/Input/' + fileName)
let stream = fs.createWriteStream(p);
list[i].fileName = fileName
request(list[i].productionFile).pipe(stream).on("close", function (err) {
console.log("文件[" + fileName + "]下载完毕");
if (i === list.length - 1) {
callback && callback(list)
}
});
}
} catch (err) {
console.log(err)
errorBack && errorBack(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, stdout2, stderr2) => {
console.log(stdout2, 1)
console.log(stderr2, 2)
console.log(err2, 4)
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('操作出现问题')
}
})
})
}
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)
}
}
"use strict";
import {contextBridge, ipcMain, ipcRenderer} from 'electron'
import {app, protocol, BrowserWindow, Menu, screen} from "electron";
import {createProtocol} from "vue-cli-plugin-electron-builder/lib";
import webApp from "@/backend/webserver/be_nodeSrv.js"
let isCreateWin = false
const isDevelopment = process.env.NODE_ENV !== "production";
let win;
let otherWindow;
protocol.registerSchemesAsPrivileged([
{scheme: "app", privileges: {secure: true, standard: true}}
]);
const winURL = process.env.NODE_ENV === 'development'
? 'http://localhost:8090'
: `file://${__dirname}/index.html`
function createWindow() {
win = new BrowserWindow({
width: 1500,
height: 1000,
icon: "./src/assets/logo.png",
webPreferences: {
webSecurity: false,
nodeIntegration: true,
// preload: path.join(__dirname, "./preload.js")
}
});
let displays = screen.getAllDisplays();
//寻找副屏幕
let externalDisplay = displays.find((display) => {
return display.bounds.x !== 0 || display.bounds.y !== 0
})
if (externalDisplay) {
otherWindow = new BrowserWindow({
fullscreen: false,
width: externalDisplay.bounds.width,
height: externalDisplay.bounds.height,
x: externalDisplay.bounds.x,
y: externalDisplay.bounds.y,
webPreferences: {
nodeIntegration: true,
//配置预加载脚本文件(preload),此处起名为preloadOther
//p.s.路径为绝对路径
// preload: path.join(__dirname, "./preloadOther.js")
}
})
//指定副屏幕打开的网页
otherWindow.loadURL(winURL + '#' + `/design-detail`);
otherWindow.on('closed', () => { //这一段放外面的话,如果你电脑没双屏会报错。
otherWindow = null
})
}
ipcMain.on('allPrint', () => {
// 获取到打印机列表
const printers = win.webContents.getPrinters()
// 把获取的打印机列表发送给渲染进程
win.webContents.send('printName', printers)
})
ipcMain.on('win-subScreen', (data, v) => {
if(otherWindow) otherWindow.webContents.send('getProductionNoInfo', v)
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
if (!process.env.IS_TEST) win.webContents.openDevTools();
} else {
createProtocol("app");
win.loadURL("app://./index.html");
}
ipcMain.on('send-card', (event, obj) => {
win.webContents.send('sendWebsockt', obj);
})
win.on("closed", () => {
win = null;
otherWindow = null;
});
}
app.on("activate", () => {
if (win === null) {
createWindow();
}
});
app.on("ready", async () => {
createWindow();
});
if (isDevelopment) {
if (process.platform === "win32") {
process.on("message", data => {
if (data === "graceful-exit") {
app.quit();
}
});
} else {
process.on("SIGTERM", () => {
app.quit();
});
}
}
import Vue from 'vue';
export default new Vue();
\ No newline at end of file
export const lang = {
slice: {
placeholder: {
name: "请输出切片名称",
nst: "请选择NST模板"
},
tips: {
sla: "带宽:{0} Mbps, 时延: {1} ms"
}
}
}
\ No newline at end of file
export const lang = {
slice: {
placeholder: {
name: "请输出切片名称",
nst: "请选择NST模板"
},
tips: {
sla: "带宽:{0} Mbps, 时延: {1} ms"
}
}
}
\ No newline at end of file
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import VueI18n from 'vue-i18n';
import VueCompositionApi from "@vue/composition-api";
import { Message } from "element-ui";
// 挂载到$message上
import api from '@/utils/axios'
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import dataStore from 'electron-store';
const DataStore = new dataStore();
Vue.config.productionTip = false;
Vue.use(ElementUI);
Vue.use(VueCompositionApi);
Vue.use(VueI18n);
Vue.prototype.$message = Message
Vue.prototype.$dataStore = DataStore
Vue.prototype.$store = store
Vue.prototype.$api = api
Vue.prototype.$message = Message
const i18n = new VueI18n({
locale: 'zh',
messages: {
'zh': require('./i18n/zh.js'),
'en': require('./i18n/en.js')
}
});
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount("#app");
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'login',
meta: {
title: '登录'
},
component: (resolve) => require(['../views/login/index.vue'], resolve)
},
{
path: '/design',
name: 'design',
meta: {
title: '设计页面'
},
component: (resolve) => require(['../views/design/index.vue'], resolve)
}, {
path: '/design-detail',
name: 'design',
meta: {
title: '设计详情页面'
},
component: (resolve) => require(['../views/design/detail/index.vue'], resolve)
}, {
path: '*',
redirect: '/'
},
];
const router = new VueRouter({
mode: "hash",
base: process.env.BASE_URL,
routes
});
// router.beforeEach((to, from, next) => {
// let user = Vue.prototype.$dataStore.get('user')
// if (to.name === 'login') {
// if (user) {
// console.log(1)
// return next({path:'/design'})
// } else {
// console.log(2)
// return next( )
// }
//
// } else {
// if (user) {
// if(!to.name) return next({path:'/design'})
// return next()
// } else {
// return next('/login')
// }
// }
//
// })
export default router;
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const defaultSetting = {
gridShow: 1,
language: 'cn',
gridValue: 1,
autoPrint: false,
gridSpacing: "10mm"
}
export default new Vuex.Store({
state: {
actionList:[],
imgList:[],
actionIndex:-1,
systemSetting: {
gridShow: 1,
gridValue: 1,
language: 'cn',
autoPrint: false,
gridSpacing: "10mm"
}
},
mutations: {
setDefaultSetting(state) {
state.systemSetting = JSON.parse(JSON.stringify(defaultSetting))
},
updateSystemSetting(state, f) {
state.systemSetting[f.field] = f.value
},
changeActionList(state, value) {
state.actionList = value
},
changeActionIndex(state, value) {
state.actionIndex = value
},
changeImgList(state, value) {
state.imgList = value
}
},
getters: {
systemSetting(state) {
return state.systemSetting;
},
getActionList(state) {
return state.actionList;
},
getActionIndex:(state)=> state.actionIndex,
imgList:(state)=> state.imgList
},
actions: {},
modules: {}
});
import axios from 'axios'
import Vue from 'vue'
import {Loading} from 'element-ui'
import router from "../router/index";
// 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 => {
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
*/
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) {
router.replace('/')
Vue.prototype.$message.error(res.msg || res.message || 'Error')
Vue.prototype.$dataStore.delete('user')
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(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
export default {
byInk:`
<b>油墨选择</b>
<p>选择所使用油墨的组合方式:</p>
<p>选择所使用油墨的组合方式:</p>
<p>彩色+白色油墨:在白色油墨的遮光层上打印彩色图像。</p>
<p>仅彩色油墨:在白底或淡色底上打印彩色图像。</p>
<p>仅黑色油墨:只使用黑色油墨,打印黑白图像。</p>
`,
bEcoMode:`
<b>模式</b>
<p>自动调整底材的白色油墨量,抑制整体的油墨消耗量。</p>
<p>但是,根据颜色,完成品的亮度有时会略微降低。</p>
`,
bMaterialBlack:
`
<b>利用底材的黑色</b>
<p>在黑色底材上打印时,利用底材的黑色打印时,设定为ON。</p>
<p>自动将黑色(RGB=0)作为透明色处理。</p>
<p>已在详细设置菜单中将其它颜色指定为透明色时,设定为OFF。</p>
`,
bMultiple:
`
<b>彩色的复合路径打印</b>
<p>彩色的复合路径打印是针对含有彩色的图像通过增加压板的进给次数(LF)来喷出更精细的油墨液滴。尽管打印时间变长,但可以更加细致地再现色彩。</p>
`,
byHighlight:
`
<b>高光</b>
<p>选择RGB=254的白度(浓度)。值越大,白度越增加。</p>
<p>打印HighlightCheckPattern.arxp选择适当的值。</p>
`,
byMask:
`
<b>遮光</b>
<p>调节底材的白色油墨量。</p>
<p>底材饱和度高时请增加。</p>
<p>1-2:用于浅粉及灰色等淡色底。</p>
<p>3:默认。用于黑白底(黑、灰)。</p>
<p>4:用于红色、紫色、绿色等鲜艳的底色。</p>
<p>5:在暗色区以外的所有区域中以最大白色油墨量打印。</p>
`,
bFastMode:
`
<b>白色高速打印</b>
<p>在白色油墨使用模式下高速打印。油墨量和浓度不变。</p>
<p>横纹明显时设定为OFF。</p>
`,
bDivide:
`
<b>白色分次打印</b>
<p>分两层,每层用一半的油墨量进行白色打印。
总油墨量不变。</p>
`,
bPause:
`
<b>白色/彩色个别打印</b>
<p>打印白色层后,暂停(等待时间)后打印彩色层。打印极小的图像时请选择。</p>
`,
bTransColor:
`
<b>透明色</b>
<p>指定打印时不使用油墨而是作为透明色处理的颜色。</p>
<p>根据颜色的再现性,建议取消选中[利用底材的黑色]。</p>
`,
byChoke:
`
<b>白色油墨的削减范围</b>
<p>通过减少白色油墨的打印范围,防止白色油墨从彩色油墨下露出。</p>
<p>通常为1-3,数字越大,白色油墨的削减量增力口。</p>
<p>如果原图像的周围能看到白色的线或点,很可能是“抗锯齿“导致,请确认原图像。</p>
`,
byMinWhite:
`
<b>最小白色油墨量</b>
<p>设置值越大,使用“彩色+白色油墨"打印时的暗色区域底材的白色油墨量越增加。</p>
<p>如果选择“特殊”,则设置值可以选择大于“3”的值。</p>
<p>请注意,设置值越大,越容易渗透。</p>
`,
bySaturation:
`
<b>饱和度</b>
<p>增加颜色的鲜艳度。请用于稍暗或色调不足的图像、CMYK颜色模式的图像、扫描仪的图像旁。</p>
`,
byBrightness:
`
<b>亮度</b>
<p>值越大,颜色变得越亮。</p>
`,
byContrast:
`
<b>对比度</b>
<p>使亮的颜色更亮、暗的颜色更暗,从而给呆板的图像增加颜色强弱。</p>
`,
iCyanBalance :
`
<b>青色</b>
<p>调整青色油墨量。</p>
<p>如果增加值,整体会偏向淡蓝色。</p>
<p>如果减少值,整体会偏红。</p>
`,
iMagentaBalance :
`
<b>红色</b>
<p>调整青色油墨量。</p>
<p>如果增加值,整体会偏向红紫色。</p>
<p>如果减少值,整体会偏绿。</p>
`,
iYellowBalance :
`
<b>黄色</b>
<p>调整黄色油墨量。</p>
<p>如果增加值,整体会偏黄。</p>
<p>如果减少值,整体会偏蓝。</p>
`,
iBlackBalance :
`
<b>黑色</b>
<p>调整黑色油墨量。</p>
<p>如果增加值,整体会偏黑。</p>
<p>如果减少值,整体会偏白。</p>
`,
printTime :
`
<b>打印时间</b>
<p>“x1”以按照高光5打印的时间作为标准。</p>
<p>提高高光增加了白色油墨量时打印时间变长。</p>
`,
whiteInk :
`
<b>白色油墨量</b>
<p>高光5的油墨量为“400%",以此作为标准。</p>
<p>实际油墨消耗量取决于打印图像内的色彩。请将其当作油墨消耗量的标准。</p>
`,
byInkVolume :
`
<b>油墨量</b>
<p>减少彩色油墨量以防止油墨渗透。</p>
<p>根据InkVolume.arxp的打印结果选择适当的值。</p>
<p>0 不减少油墨量。用于棉100%、麻和棉50%6/聚酯纤维50%的混纺材料。</p>
<p>9-7 用于薄T恤、厚毛巾、斜纹棉布</p>
<p>6-4 用于薄平纹织物和棉/聚酯纤维/聚氨酯混纺。</p>
<p>3-1用于聚酯纤维针织物和没有吸水性合成纤维。</p>
`,
bUniPrint :
`
<b>单向打印</b>
<p>将打印方向固定为一个方向。</p>
<p>优先执行来自打印机操作面板的指定,仅在打印机的设置是[自动]时有效。</p>
`
}
\ No newline at end of file
<script>
import PHead from './head/index.vue'
import PMain from './main/index.vue'
export default {
components: {PHead, PMain},
data() {
return {
user: {},
company:{}
}
},
mounted() {
this.user = this.$dataStore.get('user')
this.company = this.$dataStore.get('company')
console.log(this.$dataStore)
}
}
</script>
<template>
<div class="page">
<p-head :company="company" :user="user" />
<p-main/>
</div>
</template>
<style scoped>
.page {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
</style>
\ No newline at end of file
<script>
export default {
data() {
return {
drawerShow: false,
form: {
x: 0,
sx: 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 x_mm = Number((this.item.x * 0.84).toFixed(2).replace('.00', ''))
let w_mm = Number((this.item.w * 0.84).toFixed(2).replace('.00', ''))
let h_mm = Number((this.item.h * 0.84).toFixed(2).replace('.00', ''))
let y_mm = Number((this.item.y * 0.84).toFixed(2).replace('.00', ''))
// return
this.form.x = x_mm
this.form.y = y_mm
this.form.h = h_mm
this.form.w = w_mm
this.form.r = this.item.r
}
},
immediate: true,
deep: true,
}
},
methods: {
conversion_getDPI() {
var arrDPI = new Array;
if (window.screen.deviceXDPI) {
arrDPI[0] = window.screen.deviceXDPI;
arrDPI[1] = window.screen.deviceYDPI;
} else {
var tmpNode = document.createElement("DIV");
tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden";
document.body.appendChild(tmpNode);
arrDPI[0] = parseInt(tmpNode.offsetWidth);
arrDPI[1] = parseInt(tmpNode.offsetHeight);
tmpNode.parentNode.removeChild(tmpNode);
}
return arrDPI;
},
formChange() {
this.$emit('change', this.form)
},
addValue(f) {
let nw = Number(this.form[f]) + 1
this.$set(this.form, f, nw)
this.formChange()
},
reduceValue(f) {
let nw = Number(this.form[f]) - 1
this.$set(this.form, f, nw)
this.formChange()
},
}
}
</script>
<template>
<div class="drawer" :style="{animation:visible?`ltr-drawer-in .3s 1ms`:`ltr-drawer-out .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="sx">
<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" 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" 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="24">
<el-form-item label="r:">
<div class="form-content">
<el-input @blur="formChange" v-model="form.r">
<template slot="append">reg</template>
</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="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 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;
}
.set-value i {
width: 20px;
height: 12px;
display: block;
text-align: center;
line-height: 12px;
cursor: pointer;
border: 1px solid transparent;
}
.set-value i:hover {
border-color: #ececec;
}
.drawer .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%);
}
}
.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;
}
</style>
\ No newline at end of file
<script>
export default {
data() {
return {
rules: {
company: [{validator: this.validatePass, required: true, trigger: 'blur'}],
loginName: [{message: '请输入用户名', required: true, trigger: 'blur'}],
password: [{message: '请输入密码', required: true, trigger: 'blur'}],
},
companyList: [],
company: null,
authorityVisible: false,
authorityForm: {},
form: {
loginName: '',
company: '',
password: ''
}
}
},
created() {
let user = this.$dataStore.get('user')
this.company = this.$dataStore.get('company')
if (this.company) {
this.form.company = this.company.domain
}
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('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() {
this.$refs.formRef.validate(async valid => {
if (valid) {
let f = JSON.parse(JSON.stringify(this.form))
f.company = f.company.includes('.jomalls.com') ? f.company : f.company + '.jomalls.com'
f.deviceId = this.$dataStore.get('deviceId' + this.form.loginName)
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)
this.$message.success('登录成功')
await this.$router.push('/design')
}
})
},
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="!company" prop="company">
<el-input placeholder="客户(例如demo)" prefix-icon="el-icon-monitor" v-model="form.company"
clearable></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>
<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 scoped>
.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
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: 8090, // 访问端口
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: {
"extraResources": [
{
"from": "./print/",
"to": "../print"
}
]
}
}
}
};
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