页面完善
@@ -21,18 +21,22 @@ function createWindow () {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
useContentSize: true,
|
||||
show: false,
|
||||
fullscreen: true,
|
||||
fullscreen: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
webSecurity: false,
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.loadURL(winURL)
|
||||
require("@electron/remote/main").initialize();
|
||||
require("@electron/remote/main").enable(mainWindow.webContents);
|
||||
// 禁用默认菜单
|
||||
Menu.setApplicationMenu(null);
|
||||
// Menu.setApplicationMenu(null);
|
||||
mainWindow.maximize()
|
||||
mainWindow.show()
|
||||
mainWindow.loadURL(winURL)
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
|
||||
|
After Width: | Height: | Size: 568 B |
|
After Width: | Height: | Size: 574 B |
|
After Width: | Height: | Size: 488 B |
|
After Width: | Height: | Size: 618 B |
|
After Width: | Height: | Size: 369 B |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 698 B |
|
After Width: | Height: | Size: 544 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 789 B |
|
After Width: | Height: | Size: 262 B |
|
Before Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 658 B |
|
After Width: | Height: | Size: 770 KiB |
|
After Width: | Height: | Size: 993 B |
@@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<div id="wrapper">
|
||||
<img id="logo" src="~@/assets/logo.png" alt="electron-vue">
|
||||
<main>
|
||||
<div class="left-side">
|
||||
<span class="title">
|
||||
Welcome to your new project!
|
||||
</span>
|
||||
<system-information></system-information>
|
||||
</div>
|
||||
|
||||
<div class="right-side">
|
||||
<div class="doc">
|
||||
<div class="title">Getting Started</div>
|
||||
<p>
|
||||
electron-vue comes packed with detailed documentation that covers everything from
|
||||
internal configurations, using the project structure, building your application,
|
||||
and so much more.
|
||||
</p>
|
||||
<button @click="open('https://simulatedgreg.gitbooks.io/electron-vue/content/')">Read the Docs</button><br><br>
|
||||
</div>
|
||||
<div class="doc">
|
||||
<div class="title alt">Other Documentation</div>
|
||||
<button class="alt" @click="open('https://electron.atom.io/docs/')">Electron</button>
|
||||
<button class="alt" @click="open('https://vuejs.org/v2/guide/')">Vue.js</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SystemInformation from './LandingPage/SystemInformation'
|
||||
|
||||
export default {
|
||||
name: 'landing-page',
|
||||
components: { SystemInformation },
|
||||
methods: {
|
||||
open (link) {
|
||||
this.$electron.shell.openExternal(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro');
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body { font-family: 'Source Sans Pro', sans-serif; }
|
||||
|
||||
#wrapper {
|
||||
background:
|
||||
radial-gradient(
|
||||
ellipse at top left,
|
||||
rgba(255, 255, 255, 1) 40%,
|
||||
rgba(229, 229, 229, .9) 100%
|
||||
);
|
||||
height: 100vh;
|
||||
padding: 60px 80px;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
#logo {
|
||||
height: auto;
|
||||
margin-bottom: 20px;
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
main > div { flex-basis: 50%; }
|
||||
|
||||
.left-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.welcome {
|
||||
color: #555;
|
||||
font-size: 23px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #2c3e50;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.title.alt {
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc p {
|
||||
color: black;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc button {
|
||||
font-size: .8em;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
padding: 0.75em 2em;
|
||||
border-radius: 2em;
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
background-color: #4fc08d;
|
||||
transition: all 0.15s ease;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #4fc08d;
|
||||
}
|
||||
|
||||
.doc button.alt {
|
||||
color: #42b983;
|
||||
background-color: transparent;
|
||||
}
|
||||
</style>
|
||||
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="title">Information</div>
|
||||
<div class="items">
|
||||
<div class="item">
|
||||
<div class="name">Path:</div>
|
||||
<div class="value">{{ path }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="name">Route Name:</div>
|
||||
<div class="value">{{ name }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="name">Vue.js:</div>
|
||||
<div class="value">{{ vue }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="name">Electron:</div>
|
||||
<div class="value">{{ electron }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="name">Node:</div>
|
||||
<div class="value">{{ node }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="name">Platform:</div>
|
||||
<div class="value">{{ platform }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
electron: process.versions.electron,
|
||||
name: this.$route.name,
|
||||
node: process.versions.node,
|
||||
path: this.$route.path,
|
||||
platform: require('os').platform(),
|
||||
vue: require('vue/package.json').version
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
color: #888;
|
||||
font-size: 18px;
|
||||
font-weight: initial;
|
||||
letter-spacing: .25px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.items { margin-top: 8px; }
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.item .name {
|
||||
color: #6a6a6a;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.item .value {
|
||||
color: #35495e;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex_box flex_row_between top_box">
|
||||
<div class="flex_box top_left">
|
||||
<div @click="goHome" class="flex_box flex_row_center top_btn1">
|
||||
<img src="@/assets/images/Home_icon.png" />
|
||||
<div>回到主界面</div>
|
||||
</div>
|
||||
<div class="top_left_line"></div>
|
||||
<div class="flex_box flex_col_top tab_box">
|
||||
<div @click="goPath(item)" v-for="item in tabs" :key="item.id" class="flex_box flex_row_center flex_col tab_item" :class="{'tab_item1': active===item.id}">
|
||||
<div class="tab_name">{{item.name}}</div>
|
||||
<div class="tab_line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<user-info></user-info>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import UserInfo from '../userInfo/userInfo.vue';
|
||||
export default {
|
||||
name: 'TabBar',
|
||||
components: { UserInfo },
|
||||
props: {
|
||||
active: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tabs: [
|
||||
{
|
||||
id: 1,
|
||||
name: '系统管理',
|
||||
path: '/manage'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '用户管理',
|
||||
path: '/user'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '系统配置',
|
||||
path: '/set'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$router.go(-1)
|
||||
},
|
||||
goPath(e) {
|
||||
console.log(e)
|
||||
if (e.id === this.active) {
|
||||
return
|
||||
}
|
||||
this.$router.replace(e.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.top_box {
|
||||
height: 86px;
|
||||
padding: 0 32px;
|
||||
background-color: #ffffff;
|
||||
border-bottom: 8px solid #F8F8F8;
|
||||
.top_left {
|
||||
.top_btn1 {
|
||||
cursor: pointer;
|
||||
padding: 0 16px;
|
||||
height: 30px;
|
||||
background: #00C325;
|
||||
border-radius: 4px;
|
||||
margin-right: 16px;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
color: #FFFFFF;
|
||||
img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.top_left_line {
|
||||
width: 2px;
|
||||
height: 30px;
|
||||
background: #E0E0E0;
|
||||
margin: 0 16px;
|
||||
}
|
||||
.tab_box {
|
||||
.tab_item {
|
||||
padding: 20px 16px;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
color: #000000;
|
||||
line-height: 24px;
|
||||
cursor: pointer;
|
||||
.tab_name {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
.tab_line {
|
||||
display: none;
|
||||
width: 24px;
|
||||
height: 4px;
|
||||
background: #00C325;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.tab_item1 {
|
||||
color: #00C325;
|
||||
font-weight: bold;
|
||||
.tab_line {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex_box top_right">
|
||||
<div class="top_right_name">你好,{{name}}</div>
|
||||
<div @click="goOut" class="top_right_btn">登出</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'UserInfo',
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
methods: {
|
||||
goOut() {
|
||||
this.$store.dispatch('FedLogOut').then(() => {
|
||||
location.reload()// In order to re-instantiate the vue-router object to avoid bugs
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.top_right {
|
||||
.top_right_name {
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
color: #000000;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.top_right_btn {
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
color: #00C325;
|
||||
line-height: 50px;
|
||||
padding-left: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,96 @@
|
||||
// 第一步,导入必要的模块
|
||||
const fs = require('fs');
|
||||
const archiver = require('archiver');
|
||||
archiver.registerFormat('zip-encrypted', require("archiver-zip-encrypted"));
|
||||
function zip(filesList,zippath,callback,isPassword,pass)
|
||||
{
|
||||
// 第二步,创建可写流来写入数据
|
||||
const output = fs.createWriteStream(zippath);// 将压缩包保存到当前项目的目录下,并且压缩包名为test.zip
|
||||
if(isPassword)
|
||||
{
|
||||
|
||||
const archive = archiver.create('zip-encrypted',
|
||||
{
|
||||
zlib: {
|
||||
level: 8,//压缩等级
|
||||
},
|
||||
encryptionMethod: 'aes256',//加密方法
|
||||
password:pass ,//解压密码
|
||||
});
|
||||
|
||||
// 第三步,建立管道连接
|
||||
archive.pipe(output);
|
||||
|
||||
// 第四步,压缩多个文件到压缩包中
|
||||
for (let i in filesList) {
|
||||
console.log("压缩:")
|
||||
if(filesList[i].folder)
|
||||
{
|
||||
archive.directory(i, filesList[i].name);
|
||||
console.log(filesList[i].name)
|
||||
}else{
|
||||
archive.append(i, {name: filesList[i].name});
|
||||
console.log(filesList[i].name)
|
||||
}
|
||||
}
|
||||
|
||||
//监听所有archive数据都写完
|
||||
output.on('close', function() {
|
||||
setTimeout(() => {
|
||||
callback(true);
|
||||
}, 1000);
|
||||
console.log('压缩完成', archive.pointer() / 1024 / 1024 + 'M');
|
||||
});
|
||||
archive.on('error', function(err) {
|
||||
callback(false);
|
||||
console.log("压缩失败!");
|
||||
throw err;
|
||||
});
|
||||
|
||||
// 第五步,完成压缩
|
||||
archive.finalize();
|
||||
}else{
|
||||
const archive = archiver('zip', {zlib: {level: 9}});// 设置压缩等级
|
||||
|
||||
// 第三步,建立管道连接
|
||||
archive.pipe(output);
|
||||
|
||||
// 第四步,压缩多个文件到压缩包中
|
||||
for (let i in filesList) {
|
||||
console.log("压缩:")
|
||||
if(filesList[i].folder)
|
||||
{
|
||||
archive.directory(i, filesList[i].name);
|
||||
console.log(filesList[i].name)
|
||||
}else{
|
||||
var stream = fs.createReadStream(i);
|
||||
archive.append(stream, {name: filesList[i].name});
|
||||
console.log(filesList[i].name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//监听所有archive数据都写完
|
||||
output.on('close', function() {
|
||||
setTimeout(() => {
|
||||
callback(true);
|
||||
}, 1000);
|
||||
console.log('压缩完成', archive.pointer() / 1024 / 1024 + 'M');
|
||||
});
|
||||
archive.on('error', function(err) {
|
||||
callback(false);
|
||||
console.log("压缩失败!");
|
||||
throw err;
|
||||
});
|
||||
|
||||
// 第五步,完成压缩
|
||||
archive.finalize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
export {
|
||||
zip
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="progress">
|
||||
<div class="zip_text" v-if="isFalse" style="color: rgb(245, 31, 31)">
|
||||
{{ $t("dialog.compressFailed") }}
|
||||
</div>
|
||||
<div class="zip_text" v-else-if="isOver" style="color: rgb(103, 194, 58)">
|
||||
{{ $t("dialog.compressOver") }}
|
||||
</div>
|
||||
<div class="zip_text" v-else style="color: rgb(77, 77, 77)">
|
||||
{{ $t("dialog.compressing") }}
|
||||
</div>
|
||||
|
||||
<el-progress :percentage="percentage" :status="status"></el-progress>
|
||||
</div>
|
||||
<!-- status="success" -->
|
||||
<!-- <el-progress :percentage="100" status="warning"></el-progress>
|
||||
<el-progress :percentage="50" status="exception"></el-progress> -->
|
||||
<div class="last">
|
||||
<div class="text" v-if="isOver || isFalse">
|
||||
{{ $t("dialog.closeTips") }}
|
||||
</div>
|
||||
<div class="text" v-else>{{ $t("dialog.waitTips") }}</div>
|
||||
<div class="button">
|
||||
<el-button
|
||||
type="success"
|
||||
@click="changevisiable(false)"
|
||||
:disabled="!isOver"
|
||||
>{{ $t("dialog.over") }}</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let interval;
|
||||
export default {
|
||||
name: "archiverdialog",
|
||||
props: {
|
||||
isOver: {
|
||||
type: Boolean,
|
||||
},
|
||||
isFalse: {
|
||||
type: Boolean,
|
||||
},
|
||||
changevisiable: {
|
||||
type: Function,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
percentage: 0,
|
||||
status: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
interval = setInterval(() => {
|
||||
this.percentage++;
|
||||
}, 250);
|
||||
},
|
||||
watch: {
|
||||
percentage: {
|
||||
handler(val) {
|
||||
if (this.percentage > 98) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
isOver: {
|
||||
handler(val) {
|
||||
if (this.isOver) {
|
||||
clearInterval(interval);
|
||||
this.percentage = 100;
|
||||
this.status = "success";
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
isFalse: {
|
||||
handler(val) {
|
||||
if (this.isFalse) {
|
||||
clearInterval(interval);
|
||||
this.status = "exception";
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.progress {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.zip_text {
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.el-progress {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.last {
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
margin-top: 35px;
|
||||
.button {
|
||||
float: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
width: 50%;
|
||||
.el-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
line-height: 30px;
|
||||
float: left;
|
||||
width: 50%;
|
||||
font-size: 12px;
|
||||
color: gray;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
// 使用promisify方法来promise化指定方法
|
||||
const { promisify } = require("util");
|
||||
const stat = promisify(fs.stat);
|
||||
const readdir = promisify(fs.readdir);
|
||||
|
||||
// 异步
|
||||
export async function calcSize(dirPath, callback) {
|
||||
let fileSize = 0;
|
||||
let error = null;
|
||||
async function calc(dirPath) {
|
||||
try {
|
||||
const statObj = await stat(dirPath);
|
||||
if (statObj.isDirectory()) {
|
||||
const files = await readdir(dirPath);
|
||||
let dirs = files.map((item) => {
|
||||
return path.join(dirPath, item);
|
||||
});
|
||||
let index = 0;
|
||||
async function next() {
|
||||
if (index < dirs.length) {
|
||||
let current = dirs[index++];
|
||||
await calc(current);
|
||||
await next();
|
||||
}
|
||||
}
|
||||
return await next();
|
||||
} else {
|
||||
fileSize += statObj.size;
|
||||
}
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
}
|
||||
await calc(dirPath);
|
||||
callback(error, fileSize, dirPath);
|
||||
}
|
||||
|
||||
export function getFileName(name) {
|
||||
return name.substring(name.lastIndexOf("\\") + 1);
|
||||
}
|
||||
export function getExtension(name) {
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
export function bytesToSize(bytes) {
|
||||
if (bytes === 0) return "0 B";
|
||||
var k = 1024,
|
||||
sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
|
||||
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return (bytes / Math.pow(k, i)).toPrecision(3) + " " + sizes[i];
|
||||
}
|
||||
|
||||
export function isFolder(path) {
|
||||
let _stat = fs.lstatSync(path);
|
||||
return _stat.isDirectory();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
function copy(src, srcafter, isFolder, callback, fileList) {
|
||||
if (isFolder) {
|
||||
//复制文件夹
|
||||
fs.cp(src, srcafter, { recursive: true }, (err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
callback(fileList,false);
|
||||
}else{
|
||||
console.log("copyover");
|
||||
console.log("err");
|
||||
callback(fileList,true);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
// 复制文件
|
||||
fs.cp(src, srcafter, (err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
console.log("err");
|
||||
callback(fileList,false);
|
||||
}else{
|
||||
console.log("copyover");
|
||||
callback(fileList,true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
export { copy };
|
||||
//'./src/renderer/components/files/test'
|
||||
//'./src/renderer/components/files/testafter/tset'
|
||||
@@ -0,0 +1,369 @@
|
||||
<template>
|
||||
<div class="files">
|
||||
<div class="btn-group" v-show="false">
|
||||
<div class="btn" @click="addFolder()" style="color: #67c23a">
|
||||
<i class="el-icon-folder" />
|
||||
{{ $t("file.addFolder") }}
|
||||
</div>
|
||||
<div class="btn" @click="addFile()" style="color: #67c23a">
|
||||
<i class="el-icon-files" />
|
||||
{{ $t("file.addFile") }}
|
||||
</div>
|
||||
</div>
|
||||
<fileEmpty v-if="allNumber == 0" />
|
||||
<fileList v-else :list="filesList" :del="delFile" :key="key" />
|
||||
<div v-if="progressVisible">
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
width="500px"
|
||||
:visible.sync="progressVisible"
|
||||
:append-to-body="true"
|
||||
class="prodialog"
|
||||
>
|
||||
<progressdialog
|
||||
:list="filesList"
|
||||
:overNumber="overNumber"
|
||||
:allNumber="allNumber"
|
||||
:changevisiable="changeProgressvisible"
|
||||
:changestate="changestate"
|
||||
:isSucess="isSucess"
|
||||
ref="progressdialog"
|
||||
></progressdialog>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<div v-if="archiverVisible">
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
width="500px"
|
||||
:visible.sync="archiverVisible"
|
||||
:append-to-body="true"
|
||||
class="archiverDialog"
|
||||
:show-close="false"
|
||||
>
|
||||
<archiverdialog
|
||||
:isOver="archiverIsover"
|
||||
:isFalse="archiverIsfalse"
|
||||
:changevisiable="changeArchivervisible"
|
||||
></archiverdialog>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const { dialog } = require("@electron/remote");
|
||||
const fs = require("fs");
|
||||
import fileEmpty from "./fileEmpty";
|
||||
import fileList from "./fileList";
|
||||
import progressdialog from "./progressdialog";
|
||||
import archiverdialog from "./archiverdialog";
|
||||
import { calcSize, getFileName, isFolder } from "./calc";
|
||||
import { copy } from "./copy";
|
||||
import { zip } from "./archiver";
|
||||
export default {
|
||||
name: "Files",
|
||||
props: {
|
||||
onSizechange: {
|
||||
type: Function,
|
||||
},
|
||||
complete: {
|
||||
type: Function,
|
||||
},
|
||||
saveWorkList: {
|
||||
type: Object | undefined,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
fileEmpty,
|
||||
fileList,
|
||||
progressdialog,
|
||||
archiverdialog,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filesList: {},
|
||||
key: 0,
|
||||
allSize: 0,
|
||||
progressVisible: false,
|
||||
archiverVisible: false,
|
||||
overNumber: 0,
|
||||
allNumber: 0,
|
||||
nowstate: true,
|
||||
archiverIsover: false,
|
||||
archiverIsfalse: false,
|
||||
zip_path: "",
|
||||
isCopy: false,
|
||||
isSucess: true,
|
||||
copyPath: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// this.$set(this, filesList, this.saveWorkList)
|
||||
const _this = this;
|
||||
document.addEventListener("drop", (e) => {
|
||||
e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
for (const f of e.dataTransfer.files) {
|
||||
const isFolder = _this.dropFolderCheck(f);
|
||||
_this.insertList({
|
||||
name: getFileName(f.path),
|
||||
path: f.path,
|
||||
size: isFolder ? -1 : f.size,
|
||||
folder: isFolder,
|
||||
});
|
||||
|
||||
if (isFolder) {
|
||||
calcSize(f.path, _this.folderCalcCallback);
|
||||
}
|
||||
}
|
||||
});
|
||||
document.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
insertList(f) {
|
||||
if (!this.filesList[f.path]) {
|
||||
this.allNumber++;
|
||||
this.$set(this.filesList, f.path, f);
|
||||
if (f.size != -1) {
|
||||
// 是文件夹
|
||||
this.sizeChange(f.size);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
//有了,不用加入
|
||||
return false;
|
||||
}
|
||||
},
|
||||
addFile() {
|
||||
const _this = this;
|
||||
dialog
|
||||
.showOpenDialog({
|
||||
properties: ["multiSelections"],
|
||||
})
|
||||
.then(async (res) => {
|
||||
for (const item of res.filePaths) {
|
||||
await fs.stat(item, function (err, res) {
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
_this.insertList({
|
||||
name: getFileName(item),
|
||||
path: item,
|
||||
size: res.size,
|
||||
folder: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
addFolder() {
|
||||
const _this = this;
|
||||
dialog
|
||||
.showOpenDialog({
|
||||
properties: ["openDirectory", "multiSelections"],
|
||||
})
|
||||
.then((res) => {
|
||||
for (const item of res.filePaths) {
|
||||
const result = _this.insertList({
|
||||
name: getFileName(item),
|
||||
path: item,
|
||||
size: -1,
|
||||
folder: true,
|
||||
});
|
||||
if (result) {
|
||||
calcSize(item, _this.folderCalcCallback);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
folderCalcCallback(err, res, path) {
|
||||
if (this.filesList[path]) {
|
||||
this.filesList[path].size = res;
|
||||
this.$set(this.filesList, path, this.filesList[path]);
|
||||
this.sizeChange(this.filesList[path].size);
|
||||
}
|
||||
},
|
||||
delFile(path) {
|
||||
this.sizeChange(-this.filesList[path].size);
|
||||
delete this.filesList[path];
|
||||
this.key++;
|
||||
this.allNumber--;
|
||||
},
|
||||
dropFolderCheck(f) {
|
||||
//T是文件夹 F不是文件夹
|
||||
//拖放无法从参数判断是否为文件夹,需要额外处理
|
||||
if (f.size != 0 && f.size != 4096) {
|
||||
//返回大小不是0,则不是文件夹
|
||||
return false;
|
||||
}
|
||||
if (f.type != "") {
|
||||
//如果type不是空,则不是文件夹
|
||||
return false;
|
||||
}
|
||||
return isFolder(f.path);
|
||||
},
|
||||
sizeChange(size) {
|
||||
this.allSize = this.allSize + size;
|
||||
if (this.allSize <= 0) {
|
||||
this.allSize = 0;
|
||||
}
|
||||
this.onSizechange(this.allSize);
|
||||
},
|
||||
fileBack(fileList, Sucess) {
|
||||
if (Sucess) {
|
||||
if (this.nowstate) {
|
||||
this.isSucess = true;
|
||||
fileList.state = true;
|
||||
this.overNumber++;
|
||||
if (this.overNumber == this.allNumber) {
|
||||
setTimeout(() => {
|
||||
this.changeProgressvisible(false);
|
||||
this.complete();
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
console.log("终止!!!!");
|
||||
}
|
||||
} else {
|
||||
this.isSucess = false;
|
||||
if (this.nowstate) {
|
||||
fileList.state = false;
|
||||
} else {
|
||||
console.log("终止!!!!");
|
||||
}
|
||||
}
|
||||
},
|
||||
archiverBack(state) {
|
||||
if (state) {
|
||||
this.archiverIsover = true;
|
||||
this.complete();
|
||||
} else {
|
||||
this.archiverIsfalse = true;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.changeArchivervisible(false);
|
||||
}, 500);
|
||||
},
|
||||
resume(file_form) {
|
||||
//if (file_form == 0) {
|
||||
if (1) {
|
||||
if (this.isCopy) {
|
||||
this.overNumber = 0;
|
||||
this.changeProgressvisible(true);
|
||||
for (let i in this.filesList) {
|
||||
// const path = "D:\\copytest\\1\\" + this.filesList[i].name;
|
||||
const path = this.copyPath + this.filesList[i].name;
|
||||
console.log(this.copyPath);
|
||||
console.log(path);
|
||||
copy(
|
||||
i,
|
||||
path,
|
||||
this.filesList[i].folder,
|
||||
this.fileBack,
|
||||
this.filesList[i]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//2023-04-24修改为所有都只上传文件路径,不需要压缩
|
||||
//文件和文件夹
|
||||
this.overNumber = 0;
|
||||
for (let i in this.filesList) {
|
||||
// const path = "D:\\copytest\\1\\" + this.filesList[i].name;
|
||||
// copy(i, path, this.filesList[i].folder, this.back, this.filesList[i]);
|
||||
this.fileBack(this.filesList[i], true);
|
||||
}
|
||||
}
|
||||
} else if (file_form == 1) {
|
||||
//电子光盘
|
||||
} else if (file_form == 2) {
|
||||
//zip
|
||||
this.archiverIsover = false;
|
||||
this.archiverIsfalse = false;
|
||||
this.zip_path = "D:/archivertest/1.zip";
|
||||
zip(this.filesList, this.zip_path, this.archiverBack, false);
|
||||
} else if (file_form == 3) {
|
||||
//加密zip
|
||||
this.archiverIsover = false;
|
||||
this.archiverIsfalse = false;
|
||||
this.zip_path = "D:/archivertest/2.zip";
|
||||
let password = "123456";
|
||||
zip(this.filesList, this.zip_path, this.archiverBack, true, password);
|
||||
} else if (file_form == 4) {
|
||||
//u盘
|
||||
}
|
||||
},
|
||||
changeProgressvisible(visiable) {
|
||||
this.progressVisible = visiable;
|
||||
},
|
||||
changeArchivervisible(visiable) {
|
||||
this.archiverVisible = visiable;
|
||||
},
|
||||
changestate(state) {
|
||||
this.nowstate = state;
|
||||
},
|
||||
getLists() {
|
||||
return this.filesList;
|
||||
},
|
||||
haveFolderIsCalc() {},
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
};
|
||||
</script>
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style lang="less" scoped>
|
||||
.prodialog {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.archiverDialog {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
/deep/.el-dialog__header {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.files {
|
||||
width: 100%;
|
||||
background-color: #f5f5f5;
|
||||
margin: 10px auto 0;
|
||||
font-size: 12px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
height: 375px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
height: 30px;
|
||||
background-color: #e7e7ec;
|
||||
|
||||
.btn {
|
||||
color: #53809f;
|
||||
display: inline-block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 14px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #dfdfe4;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #d1d1d7;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div :style="'background-image:url(' + bgi + ');'" class="empty"></div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "fileEmpty",
|
||||
data() {
|
||||
return {
|
||||
fileList: [],
|
||||
};
|
||||
},
|
||||
methods: {},
|
||||
computed: {
|
||||
bgi() {
|
||||
return this.$t("work.dropBg");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.empty {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div class="list">
|
||||
<listItem v-for="(item, key) in list" :key="key" :info="item" :del="del" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import listItem from "./listItem";
|
||||
export default {
|
||||
name: "fileList",
|
||||
props: {
|
||||
list: {
|
||||
type: Object | Array,
|
||||
},
|
||||
del: {
|
||||
type: Function,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
listItem,
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {},
|
||||
};
|
||||
</script>
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style lang="less" scoped>
|
||||
.list {
|
||||
height: 374px;
|
||||
max-height: 374px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
/*滚动条整体样式*/
|
||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
/*滚动条里面小方块*/
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
background: #c7c7cb;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
/*滚动条里面轨道*/
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 10px;
|
||||
background: #ededed;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="listItem">
|
||||
<div class="item-body">
|
||||
<el-row :gutter="10" class="row">
|
||||
<el-col class="col file-name" :span="16">
|
||||
<img :src="getIcon(info.name)" class="icon" />
|
||||
<div class="name">{{ info.name }}</div>
|
||||
</el-col>
|
||||
<el-col class="col file-size" :span="5">{{
|
||||
getSize(info.size)
|
||||
}}</el-col>
|
||||
<el-col class="col file-delete" :span="3">
|
||||
<i class="el-icon-close close" @click="del(info.path)"></i>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import folder from "../../assets/files/folder.png";
|
||||
import pdf from "../../assets/files/pdf.png";
|
||||
import compress from "../../assets/files/compress.png";
|
||||
import unknown from "../../assets/files/unknown.png";
|
||||
import { bytesToSize, getExtension } from "./calc";
|
||||
const types = { compress: ["zip", "rar", "7z"], pdf: ["pdf"] };
|
||||
export default {
|
||||
name: "listItem",
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
},
|
||||
del: {
|
||||
type: Function,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.info);
|
||||
},
|
||||
methods: {
|
||||
getSize(size) {
|
||||
if (size == -1) {
|
||||
return this.$t("file.calculate");
|
||||
}
|
||||
return bytesToSize(size);
|
||||
},
|
||||
getIcon(name) {
|
||||
if (this.info.folder) {
|
||||
return folder;
|
||||
}
|
||||
console.log(getExtension(name));
|
||||
const ext = getExtension(name);
|
||||
|
||||
let icon = unknown;
|
||||
for (const typeName in types) {
|
||||
if (types[typeName].indexOf(ext) != -1) {
|
||||
//属于这个分类
|
||||
icon = this.typeToObj(typeName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return icon;
|
||||
},
|
||||
typeToObj(typeName) {
|
||||
if (typeName == "compress") {
|
||||
return compress;
|
||||
} else if (typeName == "pdf") {
|
||||
return pdf;
|
||||
} else if (typeName == "unknown") {
|
||||
return unknown;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style lang="less" scoped>
|
||||
.listItem {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.item-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-bottom: 1px solid #cdcdcd;
|
||||
}
|
||||
.row {
|
||||
height: 100%;
|
||||
}
|
||||
.col {
|
||||
height: 100%;
|
||||
}
|
||||
.file-name {
|
||||
padding-left: 20px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.name {
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.file-size {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
.file-delete {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.close {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
&:hover {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<div class="dialog">
|
||||
<div class="progress">
|
||||
<el-progress
|
||||
:percentage="parseInt(fake.progress * 100)"
|
||||
:format="format"
|
||||
></el-progress>
|
||||
<div class="txt">
|
||||
<div class="over">{{ overNumber }}</div>
|
||||
<div class="all">/{{ allNumber }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="records">
|
||||
<div class="record" v-for="(item, index) in progressList" :key="index">
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="state">
|
||||
<div v-if="item.state === true">{{ $t("dialog.haveOver") }}</div>
|
||||
<div v-else>{{ $t("dialog.notOver") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="last">
|
||||
<div class="text" v-if="allNumber === overNumber && isSucess">
|
||||
{{ $t("dialog.closeTips") }}
|
||||
</div>
|
||||
<div v-else-if="!isSucess" style="color: red">文件上传失败!!!</div>
|
||||
<div class="button">
|
||||
<el-button
|
||||
ref="btnStop"
|
||||
type="success"
|
||||
@click="stop()"
|
||||
:disabled="overNumber == allNumber || !isSucess"
|
||||
>{{ $t("dialog.stop") }}</el-button
|
||||
>
|
||||
<el-button
|
||||
ref="btnOver"
|
||||
type="success"
|
||||
@click="changevisiable(flase)"
|
||||
:disabled="overNumber != allNumber && isSucess"
|
||||
>{{ $t("dialog.over") }}</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import FakeProgress from "fake-progress";
|
||||
export default {
|
||||
name: "progressdialog",
|
||||
props: {
|
||||
list: {
|
||||
type: Object | Array,
|
||||
},
|
||||
overNumber: {
|
||||
type: Number,
|
||||
},
|
||||
allNumber: {
|
||||
type: Number,
|
||||
},
|
||||
changevisiable: {
|
||||
type: Function,
|
||||
},
|
||||
changestate: {
|
||||
type: Function,
|
||||
},
|
||||
isSucess: {
|
||||
type: Boolean,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
percentage: 0,
|
||||
progressList: [],
|
||||
fake: new FakeProgress({}),
|
||||
sub: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
format(percentage) {
|
||||
return;
|
||||
},
|
||||
getPercent(num, total) {
|
||||
num = parseFloat(num);
|
||||
total = parseFloat(total);
|
||||
if (isNaN(num) || isNaN(total)) {
|
||||
return "-";
|
||||
}
|
||||
return total <= 0 ? "0" : Math.round((num / total) * 10000) / 10000.0;
|
||||
},
|
||||
stop() {
|
||||
this.changestate(false);
|
||||
this.isSucess = false;
|
||||
this.$message({offset:100,
|
||||
message: this.$t("dialog.haveStop"),
|
||||
type: "warning",
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
//const aProgress = this.fake.createSubProgress({
|
||||
// timeConstant: 1000,
|
||||
// end: 0.1,
|
||||
// autoStart: true
|
||||
// })
|
||||
},
|
||||
watch: {
|
||||
overNumber: {
|
||||
// 数据发生变化就会调用这个函数
|
||||
handler(newVal, oldVal) {
|
||||
if (this.sub) {
|
||||
this.sub.end();
|
||||
//console.log("sub end");
|
||||
}
|
||||
|
||||
const newlist = [];
|
||||
for (let i in this.list) {
|
||||
if (this.list[i].state == true) {
|
||||
newlist.push(this.list[i]);
|
||||
} else {
|
||||
newlist.unshift(this.list[i]);
|
||||
}
|
||||
}
|
||||
this.progressList = newlist;
|
||||
if (this.overNumber == this.allNumber) {
|
||||
return;
|
||||
}
|
||||
this.sub = this.fake.createSubProgress({
|
||||
timeConstant: 10000,
|
||||
end: this.getPercent(this.overNumber + 1, this.allNumber),
|
||||
autoStart: true,
|
||||
});
|
||||
//console.log(
|
||||
// "overNumber/allNumber:" +
|
||||
// this.getPercent(this.overNumber + 1, this.allNumber)
|
||||
//);
|
||||
},
|
||||
// 立即处理 进入页面就触发
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
isSucess:{
|
||||
// 数据发生变化就会调用这个函数
|
||||
handler(newVal, oldVal) {
|
||||
if(!this.isSucess){
|
||||
this.sub.stop();
|
||||
}
|
||||
|
||||
},
|
||||
// 立即处理 进入页面就触发
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.dialog {
|
||||
}
|
||||
.progress {
|
||||
// border: 1px black solid;
|
||||
/deep/ .el-progress-bar {
|
||||
width: 97%;
|
||||
}
|
||||
/deep/.el-progress__text {
|
||||
float: right;
|
||||
}
|
||||
.txt {
|
||||
position: absolute;
|
||||
top: 55px;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
// border: 1px black solid;
|
||||
.over {
|
||||
// border: 1px black solid;
|
||||
color: rgb(103, 194, 58);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.all {
|
||||
// border: 1px black solid;
|
||||
color: black;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.records {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar {
|
||||
/*滚动条整体样式*/
|
||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
/*滚动条里面小方块*/
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
background: #c7c7cb;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
/*滚动条里面轨道*/
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 10px;
|
||||
background: #ededed;
|
||||
}
|
||||
}
|
||||
.record {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
.name {
|
||||
}
|
||||
.state {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.last {
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
.button {
|
||||
float: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
width: 50%;
|
||||
.el-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
line-height: 30px;
|
||||
float: left;
|
||||
width: 50%;
|
||||
font-size: 12px;
|
||||
color: gray;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,845 @@
|
||||
<template>
|
||||
<div class="add_box">
|
||||
<el-dialog center :visible.sync="addShow" width="80%" top="10vh" title="新建作业" :close-on-press-escape="false" :close-on-click-modal="false" :show-close="false">
|
||||
<div @click="close" class="close_box">
|
||||
<img src="@/assets/images/Close_icon.png" />
|
||||
</div>
|
||||
<div class="work_box">
|
||||
<div class="flex_box flex_row_between work_top">
|
||||
<div class="flex_box">
|
||||
<div class="flex_box work_top_item">
|
||||
<div class="work_top_label">容量:</div>
|
||||
<div class="work_top_val">
|
||||
<el-select v-model="form.capacity" placeholder="请选择">
|
||||
<el-option v-for="item in capacityList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box work_top_item">
|
||||
<div class="work_top_label">拷贝类型:</div>
|
||||
<div class="work_top_val">
|
||||
<el-select v-model="form.copy" placeholder="请选择">
|
||||
<el-option v-for="item in copyList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-popover v-model="setShow" placement="bottom-end" trigger="click">
|
||||
<div class="set_box">
|
||||
<div class="set_list">
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">优先级:</div>
|
||||
<div class="set_val">
|
||||
<el-select v-model="setForm.priority" placeholder="请选择">
|
||||
<el-option v-for="item in priorityList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">目标工作站:</div>
|
||||
<div class="set_val">
|
||||
<el-select v-model="setForm.stage" placeholder="请选择">
|
||||
<el-option v-for="item in stageList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">刻录速率:</div>
|
||||
<div class="set_val">
|
||||
<el-select v-model="setForm.speed" placeholder="请选择">
|
||||
<el-option v-for="item in speedList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">刻录完成后校验光盘:</div>
|
||||
<div class="set_val">
|
||||
<el-switch v-model="setForm.isCheck" active-color="#07C160" inactive-color="#aaa"> </el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">刻录完成后关闭光盘:</div>
|
||||
<div class="set_val">
|
||||
<el-switch v-model="setForm.isClose" active-color="#07C160" inactive-color="#aaa"> </el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">刻录完成后删除缓存:</div>
|
||||
<div class="set_val">
|
||||
<el-switch v-model="setForm.isDel" active-color="#07C160" inactive-color="#aaa"> </el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">作业失败打印标签:</div>
|
||||
<div class="set_val">
|
||||
<el-switch v-model="setForm.isPrint" active-color="#07C160" inactive-color="#aaa"> </el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box set_item">
|
||||
<div class="set_label">允许跨盘:</div>
|
||||
<div class="set_val">
|
||||
<el-switch v-model="setForm.isArrow" active-color="#07C160" inactive-color="#aaa"> </el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box flex_col_top set_item">
|
||||
<div class="set_label">分盘设置:</div>
|
||||
<div class="set_val">
|
||||
<el-radio-group v-model="setForm.disk">
|
||||
<el-radio :label="item.id" v-for="(item, index) in diskSet" :key="index">
|
||||
<div class="set_disk_name">{{ item.name }}</div>
|
||||
<div class="set_disk_desc">{{ item.desc }}</div>
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box flex_row_center set_btns">
|
||||
<el-button @click="setCancel" class="set_btn1">取消</el-button>
|
||||
<el-button @click="setSure" class="set_btn2" type="primary">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box work_top_set" slot="reference">
|
||||
<img src="@/assets/images/Setting_icon.png" />
|
||||
<div>高级作业设置</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="flex_box flex_col_top work_main">
|
||||
<div class="work_left">
|
||||
<div class="flex_box flex_row_between work_left_top">
|
||||
<div class="flex_box">
|
||||
<div class="work_left_top_label">内容</div>
|
||||
<div @click="addFolder" class="flex_box work_left_top_btn">
|
||||
<img src="@/assets/images/file_icon.png" />
|
||||
<div>添加文件夹</div>
|
||||
</div>
|
||||
<div @click="addFile" class="flex_box work_left_top_btn">
|
||||
<img src="@/assets/images/paper_icon.png" />
|
||||
<div>添加文件</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="work_left_top_input">
|
||||
<el-input placeholder="请输入卷标" v-model="form.volume">
|
||||
<template slot="prepend">卷标</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="work_files">
|
||||
<div class="work_files_box">
|
||||
<!-- 空文件 -->
|
||||
<file-empty v-if="!fileList.length"></file-empty>
|
||||
</div>
|
||||
<div class="work_files_progress">
|
||||
<div class="work_files_progress_content" :style="{ width: fileProgess + '%' }"></div>
|
||||
<div class="work_files_progress_text">0.0MB/0MB</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="work_right">
|
||||
<div class="flex_box work_right_top">
|
||||
<div class="flex_box">
|
||||
<div class="work_right_top_label">标签</div>
|
||||
<el-select v-model="form.capacity" placeholder="选择一个标签或点击创建标签">
|
||||
<el-option v-for="item in capacityList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
<div class="work_right_top_file">···</div>
|
||||
</div>
|
||||
<div class="work_right_top_add">新建标签</div>
|
||||
</div>
|
||||
<div class="wook_soon" :class="{ wook_soon1: !showList }">
|
||||
<div class="flex_box flex_row_center wook_soon_top">
|
||||
<img class="wook_soon_img" src="@/assets/images/soon.jpg" />
|
||||
<div @click="showList = !showList" class="flex_box flex_row_center wook_soon_btn" :class="{ wook_soon_btn1: !showList }">
|
||||
<img src="@/assets/images/Arrow_up_icon.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="wook_soon_list">
|
||||
<div v-for="(item, index) in soonList" :key="index" class="flex_box wook_soon_item">
|
||||
<div class="wook_soon_label">OUT_TEXT_4[正面]</div>
|
||||
<div class="wook_soon_input">
|
||||
<el-input v-model="item.value" placeholder="请输入"></el-input>
|
||||
</div>
|
||||
<div class="wook_soon_add">添加字段</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="flex_box flex_row_between footer_box">
|
||||
<div class="flex_box footer_main">
|
||||
<div class="footer_input">
|
||||
<el-input placeholder="请输入数量" v-model="form.number">
|
||||
<template slot="prepend">数量</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box footer_btns">
|
||||
<el-button type="primary" class="footer_save" @click="workSave">保存</el-button>
|
||||
<el-button type="primary" class="footer_submit" @click="workSubmit">提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const { dialog } = require('@electron/remote')
|
||||
import { mapGetters } from 'vuex'
|
||||
import fileEmpty from './files/fileEmpty'
|
||||
export default {
|
||||
name: 'UserInfo',
|
||||
components: { fileEmpty },
|
||||
data() {
|
||||
return {
|
||||
addShow: true,
|
||||
form: {
|
||||
number: 1,
|
||||
capacity: 1,
|
||||
copy: 1,
|
||||
volume: '2024-10-17'
|
||||
},
|
||||
capacityList: [
|
||||
{
|
||||
value: 1,
|
||||
label: '4GB'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '8GB'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '16GB'
|
||||
}
|
||||
],
|
||||
copyList: [
|
||||
{
|
||||
value: 1,
|
||||
label: '复制'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '打印'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '复制与打印'
|
||||
}
|
||||
],
|
||||
// 文件列表
|
||||
fileList: [],
|
||||
fileProgess: 30,
|
||||
// soon文件数据
|
||||
soonList: [
|
||||
{
|
||||
label: '正面',
|
||||
value: 'tj44545fsa13yt544r15e6h4r6'
|
||||
},
|
||||
{
|
||||
label: '二维码',
|
||||
value: 'soon'
|
||||
}
|
||||
],
|
||||
showList: true,
|
||||
setShow: false,
|
||||
setForm: {
|
||||
priority: 2,
|
||||
stage: 0,
|
||||
speed: 0,
|
||||
isCheck: true,
|
||||
isDel: true,
|
||||
isClose: true,
|
||||
isArrow: true,
|
||||
isPrint: true,
|
||||
disk: 1
|
||||
},
|
||||
priorityList: [
|
||||
{
|
||||
value: 1,
|
||||
label: '低'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '正常'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '高'
|
||||
}
|
||||
],
|
||||
stageList: [
|
||||
{
|
||||
value: 0,
|
||||
label: '任何'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '002A工作站'
|
||||
}
|
||||
],
|
||||
speedList: [
|
||||
{
|
||||
value: 0,
|
||||
label: 'Auto'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '低'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '中'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '高'
|
||||
}
|
||||
],
|
||||
diskSet: [
|
||||
{
|
||||
id: 1,
|
||||
name: '文件大小',
|
||||
desc: '按照文件大小进行排序分盘'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '文件名称',
|
||||
desc: '按照文件名称进行升序分盘'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '文件修改时间',
|
||||
desc: '按照文件修改时间进行升序分盘'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
methods: {
|
||||
// 选择文件
|
||||
addFile() {
|
||||
const _this = this
|
||||
dialog
|
||||
.showOpenDialog({
|
||||
properties: ['multiSelections']
|
||||
})
|
||||
.then(async (res) => {
|
||||
// for (const item of res.filePaths) {
|
||||
// await fs.stat(item, function (err, res) {
|
||||
// if (err) {
|
||||
// return false
|
||||
// }
|
||||
// _this.insertList({
|
||||
// name: getFileName(item),
|
||||
// path: item,
|
||||
// size: res.size,
|
||||
// folder: false
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
})
|
||||
},
|
||||
addFolder() {
|
||||
const _this = this
|
||||
dialog
|
||||
.showOpenDialog({
|
||||
properties: ['openDirectory', 'multiSelections']
|
||||
})
|
||||
.then((res) => {
|
||||
// for (const item of res.filePaths) {
|
||||
// const result = _this.insertList({
|
||||
// name: getFileName(item),
|
||||
// path: item,
|
||||
// size: -1,
|
||||
// folder: true
|
||||
// })
|
||||
// if (result) {
|
||||
// calcSize(item, _this.folderCalcCallback)
|
||||
// }
|
||||
// }
|
||||
})
|
||||
},
|
||||
// 保存
|
||||
workSave() {
|
||||
|
||||
},
|
||||
// 提交
|
||||
workSubmit() {
|
||||
|
||||
},
|
||||
show() {
|
||||
this.addShow = true
|
||||
},
|
||||
close() {
|
||||
this.addShow = false
|
||||
},
|
||||
// 高级设置
|
||||
setCancel() {
|
||||
this.setShow = false
|
||||
},
|
||||
setSure() {
|
||||
this.setShow = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.add_box {
|
||||
::v-deep {
|
||||
.el-dialog {
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.2);
|
||||
.el-dialog__header {
|
||||
padding: 28px 28px 18px 0 0;
|
||||
.el-dialog__title {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
.el-dialog__footer {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.close_box {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
padding: 24px 24px 0 0;
|
||||
img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
.work_box {
|
||||
padding: 0 28px;
|
||||
.work_top {
|
||||
height: 80px;
|
||||
.work_top_item {
|
||||
margin-right: 50px;
|
||||
.work_top_label {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.work_top_val {
|
||||
.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
width: 180px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.work_top_set {
|
||||
cursor: pointer;
|
||||
height: 36px;
|
||||
padding: 0 22px;
|
||||
background: rgba(0, 195, 37, 0.12);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(0, 195, 37, 0.32);
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #00c325;
|
||||
img {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.work_main {
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
.work_left {
|
||||
width: 50%;
|
||||
border-right: 1px solid #aaaaaa;
|
||||
padding: 0 16px 16px;
|
||||
.work_left_top {
|
||||
height: 72px;
|
||||
.work_left_top_label {
|
||||
font-size: 19px;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
padding-right: 18px;
|
||||
}
|
||||
.work_left_top_btn {
|
||||
cursor: pointer;
|
||||
height: 32px;
|
||||
padding: 0 22px;
|
||||
background: rgba(0, 195, 37, 0.12);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(0, 195, 37, 0.32);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #00c325;
|
||||
margin-right: 22px;
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.work_left_top_input {
|
||||
.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
::v-deep {
|
||||
.el-input-group__prepend {
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.el-input__inner {
|
||||
width: 180px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 16px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.work_files {
|
||||
height: 500px;
|
||||
cursor: pointer;
|
||||
.work_files_box {
|
||||
height: 478px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.work_files_progress {
|
||||
height: 22px;
|
||||
padding: 2px 0;
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
background-color: #ffe6e6;
|
||||
.work_files_progress_content {
|
||||
transition: all 0.5s;
|
||||
width: 0;
|
||||
height: 18px;
|
||||
background: #e54d4d;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.work_files_progress_text {
|
||||
font-weight: 500;
|
||||
font-size: 10px;
|
||||
color: #ffffff;
|
||||
line-height: 22px;
|
||||
padding-left: 16px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.work_right {
|
||||
width: 50%;
|
||||
padding: 0 16px 16px;
|
||||
.work_right_top {
|
||||
height: 76px;
|
||||
.work_right_top_label {
|
||||
font-size: 19px;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
padding-right: 18px;
|
||||
}
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
width: 300px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 16px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
.work_right_top_file {
|
||||
width: 63px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
background: rgba(195, 189, 0, 0.12);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(182, 195, 0, 0.4);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #d9b028;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
margin: 0 22px;
|
||||
}
|
||||
.work_right_top_add {
|
||||
width: 123px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
background: #d8f6ff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #75d5f2;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #25aed9;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.wook_soon {
|
||||
height: 500px;
|
||||
.wook_soon_top {
|
||||
height: 200px;
|
||||
position: relative;
|
||||
transition: all 0.5s;
|
||||
.wook_soon_img {
|
||||
height: 100%;
|
||||
}
|
||||
.wook_soon_btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 10px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
z-index: 9;
|
||||
background: #ffffff;
|
||||
border-radius: 4px;
|
||||
transition: all 0.5s;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 25px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.wook_soon_btn1 {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
.wook_soon_list {
|
||||
transition: all 0.5s;
|
||||
margin-top: 18px;
|
||||
height: 282px;
|
||||
background: #ffffff;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #eaeaea;
|
||||
overflow-y: scroll;
|
||||
padding: 0 22px;
|
||||
.wook_soon_item {
|
||||
height: 68px;
|
||||
border-bottom: 2px solid #e1f5e5;
|
||||
.wook_soon_label {
|
||||
width: 200px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
line-height: 28px;
|
||||
}
|
||||
.wook_soon_input {
|
||||
width: 300px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
width: 300px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 16px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
.wook_soon_add {
|
||||
width: 110px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
background: #d8f6ff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #75d5f2;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #25aed9;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.wook_soon1 {
|
||||
.wook_soon_top {
|
||||
height: 100%;
|
||||
}
|
||||
.wook_soon_list {
|
||||
height: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer_box {
|
||||
height: 90px;
|
||||
padding: 0 28px;
|
||||
.footer_main {
|
||||
.footer_input {
|
||||
}
|
||||
}
|
||||
.footer_btns {
|
||||
.footer_save {
|
||||
width: 166px;
|
||||
height: 45px;
|
||||
background: #00bcc3;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #ffffff;
|
||||
padding: 0;
|
||||
margin-right: 22px;
|
||||
}
|
||||
.footer_submit {
|
||||
width: 166px;
|
||||
height: 45px;
|
||||
background: #00c325;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #ffffff;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 高级设置
|
||||
.set_box {
|
||||
.set_list {
|
||||
padding: 24px;
|
||||
.set_item {
|
||||
padding: 10px 0;
|
||||
.set_label {
|
||||
width: 180px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
line-height: 32px;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
}
|
||||
.set_val {
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
width: 180px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
.el-switch {
|
||||
zoom: 1.3;
|
||||
}
|
||||
.el-radio-group {
|
||||
padding: 10px 0;
|
||||
.el-radio {
|
||||
display: flex;
|
||||
.set_disk_name {
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
line-height: 16px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.set_disk_desc {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
line-height: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.set_btns {
|
||||
border-top: 1px solid #e1f5e5;
|
||||
height: 62px;
|
||||
.set_btn1 {
|
||||
width: 120px;
|
||||
height: 32px;
|
||||
background: #ffffff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #000000;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
padding: 0;
|
||||
margin: 0 12px;
|
||||
}
|
||||
.set_btn2 {
|
||||
width: 120px;
|
||||
height: 32px;
|
||||
background: #00c325;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
padding: 0;
|
||||
margin: 0 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -29,13 +29,13 @@ export function getLanguage() {
|
||||
if (chooseLanguage) return chooseLanguage
|
||||
|
||||
// if has not choose language
|
||||
const language = (navigator.language || navigator.browserLanguage).toLowerCase()
|
||||
const locales = Object.keys(messages)
|
||||
for (const locale of locales) {
|
||||
if (language.indexOf(locale) > -1) {
|
||||
return locale
|
||||
}
|
||||
}
|
||||
// const language = (navigator.language || navigator.browserLanguage).toLowerCase()
|
||||
// const locales = Object.keys(messages)
|
||||
// for (const locale of locales) {
|
||||
// if (language.indexOf(locale) > -1) {
|
||||
// return locale
|
||||
// }
|
||||
// }
|
||||
return 'zhCN'
|
||||
}
|
||||
const i18n = new VueI18n({
|
||||
|
||||
@@ -7,6 +7,9 @@ export default new Router({
|
||||
routes: [
|
||||
{ path: '/login', component: () => import('@/views/login/index') },
|
||||
{ path: '/404', component: () => import('@/views/404') },
|
||||
{ path: '/', component: () => import('@/views/dashboard/index'), name: '首页' }
|
||||
{ path: '/', component: () => import('@/views/dashboard/index'), name: '首页' },
|
||||
{ path: '/manage', component: () => import('@/views/manage/index'), name: '系统管理' },
|
||||
{ path: '/user', component: () => import('@/views/user/index'), name: '用户管理' },
|
||||
{ path: '/set', component: () => import('@/views/set/index'), name: '系统配置' }
|
||||
]
|
||||
})
|
||||
|
||||
@@ -12,7 +12,7 @@ export default new Vuex.Store({
|
||||
modules,
|
||||
getters,
|
||||
plugins: [
|
||||
createPersistedState(),
|
||||
// createPersistedState(),
|
||||
// createSharedMutations()
|
||||
],
|
||||
strict: process.env.NODE_ENV !== 'production'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Cookies from 'js-cookie'
|
||||
import { getLanguage } from '@/lang/index'
|
||||
import { getLanguage } from '../../lang/index'
|
||||
|
||||
const state = {
|
||||
device: 'desktop',
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
// import { getAllList, getChatList, bindId, chatBegin } from '@/api/message'
|
||||
// import { Message, MessageBox } from 'element-ui'
|
||||
|
||||
let timeouter = null
|
||||
let websock = null
|
||||
let isConnect = false
|
||||
const getDefaultState = () => {
|
||||
return {
|
||||
reconnections: 0,
|
||||
}
|
||||
}
|
||||
|
||||
const state = getDefaultState()
|
||||
|
||||
const mutations = {
|
||||
set_client_id: (state, client_id) => {
|
||||
state.client_id = client_id
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
// 初始化websocket
|
||||
initWebSocket({ commit, dispatch, rootState }) {
|
||||
if (typeof WebSocket === 'undefined') return console.log('您的浏览器不支持websocket')
|
||||
if ((websock && isConnect) || !rootState.user.token) {
|
||||
return
|
||||
}
|
||||
websock = new WebSocket(process.env.VUE_APP_SOCKET_API)
|
||||
websock.onmessage = function (res) {
|
||||
dispatch('websocketonmessage', res)
|
||||
}
|
||||
websock.onopen = function (res) {
|
||||
dispatch('websocketonopen', res)
|
||||
}
|
||||
websock.onerror = function (res) {
|
||||
dispatch('websocketonerror', res)
|
||||
}
|
||||
websock.onclose = function (res) {
|
||||
dispatch('websocketonclose', res)
|
||||
}
|
||||
},
|
||||
// 接收消息
|
||||
websocketonmessage({ commit, dispatch }, e) {
|
||||
const data = JSON.parse(e.data) // 转json对象
|
||||
if (data.state) {
|
||||
|
||||
} else {
|
||||
if (data.type === 'init') {
|
||||
state.pingNum = 0
|
||||
clearTimeout(timeouter)
|
||||
dispatch('pingCheck')
|
||||
commit('set_client_id', data.client_id)
|
||||
// 初始化
|
||||
bindId({
|
||||
client_id: data.client_id
|
||||
})
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
alert(err.msg)
|
||||
// Message.error(err.msg)
|
||||
})
|
||||
} else if (data.type === 'ping') {
|
||||
// 心跳回执
|
||||
state.pingNum = 0
|
||||
dispatch('websocketsend', { type: 'pong' })
|
||||
} else {
|
||||
// 未知消息
|
||||
console.log('未知消息: ' + JSON.stringify(data))
|
||||
}
|
||||
}
|
||||
},
|
||||
// 心跳检测重连
|
||||
pingCheck({ state, commit, dispatch, rootState }) {
|
||||
if (state.pingNum < 4) {
|
||||
state.pingNum++
|
||||
timeouter = setTimeout(() => {
|
||||
dispatch('pingCheck')
|
||||
}, 10000)
|
||||
} else {
|
||||
dispatch('closeWebsocket')
|
||||
}
|
||||
},
|
||||
// 发送消息
|
||||
websocketsend({ commit, dispatch }, res) {
|
||||
if (!websock) {
|
||||
// Message.info('webSocket未连接,正在尝试连接')
|
||||
dispatch('initWebSocket')
|
||||
return
|
||||
}
|
||||
websock.send(JSON.stringify(res))
|
||||
},
|
||||
// 链接建立之后执行的方法
|
||||
websocketonopen: ({ commit, dispatch }, res) => {
|
||||
console.log('链接建立之后执行send方法发送数据', res)
|
||||
isConnect = true
|
||||
},
|
||||
// 链接关闭之后执行的方法
|
||||
websocketonclose: ({ commit, dispatch }, res) => {
|
||||
console.log('断开链接', res)
|
||||
// 关闭
|
||||
if (isConnect) {
|
||||
isConnect = false
|
||||
dispatch('initWebSocket')
|
||||
}
|
||||
},
|
||||
// 链接错误之后执行的方法
|
||||
websocketonerror({ commit, dispatch }, res) {
|
||||
isConnect = false
|
||||
state.reconnections += 1
|
||||
if (state.reconnections <= 3) {
|
||||
setTimeout(() => {
|
||||
dispatch('initWebSocket')
|
||||
}, 5000)
|
||||
} else {
|
||||
state.reconnections = 0
|
||||
dispatch('initWebSocket')
|
||||
// MessageBox.alert('服务器启动异常,请刷新重试', '温馨提示', {
|
||||
// confirmButtonText: '刷新',
|
||||
// showCancelButton: true
|
||||
// })
|
||||
// .then(() => {
|
||||
|
||||
// })
|
||||
// .catch(() => {})
|
||||
}
|
||||
},
|
||||
// 关闭
|
||||
closeWebsocket: () => {
|
||||
// 关闭
|
||||
if (websock) websock.close()
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// import { login, logout, getInfo } from '@/api/login'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
import { getToken, setToken, removeToken } from '../../utils/auth'
|
||||
|
||||
const user = {
|
||||
state: {
|
||||
@@ -65,12 +65,13 @@ const user = {
|
||||
},
|
||||
|
||||
// 登出
|
||||
LogOut({ commit, state }) {
|
||||
LogOut({ commit, state, dispatch }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(state.token)
|
||||
.then(() => {
|
||||
commit('SET_TOKEN', '')
|
||||
commit('SET_ROLES', [])
|
||||
dispatch('chat/closeWebsocket', {}, { root: true }) // 关闭websocket
|
||||
removeToken()
|
||||
resolve()
|
||||
})
|
||||
@@ -81,10 +82,11 @@ const user = {
|
||||
},
|
||||
|
||||
// 前端 登出
|
||||
FedLogOut({ commit }) {
|
||||
FedLogOut({ commit, dispatch }) {
|
||||
return new Promise((resolve) => {
|
||||
removeToken()
|
||||
commit('SET_TOKEN', '')
|
||||
dispatch('chat/closeWebsocket', {}, { root: true }) // 关闭websocket
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -121,3 +121,20 @@ a:hover {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px; /* 设置滚动条的宽度 */
|
||||
height: 6px;
|
||||
}
|
||||
/* 滚动条滑块样式 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #b5b5b5; /* 设置滑块背景颜色 */
|
||||
}
|
||||
/* 滚动条轨道hover状态样式 */
|
||||
::-webkit-scrollbar-track:hover {
|
||||
background-color: #efefef; /* 设置轨道hover状态时的背景颜色 */
|
||||
}
|
||||
/* 滚动条滑块hover状态样式 */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #b5b5b5; /* 设置滑块hover状态时的背景颜色 */
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="container_box">
|
||||
<!-- 头部 -->
|
||||
<div class="flex_box flex_row_between top_box">
|
||||
<div class="flex_box top_left">
|
||||
<div class="flex_box flex_row_center top_btn1">
|
||||
<div @click="showWork" class="flex_box flex_row_center top_btn1">
|
||||
<img src="@/assets/images/Plus1_icon.png" />
|
||||
<div>新建作业</div>
|
||||
</div>
|
||||
@@ -10,7 +11,7 @@
|
||||
<img src="@/assets/images/Search_icon.png" />
|
||||
<div>打开作业文件</div>
|
||||
</div>
|
||||
<div class="flex_box flex_row_center top_btn2">
|
||||
<div @click="$router.push({ path: '/manage' })" class="flex_box flex_row_center top_btn2">
|
||||
<img src="@/assets/images/Setting_icon.png" />
|
||||
<div>系统设置</div>
|
||||
</div>
|
||||
@@ -35,32 +36,286 @@
|
||||
</div>
|
||||
<div class="top_left_line"></div>
|
||||
</div>
|
||||
<div @click="goOut" class="flex_box top_right">
|
||||
<div class="top_right_name">你好,admin</div>
|
||||
<div class="top_right_btn">登出</div>
|
||||
<user-info></user-info>
|
||||
</div>
|
||||
<!-- 设备 -->
|
||||
<div class="flex_box device_box">
|
||||
<!-- 左侧 -->
|
||||
<div class="device_left">
|
||||
<div class="flex_box device_left_top">
|
||||
<img class="flex_shrink device_img" src="@/assets/images/device1.png" />
|
||||
<div class="flex_box flex_row_between device_info">
|
||||
<div class="device_info_box">
|
||||
<div class="device_info_main" :class="{'device_info_main1': infoStatus===1}">
|
||||
<div class="device_info_item">
|
||||
<div class="device_info_text">系统序列号:4F524201</div>
|
||||
<div class="device_info_text">主机名:DGF031</div>
|
||||
<div class="device_info_text">主机IP:192.168.1.25</div>
|
||||
<div class="device_info_text">缓存空间:123G(共200G)</div>
|
||||
</div>
|
||||
<div class="device_info_item">
|
||||
<div class="device_info_title">Disc Publisher 4200 Series</div>
|
||||
<div class="flex_box device_info_options">
|
||||
<div class="device_info_option">
|
||||
<div class="device_info_option_box">
|
||||
<img src="@/assets/images/device4.png" />
|
||||
</div>
|
||||
<div class="flex_box flex_row_center device_info_option_b">
|
||||
<div class="device_info_option_b_text">CD 5张</div>
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="device_info_option">
|
||||
<div class="device_info_option_box">
|
||||
<img src="@/assets/images/device4.png" />
|
||||
</div>
|
||||
<div class="flex_box flex_row_center device_info_option_b">
|
||||
<div class="device_info_option_b_text">DVD 15张</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="device_info_option">
|
||||
<img class="device_info_option_img" src="@/assets/images/device5.png" />
|
||||
<div class="flex_box flex_row_center device_info_option_b">
|
||||
<div class="device_info_option_b_text">75%</div>
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="device_info_right">
|
||||
<div @click="infoStatus=0" class="device_info_right_item">
|
||||
<img v-if="infoStatus===0" src="@/assets/images/Arrow_right_icon.png" />
|
||||
<img v-if="infoStatus===1" src="@/assets/images/Arrow_right1_icon.png" />
|
||||
</div>
|
||||
<div @click="infoStatus=1" class="device_info_right_item">
|
||||
<img v-if="infoStatus===1" src="@/assets/images/Arrow_left_icon.png" />
|
||||
<img v-if="infoStatus===0" src="@/assets/images/Arrow_left1_icon.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box device_status">
|
||||
<div class="device_status_dot"></div>
|
||||
<div class="device_status_text">{{runText}}</div>
|
||||
</div>
|
||||
<div class="flex_box device_run">
|
||||
<div class="flex_box device_run_input">
|
||||
<el-select v-model="runVal" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in runList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button type="primary" class="device_run_btn">执行</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧 -->
|
||||
<div class="device_right">
|
||||
<div class="flex_box device_right_top">
|
||||
<div class="flex_box flex_row_between device_right_top_item">
|
||||
<img class="device_right_top_img" src="@/assets/images/device2.png" />
|
||||
<div class="device_right_top_content">
|
||||
<div class="device_right_top_title">BD驱动器(S)(顶部)</div>
|
||||
<div class="device_right_top_text">状态:插入光盘中</div>
|
||||
<div class="device_right_top_text">任务:文件刻录_20210323095213</div>
|
||||
<div class="device_right_top_text">光盘:56210323002</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="device_right_top_line"></div>
|
||||
<div class="flex_box flex_row_between device_right_top_item">
|
||||
<img class="device_right_top_img" src="@/assets/images/device2.png" />
|
||||
<div class="device_right_top_content">
|
||||
<div class="device_right_top_title">21032200009(H)(底部)</div>
|
||||
<div class="flex_box device_right_top_progress">
|
||||
<div class="device_right_top_progress_box" :style="{width: progressW+'%'}"></div>
|
||||
</div>
|
||||
<div class="device_right_top_text">15GB可用,共60GB</div>
|
||||
<div class="device_right_top_text">状态:插入光盘中</div>
|
||||
<div class="device_right_top_text">任务:文件刻录_20210323095213</div>
|
||||
<div class="device_right_top_text">光盘:56210323002</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice_box">
|
||||
<div class="flex_box flex_row_between notice_top">
|
||||
<div class="flex_box notice_title">
|
||||
<img src="@/assets/images/inform1_icon.png" />
|
||||
<div>动态</div>
|
||||
</div>
|
||||
<div class="flex_box notice_all">
|
||||
<img src="@/assets/images/Calendar_icon.png" />
|
||||
<div>全部日志</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice_list">
|
||||
<div v-for="(item, index) in noticeList" :key="index" class="flex_box flex_row_between notice_item">
|
||||
<div class="notice_content"><span>{{ index+1 }}</span>{{ item.message }}</div>
|
||||
<div class="notice_time">{{ item.createtime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="device_box">
|
||||
|
||||
<!-- 作业队列 -->
|
||||
<div class="work_box">
|
||||
<div class="flex_box work_top">
|
||||
<div class="work_top_text">作业列表</div>
|
||||
</div>
|
||||
<el-table max-height="250" class="work_table" :data="workList" empty-text="暂无作业列表">
|
||||
<el-table-column type="index" width="50" label="序号"></el-table-column>
|
||||
<el-table-column prop="jId" label="作业ID"></el-table-column>
|
||||
<el-table-column prop="DataSource" label="作业来源"></el-table-column>
|
||||
<el-table-column prop="PrinterID" label="工作站"></el-table-column>
|
||||
<el-table-column prop="PrinterType" label="存储卡类型"></el-table-column>
|
||||
<el-table-column prop="TaskCapacity" label="拷贝数"></el-table-column>
|
||||
<el-table-column prop="CreateTime" label="开始时间"></el-table-column>
|
||||
<el-table-column prop="FinishTime" label="结束时间"></el-table-column>
|
||||
<el-table-column prop="JobCompletion" label="完成"></el-table-column>
|
||||
<el-table-column prop="JobStatus" label="状态">
|
||||
<template slot-scope="scope">
|
||||
<div class="flex_box work_status_box">
|
||||
<div>{{scope.row.JobStatus==1?'成功':'失败'}}</div>
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 底部 -->
|
||||
<div class="flex_box flex_row_center footer_box">
|
||||
<div>Copyright @ 2023 CARDSOON Corporation</div>
|
||||
<div class="footer_line"></div>
|
||||
<div class="footer_text">帮助</div>
|
||||
<div class="footer_line"></div>
|
||||
<div class="footer_text">关于我们</div>
|
||||
</div>
|
||||
|
||||
<!-- 新建作业 -->
|
||||
<work-add ref="workAdd"></work-add>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let that
|
||||
import { mapGetters } from 'vuex'
|
||||
import UserInfo from '@/components/userInfo/userInfo.vue';
|
||||
import WorkAdd from '@/components/workAdd/workAdd.vue';
|
||||
|
||||
export default {
|
||||
name: 'dashboard',
|
||||
components: { UserInfo, WorkAdd },
|
||||
data() {
|
||||
return {
|
||||
workStatus: true
|
||||
// 设备运行状态
|
||||
workStatus: true,
|
||||
// 工作状态
|
||||
infoStatus: 0,
|
||||
runText: '设备门盖被打开,请关闭门盖。',
|
||||
runVal: 1,
|
||||
runList: [
|
||||
{
|
||||
value: 1,
|
||||
label: '检查打印机',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '打印机换纸',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '校准打印机',
|
||||
}
|
||||
],
|
||||
// 剩余容量
|
||||
progressW: 50,
|
||||
// 日志
|
||||
noticeList: [
|
||||
{
|
||||
id: 1,
|
||||
message: '《CRMEB 开源/标准版商城系统客服配置教程》',
|
||||
createtime: '2024 10-13'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
message: '《CRMEB 开源/标准版商城系统客服配置教程》',
|
||||
createtime: '2024 10-13'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
message: '《CRMEB 开源/标准版商城系统客服配置教程》',
|
||||
createtime: '2024 10-13'
|
||||
}
|
||||
],
|
||||
// 作业列表
|
||||
workList: [
|
||||
{
|
||||
ID: '1',
|
||||
jId: '202410145423408',
|
||||
DataSource: '127.0.0.1',
|
||||
PrinterID: '002A',
|
||||
PrinterType: '4GB丨2.0',
|
||||
TaskCapacity: '1GB278MB',
|
||||
CreateTime: '10-14 15:46:24',
|
||||
FinishTime: '10-14 16:10:01',
|
||||
JobCompletion: '5/10',
|
||||
JobStatus: '1'
|
||||
},
|
||||
{
|
||||
ID: '1',
|
||||
jId: '202410145423408',
|
||||
DataSource: '127.0.0.1',
|
||||
PrinterID: '002A',
|
||||
PrinterType: '4GB丨2.0',
|
||||
TaskCapacity: '1GB278MB',
|
||||
CreateTime: '10-14 15:46:24',
|
||||
FinishTime: '10-14 16:10:01',
|
||||
JobCompletion: '5/10',
|
||||
JobStatus: '1'
|
||||
},
|
||||
{
|
||||
ID: '1',
|
||||
jId: '202410145423408',
|
||||
DataSource: '127.0.0.1',
|
||||
PrinterID: '002A',
|
||||
PrinterType: '4GB丨2.0',
|
||||
TaskCapacity: '1GB278MB',
|
||||
CreateTime: '10-14 15:46:24',
|
||||
FinishTime: '10-14 16:10:01',
|
||||
JobCompletion: '5/10',
|
||||
JobStatus: '1'
|
||||
},
|
||||
{
|
||||
ID: '1',
|
||||
jId: '202410145423408',
|
||||
DataSource: '127.0.0.1',
|
||||
PrinterID: '002A',
|
||||
PrinterType: '4GB丨2.0',
|
||||
TaskCapacity: '1GB278MB',
|
||||
CreateTime: '10-14 15:46:24',
|
||||
FinishTime: '10-14 16:10:01',
|
||||
JobCompletion: '5/10',
|
||||
JobStatus: '1'
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
mounted() {
|
||||
that = this
|
||||
},
|
||||
methods: {
|
||||
// 新建作业
|
||||
showWork() {
|
||||
that.$refs.workAdd.show()
|
||||
},
|
||||
// 退出登录
|
||||
goOut() {
|
||||
this.$store.dispatch('FedLogOut').then(() => {
|
||||
location.reload()// In order to re-instantiate the vue-router object to avoid bugs
|
||||
@@ -72,71 +327,72 @@ export default {
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.container_box {
|
||||
min-height: 100vh;
|
||||
background-color: #F8F8F8;
|
||||
height: 100vh;
|
||||
.top_box {
|
||||
height: 90px;
|
||||
padding: 0 48px;
|
||||
height: 78px;
|
||||
padding: 0 32px;
|
||||
background-color: #ffffff;
|
||||
.top_left {
|
||||
.top_btn1 {
|
||||
padding: 0 24px;
|
||||
height: 45px;
|
||||
cursor: pointer;
|
||||
padding: 0 16px;
|
||||
height: 30px;
|
||||
background: #00C325;
|
||||
border-radius: 6px;
|
||||
margin-right: 24px;
|
||||
margin-right: 16px;
|
||||
font-weight: 500;
|
||||
font-size: 21px;
|
||||
font-size: 15px;
|
||||
color: #FFFFFF;
|
||||
img {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
margin-right: 12px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.top_btn2 {
|
||||
padding: 0 24px;
|
||||
height: 45px;
|
||||
cursor: pointer;
|
||||
padding: 0 16px;
|
||||
height: 30px;
|
||||
background: rgba(0,195,37,0.12);
|
||||
border: 2px solid rgba(0,195,37,0.32);
|
||||
border-radius: 6px;
|
||||
margin-right: 24px;
|
||||
margin-right: 16px;
|
||||
font-weight: 500;
|
||||
font-size: 21px;
|
||||
font-size: 15px;
|
||||
color: #00C325;
|
||||
img {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
margin-right: 12px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.top_left_line {
|
||||
width: 2px;
|
||||
height: 45px;
|
||||
height: 30px;
|
||||
background: #E0E0E0;
|
||||
margin: 0 24px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
.top_left_status {
|
||||
padding: 0 24px;
|
||||
transform: scale(1.6);
|
||||
padding: 0 16px;
|
||||
zoom: 1.3;
|
||||
}
|
||||
.top_left_option {
|
||||
margin-left: 24px;
|
||||
margin-left: 16px;
|
||||
.top_left_text {
|
||||
font-weight: 500;
|
||||
font-size: 21px;
|
||||
font-size: 15px;
|
||||
color: #000000;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.top_left_num {
|
||||
padding: 0 14px;
|
||||
height: 36px;
|
||||
padding: 0 10px;
|
||||
height: 28px;
|
||||
background: #00C325;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
font-size: 21px;
|
||||
font-size: 15px;
|
||||
color: #FFFFFF;
|
||||
line-height: 36px;
|
||||
line-height: 28px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
.top_left_num1 {
|
||||
@@ -144,20 +400,365 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.top_right {
|
||||
.top_right_name {
|
||||
font-weight: 500;
|
||||
font-size: 21px;
|
||||
color: #000000;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.device_box {
|
||||
padding: 16px;
|
||||
background-color: #F8F8F8;
|
||||
.device_left {
|
||||
width: 50%;
|
||||
padding: 0 45px;
|
||||
.device_left_top {
|
||||
margin-bottom: 24px;
|
||||
.device_img {
|
||||
width: 255px;
|
||||
height: 180px;
|
||||
margin-right: 35px;
|
||||
}
|
||||
.device_info {
|
||||
width: calc(100% - 290px);
|
||||
.device_info_box {
|
||||
width: calc(100% - 50px);
|
||||
overflow: hidden;
|
||||
.device_info_main {
|
||||
white-space: nowrap;
|
||||
transition: all 0.5s;
|
||||
.device_info_item {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
.device_info_text {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
line-height: 38px;
|
||||
}
|
||||
.device_info_title {
|
||||
font-weight: bold;
|
||||
font-size: 25px;
|
||||
color: #000000;
|
||||
line-height: 38px;
|
||||
margin-bottom: 42px;
|
||||
}
|
||||
.device_info_options {
|
||||
.device_info_option {
|
||||
margin-right: 30px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.device_info_option_box {
|
||||
width: 84px;
|
||||
height: 67px;
|
||||
position: relative;
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.device_info_option_img {
|
||||
width: 118px;
|
||||
height: 67px;
|
||||
}
|
||||
.device_info_option_b {
|
||||
height: 30px;
|
||||
padding-top: 10px;
|
||||
font-size: 24px;
|
||||
.device_info_option_b_text {
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
}
|
||||
.el-icon-caret-bottom {
|
||||
transition: all 0.5s;
|
||||
}
|
||||
}
|
||||
.device_info_option_b1 {
|
||||
.el-icon-caret-bottom {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.device_info_main1 {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
.device_info_right {
|
||||
.device_info_right_item {
|
||||
width: 28px;
|
||||
padding: 8px 0;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.top_right_btn {
|
||||
font-weight: 500;
|
||||
font-size: 21px;
|
||||
.device_status {
|
||||
height: 44px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 24px;
|
||||
padding: 0 18px;
|
||||
.device_status_dot {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: #E54D4D;
|
||||
margin-right: 18px;
|
||||
}
|
||||
.device_status_text {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #E54D4D;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
.device_run {
|
||||
width: 100%;
|
||||
height: 44px;
|
||||
overflow: hidden;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 5 9px 2px rgba(102,102,102,0.18);
|
||||
border-radius: 6px;
|
||||
.device_run_input {
|
||||
width: calc(100% - 140px);
|
||||
height: 44px;
|
||||
border: 2px solid #00BCC3;
|
||||
overflow: hidden;
|
||||
border-radius: 6px 0 0 6px;
|
||||
.el-select {
|
||||
width: 100%;
|
||||
padding-left: 10px;
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
background-color: transparent;
|
||||
font-size: 20px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #000000;
|
||||
}
|
||||
.el-input__icon {
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.device_run_btn {
|
||||
width: 140px;
|
||||
height: 44px;
|
||||
background: #00BCC3;
|
||||
border-radius: 0px 6px 6px 0px;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
margin: 0;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.device_right {
|
||||
width: 50%;
|
||||
.device_right_top {
|
||||
height: 200px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 18px;
|
||||
padding: 0 24px;
|
||||
.device_right_top_item {
|
||||
width: calc(50% - 25px);
|
||||
.device_right_top_img {
|
||||
width: 116px;
|
||||
height: 101px;
|
||||
}
|
||||
.device_right_top_content {
|
||||
width: calc(100% - 136px);
|
||||
.device_right_top_title {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
line-height: 34px;
|
||||
}
|
||||
.device_right_top_text {
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
line-height: 30px;
|
||||
}
|
||||
.device_right_top_progress {
|
||||
height: 18px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 3px;
|
||||
border: 2px solid #707070;
|
||||
margin: 2px 0 2px;
|
||||
.device_right_top_progress_box {
|
||||
width: 0;
|
||||
height: 15px;
|
||||
background: #00C325;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.device_right_top_line {
|
||||
width: 2px;
|
||||
height: 150px;
|
||||
background: #E1F5E5;
|
||||
margin: 0 24px;
|
||||
}
|
||||
}
|
||||
.notice_box {
|
||||
background: #FFFFFF;
|
||||
border-radius: 6px;
|
||||
.notice_top {
|
||||
height: 75px;
|
||||
padding: 0 30px;
|
||||
border-bottom: 2px solid #E1F5E5;
|
||||
.notice_title {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-right: 18px;
|
||||
}
|
||||
}
|
||||
.notice_all {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #00C325;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-right: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.notice_list {
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
padding: 6px;
|
||||
::-webkit-scrollbar {
|
||||
width: 6px; /* 设置滚动条的宽度 */
|
||||
height: 6px;
|
||||
}
|
||||
/* 滚动条滑块样式 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #b5b5b5; /* 设置滑块背景颜色 */
|
||||
}
|
||||
/* 滚动条轨道hover状态样式 */
|
||||
::-webkit-scrollbar-track:hover {
|
||||
background-color: #efefef; /* 设置轨道hover状态时的背景颜色 */
|
||||
}
|
||||
/* 滚动条滑块hover状态样式 */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #b5b5b5; /* 设置滑块hover状态时的背景颜色 */
|
||||
}
|
||||
.notice_item {
|
||||
height: 42px;
|
||||
background-color: #F8F8F8;
|
||||
margin-bottom: 3px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #FFE6E6;
|
||||
.notice_content,
|
||||
.notice_time {
|
||||
color: #FF0000;
|
||||
}
|
||||
}
|
||||
.notice_content {
|
||||
width: calc(100% - 108px);
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
line-height: 24px;
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 42px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.notice_time {
|
||||
width: 108px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.work_box {
|
||||
height: calc(100vh - 590px);
|
||||
.work_top {
|
||||
height: 72px;
|
||||
.work_top_text {
|
||||
width: 132px;
|
||||
height: 72px;
|
||||
background: linear-gradient( 180deg, #C1FFCD 0%, #FFFFFF 100%);
|
||||
font-weight: bold;
|
||||
font-size: 19px;
|
||||
color: #00C325;
|
||||
line-height: 72px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.work_table {
|
||||
background-color: #F8F8F8;
|
||||
::v-deep {
|
||||
tr {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
td.el-table__cell {
|
||||
background-color: #F8F8F8;
|
||||
border-bottom: 3px solid #ffffff;
|
||||
}
|
||||
th.el-table__cell {
|
||||
background-color: #F2F9F4;
|
||||
border-bottom: 3px solid #ffffff;
|
||||
}
|
||||
.el-table__cell {
|
||||
padding: 6px 0;
|
||||
}
|
||||
.cell {
|
||||
line-height: 28px;
|
||||
font-size: 12px;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
.work_status_box {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer_box {
|
||||
height: 36px;
|
||||
background: #DCF5E1;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
.footer_line {
|
||||
width: 2px;
|
||||
height: 14px;
|
||||
background-color: #666666;
|
||||
margin: 0 20px;
|
||||
}
|
||||
.footer_text {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #00C325;
|
||||
line-height: 50px;
|
||||
padding-left: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<img class="login_bg" src="@/assets/images/login_bg.png" />
|
||||
<img class="login_bg" src="@/assets/images/login_bg.jpg" />
|
||||
<div class="flex_box form_box">
|
||||
<el-form class="flex_box flex_col flex_row_center login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginForm" label-position="left">
|
||||
<img class="login_logo" src="@/assets/images/logo.png" />
|
||||
@@ -81,6 +81,7 @@ export default {
|
||||
this.loading = true
|
||||
setToken('data.token')
|
||||
this.$store.commit('SET_TOKEN', 'data.token')
|
||||
// this.$store.dispatch('chat/initWebSocket') // 初始化websocket
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
this.$router.push({ path: '/' })
|
||||
@@ -186,6 +187,10 @@ $light_gray:#eee;
|
||||
}
|
||||
.login_check {
|
||||
::v-deep {
|
||||
.el-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.el-checkbox__inner {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<div class="container_box">
|
||||
<!-- 头部 -->
|
||||
<tab-bar :active="1"></tab-bar>
|
||||
<!-- 内容 -->
|
||||
<div class="form_box">
|
||||
<div class="form_item">
|
||||
<div class="flex_box form_title">
|
||||
<div class="flex_box flex_col">
|
||||
<div class="form_title_text">系统管理</div>
|
||||
<div class="form_title_line"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_content">
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">移动卡片到</div>
|
||||
<div class="form_val">
|
||||
<div class="flex_box flex_wrap form_tabs">
|
||||
<div v-for="(item, index) in moveList" :key="index" class="form_tab">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">维护工作站</div>
|
||||
<div class="form_val">
|
||||
<div class="flex_box flex_wrap form_tabs">
|
||||
<div v-for="(item, index) in actionList" :key="index" class="form_tab">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_item">
|
||||
<div class="flex_box form_title">
|
||||
<div class="flex_box flex_col">
|
||||
<div class="form_title_text">系统</div>
|
||||
<div class="form_title_line"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_content">
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">刷新时间</div>
|
||||
<div class="form_val">
|
||||
<div class="flex_box flex_col_top form_input">
|
||||
<el-input border="none" v-model="refreshTime" placeholder="请输入刷新时间"></el-input>
|
||||
<el-button type="primary">执行</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">休眠时间</div>
|
||||
<div class="form_val">
|
||||
<div class="flex_box flex_col_top form_input">
|
||||
<el-input border="none" v-model="refreshTime" placeholder="请输入刷新时间"></el-input>
|
||||
<el-button type="primary">执行</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">清除任务</div>
|
||||
<div class="form_val">
|
||||
<el-checkbox v-model="isDel">服务重启时是否删除已完成和已取消任务?</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_item">
|
||||
<div class="flex_box form_title">
|
||||
<div class="flex_box flex_col">
|
||||
<div class="form_title_text">语言</div>
|
||||
<div class="form_title_line"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_content">
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">切换语言</div>
|
||||
<div class="form_val">
|
||||
<div class="flex_box form_select">
|
||||
<el-select v-model="langVal" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in langList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import TabBar from '@/components/tabBar/tabBar.vue';
|
||||
|
||||
export default {
|
||||
name: 'manage',
|
||||
components: { TabBar },
|
||||
data() {
|
||||
return {
|
||||
moveList: [
|
||||
{
|
||||
id: 1,
|
||||
name: '读卡器'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '废卡盒'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '出卡口'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '等待'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '待取口'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '后出卡口'
|
||||
}
|
||||
],
|
||||
actionList: [
|
||||
{
|
||||
id: 1,
|
||||
name: '重置工作站'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '重置工作站(有卡)'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '核准色带灯'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '初始化进卡槽'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '清洁工作站'
|
||||
}
|
||||
],
|
||||
refreshTime: 3000,
|
||||
sleepTime: 300000,
|
||||
isDel: true,
|
||||
langVal: 'zhCN',
|
||||
langList: [
|
||||
{
|
||||
label: '简体中文',
|
||||
value: 'zhCN'
|
||||
},
|
||||
{
|
||||
label: 'English',
|
||||
value: 'en'
|
||||
},
|
||||
{
|
||||
label: '繁体中文',
|
||||
value: 'zhYW'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.container_box {
|
||||
.form_box {
|
||||
padding: 0 32px;
|
||||
.form_item {
|
||||
padding: 10px 0;
|
||||
.form_title {
|
||||
border-bottom: 2px solid #E1F5E5;
|
||||
.form_title_text {
|
||||
font-weight: 500;
|
||||
font-size: 25px;
|
||||
color: #000000;
|
||||
line-height: 37px;
|
||||
}
|
||||
.form_title_line {
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background: #98E8A6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.form_content {
|
||||
padding: 10px 0;
|
||||
.form_option {
|
||||
padding: 16px 0;
|
||||
}
|
||||
.form_label {
|
||||
width: 140px;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
}
|
||||
.form_val {
|
||||
max-width: 1100px;
|
||||
.form_tabs {
|
||||
.form_tab {
|
||||
width: 250px;
|
||||
height: 42px;
|
||||
cursor: pointer;
|
||||
background: rgba(0,195,37,0.12);
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(0,195,37,0.32);
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #00C325;
|
||||
margin: 6px;
|
||||
}
|
||||
}
|
||||
.form_input {
|
||||
width: 500px;
|
||||
height: 42px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #98E8A6;
|
||||
overflow: hidden;
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
width: 360px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 19px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
.el-button {
|
||||
width: 140px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background: #00C325;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.el-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.el-checkbox__inner {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.el-checkbox__input.is-checked .el-checkbox__inner {
|
||||
background-color: #00C325;
|
||||
border-color: #00C325;
|
||||
}
|
||||
.el-checkbox__inner::after {
|
||||
width: 6px;
|
||||
height: 14px;
|
||||
left: 8px;
|
||||
}
|
||||
.el-checkbox__label {
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.el-checkbox__input.is-checked+.el-checkbox__label {
|
||||
color: #00C325;
|
||||
}
|
||||
}
|
||||
.form_select {
|
||||
width: 500px;
|
||||
height: 42px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #98E8A6;
|
||||
.el-select {
|
||||
width: 100%;
|
||||
padding-left: 10px;
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
background-color: transparent;
|
||||
font-size: 20px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #000000;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 20px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,318 @@
|
||||
<template>
|
||||
<div class="container_box">
|
||||
<!-- 头部 -->
|
||||
<tab-bar :active="3"></tab-bar>
|
||||
<!-- 内容 -->
|
||||
<div class="form_box">
|
||||
<div class="form_item">
|
||||
<div class="flex_box form_title">
|
||||
<div class="flex_box flex_col">
|
||||
<div class="form_title_text">系统配置</div>
|
||||
<div class="form_title_line"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_content">
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">LogLevel</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_select">
|
||||
<el-select v-model="form.LogLevel" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in levelList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="form_text">记录日志等级,建议用户设置为INFO</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">AutoRetryTimes</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_select">
|
||||
<el-select v-model="form.AutoRetryTimes" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in timesList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="form_text">作业失败后重试次数,默认0为不重试</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">TaskDir</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_input">
|
||||
<el-input border="none" v-model="form.TaskDir" placeholder="请输入"></el-input>
|
||||
</div>
|
||||
<div class="form_text">自动作业文件路径</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">SharedDir</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_input">
|
||||
<el-input border="none" v-model="form.SharedDir" placeholder="请输入"></el-input>
|
||||
</div>
|
||||
<div class="form_text">作业缓存路径,存放作业中临时生成的内容文件、标签、合并图片、字段数据等</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">RejectConfig</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_switch">
|
||||
<el-switch active-color="#07C160" inactive-color="#aaa" v-model="form.RejectConfig"></el-switch>
|
||||
</div>
|
||||
<div class="form_text">出卡盒配置。默认勾选为正常出卡,取消勾选则从Reject出卡盒出卡</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">StopOnFailure</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_switch">
|
||||
<el-switch active-color="#07C160" inactive-color="#aaa" v-model="form.StopOnFailure"></el-switch>
|
||||
</div>
|
||||
<div class="form_text">作业失败后停止接受任务,默认不勾选</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">KeepCombinedImage</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_switch">
|
||||
<el-switch active-color="#07C160" inactive-color="#aaa" v-model="form.KeepCombinedImage"></el-switch>
|
||||
</div>
|
||||
<div class="form_text">是否保留作业临时图片和字段数据</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">CleanTaskFile</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_switch">
|
||||
<el-switch active-color="#07C160" inactive-color="#aaa" v-model="form.CleanTaskFile"></el-switch>
|
||||
</div>
|
||||
<div class="form_text">是否清除作业临时文件</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box form_option">
|
||||
<div class="form_label">UploadSharedDir</div>
|
||||
<div class="flex_box form_val">
|
||||
<div class="form_switch">
|
||||
<el-switch active-color="#07C160" inactive-color="#aaa" v-model="form.UploadSharedDir"></el-switch>
|
||||
</div>
|
||||
<div class="form_text">启用作业缓存路径,勾选后作业内容会先拷贝到缓存路径后再拷贝到存储卡</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex_box flex_row_center footer_btns">
|
||||
<el-button type="primary" class="footer_submit" @click="workSubmit">提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import TabBar from '@/components/tabBar/tabBar.vue';
|
||||
|
||||
export default {
|
||||
name: 'manage',
|
||||
components: { TabBar },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
LogLevel: 'INFO',
|
||||
AutoRetryTimes: '2',
|
||||
TaskDir: 'D:\PrintTasks',
|
||||
SharedDir: 'D:\CardSoonRepo',
|
||||
RejectConfig: true,
|
||||
StopOnFailure: false,
|
||||
KeepCombinedImage: true,
|
||||
CleanTaskFile: false,
|
||||
UploadSharedDir: false,
|
||||
},
|
||||
levelList: [
|
||||
{
|
||||
label: 'TRACE',
|
||||
value: 'TRACE'
|
||||
},
|
||||
{
|
||||
label: 'DEBUG',
|
||||
value: 'DEBUG'
|
||||
},
|
||||
{
|
||||
label: 'INFO',
|
||||
value: 'INFO'
|
||||
},
|
||||
{
|
||||
label: 'WARNING',
|
||||
value: 'WARNING'
|
||||
},
|
||||
{
|
||||
label: 'ERROR',
|
||||
value: 'ERROR'
|
||||
},
|
||||
{
|
||||
label: 'FATAL',
|
||||
value: 'FATAL'
|
||||
}
|
||||
],
|
||||
timesList: [
|
||||
{
|
||||
label: '0',
|
||||
value: '0'
|
||||
},
|
||||
{
|
||||
label: '1',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '2',
|
||||
value: '2'
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.container_box {
|
||||
.form_box {
|
||||
padding: 0 32px;
|
||||
.form_item {
|
||||
padding: 10px 0;
|
||||
.form_title {
|
||||
border-bottom: 2px solid #E1F5E5;
|
||||
.form_title_text {
|
||||
font-weight: 500;
|
||||
font-size: 25px;
|
||||
color: #000000;
|
||||
line-height: 37px;
|
||||
}
|
||||
.form_title_line {
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background: #98E8A6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.form_content {
|
||||
padding: 10px 0;
|
||||
.form_option {
|
||||
padding: 16px 0;
|
||||
}
|
||||
.form_label {
|
||||
width: 300px;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
}
|
||||
.form_val {
|
||||
.form_input {
|
||||
width: 300px;
|
||||
height: 42px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #98E8A6;
|
||||
overflow: hidden;
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
width: 360px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 20px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
.el-button {
|
||||
width: 140px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background: #00C325;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form_switch {
|
||||
width: 300px;
|
||||
.el-switch {
|
||||
zoom: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
.form_select {
|
||||
width: 300px;
|
||||
height: 42px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #98E8A6;
|
||||
.el-select {
|
||||
width: 100%;
|
||||
padding-left: 10px;
|
||||
::v-deep {
|
||||
.el-input__inner {
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
background-color: transparent;
|
||||
font-size: 20px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #000000;
|
||||
}
|
||||
.el-input__icon {
|
||||
font-size: 20px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.form_text {
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #000000;
|
||||
padding-left: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer_btns {
|
||||
height: 80px;
|
||||
.footer_submit {
|
||||
width: 166px;
|
||||
height: 45px;
|
||||
background: #00C325;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: #FFFFFF;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div class="container_box">
|
||||
<!-- 头部 -->
|
||||
<tab-bar :active="2"></tab-bar>
|
||||
<div class="table_box">
|
||||
<el-table :data="userList">
|
||||
<el-table-column prop="ID" label="序号"></el-table-column>
|
||||
<el-table-column prop="userName" label="用户名"></el-table-column>
|
||||
<el-table-column prop="role" label="用户组"></el-table-column>
|
||||
<el-table-column prop="logintime" label="最后登录时间"></el-table-column>
|
||||
<el-table-column prop="status" label="状态">
|
||||
<template slot-scope="scope">
|
||||
<div class="table_status" :class="{'table_status1': scope.row.status === 1}">{{ scope.row.status === 1 ? '在线' : '离线' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import TabBar from '@/components/tabBar/tabBar.vue';
|
||||
|
||||
export default {
|
||||
name: 'User',
|
||||
components: { TabBar },
|
||||
data() {
|
||||
return {
|
||||
userList: [
|
||||
{
|
||||
ID: '1',
|
||||
userName: 'admin',
|
||||
role: 'administrator',
|
||||
logintime: '2024-10-06 18:12:10',
|
||||
status: 1
|
||||
},
|
||||
{
|
||||
ID: '2',
|
||||
userName: '卡树测试',
|
||||
role: 'test',
|
||||
logintime: '2024-10-05 19:06:45',
|
||||
status: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['name', 'roles'])
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.container_box {
|
||||
height: 100vh;
|
||||
.table_box {
|
||||
padding: 32px;
|
||||
.el-table {
|
||||
::v-deep {
|
||||
th.el-table__cell {
|
||||
background-color: #F2F9F4;
|
||||
}
|
||||
.el-table__cell {
|
||||
padding: 6px 0;
|
||||
}
|
||||
.cell {
|
||||
line-height: 28px;
|
||||
font-size: 12px;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
.table_status {
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
}
|
||||
.table_status1 {
|
||||
color: #00C325;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||