Compare commits
10 Commits
7599c79c4c
...
9fe339f317
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fe339f317 | |||
| 0001ecc000 | |||
| 04ca328a67 | |||
| a6ce251509 | |||
| ff6df432ec | |||
| 741387aff2 | |||
| bfe8127ee8 | |||
| 01c8b05d30 | |||
| 6a4a448cfd | |||
| 5a48bf0237 |
+3
-1
@@ -26,7 +26,9 @@
|
|||||||
"output": "build"
|
"output": "build"
|
||||||
},
|
},
|
||||||
"extraFiles": [
|
"extraFiles": [
|
||||||
"lib"
|
"lib",
|
||||||
|
"ProductionServer",
|
||||||
|
"help"
|
||||||
],
|
],
|
||||||
"nsis": {
|
"nsis": {
|
||||||
"oneClick": false,
|
"oneClick": false,
|
||||||
|
|||||||
+278
-210
@@ -1,210 +1,278 @@
|
|||||||
const { Menu, app, BrowserWindow } = require("electron");
|
const { Menu, app, BrowserWindow, shell } = require("electron");
|
||||||
// Note: Store should be handled in renderer process, not main
|
// Note: Store should be handled in renderer process, not main
|
||||||
// import "../renderer/store";
|
// import "../renderer/store";
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
// 导入录制器模块(设置全局变量)
|
// 导入录制器模块(设置全局变量)
|
||||||
require('./recorder');
|
require('./recorder');
|
||||||
// require("./fingerprint/win");
|
// require("./fingerprint/win");
|
||||||
let root = "";
|
// 获取应用根目录(兼容三端,与 exe 同级)
|
||||||
if (process.env.NODE_ENV !== "development") {
|
// 开发环境:使用项目根目录
|
||||||
root = path.dirname(app.getPath("exe"));
|
// 生产环境:获取可执行文件所在目录(与 exe 同级,兼容 Windows/Linux/macOS)
|
||||||
} else {
|
let root = "";
|
||||||
root = "..\\..\\";
|
if (process.env.NODE_ENV === "development") {
|
||||||
}
|
root = path.join(__dirname, '../../');
|
||||||
|
} else {
|
||||||
// 获取日志文件的路径
|
root = path.dirname(app.getPath("exe"));
|
||||||
const logPath = path.join(app.getPath('userData'), 'app.log');
|
}
|
||||||
// 写入日志的函数
|
|
||||||
function writeLog(message) {
|
// 获取日志文件的路径
|
||||||
const timestamp = new Date().toISOString();
|
const logPath = path.join(app.getPath('userData'), 'app.log');
|
||||||
const logMessage = `${timestamp}: ${message}\n`;
|
// 写入日志的函数
|
||||||
// 异步追加日志信息
|
function writeLog(message) {
|
||||||
fs.appendFile(logPath, logMessage, (err) => {
|
const timestamp = new Date().toISOString();
|
||||||
if (err) throw err;
|
const logMessage = `${timestamp}: ${message}\n`;
|
||||||
console.log('日志信息已追加到文件');
|
// 异步追加日志信息
|
||||||
});
|
fs.appendFile(logPath, logMessage, (err) => {
|
||||||
}
|
if (err) throw err;
|
||||||
|
console.log('日志信息已追加到文件');
|
||||||
|
});
|
||||||
/**
|
}
|
||||||
* Set `__static` path to static files in production
|
|
||||||
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
|
||||||
*/
|
/**
|
||||||
if (process.env.NODE_ENV !== "development") {
|
* Set `__static` path to static files in production
|
||||||
global.__static = require("path")
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
||||||
.join(__dirname, "/static")
|
*/
|
||||||
.replace(/\\/g, "\\\\");
|
if (process.env.NODE_ENV !== "development") {
|
||||||
}
|
global.__static = require("path")
|
||||||
|
.join(__dirname, "/static")
|
||||||
let mainWindow;
|
.replace(/\\/g, "\\\\");
|
||||||
const winURL =
|
}
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? `http://localhost:9081`
|
let mainWindow;
|
||||||
: `file://${__dirname}/index.html`;
|
const winURL =
|
||||||
|
process.env.NODE_ENV === "development"
|
||||||
function createWindow() {
|
? `http://localhost:9081`
|
||||||
/**
|
: `file://${__dirname}/index.html`;
|
||||||
* Initial window options
|
|
||||||
*/
|
function createWindow() {
|
||||||
mainWindow = new BrowserWindow({
|
/**
|
||||||
height: 800,
|
* Initial window options
|
||||||
useContentSize: true,
|
*/
|
||||||
width: 1280,
|
mainWindow = new BrowserWindow({
|
||||||
title: "卡树自动拷贝打印系统 V3.1",
|
height: 800,
|
||||||
icon: "static/images/logo64.ico", // sets window icon
|
useContentSize: true,
|
||||||
webPreferences: {
|
width: 1280,
|
||||||
nodeIntegration: true,
|
title: "卡树自动拷贝打印系统 V3.1",
|
||||||
contextIsolation: false,
|
icon: "static/images/logo64.ico", // sets window icon
|
||||||
enableRemoteModule: true,
|
webPreferences: {
|
||||||
webSecurity: false,
|
nodeIntegration: true,
|
||||||
},
|
contextIsolation: false,
|
||||||
});
|
enableRemoteModule: true,
|
||||||
// mainWindow.maximize();
|
webSecurity: false,
|
||||||
// 使窗口可以拖拽
|
},
|
||||||
mainWindow.setIgnoreMouseEvents(false);
|
});
|
||||||
Menu.setApplicationMenu(null); //关闭菜单
|
// mainWindow.maximize();
|
||||||
//mainWindow.webContents.openDevTools({mode:'bottom'});
|
// 使窗口可以拖拽
|
||||||
require("@electron/remote/main").initialize();
|
mainWindow.setIgnoreMouseEvents(false);
|
||||||
require("@electron/remote/main").enable(mainWindow.webContents);
|
Menu.setApplicationMenu(null); //关闭菜单
|
||||||
global.setMainWindow(mainWindow);
|
//mainWindow.webContents.openDevTools({mode:'bottom'});
|
||||||
mainWindow.loadURL(winURL);
|
require("@electron/remote/main").initialize();
|
||||||
|
require("@electron/remote/main").enable(mainWindow.webContents);
|
||||||
mainWindow.on("closed", () => {
|
global.setMainWindow(mainWindow);
|
||||||
mainWindow = null;
|
mainWindow.loadURL(winURL);
|
||||||
});
|
|
||||||
}
|
mainWindow.on("closed", () => {
|
||||||
app.commandLine.appendSwitch("no-sandbox");
|
mainWindow = null;
|
||||||
const gotTheLock = app.requestSingleInstanceLock();
|
});
|
||||||
if (!gotTheLock) {
|
}
|
||||||
app.quit();
|
app.commandLine.appendSwitch("no-sandbox");
|
||||||
} else {
|
const gotTheLock = app.requestSingleInstanceLock();
|
||||||
app.on("second-instance", (event, commandLine, workingDirectory) => {
|
if (!gotTheLock) {
|
||||||
// 当运行第二个实例时,将会聚焦到myWindow这个窗口
|
app.quit();
|
||||||
if (mainWindow) {
|
} else {
|
||||||
if (mainWindow.isMinimized()) mainWindow.restore();
|
app.on("second-instance", (event, commandLine, workingDirectory) => {
|
||||||
mainWindow.focus();
|
// 当运行第二个实例时,将会聚焦到myWindow这个窗口
|
||||||
}
|
if (mainWindow) {
|
||||||
});
|
if (mainWindow.isMinimized()) mainWindow.restore();
|
||||||
}
|
mainWindow.focus();
|
||||||
app.on("ready", createWindow);
|
}
|
||||||
|
});
|
||||||
app.on("window-all-closed", () => {
|
}
|
||||||
if (process.platform !== "darwin") {
|
// 执行安装脚本(仅在首次安装时执行一次,兼容三端,无需额外权限)
|
||||||
app.quit();
|
function runInstallScript() {
|
||||||
}
|
const productionServerPath = path.join(root, "ProductionServer");
|
||||||
});
|
const installFlagPath = path.join(productionServerPath, ".install_completed");
|
||||||
|
|
||||||
app.on("activate", () => {
|
// 检查是否已执行过
|
||||||
if (mainWindow === null) {
|
if (fs.existsSync(installFlagPath)) {
|
||||||
createWindow();
|
console.log("安装脚本已执行过,跳过本次执行");
|
||||||
}
|
return;
|
||||||
});
|
}
|
||||||
app.on("renderer-process-crashed", function (event, webContents, details) {
|
|
||||||
// 输出一下捕捉到的reason,实际可以根据不同的“原因”进行具体处理
|
// 根据平台确定脚本文件名和命令(使用 sh 执行 .sh 文件无需执行权限)
|
||||||
console.error("renderer-process-crashed, reason => ", JSON.stringify(details));
|
const scriptName = process.platform === "win32" ? "install.bat" : "install.sh";
|
||||||
// 重启应用
|
const installScriptPath = path.join(productionServerPath, scriptName);
|
||||||
writeLog("renderer-process-crashed, reason => " + JSON.stringify(details))
|
const execCommand = process.platform === "win32"
|
||||||
});
|
? `"${installScriptPath}"`
|
||||||
|
: `sh "${installScriptPath}"`; // 使用 sh 执行,无需执行权限
|
||||||
const { ipcMain } = require("electron");
|
|
||||||
let preFilePath = "";
|
// 检查脚本是否存在
|
||||||
// app.on("will-finish-launching", () => {
|
if (!fs.existsSync(installScriptPath)) {
|
||||||
app.on("open-file", (e, filePath) => {
|
console.log("安装脚本不存在: " + installScriptPath);
|
||||||
preFilePath = filePath;
|
return;
|
||||||
});
|
}
|
||||||
|
|
||||||
ipcMain.on('open-help-file', event => {
|
// 执行安装脚本
|
||||||
var exePath = path.dirname(app.getPath('exe'));
|
console.log("首次安装,执行安装脚本: " + installScriptPath);
|
||||||
child_process.exec(`start "" "${exePath}/help/User Manual.pdf"`);
|
writeLog(`首次安装,执行安装脚本: ${installScriptPath} (平台: ${process.platform})`);
|
||||||
});
|
|
||||||
|
child_process.exec(execCommand, { cwd: productionServerPath }, (error, stdout, stderr) => {
|
||||||
ipcMain.on("get-root", (event) => {
|
if (error) {
|
||||||
event.reply("get-root-callback", root);
|
console.error("安装脚本执行错误:", error);
|
||||||
});
|
writeLog("安装脚本执行错误: " + error.message);
|
||||||
|
return;
|
||||||
if (process.platform === "win32" && process.argv.length >= 2) {
|
}
|
||||||
console.log("process argv:", process.argv);
|
|
||||||
// windows系统当没有路径参数时这个位置默认有个.,需要加以判断
|
// 执行成功,创建标记文件
|
||||||
preFilePath = process.argv[1] === "." ? "" : process.argv[1];
|
try {
|
||||||
}
|
fs.writeFileSync(installFlagPath, new Date().toISOString(), "utf-8");
|
||||||
// });
|
console.log("安装脚本执行完成");
|
||||||
|
writeLog("安装脚本执行完成");
|
||||||
ipcMain.on("open-program", (event) => {
|
if (stdout) console.log("输出:", stdout);
|
||||||
if (process.env.NODE_ENV !== "development") {
|
if (stderr) console.error("错误输出:", stderr);
|
||||||
//调试模式下不运行此行
|
} catch (writeErr) {
|
||||||
if (preFilePath != "") {
|
console.error("创建安装标记文件失败:", writeErr);
|
||||||
event.reply("open-program-callback", preFilePath);
|
writeLog("创建安装标记文件失败: " + writeErr.message);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
// 1. preFilePath
|
app.on("ready", () => {
|
||||||
//
|
// 在创建窗口后执行安装脚本
|
||||||
|
createWindow();
|
||||||
// const ffi = require('ffi-napi');
|
// 延迟执行安装脚本,确保应用已启动
|
||||||
// const { ipcMain } = require("electron");
|
setTimeout(() => {
|
||||||
// ipcMain.on("init-frp", (event) => {
|
runInstallScript();
|
||||||
// let result1 = frp_cap.LIVESCAN_Init();
|
}, 1000);
|
||||||
// let result2 = frp_cap.LIVESCAN_GetChannelCount();
|
});
|
||||||
// event.reply("init-frp-callback", result1 == 1 && result2 > 0);
|
|
||||||
|
app.on("window-all-closed", () => {
|
||||||
// });
|
if (process.platform !== "darwin") {
|
||||||
|
app.quit();
|
||||||
// const frp = new ffi.Library('../../lib/ID_FprCap.dll', {
|
}
|
||||||
// 'LIVESCAN_Init':
|
});
|
||||||
// [
|
|
||||||
// 'int', [],
|
app.on("activate", () => {
|
||||||
// ],
|
if (mainWindow === null) {
|
||||||
// 'LIVESCAN_BeginCapture':
|
createWindow();
|
||||||
// [
|
}
|
||||||
// 'int', ['int']
|
});
|
||||||
// ]
|
app.on("renderer-process-crashed", function (event, webContents, details) {
|
||||||
// });
|
// 输出一下捕捉到的reason,实际可以根据不同的“原因”进行具体处理
|
||||||
// let result = frp_cap.LIVESCAN_Init();//初始化
|
console.error("renderer-process-crashed, reason => ", JSON.stringify(details));
|
||||||
// console.log(`LIVESCAN_Init: ` + result);
|
// 重启应用
|
||||||
|
writeLog("renderer-process-crashed, reason => " + JSON.stringify(details))
|
||||||
// result = frp_cap.LIVESCAN_GetChannelCount();//获得采集器通道数量
|
});
|
||||||
// console.log(`LIVESCAN_GetChannelCount: ` + result);
|
|
||||||
|
const { ipcMain } = require("electron");
|
||||||
// result = frp_cap.LIVESCAN_BeginCapture(0);// 准备采集一帧图像
|
let preFilePath = "";
|
||||||
// console.log(`LIVESCAN_BeginCapture: ` + result);
|
// app.on("will-finish-launching", () => {
|
||||||
|
app.on("open-file", (e, filePath) => {
|
||||||
// const buf = new Buffer.alloc(256 * 360 + 1078);
|
preFilePath = filePath;
|
||||||
// console.log("BMP图像获取状态:", frp_cap.LIVESCAN_GetFPBmpData(0, buf))
|
});
|
||||||
// //console.log(buf.toString('hex'))
|
|
||||||
// fs.writeFile('./1.bmp',buf,'',()=>{});//11
|
ipcMain.on('open-help-file', async event => {
|
||||||
// const buf2 = new Buffer.alloc(256 * 360);
|
const helpFilePath = path.join(root, "help", "User Manual.pdf");
|
||||||
// console.log("图像获取状态:", frp_cap.LIVESCAN_GetFPRawData(0, buf2))
|
|
||||||
// console.log(buf2.toString('hex'))
|
try {
|
||||||
|
await shell.openPath(helpFilePath);
|
||||||
//console.log("buf", buf.toString("base64")); //12
|
} catch (error) {
|
||||||
//console.log("test", frp_cap.LIVESCAN_GetFPRawData(0, buf));
|
console.error("打开帮助文件错误:", error);
|
||||||
//console.log("buf", buf.toString("base64")); //
|
writeLog("打开帮助文件错误: " + error.message);
|
||||||
//frp_cap.LIVESCAN_EndCapture(0);
|
if (event.reply) {
|
||||||
//result = frp.FP_Begin();
|
event.reply('open-help-file-error', error.message);
|
||||||
//console.log(`FP_Begin`, result);
|
}
|
||||||
//
|
}
|
||||||
//const buf2 = new Buffer(512);
|
});
|
||||||
//frp.FP_FeatureExtract(65, 99, buf, buf2);
|
|
||||||
//console.log("buf2: ", buf2.toString("base64")); //111111
|
ipcMain.on("get-root", (event) => {
|
||||||
/**
|
event.reply("get-root-callback", root);
|
||||||
* Auto Updater
|
});
|
||||||
*
|
|
||||||
* Uncomment the following code below and install `electron-updater` to
|
if (process.platform === "win32" && process.argv.length >= 2) {
|
||||||
* support auto updating. Code Signing with a valid certificate is required.
|
console.log("process argv:", process.argv);
|
||||||
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
|
// windows系统当没有路径参数时这个位置默认有个.,需要加以判断
|
||||||
*/
|
preFilePath = process.argv[1] === "." ? "" : process.argv[1];
|
||||||
|
}
|
||||||
/*
|
// });
|
||||||
import { autoUpdater } from 'electron-updater'
|
|
||||||
|
ipcMain.on("open-program", (event) => {
|
||||||
autoUpdater.on('update-downloaded', () => {
|
if (process.env.NODE_ENV !== "development") {
|
||||||
autoUpdater.quitAndInstall()
|
//调试模式下不运行此行
|
||||||
})
|
if (preFilePath != "") {
|
||||||
|
event.reply("open-program-callback", preFilePath);
|
||||||
app.on('ready', () => {
|
}
|
||||||
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
|
}
|
||||||
})
|
});
|
||||||
*/
|
|
||||||
|
// 1. preFilePath
|
||||||
|
//
|
||||||
|
|
||||||
|
// const ffi = require('ffi-napi');
|
||||||
|
// const { ipcMain } = require("electron");
|
||||||
|
// ipcMain.on("init-frp", (event) => {
|
||||||
|
// let result1 = frp_cap.LIVESCAN_Init();
|
||||||
|
// let result2 = frp_cap.LIVESCAN_GetChannelCount();
|
||||||
|
// event.reply("init-frp-callback", result1 == 1 && result2 > 0);
|
||||||
|
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const frp = new ffi.Library('../../lib/ID_FprCap.dll', {
|
||||||
|
// 'LIVESCAN_Init':
|
||||||
|
// [
|
||||||
|
// 'int', [],
|
||||||
|
// ],
|
||||||
|
// 'LIVESCAN_BeginCapture':
|
||||||
|
// [
|
||||||
|
// 'int', ['int']
|
||||||
|
// ]
|
||||||
|
// });
|
||||||
|
// let result = frp_cap.LIVESCAN_Init();//初始化
|
||||||
|
// console.log(`LIVESCAN_Init: ` + result);
|
||||||
|
|
||||||
|
// result = frp_cap.LIVESCAN_GetChannelCount();//获得采集器通道数量
|
||||||
|
// console.log(`LIVESCAN_GetChannelCount: ` + result);
|
||||||
|
|
||||||
|
// result = frp_cap.LIVESCAN_BeginCapture(0);// 准备采集一帧图像
|
||||||
|
// console.log(`LIVESCAN_BeginCapture: ` + result);
|
||||||
|
|
||||||
|
// const buf = new Buffer.alloc(256 * 360 + 1078);
|
||||||
|
// console.log("BMP图像获取状态:", frp_cap.LIVESCAN_GetFPBmpData(0, buf))
|
||||||
|
// //console.log(buf.toString('hex'))
|
||||||
|
// fs.writeFile('./1.bmp',buf,'',()=>{});//11
|
||||||
|
// const buf2 = new Buffer.alloc(256 * 360);
|
||||||
|
// console.log("图像获取状态:", frp_cap.LIVESCAN_GetFPRawData(0, buf2))
|
||||||
|
// console.log(buf2.toString('hex'))
|
||||||
|
|
||||||
|
//console.log("buf", buf.toString("base64")); //12
|
||||||
|
//console.log("test", frp_cap.LIVESCAN_GetFPRawData(0, buf));
|
||||||
|
//console.log("buf", buf.toString("base64")); //
|
||||||
|
//frp_cap.LIVESCAN_EndCapture(0);
|
||||||
|
//result = frp.FP_Begin();
|
||||||
|
//console.log(`FP_Begin`, result);
|
||||||
|
//
|
||||||
|
//const buf2 = new Buffer(512);
|
||||||
|
//frp.FP_FeatureExtract(65, 99, buf, buf2);
|
||||||
|
//console.log("buf2: ", buf2.toString("base64")); //111111
|
||||||
|
/**
|
||||||
|
* Auto Updater
|
||||||
|
*
|
||||||
|
* Uncomment the following code below and install `electron-updater` to
|
||||||
|
* support auto updating. Code Signing with a valid certificate is required.
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
import { autoUpdater } from 'electron-updater'
|
||||||
|
|
||||||
|
autoUpdater.on('update-downloaded', () => {
|
||||||
|
autoUpdater.quitAndInstall()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('ready', () => {
|
||||||
|
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
|||||||
+55
-21
@@ -14,6 +14,14 @@ class ScreenRecorder {
|
|||||||
this.mainWindow = window;
|
this.mainWindow = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重置录制状态(用于前端初始化时清理可能的僵尸状态)
|
||||||
|
resetRecording() {
|
||||||
|
this.isRecording = false;
|
||||||
|
this.recordedChunks = [];
|
||||||
|
console.log('Recording state reset by renderer');
|
||||||
|
return { success: true, message: 'State reset' };
|
||||||
|
}
|
||||||
|
|
||||||
async startRecording() {
|
async startRecording() {
|
||||||
if (this.isRecording) {
|
if (this.isRecording) {
|
||||||
return { success: false, message: '正在录制中' };
|
return { success: false, message: '正在录制中' };
|
||||||
@@ -33,11 +41,11 @@ class ScreenRecorder {
|
|||||||
// 发送源ID到渲染进程
|
// 发送源ID到渲染进程
|
||||||
const sourceId = sources[0].id;
|
const sourceId = sources[0].id;
|
||||||
this.isRecording = true;
|
this.isRecording = true;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
sourceId: sourceId,
|
sourceId: sourceId,
|
||||||
message: '开始录制'
|
message: '开始录制'
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('启动录制失败:', error);
|
console.error('启动录制失败:', error);
|
||||||
@@ -45,26 +53,48 @@ class ScreenRecorder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopRecording(videoData) {
|
async stopRecording(videoData, taskId = '', customPath = null) {
|
||||||
if (!this.isRecording) {
|
if (!this.isRecording) {
|
||||||
return { success: false, message: '当前没有进行录制' };
|
return { success: false, message: '当前没有进行录制' };
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.isRecording = false;
|
this.isRecording = false;
|
||||||
|
|
||||||
// 确保videos目录存在 - 在应用根目录下
|
// 获取应用根目录
|
||||||
const appPath = process.env.NODE_ENV === 'development'
|
const appPath = process.env.NODE_ENV === 'development'
|
||||||
? path.join(__dirname, '../../')
|
? path.join(__dirname, '../../')
|
||||||
: path.dirname(app.getPath('exe'));
|
: path.dirname(app.getPath('exe'));
|
||||||
const videosDir = path.join(appPath, 'videos');
|
|
||||||
|
let videosDir;
|
||||||
|
if (customPath) {
|
||||||
|
// 如果是绝对路径直接使用,否则拼接应用根目录
|
||||||
|
videosDir = path.isAbsolute(customPath)
|
||||||
|
? customPath
|
||||||
|
: path.join(appPath, customPath);
|
||||||
|
} else {
|
||||||
|
// 默认目录:应用根目录/videos
|
||||||
|
videosDir = path.join(appPath, 'videos');
|
||||||
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(videosDir)) {
|
if (!fs.existsSync(videosDir)) {
|
||||||
fs.mkdirSync(videosDir, { recursive: true });
|
fs.mkdirSync(videosDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成文件名:soonworker+时间戳
|
// 生成文件名:任务ID_日期时间格式 (YYYYMMDD_HHmmss)
|
||||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
const now = new Date();
|
||||||
const fileName = `soonworker_${timestamp}.webm`;
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||||
|
const dateTimeStr = `${year}${month}${day}_${hours}${minutes}${seconds}`;
|
||||||
|
|
||||||
|
// 如果有任务ID,使用任务ID_日期时间,否则使用日期时间
|
||||||
|
const fileName = taskId
|
||||||
|
? `${taskId}_${dateTimeStr}.webm`
|
||||||
|
: `${dateTimeStr}.webm`;
|
||||||
const filePath = path.join(videosDir, fileName);
|
const filePath = path.join(videosDir, fileName);
|
||||||
|
|
||||||
// 将base64数据转换为Buffer并保存
|
// 将base64数据转换为Buffer并保存
|
||||||
@@ -72,12 +102,12 @@ class ScreenRecorder {
|
|||||||
fs.writeFileSync(filePath, buffer);
|
fs.writeFileSync(filePath, buffer);
|
||||||
|
|
||||||
console.log('视频已保存到:', filePath);
|
console.log('视频已保存到:', filePath);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
filePath: filePath,
|
filePath: filePath,
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
message: '录制已保存'
|
message: '录制已保存'
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('停止录制失败:', error);
|
console.error('停止录制失败:', error);
|
||||||
@@ -87,8 +117,8 @@ class ScreenRecorder {
|
|||||||
|
|
||||||
// 获取videos目录路径
|
// 获取videos目录路径
|
||||||
getVideosPath() {
|
getVideosPath() {
|
||||||
const appPath = process.env.NODE_ENV === 'development'
|
const appPath = process.env.NODE_ENV === 'development'
|
||||||
? path.join(__dirname, '../../')
|
? path.join(__dirname, '../../')
|
||||||
: path.dirname(app.getPath('exe'));
|
: path.dirname(app.getPath('exe'));
|
||||||
return path.join(appPath, 'videos');
|
return path.join(appPath, 'videos');
|
||||||
}
|
}
|
||||||
@@ -102,14 +132,18 @@ ipcMain.handle('start-recording', async () => {
|
|||||||
return await recorder.startRecording();
|
return await recorder.startRecording();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('stop-recording', async (event, videoData) => {
|
ipcMain.handle('stop-recording', async (event, videoData, taskId, customPath) => {
|
||||||
return await recorder.stopRecording(videoData);
|
return await recorder.stopRecording(videoData, taskId, customPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('get-videos-path', () => {
|
ipcMain.handle('get-videos-path', () => {
|
||||||
return recorder.getVideosPath();
|
return recorder.getVideosPath();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('reset-recording', async () => {
|
||||||
|
return recorder.resetRecording();
|
||||||
|
});
|
||||||
|
|
||||||
// 使用全局变量方式,避免webpack模块转换问题
|
// 使用全局变量方式,避免webpack模块转换问题
|
||||||
global.ScreenRecorderInstance = recorder;
|
global.ScreenRecorderInstance = recorder;
|
||||||
global.setMainWindow = (window) => recorder.setMainWindow(window);
|
global.setMainWindow = (window) => recorder.setMainWindow(window);
|
||||||
|
|||||||
@@ -1,50 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog :title="$t('networkAuth.title')" :visible.sync="visible" width="600px" :close-on-click-modal="false"
|
||||||
:title="$t('networkAuth.title')"
|
:close-on-press-escape="false" :show-close="false" :append-to-body="true" :z-index="9999">
|
||||||
:visible.sync="visible"
|
|
||||||
width="600px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:close-on-press-escape="false"
|
|
||||||
:show-close="false"
|
|
||||||
:append-to-body="true"
|
|
||||||
:z-index="9999"
|
|
||||||
>
|
|
||||||
<div class="network-auth-content">
|
<div class="network-auth-content">
|
||||||
<p class="auth-description">
|
<p class="auth-description">
|
||||||
{{ $t('networkAuth.description') }}
|
{{ $t('networkAuth.description') }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="network-paths">
|
<div class="network-paths">
|
||||||
<div
|
<div v-for="(path, index) in networkPaths" :key="index" class="network-path-item">
|
||||||
v-for="(path, index) in networkPaths"
|
|
||||||
:key="index"
|
|
||||||
class="network-path-item"
|
|
||||||
>
|
|
||||||
<div class="path-info">
|
<div class="path-info">
|
||||||
<span class="path-label">{{ $t('networkAuth.pathLabel') }}</span>
|
<span class="path-label">{{ $t('networkAuth.pathLabel') }}</span>
|
||||||
<span class="path-value">{{ path.path }}</span>
|
<span class="path-value">{{ path.path }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="auth-fields">
|
<div class="auth-fields">
|
||||||
<el-input
|
<el-input v-model="path.userName" :placeholder="$t('networkAuth.userName')" size="small"
|
||||||
v-model="path.userName"
|
style="width: 150px; margin-right: 10px;" />
|
||||||
:placeholder="$t('networkAuth.userName')"
|
<el-input v-model="path.password" type="password" :placeholder="$t('networkAuth.password')" size="small"
|
||||||
size="small"
|
style="width: 150px;" show-password />
|
||||||
style="width: 150px; margin-right: 10px;"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
v-model="path.password"
|
|
||||||
type="password"
|
|
||||||
:placeholder="$t('networkAuth.password')"
|
|
||||||
size="small"
|
|
||||||
style="width: 150px;"
|
|
||||||
show-password
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="handleCancel">{{ $t('networkAuth.cancel') }}</el-button>
|
<el-button @click="handleCancel">{{ $t('networkAuth.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="handleConfirm" :loading="loading">
|
<el-button type="primary" @click="handleConfirm" :loading="loading">
|
||||||
@@ -76,7 +54,7 @@ export default {
|
|||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.$emit('cancel')
|
this.$emit('cancel')
|
||||||
},
|
},
|
||||||
|
|
||||||
async handleConfirm() {
|
async handleConfirm() {
|
||||||
// 验证所有路径都填写了用户名和密码
|
// 验证所有路径都填写了用户名和密码
|
||||||
for (let path of this.networkPaths) {
|
for (let path of this.networkPaths) {
|
||||||
@@ -85,29 +63,29 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 保存到本地存储
|
// 保存到本地存储
|
||||||
this.saveNetworkCredentials()
|
this.saveNetworkCredentials()
|
||||||
|
|
||||||
// 构建 net_info 数据
|
// 构建 net_info 数据
|
||||||
const netInfo = this.networkPaths.map(path => ({
|
const netInfo = this.networkPaths.map(path => ({
|
||||||
host_name: this.extractHostName(path.path),
|
host_name: this.extractHostName(path.path),
|
||||||
user_name: path.userName,
|
user_name: path.userName,
|
||||||
password: path.password
|
password: path.password
|
||||||
}))
|
}))
|
||||||
|
|
||||||
this.$emit('confirm', netInfo)
|
this.$emit('confirm', netInfo)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存网络认证信息失败:', error)
|
console.error('保存网络认证信息失败:', error)
|
||||||
this.$message.error('保存认证信息失败')
|
this.$message.error(this.$t('networkAuth.authSaveFail'))
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
extractHostName(path) {
|
extractHostName(path) {
|
||||||
// 从网络路径中提取主机名
|
// 从网络路径中提取主机名
|
||||||
// 支持格式:\\hostname\path, //hostname/path, \\192.168.1.1\path
|
// 支持格式:\\hostname\path, //hostname/path, \\192.168.1.1\path
|
||||||
@@ -126,7 +104,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return 'unknown'
|
return 'unknown'
|
||||||
},
|
},
|
||||||
|
|
||||||
saveNetworkCredentials() {
|
saveNetworkCredentials() {
|
||||||
// 保存到 localStorage
|
// 保存到 localStorage
|
||||||
const credentials = {}
|
const credentials = {}
|
||||||
@@ -138,9 +116,9 @@ export default {
|
|||||||
lastUsed: new Date().toISOString()
|
lastUsed: new Date().toISOString()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
localStorage.setItem('networkCredentials', JSON.stringify(credentials))
|
localStorage.setItem('networkCredentials', JSON.stringify(credentials))
|
||||||
|
|
||||||
// 同时保存到 Vuex store(若可用)
|
// 同时保存到 Vuex store(若可用)
|
||||||
if (this.$store && this.$store.commit) {
|
if (this.$store && this.$store.commit) {
|
||||||
this.$store.commit('SET_NETWORK_CREDENTIALS', credentials)
|
this.$store.commit('SET_NETWORK_CREDENTIALS', credentials)
|
||||||
@@ -157,7 +135,7 @@ export default {
|
|||||||
color: #606266;
|
color: #606266;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-paths {
|
.network-paths {
|
||||||
.network-path-item {
|
.network-path-item {
|
||||||
border: 1px solid #e4e7ed;
|
border: 1px solid #e4e7ed;
|
||||||
@@ -165,16 +143,16 @@ export default {
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
|
|
||||||
.path-info {
|
.path-info {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
.path-label {
|
.path-label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path-value {
|
.path-value {
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
@@ -183,7 +161,7 @@ export default {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-fields {
|
.auth-fields {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
+125
-165
@@ -6,13 +6,8 @@
|
|||||||
<div class="title">
|
<div class="title">
|
||||||
{{ $t("index.wordSpace") }}
|
{{ $t("index.wordSpace") }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="card" v-for="(item, index) of infoData" :key="item.PrinterID" @click="() => (printData = index)"
|
||||||
class="card"
|
style="text-align: left">
|
||||||
v-for="(item, index) of infoData"
|
|
||||||
:key="item.PrinterID"
|
|
||||||
@click="() => (printData = index)"
|
|
||||||
style="text-align: left"
|
|
||||||
>
|
|
||||||
<span style="font-size: 18px; margin-left: 40px">{{
|
<span style="font-size: 18px; margin-left: 40px">{{
|
||||||
getPrintName(item.PrinterID, true)
|
getPrintName(item.PrinterID, true)
|
||||||
}}</span>
|
}}</span>
|
||||||
@@ -30,9 +25,7 @@
|
|||||||
<div :span="21" style="height: 100%; width: calc(100% - 164px)">
|
<div :span="21" style="height: 100%; width: calc(100% - 164px)">
|
||||||
<div class="grid-content bg-purple-light mid">
|
<div class="grid-content bg-purple-light mid">
|
||||||
<div class="toMain">
|
<div class="toMain">
|
||||||
<span style="margin-right: 20px"
|
<span style="margin-right: 20px">{{ $t("admin.hello") }} {{ user }}</span>
|
||||||
>{{ $t("admin.hello") }} {{ user }}</span
|
|
||||||
>
|
|
||||||
<router-link to="/main"> {{ $t("admin.home") }}</router-link>
|
<router-link to="/main"> {{ $t("admin.home") }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -46,27 +39,11 @@
|
|||||||
<el-tab-pane :label="$t('admin.userManage')" name="second">
|
<el-tab-pane :label="$t('admin.userManage')" name="second">
|
||||||
<div class="brief">
|
<div class="brief">
|
||||||
<el-row :gutter="20" style="height: 100%">
|
<el-row :gutter="20" style="height: 100%">
|
||||||
<el-table
|
<el-table :data="userData" style="width: 100%" :empty-text="$t('admin.nodata')">
|
||||||
:data="userData"
|
<el-table-column prop="userUuid" label="ID"></el-table-column>
|
||||||
style="width: 100%"
|
<el-table-column prop="userName" :label="$t('admin.userName')"></el-table-column>
|
||||||
:empty-text="$t('admin.nodata')"
|
<el-table-column prop="userRole" :label="$t('admin.role')"></el-table-column>
|
||||||
>
|
<el-table-column prop="time" :label="$t('admin.lastTime')"></el-table-column>
|
||||||
<el-table-column
|
|
||||||
prop="userUuid"
|
|
||||||
label="ID"
|
|
||||||
></el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="userName"
|
|
||||||
:label="$t('admin.userName')"
|
|
||||||
></el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="userRole"
|
|
||||||
:label="$t('admin.role')"
|
|
||||||
></el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="time"
|
|
||||||
:label="$t('admin.lastTime')"
|
|
||||||
></el-table-column>
|
|
||||||
<el-table-column prop="time" :label="$t('admin.online')">
|
<el-table-column prop="time" :label="$t('admin.online')">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{
|
{{
|
||||||
@@ -79,26 +56,12 @@
|
|||||||
<!--<el-table-column prop="describe" label="描述"></el-table-column>-->
|
<!--<el-table-column prop="describe" label="描述"></el-table-column>-->
|
||||||
<el-table-column width="120">
|
<el-table-column width="120">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button type="text" size="medium" @click="() => edit(scope.row)">{{ $t("admin.edit")
|
||||||
type="text"
|
}}</el-button>
|
||||||
size="medium"
|
<el-button type="text" size="medium" @click="adduserVisible = true"
|
||||||
@click="() => edit(scope.row)"
|
v-if="scope.row.userName == 'admin'">{{ $t("admin.add") }}</el-button>
|
||||||
>{{ $t("admin.edit") }}</el-button
|
<el-button type="text" size="medium" @click="() => deleted(scope.row)"
|
||||||
>
|
v-if="scope.row.userName != 'admin'">{{ $t("admin.delete") }}</el-button>
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
size="medium"
|
|
||||||
@click="adduserVisible = true"
|
|
||||||
v-if="scope.row.userName == 'admin'"
|
|
||||||
>{{ $t("admin.add") }}</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
size="medium"
|
|
||||||
@click="() => deleted(scope.row)"
|
|
||||||
v-if="scope.row.userName != 'admin'"
|
|
||||||
>{{ $t("admin.delete") }}</el-button
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -116,47 +79,30 @@
|
|||||||
<div class="service">
|
<div class="service">
|
||||||
<div class="lable">{{ $t("admin.selectWorkstation") }}</div>
|
<div class="lable">{{ $t("admin.selectWorkstation") }}</div>
|
||||||
<el-select v-model="workValue">
|
<el-select v-model="workValue">
|
||||||
<el-option
|
<el-option v-for="(item, index) in infoData" :key="item.PrinterID"
|
||||||
v-for="(item, index) in infoData"
|
:label="getPrintName(item.PrinterID)" :value="item.PrinterID" :disabled="runningState">
|
||||||
:key="item.PrinterID"
|
|
||||||
:label="getPrintName(item.PrinterID)"
|
|
||||||
:value="item.PrinterID"
|
|
||||||
:disabled="runningState"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<div class="lable">{{ $t("admin.formatType") }}</div>
|
<div class="lable">{{ $t("admin.formatType") }}</div>
|
||||||
<el-select v-model="formatValue">
|
<el-select v-model="formatValue">
|
||||||
<el-option
|
<el-option v-for="item in formatOptions" :key="item.value" :label="item.label" :value="item.value"
|
||||||
v-for="item in formatOptions"
|
:disabled="runningState">
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
:disabled="runningState"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<div class="lable">{{ $t("admin.number") }}</div>
|
<div class="lable">{{ $t("admin.number") }}</div>
|
||||||
<el-input
|
<el-input v-model="number" :disabled="runningState"></el-input>
|
||||||
v-model="number"
|
|
||||||
:disabled="runningState"
|
|
||||||
></el-input>
|
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button @click="
|
||||||
@click="
|
() => {
|
||||||
() => {
|
running = 0;
|
||||||
running = 0;
|
runningEmergy = false;
|
||||||
runningEmergy = false;
|
isFormat = true;
|
||||||
isFormat = true;
|
handleFormat();
|
||||||
handleFormat();
|
}
|
||||||
}
|
" :loading="runningState && isFormat" :disabled="runningState && !isFormat">{{ $t("work.submit")
|
||||||
"
|
}}</el-button>
|
||||||
:loading="runningState && isFormat"
|
|
||||||
:disabled="runningState && !isFormat"
|
|
||||||
>{{ $t("work.submit") }}</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="copy">
|
<div class="copy">
|
||||||
@@ -167,41 +113,25 @@
|
|||||||
<div class="service">
|
<div class="service">
|
||||||
<div class="lable">{{ $t("admin.selectWorkstation") }}</div>
|
<div class="lable">{{ $t("admin.selectWorkstation") }}</div>
|
||||||
<el-select v-model="workValue2">
|
<el-select v-model="workValue2">
|
||||||
<el-option
|
<el-option v-for="(item, index) in infoData" :key="index" :label="getPrintName(item.PrinterID)"
|
||||||
v-for="(item, index) in infoData"
|
:value="item.PrinterID" :disabled="runningState">
|
||||||
:key="index"
|
|
||||||
:label="getPrintName(item.PrinterID)"
|
|
||||||
:value="item.PrinterID"
|
|
||||||
:disabled="runningState"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<div class="lable">{{ $t("admin.copyPath") }}</div>
|
<div class="lable">{{ $t("admin.copyPath") }}</div>
|
||||||
<el-input
|
<el-input v-model="path" :disabled="runningState"></el-input>
|
||||||
v-model="path"
|
|
||||||
:disabled="runningState"
|
|
||||||
></el-input>
|
|
||||||
|
|
||||||
<div class="lable">{{ $t("admin.number") }}</div>
|
<div class="lable">{{ $t("admin.number") }}</div>
|
||||||
<el-input
|
<el-input v-model="number2" :disabled="runningState"></el-input>
|
||||||
v-model="number2"
|
|
||||||
:disabled="runningState"
|
|
||||||
></el-input>
|
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button :loading="runningState && !isFormat" :disabled="runningState && isFormat" @click="
|
||||||
:loading="runningState && !isFormat"
|
() => {
|
||||||
:disabled="runningState && isFormat"
|
running = 0;
|
||||||
@click="
|
runningEmergy = false;
|
||||||
() => {
|
isFormat = false;
|
||||||
running = 0;
|
handleCopy();
|
||||||
runningEmergy = false;
|
}
|
||||||
isFormat = false;
|
">{{ $t("work.submit") }}</el-button>
|
||||||
handleCopy();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>{{ $t("work.submit") }}</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -235,49 +165,22 @@
|
|||||||
<div class="wLog" v-html="wlog" style="text-align: left"></div>
|
<div class="wLog" v-html="wlog" style="text-align: left"></div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog :title="$t('admin.addUser')" :visible.sync="adduserVisible" width="450px" class="infdialog"
|
||||||
:title="$t('admin.addUser')"
|
destroy-on-close :close-on-click-modal="false">
|
||||||
:visible.sync="adduserVisible"
|
<adduser :changevisiable="this.chageAdduservisible" v-if="adduserVisible"></adduser>
|
||||||
width="450px"
|
|
||||||
class="infdialog"
|
|
||||||
destroy-on-close
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
>
|
|
||||||
<adduser
|
|
||||||
:changevisiable="this.chageAdduservisible"
|
|
||||||
v-if="adduserVisible"
|
|
||||||
></adduser>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog :title="$t('admin.editUser')" :visible.sync="edituserVisible" width="450px" class="infdialog"
|
||||||
:title="$t('admin.editUser')"
|
destroy-on-close :close-on-click-modal="false">
|
||||||
:visible.sync="edituserVisible"
|
<edituser :changevisiable="this.chageEdituservisible" v-if="edituserVisible" :data="editData" @editover="
|
||||||
width="450px"
|
() => {
|
||||||
class="infdialog"
|
chageEdituservisible(false);
|
||||||
destroy-on-close
|
getUserData();
|
||||||
:close-on-click-modal="false"
|
}
|
||||||
>
|
"></edituser>
|
||||||
<edituser
|
|
||||||
:changevisiable="this.chageEdituservisible"
|
|
||||||
v-if="edituserVisible"
|
|
||||||
:data="editData"
|
|
||||||
@editover="
|
|
||||||
() => {
|
|
||||||
chageEdituservisible(false);
|
|
||||||
getUserData();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
></edituser>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog
|
<el-dialog :title="$t('admin.copying')" :visible.sync="copyVisible" width="450px">
|
||||||
:title="$t('admin.copying')"
|
<el-progress :percentage="parseInt(copyState.progress * 100)" v-if="copyVisible"></el-progress>
|
||||||
:visible.sync="copyVisible"
|
|
||||||
width="450px"
|
|
||||||
>
|
|
||||||
<el-progress
|
|
||||||
:percentage="parseInt(copyState.progress * 100)"
|
|
||||||
v-if="copyVisible"
|
|
||||||
></el-progress>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -464,7 +367,7 @@ export default {
|
|||||||
131078: { tag: "Card_Low", err: 0 },
|
131078: { tag: "Card_Low", err: 0 },
|
||||||
131081: { tag: "Need_Cleaning", err: 0 },
|
131081: { tag: "Need_Cleaning", err: 0 },
|
||||||
1167: { tag: "PAVO_DS_OFFLINE", err: 0 },
|
1167: { tag: "PAVO_DS_OFFLINE", err: 0 },
|
||||||
196609:{ tag: "FIND_CARD", err: 0 },
|
196609: { tag: "FIND_CARD", err: 0 },
|
||||||
},
|
},
|
||||||
errList: [],
|
errList: [],
|
||||||
checkStates: {},
|
checkStates: {},
|
||||||
@@ -513,6 +416,11 @@ export default {
|
|||||||
method: "get",
|
method: "get",
|
||||||
url: "/web/get_printer_info",
|
url: "/web/get_printer_info",
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
if (!res.data || !res.data.printerList) {
|
||||||
|
console.warn('获取工作站列表返回的数据格式不正确:', res)
|
||||||
|
this.infoData = []
|
||||||
|
return
|
||||||
|
}
|
||||||
this.infoData = res.data.printerList;
|
this.infoData = res.data.printerList;
|
||||||
this.workValue2 = this.workValue =
|
this.workValue2 = this.workValue =
|
||||||
res.data.printerList.length > 0
|
res.data.printerList.length > 0
|
||||||
@@ -527,6 +435,10 @@ export default {
|
|||||||
this.DualSide = 1; //只要有一个是双面就是1
|
this.DualSide = 1; //只要有一个是双面就是1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error('获取工作站列表失败:', e)
|
||||||
|
this.infoData = []
|
||||||
|
this.$message.error('获取工作站列表失败,请检查网络连接')
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
runCheckState() {
|
runCheckState() {
|
||||||
@@ -561,8 +473,7 @@ export default {
|
|||||||
//阻止即将发生的事件
|
//阻止即将发生的事件
|
||||||
this.runningEmergy = true;
|
this.runningEmergy = true;
|
||||||
appendLog(
|
appendLog(
|
||||||
`Task ${this.running + 1}/${
|
`Task ${this.running + 1}/${this.isFormat ? this.number : this.number2
|
||||||
this.isFormat ? this.number : this.number2
|
|
||||||
} failed, Error = ${data.printer_status}`,
|
} failed, Error = ${data.printer_status}`,
|
||||||
this.root
|
this.root
|
||||||
);
|
);
|
||||||
@@ -778,10 +689,10 @@ export default {
|
|||||||
);
|
);
|
||||||
this.$message(
|
this.$message(
|
||||||
this.$t("admin.comingSoon") +
|
this.$t("admin.comingSoon") +
|
||||||
`${time[0]}` +
|
`${time[0]}` +
|
||||||
this.$t("admin.readLetter") +
|
this.$t("admin.readLetter") +
|
||||||
`${disk[0]}` +
|
`${disk[0]}` +
|
||||||
this.$t("admin.makeCpoy")
|
this.$t("admin.makeCpoy")
|
||||||
);
|
);
|
||||||
this.handleCopyFile(`${disk[0]}:\\`);
|
this.handleCopyFile(`${disk[0]}:\\`);
|
||||||
}
|
}
|
||||||
@@ -877,14 +788,14 @@ export default {
|
|||||||
) {
|
) {
|
||||||
this.$message(
|
this.$message(
|
||||||
this.$t("admin.comingSoon") +
|
this.$t("admin.comingSoon") +
|
||||||
`${time[0]}` +
|
`${time[0]}` +
|
||||||
this.$t("admin.readLetter") +
|
this.$t("admin.readLetter") +
|
||||||
`${disk[0]}` +
|
`${disk[0]}` +
|
||||||
this.$t("admin.format")
|
this.$t("admin.format")
|
||||||
);
|
);
|
||||||
await this.$axios({
|
await this.$axios({
|
||||||
method: "post",
|
method: "post",
|
||||||
url: `/admin/format_disk_notype?drive_path=${disk[0]}:&drive_type=${this.formatValue}`,
|
url: `/admin/format_disk?drive_path=${disk[0]}:&drive_type=${this.formatValue}`,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
//正常格式化
|
//正常格式化
|
||||||
@@ -1032,42 +943,50 @@ export default {
|
|||||||
/deep/ .el-tabs__content {
|
/deep/ .el-tabs__content {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.infdialog {
|
.infdialog {
|
||||||
/deep/.el-dialog {
|
/deep/.el-dialog {
|
||||||
padding: 20px 0px;
|
padding: 20px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.el-dialog__header {
|
/deep/.el-dialog__header {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.el-dialog__body {
|
/deep/.el-dialog__body {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
/deep/.el-dialog__title {
|
|
||||||
}
|
/deep/.el-dialog__title {}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wLog {
|
.wLog {
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
h2 {
|
h2 {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #42b983;
|
color: #42b983;
|
||||||
}
|
}
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
background-color: #e8e7ee;
|
background-color: #e8e7ee;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -1076,10 +995,12 @@ a {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@@ -1100,36 +1021,45 @@ a {
|
|||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
/deep/.el-tabs__header {
|
/deep/.el-tabs__header {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .el-tabs__content {
|
/deep/ .el-tabs__content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
/*滚动条整体样式*/
|
/*滚动条整体样式*/
|
||||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
width: 10px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
/*滚动条里面小方块*/
|
/*滚动条里面小方块*/
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
background: #c7c7cb;
|
background: #c7c7cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
/*滚动条里面轨道*/
|
/*滚动条里面轨道*/
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #ededed;
|
background: #ededed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.system {
|
.system {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.App {
|
.App {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1139,10 +1069,12 @@ a {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
|
||||||
.format {
|
.format {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
border-bottom: 1px rgb(224, 224, 224) solid;
|
border-bottom: 1px rgb(224, 224, 224) solid;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
@@ -1155,6 +1087,7 @@ a {
|
|||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(240, 240, 240);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -1163,22 +1096,27 @@ a {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.service {
|
.service {
|
||||||
height: 150px;
|
height: 150px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
.lable {
|
.lable {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input {
|
.el-input {
|
||||||
width: 180px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
color: rgb(154, 202, 128);
|
color: rgb(154, 202, 128);
|
||||||
width: 120px;
|
width: 120px;
|
||||||
@@ -1189,12 +1127,15 @@ a {
|
|||||||
float: right;
|
float: right;
|
||||||
margin-right: 25px;
|
margin-right: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:hover {
|
.el-button:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:active {
|
.el-button:active {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:focus {
|
.el-button:focus {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
@@ -1204,6 +1145,7 @@ a {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
border-bottom: 1px rgb(224, 224, 224) solid;
|
border-bottom: 1px rgb(224, 224, 224) solid;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -1217,6 +1159,7 @@ a {
|
|||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(240, 240, 240);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -1224,22 +1167,27 @@ a {
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.service {
|
.service {
|
||||||
height: 150px;
|
height: 150px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
.lable {
|
.lable {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input {
|
.el-input {
|
||||||
width: 180px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
color: rgb(154, 202, 128);
|
color: rgb(154, 202, 128);
|
||||||
width: 120px;
|
width: 120px;
|
||||||
@@ -1250,21 +1198,26 @@ a {
|
|||||||
float: right;
|
float: right;
|
||||||
margin-right: 25px;
|
margin-right: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:hover {
|
.el-button:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:active {
|
.el-button:active {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:focus {
|
.el-button:focus {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dispose {
|
.dispose {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brief {
|
.brief {
|
||||||
height: 90%;
|
height: 90%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1274,10 +1227,12 @@ a {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
|
||||||
.el-table {
|
.el-table {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-button {
|
.add-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
@@ -1286,6 +1241,7 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
background-color: #c8cfd7;
|
background-color: #c8cfd7;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -1295,10 +1251,12 @@ a {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log {
|
.log {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@@ -1311,11 +1269,13 @@ a {
|
|||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toMain {
|
.toMain {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 200px;
|
right: 200px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
color: blue;
|
color: blue;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@@ -4,12 +4,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lable">LogLevel</div>
|
<div class="lable">LogLevel</div>
|
||||||
<el-select v-model="iniData.LogLevel">
|
<el-select v-model="iniData.LogLevel">
|
||||||
<el-option
|
<el-option v-for="item in LogLevelOptions" :key="item.value" :label="item.label" :value="item.value">
|
||||||
v-for="item in LogLevelOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<div class="tips">{{ $t("dispose.infoTips") }}</div>
|
<div class="tips">{{ $t("dispose.infoTips") }}</div>
|
||||||
@@ -17,12 +12,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lable">AutoRetryTimes</div>
|
<div class="lable">AutoRetryTimes</div>
|
||||||
<el-select v-model="iniData.AutoRetryTimes">
|
<el-select v-model="iniData.AutoRetryTimes">
|
||||||
<el-option
|
<el-option v-for="item in autoRetryOptions" :key="item.value" :label="item.label" :value="item.value">
|
||||||
v-for="item in autoRetryOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<div class="tips">{{ $t("dispose.errorTips1") }}</div>
|
<div class="tips">{{ $t("dispose.errorTips1") }}</div>
|
||||||
@@ -43,245 +33,138 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lable">RejectConfig</div>
|
<div class="lable">RejectConfig</div>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<el-switch v-model="iniData.RejectConfig"></el-switch>
|
<el-switch v-model="iniData.RejectConfig" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">{{ $t("dispose.tips1") }}</div>
|
<div class="tips">{{ $t("dispose.tips1") }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lable">StopOnFailure</div>
|
<div class="lable">StopOnFailure</div>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<el-switch v-model="iniData.StopOnFailure"></el-switch>
|
<el-switch v-model="iniData.StopOnFailure" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">{{ $t("dispose.errorTips2") }}</div>
|
<div class="tips">{{ $t("dispose.errorTips2") }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lable">KeepCombinedImage</div>
|
<div class="lable">KeepCombinedImage</div>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<el-switch v-model="iniData.KeepCombinedImage"></el-switch>
|
<el-switch v-model="iniData.KeepCombinedImage" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">{{ $t("dispose.isReserveimg") }}</div>
|
<div class="tips">{{ $t("dispose.isReserveimg") }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lable">CleanTaskFile</div>
|
<div class="lable">CleanTaskFile</div>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<el-switch v-model="iniData.CleanTaskFile"></el-switch>
|
<el-switch v-model="iniData.CleanTaskFile" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">{{ $t("dispose.isReservetask") }}</div>
|
<div class="tips">{{ $t("dispose.isReservetask") }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="row" style="
|
||||||
class="row"
|
|
||||||
style="
|
|
||||||
align-items: start;
|
align-items: start;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
border-bottom: 1px rgb(224, 224, 224) solid;
|
border-bottom: 1px rgb(224, 224, 224) solid;
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<div class="lable">UploadSharedDir</div>
|
<div class="lable">UploadSharedDir</div>
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<el-switch v-model="iniData.UploadSharedDir"></el-switch>
|
<el-switch v-model="iniData.UploadSharedDir" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">{{ $t("dispose.isUpload") }}</div>
|
<div class="tips">{{ $t("dispose.isUpload") }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="row">
|
||||||
class="row"
|
<div class="lable">AuthorizationCode</div>
|
||||||
style="
|
<el-input v-model="iniData.AuthorizationCode" :placeholder="$t('dispose.authCodePlaceholder')"></el-input>
|
||||||
|
<div class="tips">{{ $t("dispose.authCodeTips") }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
margin-right: 40px;
|
margin-right: 40px;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<el-button @click="save">{{ $t("work.submit") }}</el-button>
|
<el-button @click="save">{{ $t("work.submit") }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const { ipcRenderer } = require("electron");
|
|
||||||
var fs = require("fs"),
|
|
||||||
ini = require("ini");
|
|
||||||
export default {
|
export default {
|
||||||
name: "dispose",
|
name: "dispose",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
autoRetryOptions: [
|
autoRetryOptions: [
|
||||||
{
|
{ value: 0, label: "0" },
|
||||||
value: 0,
|
{ value: 1, label: "1" },
|
||||||
label: "0",
|
{ value: 2, label: "2" },
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 1,
|
|
||||||
label: "1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 2,
|
|
||||||
label: "2",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
LogLevelOptions: [
|
LogLevelOptions: [
|
||||||
{
|
{ value: "TRACE", label: "TRACE" },
|
||||||
value: "TRACE",
|
{ value: "DEBUG", label: "DEBUG" },
|
||||||
label: "TRACE",
|
{ value: "INFO", label: "INFO" },
|
||||||
},
|
{ value: "WARNING", label: "WARNING" },
|
||||||
{
|
{ value: "ERROR", label: "ERROR" },
|
||||||
value: "DEBUG",
|
{ value: "FATAL", label: "FATAL" },
|
||||||
label: "DEBUG",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "INFO",
|
|
||||||
label: "INFO",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "WARNING",
|
|
||||||
label: "WARNING",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "ERROR",
|
|
||||||
label: "ERROR",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "FATAL",
|
|
||||||
label: "FATAL",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
iniData: null,
|
iniData: {
|
||||||
|
LogLevel: "INFO",
|
||||||
AutoRetryTimes: null,
|
AutoRetryTimes: 0,
|
||||||
LogLevel: "TRACE",
|
TaskDir: "",
|
||||||
TaskDir: null,
|
SharedDir: "",
|
||||||
SharedDir: null,
|
RejectConfig: 0,
|
||||||
RejectConfig: false,
|
StopOnFailure: 0,
|
||||||
StopOnFailure: false,
|
KeepCombinedImage: 0,
|
||||||
KeepCombinedImage: false,
|
CleanTaskFile: 0,
|
||||||
CleanTaskFile: false,
|
UploadSharedDir: 0,
|
||||||
|
AuthorizationCode: "",
|
||||||
|
DeleteTask: 0 // Ensure this is preserved if present in API
|
||||||
|
},
|
||||||
show: true,
|
show: true,
|
||||||
root: "",
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
save() {
|
// 获取配置
|
||||||
//console.log(this.iniData);
|
getConfig() {
|
||||||
//console.log(ini.stringify(this.iniData));
|
this.$axios.get('/web/get_config')
|
||||||
//fs.writeFileSync("../Debug/config.ini");
|
.then(res => {
|
||||||
let that = this;
|
if (res && res.data) {
|
||||||
fs.writeFile(
|
// 合并数据,确保所有字段都存在
|
||||||
this.root + "/../ProductionServer/config.ini",
|
this.iniData = { ...this.iniData, ...res.data.data };
|
||||||
ini.stringify(this.iniData),
|
|
||||||
function (err) {
|
|
||||||
if (err) {
|
|
||||||
that.$message.error(that.$t("dispose.errorReserve"));
|
|
||||||
} else {
|
} else {
|
||||||
that.$message({
|
this.$message.error(this.$t("dispose.errorRead"));
|
||||||
type: "success",
|
|
||||||
message: that.$t("dispose.successReserve"),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
this.$message.error(this.$t("dispose.errorRead"));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
// 构造 query string
|
||||||
|
let params = [];
|
||||||
|
for (let key in this.iniData) {
|
||||||
|
if (this.iniData.hasOwnProperty(key)) {
|
||||||
|
// 使用 encodeURIComponent 确保特殊字符正确传输
|
||||||
|
params.push(`${key}=${encodeURIComponent(this.iniData[key])}`);
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
|
const queryString = params.join('&');
|
||||||
|
|
||||||
|
this.$axios.post(`/web/update_config?${queryString}`)
|
||||||
|
.then(res => {
|
||||||
|
this.$message({
|
||||||
|
type: "success",
|
||||||
|
message: this.$t("dispose.successReserve"),
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
this.$message.error(this.$t("dispose.errorReserve"));
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let that = this;
|
this.getConfig();
|
||||||
//var data = ini.parse(fs.readFileSync("F:\\controll\\config.ini", "utf-8"));
|
|
||||||
ipcRenderer.on("get-root-callback", (event, data) => {
|
|
||||||
this.root = data;
|
|
||||||
fs.readFile(this.root + "/../ProductionServer/config.ini", "utf-8", (err, res) => {
|
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
this.$message.error(that.$t("dispose.errorRead"));
|
|
||||||
this.show = false;
|
|
||||||
} else {
|
|
||||||
console.log(res);
|
|
||||||
let data = ini.parse(res);
|
|
||||||
console.log(data);
|
|
||||||
this.iniData = data;
|
|
||||||
that.iniData.AutoRetryTimes = data.AutoRetryTimes
|
|
||||||
? data.AutoRetryTimes
|
|
||||||
: 0;
|
|
||||||
that.iniData.TaskDir = data.TaskDir ? data.TaskDir : "";
|
|
||||||
that.iniData.SharedDir = data.SharedDir ? data.SharedDir : "";
|
|
||||||
that.iniData.LogLevel = data.LogLevel ? data.LogLevel : "";
|
|
||||||
that.iniData.CleanTaskFile =
|
|
||||||
data.CleanTaskFile == "true" ||
|
|
||||||
data.CleanTaskFile == "True" ||
|
|
||||||
data.CleanTaskFile
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.iniData.KeepCombinedImage =
|
|
||||||
data.KeepCombinedImage == "true" ||
|
|
||||||
data.KeepCombinedImage == "True" ||
|
|
||||||
data.KeepCombinedImage
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.iniData.RejectConfig =
|
|
||||||
data.RejectConfig == "true" ||
|
|
||||||
data.RejectConfig == "True" ||
|
|
||||||
data.RejectConfig
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.iniData.StopOnFailure =
|
|
||||||
data.StopOnFailure == "true" ||
|
|
||||||
data.StopOnFailure == "True" ||
|
|
||||||
data.StopOnFailure
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.iniData.UploadSharedDir =
|
|
||||||
data.UploadSharedDir == "true" ||
|
|
||||||
data.UploadSharedDir == "True" ||
|
|
||||||
data.UploadSharedDir
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ipcRenderer.send("get-root");
|
|
||||||
|
|
||||||
//iniparser.parse("../Debug/config.ini", function (err, data) {
|
|
||||||
/*
|
|
||||||
AutoRetryTimes: "0"
|
|
||||||
CardsoonModel: "SF80"
|
|
||||||
CleanTaskFile: "false"
|
|
||||||
RejectConfig: "false"
|
|
||||||
KeepCombinedImage: "True"
|
|
||||||
LogLevel: "DEBUG"
|
|
||||||
SharedDir: "C:\\CardSoonRepo"
|
|
||||||
StopOnFailure: "false"
|
|
||||||
SystemSn: "830001"
|
|
||||||
TaskDir: "C:\\PrintTasks"
|
|
||||||
Version: "V3.1"
|
|
||||||
|
|
||||||
iniparser.parse("F:\\controll\\config.ini", function (err, data) {
|
|
||||||
console.log(err);
|
|
||||||
if (err) {
|
|
||||||
that.$message.error("读取配置文件失败!");
|
|
||||||
} else {
|
|
||||||
console.log(data);
|
|
||||||
that.AutoRetryTimes = data.AutoRetryTimes ? data.AutoRetryTimes : 0;
|
|
||||||
that.TaskDir = data.TaskDir ? data.TaskDir : "";
|
|
||||||
that.SharedDir = data.SharedDir ? data.SharedDir : "";
|
|
||||||
that.LogLevel = data.LogLevel ? data.LogLevel : "";
|
|
||||||
that.CleanTaskFile =
|
|
||||||
data.CleanTaskFile == "true" || data.CleanTaskFile == "True"
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.KeepCombinedImage =
|
|
||||||
data.KeepCombinedImage == "true" || data.KeepCombinedImage == "True"
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.RejectConfig =
|
|
||||||
data.RejectConfig == "true" || data.RejectConfig == "True"
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
that.StopOnFailure =
|
|
||||||
data.StopOnFailure == "true" || data.StopOnFailure == "True"
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -298,6 +181,7 @@ export default {
|
|||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -310,38 +194,45 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(240, 240, 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|
||||||
.lable {
|
.lable {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input {
|
.el-input {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.switch {
|
.switch {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
width: calc(100% - 440px);
|
width: calc(100% - 440px);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
color: rgb(154, 202, 128);
|
color: rgb(154, 202, 128);
|
||||||
width: 120px;
|
width: 120px;
|
||||||
@@ -350,12 +241,15 @@ export default {
|
|||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
box-shadow: 1px 0px 2px 0px grey;
|
box-shadow: 1px 0px 2px 0px grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:hover {
|
.el-button:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:active {
|
.el-button:active {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:focus {
|
.el-button:focus {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,39 +13,19 @@
|
|||||||
<fileEmpty v-if="allNumber == 0" />
|
<fileEmpty v-if="allNumber == 0" />
|
||||||
<fileList v-else :list="filesList" :del="delFile" :key="key" />
|
<fileList v-else :list="filesList" :del="delFile" :key="key" />
|
||||||
<div v-if="progressVisible">
|
<div v-if="progressVisible">
|
||||||
<el-dialog
|
<el-dialog :close-on-click-modal="false" width="500px" :visible.sync="progressVisible" :append-to-body="true"
|
||||||
:close-on-click-modal="false"
|
class="prodialog">
|
||||||
width="500px"
|
<progressdialog :list="filesList" :overNumber="overNumber" :allNumber="allNumber"
|
||||||
:visible.sync="progressVisible"
|
:changevisiable="changeProgressvisible" :changestate="changestate" :isSucess="isSucess" ref="progressdialog">
|
||||||
:append-to-body="true"
|
</progressdialog>
|
||||||
class="prodialog"
|
|
||||||
>
|
|
||||||
<progressdialog
|
|
||||||
:list="filesList"
|
|
||||||
:overNumber="overNumber"
|
|
||||||
:allNumber="allNumber"
|
|
||||||
:changevisiable="changeProgressvisible"
|
|
||||||
:changestate="changestate"
|
|
||||||
:isSucess="isSucess"
|
|
||||||
ref="progressdialog"
|
|
||||||
></progressdialog>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="archiverVisible">
|
<div v-if="archiverVisible">
|
||||||
<el-dialog
|
<el-dialog :close-on-click-modal="false" width="500px" :visible.sync="archiverVisible" :append-to-body="true"
|
||||||
:close-on-click-modal="false"
|
class="archiverDialog" :show-close="false">
|
||||||
width="500px"
|
<archiverdialog :isOver="archiverIsover" :isFalse="archiverIsfalse" :changevisiable="changeArchivervisible">
|
||||||
:visible.sync="archiverVisible"
|
</archiverdialog>
|
||||||
:append-to-body="true"
|
|
||||||
class="archiverDialog"
|
|
||||||
:show-close="false"
|
|
||||||
>
|
|
||||||
<archiverdialog
|
|
||||||
:isOver="archiverIsover"
|
|
||||||
:isFalse="archiverIsfalse"
|
|
||||||
:changevisiable="changeArchivervisible"
|
|
||||||
></archiverdialog>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
@@ -68,8 +48,8 @@ const isNetworkPath = (path) => {
|
|||||||
// 检测是否为网络路径
|
// 检测是否为网络路径
|
||||||
// Windows 网络路径: \\hostname\path 或 \\IP\path
|
// Windows 网络路径: \\hostname\path 或 \\IP\path
|
||||||
// Unix 网络路径: //hostname/path 或 //IP/path
|
// Unix 网络路径: //hostname/path 或 //IP/path
|
||||||
return path.startsWith('\\\\') || path.startsWith('//') ||
|
return path.startsWith('\\\\') || path.startsWith('//') ||
|
||||||
(path.includes(':') && !path.includes('\\') && !path.includes('/'));
|
(path.includes(':') && !path.includes('\\') && !path.includes('/'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const extractHostName = (path) => {
|
const extractHostName = (path) => {
|
||||||
@@ -190,12 +170,12 @@ export default {
|
|||||||
// 是文件夹
|
// 是文件夹
|
||||||
this.sizeChange(f.size);
|
this.sizeChange(f.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检测是否为网络路径
|
// 检测是否为网络路径
|
||||||
if (isNetworkPath(f.path)) {
|
if (isNetworkPath(f.path)) {
|
||||||
this.addNetworkPath(f.path);
|
this.addNetworkPath(f.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
//有了,不用加入
|
//有了,不用加入
|
||||||
@@ -369,7 +349,11 @@ export default {
|
|||||||
entries.forEach((f) => this.fileBack(f, false));
|
entries.forEach((f) => this.fileBack(f, false));
|
||||||
}
|
}
|
||||||
} else if (file_form == 1) {
|
} else if (file_form == 1) {
|
||||||
//电子光盘
|
// 电子光盘:不需要拷贝,直接标记为完成
|
||||||
|
this.overNumber = 0;
|
||||||
|
for (const file of entries) {
|
||||||
|
this.fileBack(file, true);
|
||||||
|
}
|
||||||
} else if (file_form == 2) {
|
} else if (file_form == 2) {
|
||||||
//zip
|
//zip
|
||||||
this.archiverIsover = false;
|
this.archiverIsover = false;
|
||||||
@@ -384,7 +368,11 @@ export default {
|
|||||||
let password = "123456";
|
let password = "123456";
|
||||||
zip(this.filesList, this.zip_path, this.archiverBack, true, password);
|
zip(this.filesList, this.zip_path, this.archiverBack, true, password);
|
||||||
} else if (file_form == 4) {
|
} else if (file_form == 4) {
|
||||||
//u盘
|
// 禁拷贝U盘:不需要拷贝,直接标记为完成
|
||||||
|
this.overNumber = 0;
|
||||||
|
for (const file of entries) {
|
||||||
|
this.fileBack(file, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 默认路径上传:不实际拷贝,仅回调推进流程
|
// 默认路径上传:不实际拷贝,仅回调推进流程
|
||||||
this.overNumber = 0;
|
this.overNumber = 0;
|
||||||
@@ -405,7 +393,7 @@ export default {
|
|||||||
getLists() {
|
getLists() {
|
||||||
return this.filesList;
|
return this.filesList;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 添加网络路径到列表(按主机去重,仅认证根目录,如 \\\\NAS)
|
// 添加网络路径到列表(按主机去重,仅认证根目录,如 \\\\NAS)
|
||||||
addNetworkPath(path) {
|
addNetworkPath(path) {
|
||||||
const hostName = extractHostName(path);
|
const hostName = extractHostName(path);
|
||||||
@@ -440,7 +428,7 @@ export default {
|
|||||||
this.$emit('network-paths-changed', this.getNetworkPaths());
|
this.$emit('network-paths-changed', this.getNetworkPaths());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取网络路径列表(按主机去重,返回根路径)
|
// 获取网络路径列表(按主机去重,返回根路径)
|
||||||
getNetworkPaths() {
|
getNetworkPaths() {
|
||||||
const uniqueByHost = {};
|
const uniqueByHost = {};
|
||||||
@@ -456,13 +444,13 @@ export default {
|
|||||||
}
|
}
|
||||||
return Object.values(uniqueByHost);
|
return Object.values(uniqueByHost);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 检查是否有网络路径
|
// 检查是否有网络路径
|
||||||
hasNetworkPaths() {
|
hasNetworkPaths() {
|
||||||
return this.networkPaths.length > 0;
|
return this.networkPaths.length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
haveFolderIsCalc() {},
|
haveFolderIsCalc() { },
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
@@ -476,11 +464,13 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.archiverDialog {
|
.archiverDialog {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
/deep/.el-dialog__header {
|
/deep/.el-dialog__header {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
@@ -488,12 +478,15 @@ export default {
|
|||||||
|
|
||||||
.files {
|
.files {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #f5f5f5;
|
background-color: transparent;
|
||||||
margin: 10px auto 0;
|
margin: 0;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
box-shadow: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 375px;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-group {
|
.btn-group {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="'background-image:url(' + bgi + ');background-repeat: no-repeat;background-position: 50% 50%;'" class="empty"></div>
|
<div :style="'background-image:url(' + bgi + ');background-repeat: no-repeat;background-position: 50% 50%;'"
|
||||||
|
class="empty"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
@@ -20,7 +21,7 @@ export default {
|
|||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.empty {
|
.empty {
|
||||||
height: 345px;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -27,21 +27,25 @@ export default {
|
|||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.list {
|
.list {
|
||||||
height: 374px;
|
flex: 1;
|
||||||
max-height: 374px;
|
height: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
/*滚动条整体样式*/
|
/*滚动条整体样式*/
|
||||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
width: 10px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
/*滚动条里面小方块*/
|
/*滚动条里面小方块*/
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
background: #c7c7cb;
|
background: #c7c7cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
/*滚动条里面轨道*/
|
/*滚动条里面轨道*/
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<el-progress
|
<el-progress :percentage="Math.min(100, Math.max(0, parseInt(fake.progress * 100) || 0))"
|
||||||
:percentage="parseInt(fake.progress * 100)"
|
:format="format"></el-progress>
|
||||||
:format="format"
|
|
||||||
></el-progress>
|
|
||||||
<div class="txt">
|
<div class="txt">
|
||||||
<div class="over">{{ overNumber }}</div>
|
<div class="over">{{ overNumber }}</div>
|
||||||
<div class="all">/{{ allNumber }}</div>
|
<div class="all">/{{ allNumber }}</div>
|
||||||
@@ -26,20 +24,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else-if="!isSucess" style="color: red">文件上传失败!!!</div>
|
<div v-else-if="!isSucess" style="color: red">文件上传失败!!!</div>
|
||||||
<div class="button">
|
<div class="button">
|
||||||
<el-button
|
<el-button ref="btnStop" type="success" @click="stop()" :disabled="overNumber == allNumber || !isSucess">{{
|
||||||
ref="btnStop"
|
$t("dialog.stop") }}</el-button>
|
||||||
type="success"
|
<el-button ref="btnOver" type="success" @click="changevisiable(flase)"
|
||||||
@click="stop()"
|
:disabled="overNumber != allNumber && isSucess">{{ $t("dialog.over") }}</el-button>
|
||||||
: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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,15 +71,17 @@ export default {
|
|||||||
getPercent(num, total) {
|
getPercent(num, total) {
|
||||||
num = parseFloat(num);
|
num = parseFloat(num);
|
||||||
total = parseFloat(total);
|
total = parseFloat(total);
|
||||||
if (isNaN(num) || isNaN(total)) {
|
if (isNaN(num) || isNaN(total) || total <= 0) {
|
||||||
return "-";
|
return 0;
|
||||||
}
|
}
|
||||||
return total <= 0 ? "0" : Math.round((num / total) * 10000) / 10000.0;
|
let per = num / total;
|
||||||
|
return per > 1 ? 1 : per;
|
||||||
},
|
},
|
||||||
stop() {
|
stop() {
|
||||||
this.changestate(false);
|
this.changestate(false);
|
||||||
this.isSucess = false;
|
this.isSucess = false;
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("dialog.haveStop"),
|
message: this.$t("dialog.haveStop"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -112,7 +102,7 @@ export default {
|
|||||||
this.sub.end();
|
this.sub.end();
|
||||||
//console.log("sub end");
|
//console.log("sub end");
|
||||||
}
|
}
|
||||||
|
|
||||||
const newlist = [];
|
const newlist = [];
|
||||||
for (let i in this.list) {
|
for (let i in this.list) {
|
||||||
if (this.list[i].state == true) {
|
if (this.list[i].state == true) {
|
||||||
@@ -139,34 +129,35 @@ export default {
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
isSucess:{
|
isSucess: {
|
||||||
// 数据发生变化就会调用这个函数
|
// 数据发生变化就会调用这个函数
|
||||||
handler(newVal, oldVal) {
|
handler(newVal, oldVal) {
|
||||||
if(!this.isSucess){
|
if (!this.isSucess) {
|
||||||
this.sub.stop();
|
this.sub.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
// 立即处理 进入页面就触发
|
// 立即处理 进入页面就触发
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.dialog {
|
|
||||||
}
|
|
||||||
.progress {
|
.progress {
|
||||||
|
|
||||||
// border: 1px black solid;
|
// border: 1px black solid;
|
||||||
/deep/ .el-progress-bar {
|
/deep/ .el-progress-bar {
|
||||||
width: 97%;
|
width: 97%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.el-progress__text {
|
/deep/.el-progress__text {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.txt {
|
.txt {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 55px;
|
top: 55px;
|
||||||
@@ -183,6 +174,7 @@ export default {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.all {
|
.all {
|
||||||
// border: 1px black solid;
|
// border: 1px black solid;
|
||||||
color: black;
|
color: black;
|
||||||
@@ -194,17 +186,21 @@ export default {
|
|||||||
.records {
|
.records {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
/*滚动条整体样式*/
|
/*滚动条整体样式*/
|
||||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
width: 10px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
/*滚动条里面小方块*/
|
/*滚动条里面小方块*/
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
background: #c7c7cb;
|
background: #c7c7cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
/*滚动条里面轨道*/
|
/*滚动条里面轨道*/
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
@@ -212,13 +208,15 @@ export default {
|
|||||||
background: #ededed;
|
background: #ededed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.record {
|
.record {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
.name {
|
|
||||||
}
|
|
||||||
|
|
||||||
.state {
|
.state {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
@@ -228,6 +226,7 @@ export default {
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
float: right;
|
float: right;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -235,6 +234,7 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -243,6 +243,7 @@ export default {
|
|||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
float: left;
|
float: left;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+248
-545
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="screen-recorder">
|
<div class="screen-recorder">
|
||||||
<el-tooltip
|
<template v-if="!statusOnly">
|
||||||
:content="isRecording ? $t('recorder.stopRecording') : $t('recorder.startRecording')"
|
<el-tooltip :content="isRecording ? $t('recorder.stopRecording') : $t('recorder.startRecording')" placement="top">
|
||||||
placement="top">
|
<el-button size="medium" :type="isRecording ? 'danger' : 'primary'"
|
||||||
<el-button
|
:icon="isRecording ? 'el-icon-switch-button' : 'el-icon-video-camera'" circle @click="toggleRecording"
|
||||||
size="medium"
|
:loading="loading" class="record-btn">
|
||||||
:type="isRecording ? 'danger' : 'primary'"
|
</el-button>
|
||||||
:icon="isRecording ? 'el-icon-video-pause' : 'el-icon-video-camera'"
|
</el-tooltip>
|
||||||
circle
|
</template>
|
||||||
@click="toggleRecording"
|
|
||||||
:loading="loading"
|
|
||||||
class="record-btn"
|
|
||||||
>
|
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
|
|
||||||
<!-- 录制状态指示器 -->
|
<!-- 录制状态指示器 -->
|
||||||
<div v-if="isRecording" class="recording-indicator">
|
<div v-if="isRecording" class="recording-indicator" :class="{ 'status-only': statusOnly }">
|
||||||
<span class="recording-dot"></span>
|
<span class="recording-dot"></span>
|
||||||
<span class="recording-text">{{ recordingTime }}</span>
|
<span class="recording-text">{{ statusOnly ? $t('recorder.recording') : recordingTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,6 +22,16 @@ const { ipcRenderer } = require('electron');
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ScreenRecorder',
|
name: 'ScreenRecorder',
|
||||||
|
props: {
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
statusOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isRecording: false,
|
isRecording: false,
|
||||||
@@ -37,7 +41,11 @@ export default {
|
|||||||
startTime: null,
|
startTime: null,
|
||||||
recordingTime: '00:00',
|
recordingTime: '00:00',
|
||||||
timer: null,
|
timer: null,
|
||||||
stream: null
|
stream: null,
|
||||||
|
currentTaskId: '', // 录屏开始时的任务ID
|
||||||
|
autoSave: true, // 是否在停止时保存
|
||||||
|
videoPath: '', // 录制视频的绝对路径
|
||||||
|
customSavePath: '' // 存储启动时传入的保存路径
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -49,13 +57,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async startRecording() {
|
async startRecording(options = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
this.autoSave = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 调用主进程开始录制
|
// 调用主进程开始录制
|
||||||
const result = await ipcRenderer.invoke('start-recording');
|
const result = await ipcRenderer.invoke('start-recording');
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
this.$message.error(result.message);
|
this.$message.error(result.message);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@@ -79,7 +88,8 @@ export default {
|
|||||||
|
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.recordedChunks = [];
|
this.recordedChunks = [];
|
||||||
|
this.customSavePath = options.savePath || ''; // 保存自定义路径
|
||||||
|
|
||||||
// 创建MediaRecorder
|
// 创建MediaRecorder
|
||||||
this.mediaRecorder = new MediaRecorder(stream, {
|
this.mediaRecorder = new MediaRecorder(stream, {
|
||||||
mimeType: 'video/webm'
|
mimeType: 'video/webm'
|
||||||
@@ -92,84 +102,124 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.mediaRecorder.onstop = async () => {
|
this.mediaRecorder.onstop = async () => {
|
||||||
await this.saveRecording();
|
if (this.autoSave) {
|
||||||
|
await this.saveRecording(this.customSavePath); // 使用保存的路径
|
||||||
|
}
|
||||||
|
this.recordedChunks = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
// 开始录制
|
// 开始录制
|
||||||
this.mediaRecorder.start();
|
this.mediaRecorder.start();
|
||||||
this.isRecording = true;
|
this.isRecording = true;
|
||||||
this.startTime = Date.now();
|
this.startTime = Date.now();
|
||||||
|
// 保存录屏开始时的任务ID
|
||||||
|
this.currentTaskId = this.taskId || '';
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
|
|
||||||
this.$message.success(this.$t('recorder.recordingStarted') || '开始录制');
|
this.$message.success(this.$t('recorder.recordingStarted'));
|
||||||
this.$emit('recording-started');
|
this.$emit('recording-started');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('启动录制失败:', error);
|
console.error('启动录制失败:', error);
|
||||||
this.$message.error(this.$t('recorder.startFailed') || '启动录制失败');
|
this.$message.error(this.$t('recorder.startFailed'));
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async stopRecording() {
|
async stopRecording(save = true) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
this.autoSave = save;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
|
if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
|
||||||
this.mediaRecorder.stop();
|
// 创建 Promise 等待 onstop 回调完成
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
// 保存原有的 onstop 处理器
|
||||||
|
const originalOnStop = this.mediaRecorder.onstop;
|
||||||
|
|
||||||
|
// 包装 onstop,在原处理器完成后 resolve
|
||||||
|
this.mediaRecorder.onstop = async (event) => {
|
||||||
|
if (originalOnStop) {
|
||||||
|
await originalOnStop.call(this, event);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 触发 stop 事件
|
||||||
|
this.mediaRecorder.stop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 停止所有轨道
|
// 停止所有轨道
|
||||||
if (this.stream) {
|
if (this.stream) {
|
||||||
this.stream.getTracks().forEach(track => track.stop());
|
this.stream.getTracks().forEach(track => track.stop());
|
||||||
this.stream = null;
|
this.stream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isRecording = false;
|
this.isRecording = false;
|
||||||
this.stopTimer();
|
this.stopTimer();
|
||||||
this.$emit('recording-stopped');
|
this.$emit('recording-stopped');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('停止录制失败:', error);
|
console.error('停止录制失败:', error);
|
||||||
this.$message.error(this.$t('recorder.stopFailed') || '停止录制失败');
|
this.$message.error(this.$t('recorder.stopFailed'));
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveRecording() {
|
async cancelRecording() {
|
||||||
|
await this.stopRecording(false);
|
||||||
|
this.$message.info(this.$t('recorder.recordingCanceled'));
|
||||||
|
},
|
||||||
|
|
||||||
|
async saveRecording(customPath) {
|
||||||
if (this.recordedChunks.length === 0) {
|
if (this.recordedChunks.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return new Promise((resolve, reject) => {
|
||||||
// 将录制的数据块合并为Blob
|
try {
|
||||||
const blob = new Blob(this.recordedChunks, {
|
// 将录制的数据块合并为Blob
|
||||||
type: 'video/webm'
|
const blob = new Blob(this.recordedChunks, {
|
||||||
});
|
type: 'video/webm'
|
||||||
|
});
|
||||||
|
|
||||||
// 转换为base64
|
// 转换为base64
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onloadend = async () => {
|
reader.onloadend = async () => {
|
||||||
const base64data = reader.result;
|
if (this._isDestroyed) return;
|
||||||
|
try {
|
||||||
// 发送到主进程保存
|
const base64data = reader.result;
|
||||||
const result = await ipcRenderer.invoke('stop-recording', base64data);
|
|
||||||
|
// 发送到主进程保存,传递任务ID和可选路径
|
||||||
if (result.success) {
|
const result = await ipcRenderer.invoke('stop-recording', base64data, this.currentTaskId, customPath);
|
||||||
this.$message.success(this.$t('recorder.savedSuccess') || `录制已保存: ${result.fileName}`);
|
|
||||||
this.$emit('recording-saved', result);
|
if (this._isDestroyed) return;
|
||||||
} else {
|
|
||||||
this.$message.error(result.message);
|
if (result.success) {
|
||||||
}
|
this.$message.success(this.$t('recorder.savedSuccess') + `: ${result.fileName}`);
|
||||||
};
|
this.videoPath = result.filePath; // 保存视频绝对路径供外部使用
|
||||||
reader.readAsDataURL(blob);
|
this.$emit('recording-saved', result);
|
||||||
|
resolve(result);
|
||||||
} catch (error) {
|
} else {
|
||||||
console.error('保存录制失败:', error);
|
this.$message.error(result.message);
|
||||||
this.$message.error(this.$t('recorder.saveFailed') || '保存录制失败');
|
reject(new Error(result.message));
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存录制失败:', error);
|
||||||
|
this.$message.error(this.$t('recorder.saveFailed'));
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
startTimer() {
|
startTimer() {
|
||||||
@@ -243,9 +293,12 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes blink {
|
@keyframes blink {
|
||||||
0%, 100% {
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,24 +9,14 @@
|
|||||||
state == null
|
state == null
|
||||||
? this.$t("systemControl.detecting")
|
? this.$t("systemControl.detecting")
|
||||||
: state
|
: state
|
||||||
? this.$t("systemControl.start")
|
? this.$t("systemControl.start")
|
||||||
: this.$t("systemControl.stop")
|
: this.$t("systemControl.stop")
|
||||||
}}</span>
|
}}</span>
|
||||||
<div>{{ $t("systemControl.tips1") }}</div>
|
<div>{{ $t("systemControl.tips1") }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="serviceImg">
|
<div class="serviceImg">
|
||||||
<el-button
|
<el-button icon="el-icon-video-play" circle @click="play" :disabled="state || state == null"></el-button>
|
||||||
icon="el-icon-video-play"
|
<el-button icon="el-icon-video-pause" circle @click="pause" :disabled="!state || state == null"></el-button>
|
||||||
circle
|
|
||||||
@click="play"
|
|
||||||
:disabled="state || state == null"
|
|
||||||
></el-button>
|
|
||||||
<el-button
|
|
||||||
icon="el-icon-video-pause"
|
|
||||||
circle
|
|
||||||
@click="pause"
|
|
||||||
:disabled="!state || state == null"
|
|
||||||
></el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -36,12 +26,8 @@
|
|||||||
<div class="select">
|
<div class="select">
|
||||||
<div class="lable">{{ $t("systemControl.selectWorkstation") }}</div>
|
<div class="lable">{{ $t("systemControl.selectWorkstation") }}</div>
|
||||||
<el-select v-model="workValue">
|
<el-select v-model="workValue">
|
||||||
<el-option
|
<el-option v-for="item in printData" :key="item.PrinterID" :label="getPrintName(item.PrinterID)"
|
||||||
v-for="item in printData"
|
:value="item.PrinterID">
|
||||||
:key="item.PrinterID"
|
|
||||||
:label="getPrintName(item.PrinterID)"
|
|
||||||
:value="item.PrinterID"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,27 +104,18 @@
|
|||||||
<div class="select">
|
<div class="select">
|
||||||
<div class="lable">{{ $t("systemControl.refreshTime1") }}</div>
|
<div class="lable">{{ $t("systemControl.refreshTime1") }}</div>
|
||||||
<el-input v-model="refreshTime1" type="number" style="width: 300px">
|
<el-input v-model="refreshTime1" type="number" style="width: 300px">
|
||||||
<el-button
|
<el-button slot="append" icon="el-icon-finished" @click="handleSaveTime1"></el-button>
|
||||||
slot="append"
|
></el-input>
|
||||||
icon="el-icon-finished"
|
|
||||||
@click="handleSaveTime1"
|
|
||||||
></el-button>
|
|
||||||
></el-input
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="select">
|
<div class="select">
|
||||||
<div class="lable">{{ $t("systemControl.refreshTime2") }}</div>
|
<div class="lable">{{ $t("systemControl.refreshTime2") }}</div>
|
||||||
<el-input v-model="refreshTime2" type="number" style="width: 300px">
|
<el-input v-model="refreshTime2" type="number" style="width: 300px">
|
||||||
<el-button
|
<el-button slot="append" icon="el-icon-finished" @click="handleSaveTime2"></el-button></el-input>
|
||||||
slot="append"
|
|
||||||
icon="el-icon-finished"
|
|
||||||
@click="handleSaveTime2"
|
|
||||||
></el-button
|
|
||||||
></el-input>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="select">
|
<div class="select">
|
||||||
<div class="lable">{{ $t("systemControl.guide") }}</div>
|
<div class="lable">{{ $t("systemControl.guide") }}</div>
|
||||||
<el-switch @change="changeStep" v-model="showStep" :active-text="$t('systemControl.show')" :inactive-text="$t('systemControl.hide')"></el-switch>
|
<el-switch @change="changeStep" v-model="showStep" :active-text="$t('systemControl.show')"
|
||||||
|
:inactive-text="$t('systemControl.hide')"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -147,12 +124,7 @@
|
|||||||
<div class="select">
|
<div class="select">
|
||||||
<div class="lable">{{ $t("systemControl.changeLanguage") }}</div>
|
<div class="lable">{{ $t("systemControl.changeLanguage") }}</div>
|
||||||
<el-select v-model="selectLan">
|
<el-select v-model="selectLan">
|
||||||
<el-option
|
<el-option v-for="item in languages" :key="item.value" :label="item.label" :value="item.value">
|
||||||
v-for="item in languages"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -323,7 +295,7 @@ export default {
|
|||||||
// );
|
// );
|
||||||
//}, 2000);
|
//}, 2000);
|
||||||
//this.workValue = !this.printData ? null : this.printData[0].PrinterID;
|
//this.workValue = !this.printData ? null : this.printData[0].PrinterID;
|
||||||
if (!localStorage.getItem('hideStep')||localStorage.getItem('hideStep')==0) this.showStep = true
|
if (!localStorage.getItem('hideStep') || localStorage.getItem('hideStep') == 0) this.showStep = true
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.timer = null;
|
this.timer = null;
|
||||||
@@ -360,11 +332,20 @@ export default {
|
|||||||
method: "get",
|
method: "get",
|
||||||
url: "/web/get_printer_info",
|
url: "/web/get_printer_info",
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
if (!res.data || !res.data.printerList) {
|
||||||
|
console.warn('获取工作站列表返回的数据格式不正确:', res)
|
||||||
|
this.printData = []
|
||||||
|
return
|
||||||
|
}
|
||||||
this.printData = res.data.printerList;
|
this.printData = res.data.printerList;
|
||||||
if (this.printData.length != 0) {
|
if (this.printData.length != 0) {
|
||||||
//自动选择第一个
|
//自动选择第一个
|
||||||
this.workValue = this.printData[0].PrinterID;
|
this.workValue = this.printData[0].PrinterID;
|
||||||
}
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error('获取工作站列表失败:', e)
|
||||||
|
this.printData = []
|
||||||
|
this.$message.error('获取工作站列表失败,请检查网络连接')
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
checkServerState(callback) {
|
checkServerState(callback) {
|
||||||
@@ -779,12 +760,14 @@ export default {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
|
||||||
.restart {
|
.restart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-bottom: 1px rgb(224, 224, 224) solid;
|
border-bottom: 1px rgb(224, 224, 224) solid;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
@@ -797,27 +780,32 @@ export default {
|
|||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(240, 240, 240);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.service {
|
.service {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
color: rgb(94, 94, 94);
|
color: rgb(94, 94, 94);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.serviceImg {
|
.serviceImg {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin-left: 100px;
|
margin-left: 100px;
|
||||||
|
|
||||||
.begin {
|
.begin {
|
||||||
width: 55px;
|
width: 55px;
|
||||||
height: 55px;
|
height: 55px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stop {
|
.stop {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
@@ -826,12 +814,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 420px;
|
height: 420px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-bottom: 1px rgb(224, 224, 224) solid;
|
border-bottom: 1px rgb(224, 224, 224) solid;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -845,9 +835,11 @@ export default {
|
|||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(240, 240, 240);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.service {
|
.service {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.select {
|
.select {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -865,10 +857,12 @@ export default {
|
|||||||
width: 150px;
|
width: 150px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 180px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.concrete {
|
.concrete {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -894,6 +888,7 @@ export default {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
width: 180px;
|
width: 180px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
@@ -911,15 +906,19 @@ export default {
|
|||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
box-shadow: 1px 0px 2px 0px grey;
|
box-shadow: 1px 0px 2px 0px grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:nth-child(4) {
|
.el-button:nth-child(4) {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:hover {
|
.el-button:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:active {
|
.el-button:active {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:focus {
|
.el-button:focus {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
@@ -927,11 +926,13 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.languageer {
|
.languageer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 220px;
|
height: 220px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -945,6 +946,7 @@ export default {
|
|||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(240, 240, 240);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select {
|
.select {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -952,12 +954,14 @@ export default {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|
||||||
.lable {
|
.lable {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 180px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+18
-2983
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="$t('work.senior')" :visible.sync="visibleSync" width="780px" append-to-body
|
||||||
|
custom-class="grand-dialog" :close-on-click-modal="false" top="5vh" @close="handleClose">
|
||||||
|
<div class="grand-setting-content" style="max-height: 75vh; overflow-y: auto; padding-right: 10px;">
|
||||||
|
<el-form :model="form" label-position="right" label-width="120px" size="small">
|
||||||
|
|
||||||
|
<!-- 动态分模式渲染 -->
|
||||||
|
<basic-config :form="form" :file-form="fileForm" :options="options" :printer-list="printerList"
|
||||||
|
:size-form="sizeForm" />
|
||||||
|
|
||||||
|
<!-- 高级功能(ISO/ZIP/HASH/计数器) -->
|
||||||
|
<advanced-features :form="form" :file-form="fileForm" />
|
||||||
|
|
||||||
|
<!-- 屏幕录制 -->
|
||||||
|
<recording-settings :form="form" :file-form="fileForm"
|
||||||
|
@test-recording="$emit('test-recording', $event)" />
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasicConfig from './sections/BasicConfig.vue'
|
||||||
|
import AdvancedFeatures from './sections/AdvancedFeatures.vue'
|
||||||
|
import RecordingSettings from './sections/RecordingSettings.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AdvancedSettings',
|
||||||
|
components: {
|
||||||
|
BasicConfig,
|
||||||
|
AdvancedFeatures,
|
||||||
|
RecordingSettings
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fileForm: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
printerList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
sizeForm: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visibleSync: {
|
||||||
|
get() {
|
||||||
|
return this.visible
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:visible', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.visibleSync = false
|
||||||
|
},
|
||||||
|
handleSave() {
|
||||||
|
// 验证加密狗计数
|
||||||
|
if (this.form.enable_dongle_counter) {
|
||||||
|
if (!this.form.install_dongle_count || this.form.install_dongle_count < 0 || !Number.isInteger(this.form.install_dongle_count)) {
|
||||||
|
this.$message.warning(this.$t('work.dongleCountRequired'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证 ISO 文件名
|
||||||
|
if (this.form.is_generate_iso && !this.form.iso_file_name) {
|
||||||
|
this.$message.warning(this.$t('work.isoNameInput'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证 ZIP 文件名
|
||||||
|
if (this.form.is_generate_zip) {
|
||||||
|
if (!this.form.zip_file_name) {
|
||||||
|
this.$message.warning(this.$t('work.zipNameInput'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证 ZIP 加密密码
|
||||||
|
if (this.form.is_zip_encrypt) {
|
||||||
|
if (!this.form.zip_password) {
|
||||||
|
this.$message.warning(this.$t('work.pleasePassword'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.form.zip_password !== this.form.zip_repassword) {
|
||||||
|
this.$message.warning(this.$t('work.zipPassWrong'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('save')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 样式将包含在主组件中或按需引入 */
|
||||||
|
.grand-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file">
|
||||||
|
<div class="section-title">
|
||||||
|
<div class="title-left">
|
||||||
|
<i class="el-icon-folder-opened"></i>
|
||||||
|
<span class="title-text">{{ $t('work.contentTitle') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="content-header-actions">
|
||||||
|
<el-button size="small" @click="$refs.files.addFolder()">{{ $t("file.addFolder") }}</el-button>
|
||||||
|
<el-button size="small" @click="$refs.files.addFile()">{{ $t("file.addFile") }}</el-button>
|
||||||
|
<div class="volume-label-group">
|
||||||
|
<span class="label-text">{{ $t('work.sign') }}</span>
|
||||||
|
<el-input :value="juanbiao" @input="$emit('update:juanbiao', $event)" size="small"
|
||||||
|
:placeholder="$t('work.pleaseInput')" class="volume-input" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 列表容器 -->
|
||||||
|
<div class="content-container mt-10">
|
||||||
|
<files ref="files" :onSizechange="onSizeChange" :complete="onUploadOver" :saveWorkList="saveWorkList"
|
||||||
|
class="flex-1-files" @network-paths-changed="$emit('network-paths-changed', $event)">
|
||||||
|
<slot name="progress"></slot>
|
||||||
|
</files>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Files from '../files/file.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FileManagement',
|
||||||
|
components: { Files },
|
||||||
|
props: {
|
||||||
|
saveWorkList: Object,
|
||||||
|
juanbiao: String
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleCommand(command) {
|
||||||
|
if (command === 'folder') {
|
||||||
|
this.$refs.files.addFolder()
|
||||||
|
} else {
|
||||||
|
this.$refs.files.addFile()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSizeChange(size) {
|
||||||
|
this.$emit('size-change', size)
|
||||||
|
},
|
||||||
|
onUploadOver() {
|
||||||
|
this.$emit('upload-over')
|
||||||
|
},
|
||||||
|
// 将父组件需要的 ref 方法公开
|
||||||
|
hasNetworkPaths() { return this.$refs.files.hasNetworkPaths() },
|
||||||
|
getNetworkPaths() { return this.$refs.files.getNetworkPaths() },
|
||||||
|
resume(form) { this.$refs.files.resume(form) },
|
||||||
|
getLists() { return this.$refs.files.getLists() }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 暴露 allNumber 供父组件校验
|
||||||
|
allNumber() {
|
||||||
|
return (this.$refs && this.$refs.files) ? this.$refs.files.allNumber : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@import './styles/work-styles.css';
|
||||||
|
|
||||||
|
.file {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1-files {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume-label-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-text {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume-input {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<el-popover v-if="guideStep && guideStep[step]" :placement="guideStep[step].placement" width="250" trigger="manual"
|
||||||
|
v-model="guideStep[step].show">
|
||||||
|
<div class="guide_box">
|
||||||
|
<div class="guide_title">
|
||||||
|
{{ $t('guide.title') }}<span>({{ parseInt(currentStep) + 1 }}/{{ guideStep.length }})</span>
|
||||||
|
</div>
|
||||||
|
<div class="guide_desc">{{ $t(`guide.step${step + 1}`) }}</div>
|
||||||
|
<div class="guide_btns">
|
||||||
|
<el-button @click="$emit('exit-guide')" class="guide_btn1" size="mini" type="text">
|
||||||
|
{{ $t('guide.skip') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="parseInt(currentStep) > 0" @click="$emit('prev-step')" class="guide_btn1" size="mini">
|
||||||
|
{{ $t('guide.prev') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="$emit('next-step')" class="guide_btn2" size="mini" type="primary">
|
||||||
|
{{ currentStep == guideStep.length - 1 ? $t('guide.complete') : $t('guide.next') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="reference" :class="{ guide_body: currentStep == step }">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<div v-else>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'GuidePopover',
|
||||||
|
props: {
|
||||||
|
step: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
guideStep: {
|
||||||
|
type: [Object, Array],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
currentStep: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.guide_body {
|
||||||
|
position: relative;
|
||||||
|
z-index: 9999;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_box {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_title span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_desc {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_btns {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_btn1 {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide_btn2 {
|
||||||
|
background-color: #409EFF;
|
||||||
|
border-color: #409EFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,448 @@
|
|||||||
|
<template>
|
||||||
|
<div class="label">
|
||||||
|
<div class="section-title">
|
||||||
|
<div class="title-left">
|
||||||
|
<i class="el-icon-collection-tag"></i>
|
||||||
|
<span class="title-text">{{ $t('work.tag') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="header-right-actions">
|
||||||
|
<el-select v-model="currentTemplateLocal" :placeholder="$t('work.pleaseSelect')" size="small"
|
||||||
|
class="template-select" @change="onTemplateChange" clearable filterable>
|
||||||
|
<el-option v-for="(item, index) in templates" :key="index" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
<el-button size="small" @click="$emit('open-design')">
|
||||||
|
{{ $t('work.design') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button size="small" @click="$emit('open-file')">
|
||||||
|
{{ $t('work.import') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<div class="display_box" v-if="fileData.frontDisplayPic || fileData.backDisplayPic">
|
||||||
|
<el-tooltip effect="light" content="打印正面" placement="bottom">
|
||||||
|
<div class="display_item" @click="setPrintFlag(2)">
|
||||||
|
<div class="display_bg" v-if="printFlag === 3"></div>
|
||||||
|
<img :src="fileData.frontDisplayPic" />
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip effect="light" content="打印反面" placement="bottom">
|
||||||
|
<div class="display_item" @click="setPrintFlag(3)">
|
||||||
|
<div class="display_bg" v-if="printFlag === 2"></div>
|
||||||
|
<img :src="fileData.backDisplayPic" />
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="display_box display_box_placeholder" v-else>
|
||||||
|
<span class="empty-text-dark">{{ $t('work.nodata') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 详细参数列表 -->
|
||||||
|
<div class="metadata-container mt-10">
|
||||||
|
<div class="sub-title">
|
||||||
|
<i class="el-icon-edit-outline"></i>
|
||||||
|
<span>{{ $t('work.metadataEdit') }}</span>
|
||||||
|
<span class="field-count" v-if="tableData && tableData.length > 0">({{ tableData.length }})</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 卡片式布局替代表格 -->
|
||||||
|
<div v-if="tableData && tableData.length > 0" class="metadata-fields-list">
|
||||||
|
<div v-for="(item, index) in tableData" :key="index" class="field-item"
|
||||||
|
:class="{ 'field-disabled': csvIsExist && (item.type == 3 || item.type == 4 || item.type == 5) }">
|
||||||
|
|
||||||
|
<!-- 左侧:字段名称区域 -->
|
||||||
|
<div class="field-label-area">
|
||||||
|
<div class="field-info">
|
||||||
|
<div class="field-name-row">
|
||||||
|
<span class="field-name" :title="item.name">{{ item.name }}</span>
|
||||||
|
<span v-if="item.sideLabel" class="side-badge"
|
||||||
|
:class="{ 'side-front': item.sideLabel.includes('正'), 'side-back': item.sideLabel.includes('背') }">
|
||||||
|
{{ item.sideLabel.replace('[', '').replace(']', '') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧:输入区域 -->
|
||||||
|
<div class="field-input-area">
|
||||||
|
<!-- 图片类型 -->
|
||||||
|
<div v-if="item.type == 1" class="image-upload-wrapper">
|
||||||
|
<!-- 预览图 -->
|
||||||
|
<div v-if="imgPreviews[item.origin_name]" class="image-preview mb-5">
|
||||||
|
<img :src="imgPreviews[item.origin_name]" class="preview-img" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label :for="'upload-' + item.origin_name" class="upload-label">
|
||||||
|
<i class="el-icon-picture-outline"></i>
|
||||||
|
<span>{{ $t('work.selectImage') }}</span>
|
||||||
|
</label>
|
||||||
|
<input :id="'upload-' + item.origin_name" type="file" accept="image/*"
|
||||||
|
:ref="item.origin_name" :data-name="item.origin_name" class="hidden-file-input"
|
||||||
|
@change="(e) => handleImageChange(item.origin_name, e)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 文本/条码类型 -->
|
||||||
|
<div v-else-if="item.type == 3 || item.type == 4 || item.type == 5" class="text-input-wrapper">
|
||||||
|
<el-input v-model="form[item.origin_name]" :placeholder="$t('work.pleaseInput')" clearable
|
||||||
|
size="small" :disabled="csvIsExist" class="modern-input" />
|
||||||
|
<el-button size="small" icon="el-icon-upload2" @click="$emit('open-csv')"
|
||||||
|
class="csv-import-btn" :title="$t('work.binfile')">
|
||||||
|
<span class="btn-text">{{ file_name || $t('work.binfile') }}</span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 其他类型 -->
|
||||||
|
<div v-else class="field-value-display">
|
||||||
|
{{ item.origin_name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 空状态占位框 (当无数据时显示) -->
|
||||||
|
<div v-else class="empty-state-modern">
|
||||||
|
<i class="el-icon-document"></i>
|
||||||
|
<p class="empty-title">{{ $t('work.noTemplate') }}</p>
|
||||||
|
<p class="empty-hint">{{ $t('work.selectTemplateHint') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'TagMetadata',
|
||||||
|
props: {
|
||||||
|
templates: Array,
|
||||||
|
currentTemplate: String,
|
||||||
|
fileData: Object,
|
||||||
|
printFlag: Number,
|
||||||
|
tableData: Array,
|
||||||
|
form: Object,
|
||||||
|
csvIsExist: Boolean,
|
||||||
|
file_name: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentTemplateLocal: this.currentTemplate,
|
||||||
|
imgPreviews: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
currentTemplate(val) { this.currentTemplateLocal = val }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onTemplateChange(val) {
|
||||||
|
this.$emit('update:current-template', val)
|
||||||
|
this.$emit('template-change', val)
|
||||||
|
},
|
||||||
|
setPrintFlag(flag) {
|
||||||
|
this.$emit('update:print-flag', flag)
|
||||||
|
},
|
||||||
|
handleImageChange(fieldName, event) {
|
||||||
|
const file = event.target.files[0]
|
||||||
|
if (file) {
|
||||||
|
// 生成预览URL
|
||||||
|
if (this.imgPreviews[fieldName]) {
|
||||||
|
URL.revokeObjectURL(this.imgPreviews[fieldName]) // 释放旧URL
|
||||||
|
}
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
this.$set(this.imgPreviews, fieldName, url)
|
||||||
|
|
||||||
|
// 触发原有事件
|
||||||
|
this.$emit('image-change', fieldName, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@import './styles/work-styles.css';
|
||||||
|
|
||||||
|
.header-right-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right-actions ::v-deep .el-button {
|
||||||
|
border-radius: 8px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-grow-table {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-select {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================== 现代化卡片式字段列表 ================== */
|
||||||
|
.metadata-fields-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 字段项卡片 */
|
||||||
|
.field-item {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-item:hover {
|
||||||
|
border-color: #cbd5e1;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 左侧:字段名称区域 */
|
||||||
|
.field-label-area {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
min-width: 180px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1f2937;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-name-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-badge {
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 1px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-front {
|
||||||
|
background-color: #e0f2fe;
|
||||||
|
color: #0369a1;
|
||||||
|
border: 1px solid #bae6fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-back {
|
||||||
|
background-color: #fce7f3;
|
||||||
|
color: #be185d;
|
||||||
|
border: 1px solid #fbcfe8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧:输入区域 */
|
||||||
|
.field-input-area {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图片上传样式 */
|
||||||
|
.image-upload-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
/* 固定高度或自适应 */
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px dashed #d1d5db;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f9fafb;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-label {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 7px 14px;
|
||||||
|
background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #4b5563;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-label:hover {
|
||||||
|
background: linear-gradient(135deg, #e5e7eb 0%, #d1d5db 100%);
|
||||||
|
border-color: #9ca3af;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-label i {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文本输入样式 */
|
||||||
|
.text-input-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modern-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-import-btn {
|
||||||
|
border-radius: 8px;
|
||||||
|
border-color: #d1d5db;
|
||||||
|
background: #ffffff;
|
||||||
|
transition: all 0.2s;
|
||||||
|
max-width: 140px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-import-btn:hover {
|
||||||
|
background: #f9fafb;
|
||||||
|
border-color: #9ca3af;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-import-btn .btn-text {
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 100px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-value-display {
|
||||||
|
padding: 7px 12px;
|
||||||
|
background: #f9fafb;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================== 字段计数 ================== */
|
||||||
|
.field-count {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9ca3af;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-left: 4px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
background: #f3f4f6;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================== 现代化空状态 ================== */
|
||||||
|
.empty-state-modern {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 48px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state-modern i {
|
||||||
|
font-size: 56px;
|
||||||
|
color: #cbd5e1;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #64748b;
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-hint {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #94a3b8;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================== 滚动条美化 ================== */
|
||||||
|
.metadata-fields-list::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-fields-list::-webkit-scrollbar-thumb {
|
||||||
|
background: #cbd5e1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-fields-list::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #94a3b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-fields-list::-webkit-scrollbar-track {
|
||||||
|
background: #f1f5f9;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
<template>
|
||||||
|
<div class="task-header-container">
|
||||||
|
<div class="task-header-flex">
|
||||||
|
<!-- 容量选择 - 步骤8 -->
|
||||||
|
<guide-popover :step="8" :guide-step="guideStep" :current-step="currentStep"
|
||||||
|
@exit-guide="$emit('exit-guide')" @prev-step="$emit('prev-step')" @next-step="$emit('next-step')">
|
||||||
|
<div class="header-item">
|
||||||
|
<label class="inline-label">{{ $t('work.size') }}</label>
|
||||||
|
<el-select v-model="sizeFormLocal" class="header-select size-select" size="small"
|
||||||
|
@change="$emit('update:size_form', $event)" :placeholder="$t('work.pleaseSelect')">
|
||||||
|
<el-option v-for="item in sizeTypeOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
:disabled="filterPassedType && filterPassedType.length > 0 && filterPassedType.indexOf(item.value) == -1" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</guide-popover>
|
||||||
|
|
||||||
|
<!-- 拷贝类型 - 步骤9 -->
|
||||||
|
<guide-popover :step="9" :guide-step="guideStep" :current-step="currentStep"
|
||||||
|
@exit-guide="$emit('exit-guide')" @prev-step="$emit('prev-step')" @next-step="$emit('next-step')">
|
||||||
|
<div class="header-item">
|
||||||
|
<label class="inline-label">{{ $t('work.content') }}</label>
|
||||||
|
<el-select v-model="fileFormLocal" class="header-select" size="small"
|
||||||
|
@change="$emit('update:file_form', $event)">
|
||||||
|
<el-option v-for="item in fileTypeOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</guide-popover>
|
||||||
|
|
||||||
|
<!-- 分区模式 (如果需要显示) -->
|
||||||
|
<div class="header-item" v-if="false">
|
||||||
|
<!-- Screenshot doesn't show partition mode clearly or it might be hidden/dynamic.
|
||||||
|
Users previous layout had it. I will keep it but maybe conditional or just append?
|
||||||
|
The screenshot only shows 2 selects clearly. Keeping it visible for functionality but later in flow?
|
||||||
|
Actually I'll keep it but ensure flex flow handles it. -->
|
||||||
|
<label class="inline-label">{{ $t('work.partType') }}:</label>
|
||||||
|
<el-select v-model="typeFormLocal" class="header-select" size="small"
|
||||||
|
@change="$emit('update:type_form', $event)">
|
||||||
|
<el-option v-for="item in partitionOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import GuidePopover from './GuidePopover.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TaskHeader',
|
||||||
|
components: {
|
||||||
|
GuidePopover
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
juanbiao_form: String,
|
||||||
|
file_form: Number,
|
||||||
|
size_form: [Number, String],
|
||||||
|
type_form: Number,
|
||||||
|
sizeType: Array,
|
||||||
|
filterPassedType: Array,
|
||||||
|
guideStep: [Object, Array],
|
||||||
|
currentStep: [Number, String]
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
fileFormLocal: this.file_form,
|
||||||
|
sizeFormLocal: this.size_form,
|
||||||
|
typeFormLocal: this.type_form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
file_form(val) { this.fileFormLocal = val },
|
||||||
|
size_form(val) { this.sizeFormLocal = val },
|
||||||
|
type_form(val) { this.typeFormLocal = val }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
juanbiao: {
|
||||||
|
get() { return this.juanbiao_form },
|
||||||
|
set(val) { this.$emit('update:juanbiao_form', val) }
|
||||||
|
},
|
||||||
|
fileTypeOptions() {
|
||||||
|
return [
|
||||||
|
{ label: this.$t('work.fileAnd'), value: 0 },
|
||||||
|
{ label: this.$t('work.eCd'), value: 1 },
|
||||||
|
{ label: this.$t('work.encryptCard'), value: 2 },
|
||||||
|
{ label: this.$t('work.forbidCopyU'), value: 4 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
sizeTypeOptions() {
|
||||||
|
// 如果没有传入 sizeType,则提供默认
|
||||||
|
if (this.sizeType && this.sizeType.length > 0) return this.sizeType
|
||||||
|
return [
|
||||||
|
{ value: 0.512, label: "512MB" },
|
||||||
|
{ value: 4, label: "4GB" },
|
||||||
|
{ value: 32, label: "32GB" },
|
||||||
|
{ value: 64, label: "64GB" },
|
||||||
|
{ value: 128, label: "128GB" },
|
||||||
|
{ value: 256, label: "256GB" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
partitionOptions() {
|
||||||
|
return [
|
||||||
|
{ value: 0, label: this.$t("work.diskPart") },
|
||||||
|
{ value: 1, label: this.$t("work.cdPart") },
|
||||||
|
{ value: 3, label: this.$t("work.forbidCopyPart") },
|
||||||
|
{ value: 5, label: this.$t("work.cdWithDisk") }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.task-header-container {
|
||||||
|
padding: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-header-flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 5px;
|
||||||
|
/* Alignment tweak */
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-select {
|
||||||
|
width: 160px;
|
||||||
|
/* Wider selects */
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-select.size-select {
|
||||||
|
width: 220px;
|
||||||
|
/* Capacity select needs even more width for placeholders */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
|||||||
|
import WorkMain from './WorkMain.vue'
|
||||||
|
|
||||||
|
export default WorkMain
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<div class="grand-section">
|
||||||
|
<div class="grand-title">
|
||||||
|
<span>{{ $t('work.advancedFeatures') }}</span>
|
||||||
|
<div class="title-line"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ISO / ZIP (仅模式 0 和 2) -->
|
||||||
|
<template v-if="fileForm === 0 || fileForm === 2">
|
||||||
|
<!-- ISO 生成组 -->
|
||||||
|
<div class="feature-group" :class="{ active: form.is_generate_iso }">
|
||||||
|
<div class="feature-header">
|
||||||
|
<el-checkbox v-model="form.is_generate_iso">
|
||||||
|
{{ $t('work.generateISO') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div v-if="form.is_generate_iso" class="feature-content">
|
||||||
|
<el-form-item :label="$t('work.isoFileName')" label-width="100px">
|
||||||
|
<el-input v-model="form.iso_file_name" :placeholder="$t('work.inputIsoName')" size="small" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ZIP 生成组 -->
|
||||||
|
<div class="feature-group" :class="{ active: form.is_generate_zip }">
|
||||||
|
<div class="feature-header">
|
||||||
|
<el-checkbox v-model="form.is_generate_zip">
|
||||||
|
{{ $t('work.generateZIP') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div v-if="form.is_generate_zip" class="feature-content">
|
||||||
|
<el-form-item :label="$t('work.zipFileName')" label-width="100px">
|
||||||
|
<el-input v-model="form.zip_file_name" :placeholder="$t('work.inputZipName')" size="small" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 嵌套加密设置 -->
|
||||||
|
<div class="sub-feature">
|
||||||
|
<el-checkbox v-model="form.is_zip_encrypt">{{ $t('work.isEncrypt') }}</el-checkbox>
|
||||||
|
<div v-if="form.is_zip_encrypt" class="mt-10">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('work.inputPassword')" label-width="80px">
|
||||||
|
<el-input type="password" v-model="form.zip_password" show-password
|
||||||
|
size="small" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('work.confirmPassword')" label-width="80px">
|
||||||
|
<el-input type="password" v-model="form.zip_repassword" show-password
|
||||||
|
size="small" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="divider-h mb-15" v-if="form.is_generate_iso || form.is_generate_zip"></div>
|
||||||
|
|
||||||
|
<div class="grand-switch-grid" v-if="form.is_generate_iso || form.is_generate_zip">
|
||||||
|
<div class="g-switch-item">
|
||||||
|
<span class="g-label">{{ $t('work.genMD5') }}</span>
|
||||||
|
<el-switch v-model="form.s1"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item">
|
||||||
|
<span class="g-label">{{ $t('work.copyHash') }}</span>
|
||||||
|
<el-switch v-model="form.copy_hash"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item">
|
||||||
|
<span class="g-label">{{ $t('work.printMD5') }}</span>
|
||||||
|
<el-switch v-model="form.s2"></el-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="divider-h mt-15 mb-15" v-if="form.is_generate_iso || form.is_generate_zip"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 通用开关组 -->
|
||||||
|
<div class="grand-switch-grid">
|
||||||
|
<div class="g-switch-item">
|
||||||
|
<span class="g-label">{{ $t('work.fail') }}</span>
|
||||||
|
<el-switch v-model="form.s3"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item" v-if="fileForm !== 4">
|
||||||
|
<span class="g-label">{{ $t('work.allowSpanCard') }}</span>
|
||||||
|
<el-switch v-model="form.Span_USBcard"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item" v-if="fileForm !== 4">
|
||||||
|
<span class="g-label">{{ $t('work.presetContent') }}</span>
|
||||||
|
<el-switch v-model="form.hasAddFile"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item highlight" v-if="fileForm === 1">
|
||||||
|
<span class="g-label">{{ $t('work.mixMode') }}</span>
|
||||||
|
<el-switch v-model="form.is_blend"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item">
|
||||||
|
<span class="g-label">{{ $t('work.installDongle') }}</span>
|
||||||
|
<el-switch v-model="form.enable_dongle_counter"></el-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 计数器详细 -->
|
||||||
|
<div v-if="form.enable_dongle_counter" class="mt-10 p-10"
|
||||||
|
style="background: #fdf6ec; border-radius: 6px; border: 1px solid #faecd8;">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item :label="$t('work.installCount')" label-width="120px" class="mb-0">
|
||||||
|
<el-input-number v-model="form.install_dongle_count" :min="0" :step="1" :precision="0"
|
||||||
|
size="mini" controls-position="right" style="width: 100%;" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="14">
|
||||||
|
<el-form-item :label="$t('work.authCode')" label-width="100px" class="mb-0">
|
||||||
|
<el-input v-model="form.auth_code" :placeholder="$t('work.inputAuthCode')" size="mini"
|
||||||
|
style="width: 100%;" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AdvancedFeatures',
|
||||||
|
props: {
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fileForm: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
<template>
|
||||||
|
<div class="grand-section">
|
||||||
|
<div class="grand-title">
|
||||||
|
<span>{{ $t('work.basicConfig') }}</span>
|
||||||
|
<div class="title-line"></div>
|
||||||
|
</div>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12" v-if="fileForm !== 2">
|
||||||
|
<el-form-item :label="$t('work.better')">
|
||||||
|
<el-select v-model="form.priority" class="w-full" :disabled="fileForm === 4">
|
||||||
|
<el-option v-for="item in priorityOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" v-if="fileForm !== 2">
|
||||||
|
<el-form-item :label="$t('work.startWorkSpace')">
|
||||||
|
<el-select v-model="form.target_work" class="w-full" :disabled="fileForm === 4">
|
||||||
|
<el-option v-for="item in targetWorkOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('work.ribbonType')">
|
||||||
|
<el-select v-model="form.color_type" class="w-full">
|
||||||
|
<el-option v-for="item in colorTypeOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" v-if="fileForm === 0 || fileForm === 2">
|
||||||
|
<el-form-item :label="$t('work.formatFile')">
|
||||||
|
<el-select v-model="form.formatFile" class="w-full">
|
||||||
|
<el-option v-for="item in formatOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'BasicConfig',
|
||||||
|
props: {
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fileForm: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
printerList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
sizeForm: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
priorityOptions() {
|
||||||
|
return [
|
||||||
|
{ value: 1, label: this.$t("work.low") },
|
||||||
|
{ value: 0, label: this.$t("work.normal") },
|
||||||
|
{ value: 2, label: this.$t("work.high") }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
targetWorkOptions() {
|
||||||
|
let list = [{ value: 0, label: this.$t("work.any") }]
|
||||||
|
|
||||||
|
if (this.printerList && this.printerList.length > 0) {
|
||||||
|
const requiredSize = parseFloat(this.sizeForm)
|
||||||
|
let filtered = this.printerList
|
||||||
|
|
||||||
|
// Filter by capacity if size is selected
|
||||||
|
if (requiredSize && requiredSize > 0) {
|
||||||
|
filtered = this.printerList.filter(p => {
|
||||||
|
if (!p.PrinterType) return false
|
||||||
|
const type = p.PrinterType.toUpperCase()
|
||||||
|
|
||||||
|
if (requiredSize < 1) {
|
||||||
|
// MB case (e.g. 0.512 -> 512M)
|
||||||
|
const mb = Math.round(requiredSize * 1000)
|
||||||
|
return type.includes(mb + "M")
|
||||||
|
} else {
|
||||||
|
// GB case (e.g. 4 -> 4G)
|
||||||
|
return type.includes(requiredSize + "G")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map to options
|
||||||
|
if (filtered.length > 0) {
|
||||||
|
list = list.concat(filtered.map(p => ({
|
||||||
|
value: p.PrinterID,
|
||||||
|
label: `${p.PrinterID} (${p.PrinterType})`
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
},
|
||||||
|
colorTypeOptions() {
|
||||||
|
return [
|
||||||
|
{ value: 0, label: this.$t("work.any") },
|
||||||
|
{ value: 1, label: this.$t("work.sigleColor") },
|
||||||
|
{ value: 2, label: this.$t("work.colorful") }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
formatOptions() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: this.$t("work.auto"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "FAT",
|
||||||
|
label: "FAT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "FAT32",
|
||||||
|
label: "FAT32",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "NTFS",
|
||||||
|
label: "NTFS",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "EXFAT",
|
||||||
|
label: "EXFAT",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="grand-section">
|
||||||
|
<div class="grand-title">
|
||||||
|
<span>{{ $t('work.hardwareControl') }}</span>
|
||||||
|
<div class="title-line"></div>
|
||||||
|
</div>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<div class="hardware-box">
|
||||||
|
<div class="mb-10">
|
||||||
|
<el-checkbox v-model="form.enable_dongle_counter">
|
||||||
|
{{ $t('work.installDongle') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<transition name="el-zoom-in-top">
|
||||||
|
<div v-if="form.enable_dongle_counter" class="ml-20">
|
||||||
|
<el-form-item :label="$t('work.installCount')" label-width="80px">
|
||||||
|
<el-input-number size="small" v-model="form.install_dongle_count" :min="0" :max="999" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HardwareControl',
|
||||||
|
props: {
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.hardware-box {
|
||||||
|
padding: 10px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
<template>
|
||||||
|
<div class="grand-section">
|
||||||
|
<div class="grand-title">
|
||||||
|
<span>{{ $t('work.screenRecordReview') }}</span>
|
||||||
|
<div class="title-line"></div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-row mb-10">
|
||||||
|
<div class="grand-switch-grid mb-10">
|
||||||
|
<div class="g-switch-item">
|
||||||
|
<span class="g-label">{{ $t('work.enableScreenRecord') }}</span>
|
||||||
|
<el-switch v-model="form.record_screen"></el-switch>
|
||||||
|
</div>
|
||||||
|
<div class="g-switch-item" v-if="form.record_screen">
|
||||||
|
<div class="flex-align-center">
|
||||||
|
<span class="g-label">{{ $t('work.printRecordLogo') }}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<el-switch v-model="form.print_record_logo"></el-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="form.record_screen" class="path-box-container">
|
||||||
|
<div class="path-box">
|
||||||
|
<el-form-item :label="$t('work.recordPath')" label-width="110px">
|
||||||
|
<el-input v-model="form.record_screen_path" :placeholder="$t('work.defaultPath')" size="small">
|
||||||
|
<el-button slot="append" icon="el-icon-folder-opened" @click="selectRecordPath"></el-button>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div class="recording-actions mt-10">
|
||||||
|
<el-button type="danger" size="small" icon="el-icon-video-camera" plain @click="testRecording">
|
||||||
|
{{ $t('recorder.startRecording') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'RecordingSettings',
|
||||||
|
props: {
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fileForm: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectRecordPath() {
|
||||||
|
const { dialog } = require('@electron/remote')
|
||||||
|
dialog.showOpenDialog({
|
||||||
|
properties: ['openDirectory']
|
||||||
|
}).then(result => {
|
||||||
|
if (!result.canceled && result.filePaths.length > 0) {
|
||||||
|
this.$set(this.form, 'record_screen_path', result.filePaths[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
testRecording() {
|
||||||
|
this.$emit('test-recording', this.form.record_screen_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.flex-align-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-icon-active {
|
||||||
|
color: #409EFF;
|
||||||
|
font-size: 16px;
|
||||||
|
animation: logo-glow 2s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes logo-glow {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.recording-tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #fdf6ec;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 3px solid #e6a23c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recording-tip i {
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #e6a23c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider-v {
|
||||||
|
width: 1px;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
/* Compact Dialog Styles for Advanced Settings */
|
||||||
|
/* 注意:此文件为纯 CSS,不应包含 /deep/。穿透逻辑应在引用它的 Vue 组件中通过 ::v-deep 实现 */
|
||||||
|
|
||||||
|
.grand-dialog {
|
||||||
|
border-radius: 12px !important;
|
||||||
|
overflow: hidden; /* Ensure header/footer respect radius */
|
||||||
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12) !important;
|
||||||
|
}
|
||||||
|
.grand-dialog .el-dialog__header {
|
||||||
|
padding: 20px 24px !important;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.grand-dialog .el-dialog__title {
|
||||||
|
font-size: 18px !important;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
.grand-dialog .el-dialog__body {
|
||||||
|
padding: 24px !important;
|
||||||
|
background-color: #f6f8fa; /* Global gray background for contrast */
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-section {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||||
|
padding: 16px 20px !important;
|
||||||
|
margin-bottom: 16px !important;
|
||||||
|
border: 1px solid #eef0f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-title {
|
||||||
|
font-size: 13px !important;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
color: #1f2937;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-title .title-line {
|
||||||
|
flex: 1;
|
||||||
|
height: 1px;
|
||||||
|
background: #f3f4f6;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider-h {
|
||||||
|
height: 1px;
|
||||||
|
background: #f3f4f6;
|
||||||
|
margin: 8px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-group {
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-group.active {
|
||||||
|
background: #ffffff;
|
||||||
|
border-color: #67c23a;
|
||||||
|
box-shadow: 0 4px 12px rgba(103, 194, 58, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 覆盖 checkbox 文字颜色 */
|
||||||
|
.feature-header ::v-deep .el-checkbox__label {
|
||||||
|
font-weight: 600 !important;
|
||||||
|
color: #374151 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-content {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #f8fafc;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #edf2f7;
|
||||||
|
animation: slideDown 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-feature {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding-top: 8px;
|
||||||
|
border-top: 1px dashed #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-section .el-form-item {
|
||||||
|
margin-bottom: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 最后一个元素不需要下边距 */
|
||||||
|
.grand-section .el-col:nth-last-child(-n + 2) .el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-section ::v-deep .el-form-item__label {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-switch-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.g-switch-item {
|
||||||
|
padding: 8px 12px !important;
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.g-switch-item:hover {
|
||||||
|
background: #fff;
|
||||||
|
border-color: #67c23a;
|
||||||
|
box-shadow: 0 3px 8px rgba(103, 194, 58, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.g-label {
|
||||||
|
font-size: 13px !important;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #374151;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-box-container {
|
||||||
|
margin-top: 16px !important;
|
||||||
|
padding-top: 16px !important;
|
||||||
|
border-top: 1px dashed #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-box {
|
||||||
|
background: #f8fafc;
|
||||||
|
padding: 12px !important;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grand-setting-content::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
.grand-setting-content::-webkit-scrollbar-thumb {
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,297 @@
|
|||||||
|
/* 还原原始业务样式 - 完全兼容原始类名 */
|
||||||
|
|
||||||
|
.work {
|
||||||
|
background-color: #f8fafc; /* Softer, modern background */
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 左侧文件管理区域原始样式 */
|
||||||
|
/* 左侧文件管理区域原始样式 */
|
||||||
|
.file {
|
||||||
|
height: 500px;
|
||||||
|
width: 100%;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 10px 15px -3px rgba(0, 0, 0, 0.03);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 12px;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
animation: cardFadeIn 0.6s ease-out;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes cardFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧标签元数据区域原始样式 */
|
||||||
|
.label {
|
||||||
|
height: 500px;
|
||||||
|
width: 100%;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 10px 15px -3px rgba(0, 0, 0, 0.03);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 12px;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
animation: cardFadeIn 0.6s ease-out;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题行布局 */
|
||||||
|
.section-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 38px;
|
||||||
|
line-height: 38px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-left i {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-text {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #303133;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-select {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览框微调 */
|
||||||
|
/* 预览框微调 */
|
||||||
|
.display_box {
|
||||||
|
margin-top: 10px;
|
||||||
|
background: #111827; /* Deeper navy for professional contrast */
|
||||||
|
height: 180px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
|
box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.display_item {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px dashed #c0ccda;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display_item img {
|
||||||
|
height: 140px;
|
||||||
|
/* background-color: #1e252d; Optional: match bg if image has transparency */
|
||||||
|
}
|
||||||
|
|
||||||
|
.display_bg {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部统计与按钮 */
|
||||||
|
/* 底部统计与按钮 */
|
||||||
|
.footer-actions {
|
||||||
|
margin-top: 15px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count-input-new {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 子标题样式 */
|
||||||
|
.sub-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #374151;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-title i {
|
||||||
|
color: #fbbf24;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata-table {
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Uploader 样式 */
|
||||||
|
.uploader-example {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px auto 0;
|
||||||
|
font-size: 12px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); /* Softer shadow */
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
flex: 1; /* Expand to fill parent flex container */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploader-example .uploader-list {
|
||||||
|
flex: 1; /* Expand list to fill example box */
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滚动条美化 (还原原始样式) */
|
||||||
|
.uploader-list::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploader-list::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
background: #c7c7cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploader-list::-webkit-scrollbar-track {
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #ededed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 工具类 */
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.mt-10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.mb-10 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.empty-placeholder-box {
|
||||||
|
flex: 1; /* Fill the metadata container area when empty */
|
||||||
|
min-height: 200px;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 13px;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display_box_placeholder {
|
||||||
|
justify-content: center;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 14px;
|
||||||
|
border: 2px dashed rgba(255, 255, 255, 0.1);
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.display_box_placeholder::before {
|
||||||
|
content: '\e731'; /* Better icon if available, or stay with pic */
|
||||||
|
font-family: 'element-icons' !important;
|
||||||
|
font-size: 32px;
|
||||||
|
opacity: 0.4;
|
||||||
|
background: linear-gradient(135deg, #9ca3af, #4b5563);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text-dark {
|
||||||
|
color: #5e6d82;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式适配:大屏幕高度扩展 */
|
||||||
|
@media (min-height: 900px) {
|
||||||
|
.file,
|
||||||
|
.label {
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.uploader-example .uploader-list {
|
||||||
|
max-height: 485px;
|
||||||
|
}
|
||||||
|
.empty-placeholder-box {
|
||||||
|
height: 315px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* Work component utilities
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function extendStringPrototypes() {
|
||||||
|
if (String.prototype.strLen) return;
|
||||||
|
|
||||||
|
String.prototype.strLen = function () {
|
||||||
|
var len = 0
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
if (this.charCodeAt(i) > 255 || this.charCodeAt(i) < 0) len += 2
|
||||||
|
else len++
|
||||||
|
}
|
||||||
|
return len
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.strToChars = function () {
|
||||||
|
var chars = new Array()
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
chars[i] = [this.substr(i, 1), this.isCHS(i)]
|
||||||
|
}
|
||||||
|
String.prototype.charsArray = chars
|
||||||
|
return chars
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.isCHS = function (i) {
|
||||||
|
if (this.charCodeAt(i) > 255 || this.charCodeAt(i) < 0) return true
|
||||||
|
else return false
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.subCHString = function (start, end) {
|
||||||
|
var len = 0
|
||||||
|
var str = ''
|
||||||
|
this.strToChars()
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
if (this.charsArray[i][1]) len += 2
|
||||||
|
else len++
|
||||||
|
if (end < len) return str
|
||||||
|
else if (start < len) str += this.charsArray[i][0]
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.subCHStr = function (start, length) {
|
||||||
|
return this.subCHString(start, start + length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNowFormatDate() {
|
||||||
|
var date = new Date()
|
||||||
|
var seperator1 = '-'
|
||||||
|
var year = date.getFullYear()
|
||||||
|
var month = date.getMonth() + 1
|
||||||
|
var strDate = date.getDate()
|
||||||
|
if (month >= 1 && month <= 9) {
|
||||||
|
month = '0' + month
|
||||||
|
}
|
||||||
|
if (strDate >= 0 && strDate <= 9) {
|
||||||
|
strDate = '0' + strDate
|
||||||
|
}
|
||||||
|
return year + seperator1 + month + seperator1 + strDate
|
||||||
|
}
|
||||||
|
|
||||||
|
export function genTaskUUID() {
|
||||||
|
var myDate = new Date()
|
||||||
|
var dateStr =
|
||||||
|
myDate.getFullYear().toString() +
|
||||||
|
(myDate.getMonth() + 1 >= 10 ? (myDate.getMonth() + 1).toString() : '0' + (myDate.getMonth() + 1).toString()) +
|
||||||
|
(myDate.getDate() > 9 ? myDate.getDate().toString() : '0' + myDate.getDate().toString()) +
|
||||||
|
(myDate.getHours() > 9 ? myDate.getHours().toString() : '0' + myDate.getHours().toString()) +
|
||||||
|
(myDate.getMinutes() > 9 ? myDate.getMinutes().toString() : '0' + myDate.getMinutes().toString()) +
|
||||||
|
(myDate.getSeconds() > 9 ? myDate.getSeconds().toString() : '0' + myDate.getSeconds().toString()) +
|
||||||
|
myDate.getTime().toString().slice(-2);
|
||||||
|
return dateStr
|
||||||
|
}
|
||||||
+140
-291
@@ -13,17 +13,8 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
<div class="grid-content bg-purple">
|
<div class="grid-content bg-purple">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" style="width: 160px" v-model="size_form">
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
<el-option v-for="item in size_type" :key="item.value" :label="item.label" :value="item.value">
|
||||||
style="width: 160px"
|
|
||||||
v-model="size_form"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in size_type"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,8 +25,8 @@
|
|||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{$t("work.sign")}}
|
{{$t("work.sign")}}
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
-->
|
-->
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-row :gutter="0">
|
<el-row :gutter="0">
|
||||||
@@ -48,17 +39,9 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
<div class="grid-content bg-purple">
|
<div class="grid-content bg-purple">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" style="float: left; margin-left: 10px"
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
v-model="file_form">
|
||||||
style="float: left; margin-left: 10px"
|
<el-option v-for="item in file_type" :key="item.value" :label="item.label" :value="item.value">
|
||||||
v-model="file_form"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in file_type"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -76,17 +59,9 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
<div class="grid-content bg-purple">
|
<div class="grid-content bg-purple">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" v-model="type_form">
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
<el-option v-for="item in type" :key="item.value" :label="item.label" :value="item.value"
|
||||||
v-model="type_form"
|
:disabled="item.disabled">
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in type"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -94,25 +69,13 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-popover
|
<el-popover style="float: right" placement="left" width="600" trigger="click">
|
||||||
style="float: right"
|
|
||||||
placement="left"
|
|
||||||
width="600"
|
|
||||||
trigger="click"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<el-form :label-position="'right'" label-width="250px">
|
<el-form :label-position="'right'" label-width="250px">
|
||||||
<el-form-item :label="$t('work.better')">
|
<el-form-item :label="$t('work.better')">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" v-model="high_setting_form.priority">
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
<el-option v-for="item in high_setting.priority" :key="item.value" :label="item.label"
|
||||||
v-model="high_setting_form.priority"
|
:value="item.value">
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in high_setting.priority"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -124,44 +87,23 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>-->
|
</el-form-item>-->
|
||||||
<el-form-item :label="$t('work.startWorkSpace')">
|
<el-form-item :label="$t('work.startWorkSpace')">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" v-model="high_setting_form.target_work">
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
<el-option v-for="item in high_setting.target_work" :key="item.value" :label="item.label"
|
||||||
v-model="high_setting_form.target_work"
|
:value="item.value">
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in high_setting.target_work"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('work.ribbonType')">
|
<el-form-item :label="$t('work.ribbonType')">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" v-model="high_setting_form.color_type">
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
<el-option v-for="item in high_setting.color_type" :key="item.value" :label="item.label"
|
||||||
v-model="high_setting_form.color_type"
|
:value="item.value">
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in high_setting.color_type"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('work.formatFile')">
|
<el-form-item :label="$t('work.formatFile')">
|
||||||
<el-select
|
<el-select :placeholder="$t('work.pleaseSelect')" v-model="high_setting_form.formatFile">
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
<el-option v-for="item in high_setting.formatFile" :key="item.value" :label="item.label"
|
||||||
v-model="high_setting_form.formatFile"
|
:value="item.value">
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in high_setting.formatFile"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -209,82 +151,47 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-row :gutter="20" style="margin-top: 10px">
|
<el-row :gutter="20" style="margin-top: 10px">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-switch
|
<el-switch v-model="switch_cont" :active-text="$t('work.addContent')" style="float: left">
|
||||||
v-model="switch_cont"
|
|
||||||
:active-text="$t('work.addContent')"
|
|
||||||
style="float: left"
|
|
||||||
>
|
|
||||||
</el-switch>
|
</el-switch>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-switch
|
<el-switch v-model="switch_tag" style="float: right" :active-text="$t('work.addTag')">
|
||||||
v-model="switch_tag"
|
|
||||||
style="float: right"
|
|
||||||
:active-text="$t('work.addTag')"
|
|
||||||
>
|
|
||||||
</el-switch>
|
</el-switch>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="0" style="margin-top: 10px">
|
<el-row :gutter="0" style="margin-top: 10px">
|
||||||
<el-col
|
<el-col :span="switch_tag && switch_cont ? 12 : switch_tag && !switch_cont ? 0 : 24
|
||||||
:span="
|
">
|
||||||
switch_tag && switch_cont ? 12 : switch_tag && !switch_cont ? 0 : 24
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="grid-content bg-purple">
|
<div class="grid-content bg-purple">
|
||||||
<div class="file">
|
<div class="file">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="3">
|
<el-col :span="3">
|
||||||
<span
|
<span style="
|
||||||
style="
|
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
"
|
">{{ $t("work.contentTitle") }}</span>
|
||||||
>{{ $t("work.contentTitle") }}</span
|
|
||||||
>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="11">
|
<el-col :span="11">
|
||||||
<el-input
|
<el-input v-model="juanbiao_form" :placeholder="$t('work.pleaseInput')"
|
||||||
v-model="juanbiao_form"
|
style="width: 200px; float: left">
|
||||||
:placeholder="$t('work.pleaseInput')"
|
|
||||||
style="width: 200px; float: left"
|
|
||||||
>
|
|
||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{ $t("work.sign") }}
|
{{ $t("work.sign") }}
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<el-progress
|
<el-progress :text-inside="true" :percentage="file_percent" :format="format" style="line-height: 40px"
|
||||||
:text-inside="true"
|
:stroke-width="20" :color="customColors"></el-progress>
|
||||||
:percentage="file_percent"
|
|
||||||
:format="format"
|
|
||||||
style="line-height: 40px"
|
|
||||||
:stroke-width="20"
|
|
||||||
:color="customColors"
|
|
||||||
></el-progress>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div style="clear: both"></div>
|
<div style="clear: both"></div>
|
||||||
<uploader
|
<uploader :options="options" class="uploader-example" ref="uploader" @file-added="onFileAdded"
|
||||||
:options="options"
|
@file-removed="onFileRemoved" :autoStart="false" @complete="upload_over" @drop.prevent="onDrag">
|
||||||
class="uploader-example"
|
|
||||||
ref="uploader"
|
|
||||||
@file-added="onFileAdded"
|
|
||||||
@file-removed="onFileRemoved"
|
|
||||||
:autoStart="false"
|
|
||||||
@complete="upload_over"
|
|
||||||
@drop.prevent="onDrag"
|
|
||||||
>
|
|
||||||
<uploader-unsupport> </uploader-unsupport>
|
<uploader-unsupport> </uploader-unsupport>
|
||||||
<uploader-drop
|
<uploader-drop style="height: 405px" class="drag-bg" :style="'background-image:url(' + bgi + ');'">
|
||||||
style="height: 405px"
|
|
||||||
class="drag-bg"
|
|
||||||
:style="'background-image:url(' + bgi + ');'"
|
|
||||||
>
|
|
||||||
<uploader-btn> {{ $t("work.selectFile") }}</uploader-btn>
|
<uploader-btn> {{ $t("work.selectFile") }}</uploader-btn>
|
||||||
<uploader-btn :directory="true">{{
|
<uploader-btn :directory="true">{{
|
||||||
$t("work.selectFloder")
|
$t("work.selectFloder")
|
||||||
@@ -321,131 +228,72 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col
|
<el-col :span="switch_cont && switch_tag ? 12 : switch_cont && !switch_tag ? 0 : 24
|
||||||
:span="
|
">
|
||||||
switch_cont && switch_tag ? 12 : switch_cont && !switch_tag ? 0 : 24
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="grid-content bg-purple">
|
<div class="grid-content bg-purple">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<div class="title" style="width: 100%">
|
<div class="title" style="width: 100%">
|
||||||
<div style="display: inline-block; float: left">
|
<div style="float: left">
|
||||||
{{ $t("work.tag") }}
|
{{ $t("work.tag") }}
|
||||||
<el-button
|
<el-button type="text" icon="el-icon-upload2" style="margin-left: 10px; font-size: 14px"
|
||||||
type="text"
|
@click="openFile">
|
||||||
icon="el-icon-upload2"
|
|
||||||
style="margin-left: 10px; font-size: 14px"
|
|
||||||
@click="openFile"
|
|
||||||
>
|
|
||||||
{{ $t("work.importTag") }}
|
{{ $t("work.importTag") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!--<el-checkbox v-model="flag">单面打印</el-checkbox>-->
|
<!--<el-checkbox v-model="flag">单面打印</el-checkbox>-->
|
||||||
<div style="display: inline-block; float: right; right: 0px">
|
<div style="float: right; right: 0px">
|
||||||
<span
|
<span style="font-size: 14px; color: #606266; font-weight: normal">
|
||||||
style="font-size: 14px; color: #606266; font-weight: normal"
|
|
||||||
>
|
|
||||||
{{ $t("work.print") }}
|
{{ $t("work.print") }}
|
||||||
</span>
|
</span>
|
||||||
<el-select
|
<el-select v-model="print_flag" :placeholder="$t('work.pleaseSelect')" size="mini">
|
||||||
v-model="print_flag"
|
<el-option v-for="item in print_op" v-if="!(flag && item.value == 1)" :key="item.value"
|
||||||
:placeholder="$t('work.pleaseSelect')"
|
:label="item.label" :value="item.value">
|
||||||
size="mini"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in print_op"
|
|
||||||
v-if="!(flag && item.value == 1)"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="float: right"></div>
|
<div style="float: right"></div>
|
||||||
<input
|
<input type="file" accept=".soon,.cs" @change="fileLoad" ref="refFile" style="display: none" />
|
||||||
type="file"
|
|
||||||
accept=".soon,.cs"
|
|
||||||
@change="fileLoad"
|
|
||||||
ref="refFile"
|
|
||||||
style="display: none"
|
|
||||||
/>
|
|
||||||
<div style="clear: both"></div>
|
<div style="clear: both"></div>
|
||||||
<div class="display">
|
<div class="display">
|
||||||
<img
|
<img v-if="print_flag == 1 || print_flag == 2" :src="fileData.frontDisplayPic" style="
|
||||||
v-if="print_flag == 1 || print_flag == 2"
|
|
||||||
:src="fileData.frontDisplayPic"
|
|
||||||
style="
|
|
||||||
height: 120px;
|
height: 120px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
"
|
" />
|
||||||
/>
|
<img v-if="print_flag == 1 || print_flag == 3" :src="fileData.backDisplayPic" style="
|
||||||
<img
|
|
||||||
v-if="print_flag == 1 || print_flag == 3"
|
|
||||||
:src="fileData.backDisplayPic"
|
|
||||||
style="
|
|
||||||
height: 120px;
|
height: 120px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
"
|
" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table :data="tableData" height="185" style="width: 100%" :empty-text="$t('work.nodata')">
|
||||||
:data="tableData"
|
|
||||||
height="185"
|
|
||||||
style="width: 100%"
|
|
||||||
:empty-text="$t('work.nodata')"
|
|
||||||
>
|
|
||||||
<el-table-column prop="name" :label="$t('work.fieldName')">
|
<el-table-column prop="name" :label="$t('work.fieldName')">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="val" width="400">
|
<el-table-column prop="val" width="400">
|
||||||
<template slot="header" slot-scope="scope">
|
<template slot="header" slot-scope="scope">
|
||||||
<input
|
<input type="file" accept=".csv" @change="fileLoad2" ref="refFile2" style="display: none" />
|
||||||
type="file"
|
<el-tooltip class="item" effect="dark" :content="file_name == null
|
||||||
accept=".csv"
|
? $t('work.binfile')
|
||||||
@change="fileLoad2"
|
: file_name.strLen() > 12
|
||||||
ref="refFile2"
|
? file_name.subCHStr(0, 12) + '...'
|
||||||
style="display: none"
|
: file_name
|
||||||
/>
|
" placement="top-start">
|
||||||
<el-tooltip
|
<el-button type="text" icon="el-icon-upload2" style="margin-left: 10px; font-size: 14px"
|
||||||
class="item"
|
@click="openFile2">
|
||||||
effect="dark"
|
|
||||||
:content="
|
|
||||||
file_name == null
|
|
||||||
? $t('work.binfile')
|
|
||||||
: file_name.strLen() > 12
|
|
||||||
? file_name.subCHStr(0, 12) + '...'
|
|
||||||
: file_name
|
|
||||||
"
|
|
||||||
placement="top-start"
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
icon="el-icon-upload2"
|
|
||||||
style="margin-left: 10px; font-size: 14px"
|
|
||||||
@click="openFile2"
|
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
file_name == null
|
file_name == null
|
||||||
? $t("work.binfile")
|
? $t("work.binfile")
|
||||||
: file_name.strLen() > 12
|
: file_name.strLen() > 12
|
||||||
? file_name.subCHStr(0, 12) + "..."
|
? file_name.subCHStr(0, 12) + "..."
|
||||||
: file_name
|
: file_name
|
||||||
}}
|
}}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<input
|
<input type="file" accept="..zip,.rar" @change="fileLoad3" ref="refFile3" style="display: none" />
|
||||||
type="file"
|
|
||||||
accept="..zip,.rar"
|
|
||||||
@change="fileLoad3"
|
|
||||||
ref="refFile3"
|
|
||||||
style="display: none"
|
|
||||||
/>
|
|
||||||
<!--<el-tooltip class="item" effect="dark" :content="file_name3" placement="top-start">
|
<!--<el-tooltip class="item" effect="dark" :content="file_name3" placement="top-start">
|
||||||
<el-button type="text" icon="el-icon-upload2" style="margin-left: 10px;font-size: 14px"
|
<el-button type="text" icon="el-icon-upload2" style="margin-left: 10px;font-size: 14px"
|
||||||
@click="openFile3">
|
@click="openFile3">
|
||||||
@@ -455,28 +303,17 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div v-if="scope.row.type == 1">
|
<div v-if="scope.row.type == 1">
|
||||||
<input
|
<input type="file" accept="image/*" :ref="scope.row.origin_name"
|
||||||
type="file"
|
:data-name="scope.row.origin_name" />
|
||||||
accept="image/*"
|
|
||||||
:ref="scope.row.origin_name"
|
|
||||||
:data-name="scope.row.origin_name"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="
|
||||||
v-if="
|
scope.row.type == 3 ||
|
||||||
scope.row.type == 3 ||
|
scope.row.type == 4 ||
|
||||||
scope.row.type == 4 ||
|
scope.row.type == 5
|
||||||
scope.row.type == 5
|
">
|
||||||
"
|
|
||||||
>
|
|
||||||
<!--合成文本-->
|
<!--合成文本-->
|
||||||
<el-input
|
<el-input :placeholder="$t('work.pleaseInput')" v-model="form[scope.row.origin_name]" clearable
|
||||||
:placeholder="$t('work.pleaseInput')"
|
style="width: calc(100% - 30px) !important" :disabled="csvIsExist">
|
||||||
v-model="form[scope.row.origin_name]"
|
|
||||||
clearable
|
|
||||||
style="width: calc(100% - 30px) !important"
|
|
||||||
:disabled="csvIsExist"
|
|
||||||
>
|
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -489,42 +326,26 @@
|
|||||||
<el-row :gutter="20" style="height: 30px; margin-top: 20px">
|
<el-row :gutter="20" style="height: 30px; margin-top: 20px">
|
||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
<div v-if="file_form == 3 && switch_cont">
|
<div v-if="file_form == 3 && switch_cont">
|
||||||
<el-input
|
<el-input :placeholder="$t('work.pleasePassword')" style="width: 25%; float: left" show-password v-model="p1">
|
||||||
:placeholder="$t('work.pleasePassword')"
|
|
||||||
style="width: 25%; float: left"
|
|
||||||
show-password
|
|
||||||
v-model="p1"
|
|
||||||
>
|
|
||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{ $t("work.password") }}
|
{{ $t("work.password") }}
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-input
|
<el-input :placeholder="$t('work.pleasePassword')" style="width: 25%; float: left; margin-left: 10px"
|
||||||
:placeholder="$t('work.pleasePassword')"
|
show-password v-model="p2">
|
||||||
style="width: 25%; float: left; margin-left: 10px"
|
|
||||||
show-password
|
|
||||||
v-model="p2"
|
|
||||||
>
|
|
||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{ $t("work.comfirm") }}
|
{{ $t("work.comfirm") }}
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-input
|
<el-input :placeholder="$t('work.addContent')" style="width: 40%; float: left; margin-left: 10px"
|
||||||
:placeholder="$t('work.addContent')"
|
v-model="zip_name">
|
||||||
style="width: 40%; float: left; margin-left: 10px"
|
|
||||||
v-model="zip_name"
|
|
||||||
>
|
|
||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{ $t("work.name") }}
|
{{ $t("work.name") }}
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="file_form == 2 && switch_cont">
|
<div v-else-if="file_form == 2 && switch_cont">
|
||||||
<el-input
|
<el-input :placeholder="$t('work.addContent')" style="width: 40%; float: left" v-model="zip_name">
|
||||||
:placeholder="$t('work.addContent')"
|
|
||||||
style="width: 40%; float: left"
|
|
||||||
v-model="zip_name"
|
|
||||||
>
|
|
||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{ $t("work.name") }}
|
{{ $t("work.name") }}
|
||||||
</template>
|
</template>
|
||||||
@@ -533,11 +354,7 @@
|
|||||||
<div style="width: 100%" v-else> </div>
|
<div style="width: 100%" v-else> </div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<el-input
|
<el-input :placeholder="$t('work.addContent')" v-model="number" style="width: 200px; float: left">
|
||||||
:placeholder="$t('work.addContent')"
|
|
||||||
v-model="number"
|
|
||||||
style="width: 200px; float: left"
|
|
||||||
>
|
|
||||||
<template slot="prepend">
|
<template slot="prepend">
|
||||||
{{ $t("work.num") }}
|
{{ $t("work.num") }}
|
||||||
</template>
|
</template>
|
||||||
@@ -998,7 +815,8 @@ export default {
|
|||||||
data1.append(`file${files_n_incr}`, this.$refs.refFile.files[0]); //标签cs文件
|
data1.append(`file${files_n_incr}`, this.$refs.refFile.files[0]); //标签cs文件
|
||||||
files_n_incr++;
|
files_n_incr++;
|
||||||
} else {
|
} else {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.pleaseUploadTag"),
|
message: this.$t("work.pleaseUploadTag"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1057,7 +875,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.uploadingTag"),
|
message: this.$t("work.uploadingTag"),
|
||||||
});
|
});
|
||||||
let pathName;
|
let pathName;
|
||||||
@@ -1065,7 +884,8 @@ export default {
|
|||||||
//打开本地选项
|
//打开本地选项
|
||||||
let rootFile = this.$refs.uploader.uploader.getRoot();
|
let rootFile = this.$refs.uploader.uploader.getRoot();
|
||||||
if (rootFile.fileList.length != 1) {
|
if (rootFile.fileList.length != 1) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.oneFolder"),
|
message: this.$t("work.oneFolder"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1073,7 +893,8 @@ export default {
|
|||||||
}
|
}
|
||||||
let filePath = rootFile.fileList[0];
|
let filePath = rootFile.fileList[0];
|
||||||
if (!filePath.isFolder) {
|
if (!filePath.isFolder) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.notFolder"),
|
message: this.$t("work.notFolder"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1191,7 +1012,8 @@ export default {
|
|||||||
}
|
}
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
//报错内容
|
//报错内容
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.pleaseUploadingImgBin"),
|
message: this.$t("work.pleaseUploadingImgBin"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1211,7 +1033,8 @@ export default {
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.UploadingImgBin"),
|
message: this.$t("work.UploadingImgBin"),
|
||||||
});
|
});
|
||||||
let re;
|
let re;
|
||||||
@@ -1228,7 +1051,8 @@ export default {
|
|||||||
re = true;
|
re = true;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.UploadingImgBinFail"),
|
message: this.$t("work.UploadingImgBinFail"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1242,7 +1066,8 @@ export default {
|
|||||||
if (this.switch_cont) {
|
if (this.switch_cont) {
|
||||||
//开启了左边内容则先左边
|
//开启了左边内容则先左边
|
||||||
if (this.size == 0) {
|
if (this.size == 0) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.pleaseUploadContent"),
|
message: this.$t("work.pleaseUploadContent"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1261,7 +1086,8 @@ export default {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.$refs.uploader.uploader.resume();
|
this.$refs.uploader.uploader.resume();
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.uploadingContent"),
|
message: this.$t("work.uploadingContent"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1274,7 +1100,8 @@ export default {
|
|||||||
data1.append(`file${files_n_incr}`, this.$refs.refFile.files[0]); //标签cs文件
|
data1.append(`file${files_n_incr}`, this.$refs.refFile.files[0]); //标签cs文件
|
||||||
files_n_incr++;
|
files_n_incr++;
|
||||||
} else {
|
} else {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.pleaseUploadTag"),
|
message: this.$t("work.pleaseUploadTag"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1330,7 +1157,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.uploadingTag"),
|
message: this.$t("work.uploadingTag"),
|
||||||
});
|
});
|
||||||
this.$axios({
|
this.$axios({
|
||||||
@@ -1476,7 +1304,8 @@ export default {
|
|||||||
let rootFile = this.$refs.uploader.uploader.getRoot();
|
let rootFile = this.$refs.uploader.uploader.getRoot();
|
||||||
console.log(rootFile);
|
console.log(rootFile);
|
||||||
if (rootFile.fileList.length != 1) {
|
if (rootFile.fileList.length != 1) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.oneFolder"),
|
message: this.$t("work.oneFolder"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1484,7 +1313,8 @@ export default {
|
|||||||
}
|
}
|
||||||
let filePath = rootFile.fileList[0];
|
let filePath = rootFile.fileList[0];
|
||||||
if (!filePath.isFolder) {
|
if (!filePath.isFolder) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.notFolder"),
|
message: this.$t("work.notFolder"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1509,7 +1339,8 @@ export default {
|
|||||||
!this.$refs.uploader.uploader.isComplete() &&
|
!this.$refs.uploader.uploader.isComplete() &&
|
||||||
!this.high_setting_form.localfiles
|
!this.high_setting_form.localfiles
|
||||||
) {
|
) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.uploadFail"),
|
message: this.$t("work.uploadFail"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1532,7 +1363,8 @@ export default {
|
|||||||
//选择的是zip文档,则名称一定要填写
|
//选择的是zip文档,则名称一定要填写
|
||||||
if (this.file_form == 2) {
|
if (this.file_form == 2) {
|
||||||
if (this.zip_name == "") {
|
if (this.zip_name == "") {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.zipNameInput"),
|
message: this.$t("work.zipNameInput"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1543,7 +1375,8 @@ export default {
|
|||||||
//选择的是zip加密,名称和密码需要校验
|
//选择的是zip加密,名称和密码需要校验
|
||||||
if (this.file_form == 3) {
|
if (this.file_form == 3) {
|
||||||
if (this.zip_name == "") {
|
if (this.zip_name == "") {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.zipNameInput"),
|
message: this.$t("work.zipNameInput"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1551,7 +1384,8 @@ export default {
|
|||||||
}
|
}
|
||||||
data += "&zip_name=" + this.zip_name;
|
data += "&zip_name=" + this.zip_name;
|
||||||
if (this.p1 == "" || this.p1 != this.p2) {
|
if (this.p1 == "" || this.p1 != this.p2) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.zipPassWrong"),
|
message: this.$t("work.zipPassWrong"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1564,7 +1398,8 @@ export default {
|
|||||||
if (this.switch_tag) {
|
if (this.switch_tag) {
|
||||||
//标签开启,则标签文件一定要上传
|
//标签开启,则标签文件一定要上传
|
||||||
if (this.$refs.refFile.files.length == 0) {
|
if (this.$refs.refFile.files.length == 0) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.pleaseUploadTag"),
|
message: this.$t("work.pleaseUploadTag"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1584,7 +1419,8 @@ export default {
|
|||||||
//打印面数print_flag为1 - 双面的时候,模板flag必须为1 - 双面
|
//打印面数print_flag为1 - 双面的时候,模板flag必须为1 - 双面
|
||||||
//打印面数print_flag为2 - 正 的时候 模板正面必须有内容 (flag != 3)
|
//打印面数print_flag为2 - 正 的时候 模板正面必须有内容 (flag != 3)
|
||||||
//打印面数print_flag为3 - 反 的时候 模板背面必须有内容 (flag != 2)
|
//打印面数print_flag为3 - 反 的时候 模板背面必须有内容 (flag != 2)
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.print_flagError"),
|
message: this.$t("work.print_flagError"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1593,7 +1429,8 @@ export default {
|
|||||||
data += "&print_flag=" + this.print_flag; //打印面数需要在开启了标签时,1双 2正3背
|
data += "&print_flag=" + this.print_flag; //打印面数需要在开启了标签时,1双 2正3背
|
||||||
}
|
}
|
||||||
if (this.juanbiao_form == "") {
|
if (this.juanbiao_form == "") {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.juanbiaoInput"),
|
message: this.$t("work.juanbiaoInput"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1620,7 +1457,8 @@ export default {
|
|||||||
//}
|
//}
|
||||||
//console.log(data);
|
//console.log(data);
|
||||||
//console.log(data_param)
|
//console.log(data_param)
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.submiting"),
|
message: this.$t("work.submiting"),
|
||||||
});
|
});
|
||||||
this.$emit("jobPost");
|
this.$emit("jobPost");
|
||||||
@@ -1628,16 +1466,19 @@ export default {
|
|||||||
method: "post",
|
method: "post",
|
||||||
url: "/rest/job/?" + data_param + data,
|
url: "/rest/job/?" + data_param + data,
|
||||||
//data: post_data
|
//data: post_data
|
||||||
}).then((res) => {});
|
}).then((res) => { });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
file_percent() {
|
file_percent() {
|
||||||
|
const sizeFormNum = parseFloat(this.size_form);
|
||||||
|
if (isNaN(sizeFormNum) || sizeFormNum <= 0) return 0;
|
||||||
let t =
|
let t =
|
||||||
(this.size /
|
(this.size /
|
||||||
(((this.size_form * 1000) / 1.024 / 1.024 / 1.024) * 1024 * 1024)) *
|
(((sizeFormNum * 1000) / 1.024 / 1.024 / 1.024) * 1024 * 1024)) *
|
||||||
100;
|
100;
|
||||||
return t ? t > 100 ? 100.1 : t : 0
|
if (isNaN(t) || !isFinite(t)) return 0;
|
||||||
|
return t > 100 ? 100.1 : t;
|
||||||
},
|
},
|
||||||
print_op() {
|
print_op() {
|
||||||
return [
|
return [
|
||||||
@@ -1812,7 +1653,8 @@ export default {
|
|||||||
},
|
},
|
||||||
file_percent(val) {
|
file_percent(val) {
|
||||||
if (val == 100.1) {
|
if (val == 100.1) {
|
||||||
this.$message({offset:100,
|
this.$message({
|
||||||
|
offset: 100,
|
||||||
message: this.$t("work.sizeExtra"),
|
message: this.$t("work.sizeExtra"),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
@@ -1861,6 +1703,7 @@ export default {
|
|||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
float: left;
|
float: left;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@@ -1869,6 +1712,7 @@ export default {
|
|||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
height: 500px;
|
height: 500px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1895,8 +1739,7 @@ export default {
|
|||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploader-example .uploader-btn {
|
|
||||||
}
|
|
||||||
|
|
||||||
.uploader-example .uploader-list {
|
.uploader-example .uploader-list {
|
||||||
max-height: 405px;
|
max-height: 405px;
|
||||||
@@ -1904,23 +1747,28 @@ export default {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploader-list::-webkit-scrollbar {
|
.uploader-list::-webkit-scrollbar {
|
||||||
/*滚动条整体样式*/
|
/*滚动条整体样式*/
|
||||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
width: 10px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploader-list::-webkit-scrollbar-thumb {
|
.uploader-list::-webkit-scrollbar-thumb {
|
||||||
/*滚动条里面小方块*/
|
/*滚动条里面小方块*/
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
background: #c7c7cb;
|
background: #c7c7cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploader-list::-webkit-scrollbar-track {
|
.uploader-list::-webkit-scrollbar-track {
|
||||||
/*滚动条里面轨道*/
|
/*滚动条里面轨道*/
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #ededed;
|
background: #ededed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.display {
|
.display {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
background-color: #212830;
|
background-color: #212830;
|
||||||
@@ -1939,6 +1787,7 @@ export default {
|
|||||||
/deep/ .uploader-file-name {
|
/deep/ .uploader-file-name {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .el-progress-bar__outer {
|
/deep/ .el-progress-bar__outer {
|
||||||
background-color: #bac2d7;
|
background-color: #bac2d7;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+89
-28
File diff suppressed because one or more lines are too long
+91
-27
File diff suppressed because one or more lines are too long
+420
-352
File diff suppressed because one or more lines are too long
+16
-15
@@ -16,39 +16,40 @@ Vue.use(ElementUI);
|
|||||||
/* eslint-disable no-new */
|
/* eslint-disable no-new */
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
var type = navigator.appName;
|
var type = navigator.appName;
|
||||||
if (type == "Netscape"){
|
if (type == "Netscape") {
|
||||||
var lang = navigator.language;//获取浏览器配置语言,支持非IE浏览器
|
var lang = navigator.language;//获取浏览器配置语言,支持非IE浏览器
|
||||||
}else{
|
} else {
|
||||||
var lang = navigator.userLanguage;//获取浏览器配置语言,支持IE5+ == navigator.systemLanguage
|
var lang = navigator.userLanguage;//获取浏览器配置语言,支持IE5+ == navigator.systemLanguage
|
||||||
};
|
};
|
||||||
var lang1 = lang.substr(0, 2);//获取浏览器配置语言前两位
|
var lang1 = lang.substr(0, 2);//获取浏览器配置语言前两位
|
||||||
console.log(lang,lang1);
|
console.log(lang, lang1);
|
||||||
let lan = 'en';
|
let lan = 'en';
|
||||||
if(lang1=='zh'){
|
if (lang1 == 'zh') {
|
||||||
if(lang == 'zh-TW' || lang == 'zh-HK'){
|
if (lang == 'zh-TW' || lang == 'zh-HK') {
|
||||||
lan = 'ozh';
|
lan = 'ozh';
|
||||||
}else{
|
} else {
|
||||||
lan = 'zh';
|
lan = 'zh';
|
||||||
}
|
}
|
||||||
}else if(lang1=="en"){
|
} else if (lang1 == "en") {
|
||||||
lan = 'en';
|
lan = 'en';
|
||||||
}
|
}
|
||||||
if(!localStorage.getItem('lang')){
|
if (!localStorage.getItem('lang')) {
|
||||||
localStorage.setItem("lang",lan);
|
localStorage.setItem("lang", lan);
|
||||||
}
|
}
|
||||||
|
|
||||||
const i18n = new VueI18n({
|
const i18n = new VueI18n({
|
||||||
|
silentTranslationWarn: true,
|
||||||
//locale: lan, // 默认语言
|
//locale: lan, // 默认语言
|
||||||
locale:(function(){
|
locale: (function () {
|
||||||
if(localStorage.getItem('lang')){
|
if (localStorage.getItem('lang')) {
|
||||||
return localStorage.getItem('lang')
|
return localStorage.getItem('lang')
|
||||||
}
|
}
|
||||||
return 'en'
|
return 'en'
|
||||||
}()),
|
}()),
|
||||||
messages: {
|
messages: {
|
||||||
'zh': cnlang,
|
'zh': cnlang,
|
||||||
'ozh': ocnlang,
|
'ozh': ocnlang,
|
||||||
'en': enlang
|
'en': enlang
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
axios.defaults.baseURL = 'http://localhost:5080';
|
axios.defaults.baseURL = 'http://localhost:5080';
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const state = {
|
||||||
|
setFormDefault: {
|
||||||
|
is_blend: false,
|
||||||
|
record_screen: false,
|
||||||
|
record_screen_path: '',
|
||||||
|
print_record_logo: false,
|
||||||
|
install_dongle_count: 0 // Changed from boolean to number (0-256)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
SET_FORM_DEFAULT(state, payload) {
|
||||||
|
state.setFormDefault = payload
|
||||||
|
},
|
||||||
|
UPDATE_FORM_DEFAULT(state, payload) {
|
||||||
|
state.setFormDefault = { ...state.setFormDefault, ...payload }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
setFormDefault({ commit }, payload) {
|
||||||
|
commit('SET_FORM_DEFAULT', payload)
|
||||||
|
},
|
||||||
|
updateFormDefault({ commit }, payload) {
|
||||||
|
commit('UPDATE_FORM_DEFAULT', payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user