新增界面最小化 监控文件夹

master
姜雪 2 weeks ago
parent 2b96250186
commit 1f0720c8ad
  1. 13
      config.json
  2. 2
      dist_electron/bundled/background.js
  3. 2
      dist_electron/bundled/css/app.9e213d8c.css
  4. 2
      dist_electron/bundled/index.html
  5. 2
      dist_electron/bundled/js/app.08bbb89f.js
  6. 1
      dist_electron/bundled/js/app.08bbb89f.js.map
  7. 2
      dist_electron/bundled/js/app.4109ee0c.js
  8. 1
      dist_electron/bundled/js/app.4109ee0c.js.map
  9. 49
      dist_electron/bundled/js/chunk-vendors.1c7644b8.js
  10. 1
      dist_electron/bundled/js/chunk-vendors.1c7644b8.js.map
  11. 49
      dist_electron/bundled/js/chunk-vendors.8e57b122.js
  12. 1
      dist_electron/bundled/js/chunk-vendors.8e57b122.js.map
  13. 739
      dist_electron/index.js
  14. 4
      dist_electron/preload.js
  15. 28259
      package-lock.json
  16. 212
      src/listener.js
  17. 9
      src/preload.js
  18. 6
      src/router/index.js
  19. 32
      src/tray.js
  20. 470
      src/views/AutoMode.vue
  21. 147
      src/views/ModeSelect.vue
  22. 65
      src/views/config/configFile.vue
  23. 24
      src/views/index.vue

@ -10,15 +10,14 @@
"topic": "6" "topic": "6"
}, },
"device": { "device": {
"username": "12111",
"code": "Z139009/202402", "code": "Z139009/202402",
"model": "1",
"address": "http://10.1.19.52:9999",
"file_path": "测试",
"no_report_path": "未上传记录",
"codeType": "dd", "codeType": "dd",
"reconnect_time": "3", "reconnect_time": "3",
"deviceAddress": "http://124.221.142.15:8088/api", "address": "http://10.1.19.52:9999",
"filePathDisc": "C", "filePathDisc": "D",
"updateFileName": "1" "file_path": "ai",
"no_report_path": "未上传记录",
"searchMode": "manual"
} }
} }

File diff suppressed because one or more lines are too long

@ -1 +1 @@
.desc[data-v-82f773be]{margin-top:40px;font-size:12px}.common[data-v-673c0bf5]{margin-top:20px}.mark[data-v-a0343704]{width:100%;height:100%;overflow:hidden;position:fixed;top:0;left:0;z-index:10}h3[data-v-a0343704]{margin:40px 0 0}ul[data-v-a0343704]{list-style-type:none;padding:0}li[data-v-a0343704]{display:inline-block;margin:0 10px}a[data-v-a0343704]{color:#42b983}.box-card[data-v-a0343704]{margin-top:12px}[data-v-a0343704] .el-form-item{margin-bottom:0!important}.box-card[data-v-7f6132b8]{width:250px;height:200px;float:left;margin-left:43px;margin-top:40px}.box-card[data-v-7f6132b8]:hover{border:1px solid #409eff;cursor:pointer}.descCls[data-v-7f6132b8]{font-size:12px}.file-upload[data-v-4d46612a]{padding:20px}.upload-area[data-v-4d46612a]{border:2px dashed #dcdfe6;border-radius:6px;padding:60px 0;text-align:center;cursor:pointer;transition:all .3s;background-color:#fafafa}.upload-area[data-v-4d46612a]:hover{border-color:#409eff;background-color:#f0f7ff}.upload-content[data-v-4d46612a]{color:#909399}.upload-content i[data-v-4d46612a]{font-size:48px;margin-bottom:16px}.file-info[data-v-4d46612a]{margin-top:20px;padding:20px;border:1px solid #ebeef5;border-radius:6px;background-color:#f8f9fa}.file-item[data-v-4d46612a]{margin-bottom:20px;padding-bottom:20px;border-bottom:1px solid #ebeef5}.file-name[data-v-4d46612a]{font-size:16px;font-weight:700;color:#303133;margin-bottom:8px}.file-path[data-v-4d46612a]{font-size:12px;color:#909399;margin-bottom:4px;word-break:break-all}.file-size[data-v-4d46612a]{font-size:12px;color:#67c23a}.rename-section[data-v-4d46612a]{margin-top:20px}.file-ext[data-v-4d46612a]{background-color:#f0f0f0;padding:0 8px;color:#666}.action-buttons[data-v-4d46612a]{margin-top:20px;display:flex;gap:10px}.renamed-info[data-v-4d46612a],.upload-result[data-v-4d46612a]{margin-top:20px} .desc[data-v-82f773be]{margin-top:40px;font-size:12px}.common[data-v-673c0bf5]{margin-top:20px}.mark[data-v-6f30a2d4]{width:100%;height:100%;overflow:hidden;position:fixed;top:0;left:0;z-index:10}h3[data-v-6f30a2d4]{margin:40px 0 0}ul[data-v-6f30a2d4]{list-style-type:none;padding:0}li[data-v-6f30a2d4]{display:inline-block;margin:0 10px}a[data-v-6f30a2d4]{color:#42b983}.box-card[data-v-6f30a2d4]{margin-top:12px}[data-v-6f30a2d4] .el-form-item{margin-bottom:0!important}.box-card[data-v-7f6132b8]{width:250px;height:200px;float:left;margin-left:43px;margin-top:40px}.box-card[data-v-7f6132b8]:hover{border:1px solid #409eff;cursor:pointer}.descCls[data-v-7f6132b8]{font-size:12px}.file-upload[data-v-4d46612a]{padding:20px}.upload-area[data-v-4d46612a]{border:2px dashed #dcdfe6;border-radius:6px;padding:60px 0;text-align:center;cursor:pointer;transition:all .3s;background-color:#fafafa}.upload-area[data-v-4d46612a]:hover{border-color:#409eff;background-color:#f0f7ff}.upload-content[data-v-4d46612a]{color:#909399}.upload-content i[data-v-4d46612a]{font-size:48px;margin-bottom:16px}.file-info[data-v-4d46612a]{margin-top:20px;padding:20px;border:1px solid #ebeef5;border-radius:6px;background-color:#f8f9fa}.file-item[data-v-4d46612a]{margin-bottom:20px;padding-bottom:20px;border-bottom:1px solid #ebeef5}.file-name[data-v-4d46612a]{font-size:16px;font-weight:700;color:#303133;margin-bottom:8px}.file-path[data-v-4d46612a]{font-size:12px;color:#909399;margin-bottom:4px;word-break:break-all}.file-size[data-v-4d46612a]{font-size:12px;color:#67c23a}.rename-section[data-v-4d46612a]{margin-top:20px}.file-ext[data-v-4d46612a]{background-color:#f0f0f0;padding:0 8px;color:#666}.action-buttons[data-v-4d46612a]{margin-top:20px;display:flex;gap:10px}.renamed-info[data-v-4d46612a],.upload-result[data-v-4d46612a]{margin-top:20px}

@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="stylesheet" href="app://./element-ui/theme-chalk/index.css"><link rel="icon" href="app://./favicon.ico"><title>utils-hub-demo</title><script defer="defer" src="app://./js/chunk-vendors.8e57b122.js"></script><script defer="defer" src="app://./js/app.08bbb89f.js"></script><link href="app://./css/chunk-vendors.ccd066bc.css" rel="stylesheet"><link href="app://./css/app.e13669ee.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but utils-hub-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html> <!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="stylesheet" href="app://./element-ui/theme-chalk/index.css"><link rel="icon" href="app://./favicon.ico"><title>utils-hub-demo</title><script defer="defer" src="app://./js/chunk-vendors.1c7644b8.js"></script><script defer="defer" src="app://./js/app.4109ee0c.js"></script><link href="app://./css/chunk-vendors.ccd066bc.css" rel="stylesheet"><link href="app://./css/app.9e213d8c.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but utils-hub-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -93,7 +93,7 @@
/*! no static exports found */ /*! no static exports found */
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
eval("const { contextBridge, ipcRenderer } = __webpack_require__(/*! electron */ \"electron\")\r\nconst Store = __webpack_require__(/*! electron-store */ \"electron-store\");\r\nconst store = new Store();\r\ncontextBridge.exposeInMainWorld('api', {\r\n createUtilsWindow: (flag) => {\r\n ipcRenderer.send('create-utils-window', flag)\r\n },\r\n uploadFile: (id) => {\r\n ipcRenderer.send(\"upload-file\", id);\r\n },\r\n watchuploadFile: (id) => {\r\n ipcRenderer.invoke(\"watch-upload-file\", id);\r\n },\r\n getConfig: () => ipcRenderer.invoke('get-config'),\r\n updateConfig: (config) => ipcRenderer.invoke('update-config', config),\r\n getStoreValue: (key) => store.get(key),\r\n removeStoreValue: (key) => store.delete(key),\r\n watchUploadLatestAnalysisFile: (id) => {\r\n ipcRenderer.invoke(\"watch-upload-analysis-file\", id);\r\n },\r\n // 读取C盘文件夹文件\r\n readCFolder: (config) => ipcRenderer.invoke('read-c-folder', config),\r\n // 可选:获取Electron版本(测试用)\r\n getElectronVersion: () => process.versions.electron,\r\n saveFileInfo: (fileInfoList) => ipcRenderer.invoke('save-file-info', fileInfoList), // 新增\r\n getSavedFileInfo: () => ipcRenderer.invoke('get-saved-file-info'), // 新增\r\n renameFile: (data) => ipcRenderer.invoke('rename-file', data),\r\n})\n\n//# sourceURL=webpack:///./src/preload.js?"); eval("const { contextBridge, ipcRenderer } = __webpack_require__(/*! electron */ \"electron\")\r\nconst Store = __webpack_require__(/*! electron-store */ \"electron-store\");\r\nconst store = new Store();\r\ncontextBridge.exposeInMainWorld('api', {\r\n createUtilsWindow: (flag) => {\r\n ipcRenderer.send('create-utils-window', flag)\r\n },\r\n uploadFile: (id) => {\r\n ipcRenderer.send(\"upload-file\", id);\r\n },\r\n watchuploadFile: (id) => {\r\n ipcRenderer.invoke(\"watch-upload-file\", id);\r\n },\r\n getConfig: () => ipcRenderer.invoke('get-config'),\r\n updateConfig: (config) => ipcRenderer.invoke('update-config', config),\r\n getStoreValue: (key) => store.get(key),\r\n removeStoreValue: (key) => store.delete(key),\r\n watchUploadLatestAnalysisFile: (id) => {\r\n ipcRenderer.invoke(\"watch-upload-analysis-file\", id);\r\n },\r\n // 读取C盘文件夹文件\r\n readCFolder: (config) => ipcRenderer.invoke('read-c-folder', config),\r\n // 可选:获取Electron版本(测试用)\r\n getElectronVersion: () => process.versions.electron,\r\n saveFileInfo: (fileInfoList) => ipcRenderer.invoke('save-file-info', fileInfoList), // 新增\r\n getSavedFileInfo: () => ipcRenderer.invoke('get-saved-file-info'), // 新增\r\n renameFile: (data) => ipcRenderer.invoke('rename-file', data),\r\n minimizeWindow: () => ipcRenderer.send('minimize-window'),\r\n startWatchFolder: (path) => ipcRenderer.send('start-watch-folder', path),\r\n stopWatchFolder: () => ipcRenderer.send('stop-watch-folder'),\r\n onFileChanged: (callback) => ipcRenderer.on('file-changed', (event, data) => callback(data)),\r\n removeFileChangedListener: (callback) => {\r\n if (callback) {\r\n ipcRenderer.removeListener('file-changed', callback);\r\n }\r\n },\r\n})\n\n//# sourceURL=webpack:///./src/preload.js?");
/***/ }), /***/ }),
@ -104,7 +104,7 @@ eval("const { contextBridge, ipcRenderer } = __webpack_require__(/*! electron */
/*! no static exports found */ /*! no static exports found */
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
eval("module.exports = __webpack_require__(/*! E:\\shuojinkeji\\WJSC\\utils-hub-demo\\src\\preload.js */\"./src/preload.js\");\n\n\n//# sourceURL=webpack:///multi_./src/preload.js?"); eval("module.exports = __webpack_require__(/*! C:\\Users\\jiangxue\\Desktop\\xiaochengxu\\file-upload-application-mes\\src\\preload.js */\"./src/preload.js\");\n\n\n//# sourceURL=webpack:///multi_./src/preload.js?");
/***/ }), /***/ }),

28259
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
/** 主进程监听与处理 */ /** 主进程监听与处理 */
import { ipcMain, app } from 'electron' import { ipcMain, app, BrowserWindow } from 'electron'
import * as iconManger from '@/iconManager' import * as iconManger from '@/iconManager'
import commonCreateWindow from '@/windowManager' import commonCreateWindow from '@/windowManager'
import path from 'path'; import path from 'path';
@ -8,6 +8,12 @@ import { uploadLatestFile, watchUploadLatestFile, watchUploadLatestAnalysisFile
const userDataPath = process.cwd() const userDataPath = process.cwd()
// 获取配置文件路径 // 获取配置文件路径
const configPath = path.join(userDataPath, 'config.json'); const configPath = path.join(userDataPath, 'config.json');
// 文件夹监控器
let folderWatcher = null;
let lastUploadTime = 0;
const UPLOAD_INTERVAL = 3000; // 3秒内不重复上传
// 读取配置文件 // 读取配置文件
function loadConfig() { function loadConfig() {
try { try {
@ -19,6 +25,89 @@ function loadConfig() {
} }
} }
// 最小化窗口
ipcMain.on('minimize-window', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win) {
win.minimize();
}
});
// 开始监控文件夹
ipcMain.on('start-watch-folder', (event, folderPath) => {
console.log('开始监控文件夹:', folderPath);
// 停止之前的监控
if (folderWatcher) {
folderWatcher.close();
folderWatcher = null;
}
// 检查文件夹是否存在
if (!fs.existsSync(folderPath)) {
console.error('文件夹不存在:', folderPath);
return;
}
// 开始监控
// eventType: 'rename' - 新建/删除/重命名文件, 'change' - 文件内容修改
folderWatcher = fs.watch(folderPath, { recursive: true }, (eventType, filename) => {
if (filename) {
const now = Date.now();
// 防抖:3秒内不重复上传
if (now - lastUploadTime < UPLOAD_INTERVAL) {
return;
}
lastUploadTime = now;
console.log('检测到文件变化:', filename, '事件类型:', eventType);
// 检查文件是否存在(排除删除事件)
const fullPath = path.join(folderPath, filename);
if (!fs.existsSync(fullPath)) {
console.log('文件已被删除,忽略:', filename);
return;
}
// 检查是否是文件(排除文件夹)
try {
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
console.log('是文件夹,忽略:', filename);
return;
}
} catch (err) {
console.log('获取文件状态失败,忽略:', filename);
return;
}
// 通知渲染进程文件发生变化
event.sender.send('file-changed', {
filename: filename,
eventType: eventType,
folderPath: folderPath,
fullPath: fullPath,
time: new Date().toLocaleString()
});
}
});
folderWatcher.on('error', (err) => {
console.error('文件夹监控错误:', err);
});
console.log('文件夹监控已启动');
});
// 停止监控文件夹
ipcMain.on('stop-watch-folder', () => {
console.log('停止监控文件夹');
if (folderWatcher) {
folderWatcher.close();
folderWatcher = null;
}
});
ipcMain.on('create-utils-window', (e, flag) => { ipcMain.on('create-utils-window', (e, flag) => {
// console.log('主进程方法被调用了') // console.log('主进程方法被调用了')
//创建窗口 //创建窗口
@ -100,42 +189,127 @@ ipcMain.handle('watch-upload-analysis-file', async (e, id) => {
} }
}); });
// 递归获取所有文件(包括子文件夹中的文件)
function getAllFilesRecursively(dir, fileList = []) {
console.log(`扫描目录: ${dir}`);
try {
const files = fs.readdirSync(dir);
console.log(`找到 ${files.length} 个项目:`, files);
files.forEach(file => {
const fullPath = path.join(dir, file);
try {
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
// 如果是文件夹,递归查找
console.log(` 发现子文件夹: ${file}`);
getAllFilesRecursively(fullPath, fileList);
} else if (stat.isFile()) {
// 如果是文件,添加到列表
console.log(` 发现文件: ${file}, 大小: ${stat.size} bytes, 修改时间: ${stat.mtime}`);
fileList.push({
file: file,
fullPath: fullPath,
stat: stat
});
}
} catch (err) {
console.warn(`无法访问文件: ${fullPath}`, err.message);
}
});
} catch (err) {
console.error(`读取目录失败 ${dir}:`, err.message);
}
return fileList;
}
// 判断是否是Windows默认新建文件名
function isWindowsDefaultName(filename) {
const patterns = [
/^新建\s*文本文档\.txt$/i, // 中文Windows
/^新建\s*文件夹$/i, // 中文Windows文件夹
/^New\s*Text\s*Document\.txt$/i, // 英文Windows
/^New\s*Folder$/i, // 英文Windows文件夹
/^新建\s*Microsoft\s*Word\s*文档\.docx?$/i,
/^新建\s*Microsoft\s*Excel\s*工作表\.xlsx?$/i,
/^新建\s*Microsoft\s*PowerPoint\s*演示文稿\.pptx?$/i,
/^Document\d*\.txt$/i, // 某些系统
/^Untitled\d*\.\w+$/i, // 未命名文件
];
return patterns.some(pattern => pattern.test(filename));
}
// 延迟函数
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 注册IPC方法:读取C盘指定文件夹的文件列表 // 注册IPC方法:读取C盘指定文件夹的文件列表
ipcMain.handle('read-c-folder', async (event, folderPath) => { ipcMain.handle('read-c-folder', async (event, folderPath) => {
try { try {
let dataJson = loadConfig() let dataJson = loadConfig()
const { path: targetPath, orderNum } = folderPath; const { path: targetPath, orderNum } = folderPath;
console.log('开始扫描目录:', targetPath);
// const targetPath = folderPath; // const targetPath = folderPath;
if (!fs.existsSync(targetPath)) { if (!fs.existsSync(targetPath)) {
return { success: false, msg: `文件夹不存在:${targetPath}` }; return { success: false, msg: `文件夹不存在:${targetPath}` };
} }
// 读取所有文件(过滤掉目录) // 递归读取所有文件(包括子文件夹中的文件)
const files = fs.readdirSync(targetPath).map(file => { const files = getAllFilesRecursively(targetPath);
const fullPath = path.join(targetPath, file); console.log(`总共找到 ${files.length} 个文件`);
const stat = fs.statSync(fullPath);
return { file, fullPath, stat };
})
.filter(item => item.stat.isFile());
if (files.length === 0) { if (files.length === 0) {
return { success: false, msg: '文件夹中没有文件' }; return { success: false, msg: '文件夹中没有文件' };
} }
// 找出最新修改的文件(使用 mtimeMs 精确到毫秒) // 找出最新修改的文件(使用 mtimeMs 精确到毫秒)
const latestFile = files.reduce((prev, current) => { let latestFile = files.reduce((prev, current) => {
return current.stat.mtimeMs > prev.stat.mtimeMs ? current : prev; return current.stat.mtimeMs > prev.stat.mtimeMs ? current : prev;
}); });
console.log(`最新文件: ${latestFile.file}, 路径: ${latestFile.fullPath}, 修改时间: ${latestFile.stat.mtime}`);
// 🔥 如果是Windows默认新建文件名,等待用户重命名
let waitCount = 0;
const maxWaitCount = 10; // 最多等待5秒(10次 × 500ms)
while (isWindowsDefaultName(latestFile.file) && waitCount < maxWaitCount) {
console.log(`检测到默认新建文件名 "${latestFile.file}",等待用户重命名... (${waitCount + 1}/${maxWaitCount})`);
await delay(500); // 等待500ms
// 重新扫描文件
const newFiles = getAllFilesRecursively(targetPath);
if (newFiles.length === 0) {
return { success: false, msg: '文件夹中没有文件(用户可能取消了创建)' };
}
// 找出最新文件
latestFile = newFiles.reduce((prev, current) => {
return current.stat.mtimeMs > prev.stat.mtimeMs ? current : prev;
});
waitCount++;
}
if (isWindowsDefaultName(latestFile.file)) {
console.log(`等待超时,用户未重命名,使用默认文件名: ${latestFile.file}`);
} else {
console.log(`获取到最终文件名: ${latestFile.file}`);
}
const { file: oldName, fullPath: oldPath, stat } = latestFile; const { file: oldName, fullPath: oldPath, stat } = latestFile;
console.log('latestFile', latestFile); // 获取文件所在目录(可能是子文件夹)
const fileDir = path.dirname(oldPath);
// 如果未提供 orderNum // 如果未提供 orderNum
const ext = path.extname(oldName); // 保留原扩展名,如 .txt const ext = path.extname(oldName); // 保留原扩展名,如 .txt
const baseNewName = orderNum; const baseNewName = orderNum;
const newName = baseNewName + (ext.startsWith('.') ? ext : ''); const newName = baseNewName + (ext.startsWith('.') ? ext : '');
const newPath = path.join(targetPath, newName); const newPath = path.join(fileDir, newName);
console.log('newPath', newPath, dataJson.device.updateFileName == '1'); console.log('newPath', newPath, dataJson.device.updateFileName == '1');
if (dataJson.device.updateFileName == '1') { if (dataJson.device.updateFileName == '1') {
fs.renameSync(oldPath, newPath); fs.renameSync(oldPath, newPath);
@ -156,10 +330,7 @@ ipcMain.handle('read-c-folder', async (event, folderPath) => {
}; };
} else { } else {
fs.renameSync(oldPath, oldPath); // 不重命名,直接使用原文件
// 执行重命名
// 可选:读取文件 Buffer(注意大文件内存问题)
// 如果不需要内容,可移除 fileBuffer 字段
const fileBuffer = fs.readFileSync(oldPath); const fileBuffer = fs.readFileSync(oldPath);
return { return {
@ -175,6 +346,7 @@ ipcMain.handle('read-c-folder', async (event, folderPath) => {
} }
} catch (err) { } catch (err) {
console.error('read-c-folder 错误:', err);
return { success: false, msg: `读取最新文件失败:${err.message}` }; return { success: false, msg: `读取最新文件失败:${err.message}` };
} }
}); });
@ -286,17 +458,15 @@ ipcMain.handle('rename-file', async (event, data) => {
}; };
} else { } else {
fs.renameSync(oldPath, oldPath); // 不重命名,直接使用原文件
// 执行重命名 const oldName = path.basename(filePath);
// 可选:读取文件 Buffer(注意大文件内存问题) const fileBuffer = fs.readFileSync(filePath);
// 如果不需要内容,可移除 fileBuffer 字段
const fileBuffer = fs.readFileSync(oldPath);
return { return {
success: true, success: true,
data: { data: {
fileName: oldName, fileName: oldName,
filePath: oldPath, filePath: filePath,
fileSize: (stat.size / 1024).toFixed(2) + 'KB', fileSize: (stat.size / 1024).toFixed(2) + 'KB',
updateTime: new Date(stat.mtime).toLocaleString(), updateTime: new Date(stat.mtime).toLocaleString(),
fileBuffer: fileBuffer // 若不需要,可删除此行 fileBuffer: fileBuffer // 若不需要,可删除此行

@ -25,4 +25,13 @@ contextBridge.exposeInMainWorld('api', {
saveFileInfo: (fileInfoList) => ipcRenderer.invoke('save-file-info', fileInfoList), // 新增 saveFileInfo: (fileInfoList) => ipcRenderer.invoke('save-file-info', fileInfoList), // 新增
getSavedFileInfo: () => ipcRenderer.invoke('get-saved-file-info'), // 新增 getSavedFileInfo: () => ipcRenderer.invoke('get-saved-file-info'), // 新增
renameFile: (data) => ipcRenderer.invoke('rename-file', data), renameFile: (data) => ipcRenderer.invoke('rename-file', data),
minimizeWindow: () => ipcRenderer.send('minimize-window'),
startWatchFolder: (path) => ipcRenderer.send('start-watch-folder', path),
stopWatchFolder: () => ipcRenderer.send('stop-watch-folder'),
onFileChanged: (callback) => ipcRenderer.on('file-changed', (event, data) => callback(data)),
removeFileChangedListener: (callback) => {
if (callback) {
ipcRenderer.removeListener('file-changed', callback);
}
},
}) })

@ -10,6 +10,8 @@ import TransferWin from "@/views/windows/commonUtils/TransferWin.vue";
/** 引入页面 */ /** 引入页面 */
import ModeSelect from '@/views/ModeSelect.vue'
import AutoMode from '@/views/AutoMode.vue'
import index from '@/views/index.vue' import index from '@/views/index.vue'
import Dashboard from "@/views/pages/Dashboard.vue"; import Dashboard from "@/views/pages/Dashboard.vue";
import CommonUtils from "@/views/pages/CommonUtils.vue"; import CommonUtils from "@/views/pages/CommonUtils.vue";
@ -23,7 +25,9 @@ const routes = [
path: "/", path: "/",
component: BaseLayout, component: BaseLayout,
children: [ children: [
{ path: '', component: index }, { path: '', component: ModeSelect },
{ path: 'auto', component: AutoMode },
{ path: 'manual', component: index },
{ path: 'dashboard', component: Dashboard }, { path: 'dashboard', component: Dashboard },
{ path: 'common-utils', component: CommonUtils }, { path: 'common-utils', component: CommonUtils },
{ path: 'history', component: FileUpload }, { path: 'history', component: FileUpload },

@ -2,21 +2,47 @@
const { Tray, Menu } = require('electron'); const { Tray, Menu } = require('electron');
const path = require('path'); const path = require('path');
import * as iconSupport from '@/iconManager' import * as iconSupport from '@/iconManager'
const fs = require('fs');
let appTray = null; let appTray = null;
let win = null; // 你需要从外部传递窗口实例 let win = null; // 你需要从外部传递窗口实例
// 获取图标文件的绝对路径
function getIconPath(iconPath) {
// 尝试从 dist_electron 目录加载
const distPath = path.join(__dirname, iconPath);
if (fs.existsSync(distPath)) {
return distPath;
}
// 如果不存在,尝试从 public 目录加载(开发模式)
const publicPath = path.join(process.cwd(), 'public', iconPath);
if (fs.existsSync(publicPath)) {
return publicPath;
}
// 都不存在,返回原路径
return distPath;
}
function createTray(app,mainWindow,nativeImage) { function createTray(app,mainWindow,nativeImage) {
win = mainWindow; win = mainWindow;
// 获取图标路径
const openIconPath = getIconPath(iconSupport.ICON_PATHS.OPEN_ICON);
const exitIconPath = getIconPath(iconSupport.ICON_PATHS.EXIT_ICON);
const appIconPath = getIconPath(iconSupport.ICON_PATHS.APP_ICON);
console.log('图标路径 - 打开:', openIconPath);
console.log('图标路径 - 退出:', exitIconPath);
console.log('图标路径 - 应用:', appIconPath);
// 打开图标缩小设置 // 打开图标缩小设置
const openResizedIcon = nativeImage.createFromPath(path.join(__dirname, iconSupport.ICON_PATHS.OPEN_ICON)).resize({ const openResizedIcon = nativeImage.createFromPath(openIconPath).resize({
width: 16, width: 16,
height: 16 height: 16
}); });
// 退出图标缩小设置 // 退出图标缩小设置
const exitResizedIcon = nativeImage.createFromPath(path.join(__dirname, iconSupport.ICON_PATHS.EXIT_ICON)).resize({ const exitResizedIcon = nativeImage.createFromPath(exitIconPath).resize({
width: 16, width: 16,
height: 16 height: 16
}); });
@ -41,7 +67,7 @@ function createTray(app,mainWindow,nativeImage) {
} }
]; ];
appTray = new Tray(path.join(__dirname, iconSupport.ICON_PATHS.APP_ICON)); appTray = new Tray(appIconPath);
const contextMenu = Menu.buildFromTemplate(trayMenuTemplate); const contextMenu = Menu.buildFromTemplate(trayMenuTemplate);
appTray.setToolTip('utils-hub'); appTray.setToolTip('utils-hub');
appTray.setContextMenu(contextMenu); appTray.setContextMenu(contextMenu);

@ -0,0 +1,470 @@
<template>
<div class="auto-mode-container">
<div class="header">
<el-button type="text" @click="goBack()">
<i class="el-icon-arrow-left"></i> 返回选择模式
</el-button>
<span class="mode-title">自动上传模式</span>
</div>
<div class="auto-content">
<div class="upload-status" v-if="lastUploadStatus">
<el-alert
:title="lastUploadStatus.title"
:type="lastUploadStatus.type"
show-icon
:closable="false"
>
</el-alert>
</div>
<!-- 当前正在处理的文件 -->
<div class="current-file" v-if="currentFile">
<el-alert
:title="'正在处理文件: ' + currentFile"
type="info"
show-icon
:closable="false"
>
</el-alert>
</div>
<!-- 上传记录列表 -->
<div class="upload-list">
<h3>上传记录</h3>
<el-table :data="savedFileList" style="width: 100%" v-loading="tableLoading">
<el-table-column
type="index"
width="50"
label="序号"
align="center"
>
</el-table-column>
<el-table-column
prop="orderNumber"
label="订单号"
width="150"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="fileName"
label="文件名"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="deviceId"
label="设备编号"
width="120"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="uploadType"
label="上传类型"
width="100"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="deviceModel"
label="设备型号"
width="120"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="date"
label="上传日期"
width="180"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="analysisDate"
label="上传结果"
align="center"
show-overflow-tooltip
>
<template slot-scope="scope">
<span v-if="scope.row.uploading" style="color: #E6A23C;">
<i class="el-icon-loading"></i> 上传中...
</span>
<span v-else>{{ scope.row.analysisDate }}</span>
</template>
</el-table-column>
</el-table>
<div style="float: right; margin-top: 20px">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 20, 30, 50]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "AutoMode",
data() {
return {
configData: {},
lastUploadStatus: null,
savedFileList: [],
allSavedFileList: [],
currentPage: 1,
pageSize: 10,
total: 0,
tableLoading: false,
isWatching: false, //
currentFile: null, //
fileChangedCallback: null, //
};
},
async mounted() {
this.configData = await window.api.getConfig();
await this.getSavedFileInfo();
// 🔥
console.log("自动模式:启动监控和上传");
//
window.api.minimizeWindow();
//
await this.startAutoWatch();
//
await this.autoUploadFiles();
//
this.fileChangedCallback = (data) => {
console.log("🔥 收到文件变化通知:", data);
this.handleFileChanged(data);
};
window.api.onFileChanged(this.fileChangedCallback);
console.log("🔥 文件变化监听器已设置");
},
methods: {
async goBack() {
// searchMode
try {
if (this.configData && this.configData.device) {
this.configData.device.searchMode = "";
await window.api.updateConfig(this.configData);
console.log("已清空检索模式配置");
}
} catch (err) {
console.error("清空配置失败:", err);
}
//
if (this.isWatching) {
window.api.stopWatchFolder();
this.isWatching = false;
}
this.$router.push("/");
},
// 🔥
async startAutoWatch() {
try {
if (!this.configData || !this.configData.device) {
console.error("配置信息不存在");
return;
}
const device = this.configData.device;
const folderPath = `${device.filePathDisc}:/${device.file_path}`;
console.log("启动文件夹监控:", folderPath);
window.api.startWatchFolder(folderPath);
this.isWatching = true;
} catch (err) {
console.error("启动监控失败:", err);
}
},
// 🔥
async handleFileChanged(data) {
console.log("🔥 handleFileChanged 被调用,参数:", data);
console.log("🔥 文件发生变化,开始自动上传...");
// 🔥 getSavedFileInfo()
await this.autoUploadFiles();
},
// 🔥
async autoUploadFiles() {
try {
console.log("🔥 开始自动上传流程...");
if (!this.configData || !this.configData.device) {
console.error("🔥 配置信息不存在");
return;
}
const device = this.configData.device;
const path = `${device.filePathDisc}:/${device.file_path}`;
console.log("🔥 配置的文件路径:", path);
console.log("🔥 设备信息:", device);
//
console.log("🔥 正在读取文件夹...");
const res = await window.api.readCFolder({
path: path,
orderNum: this.getCurrentDateTime().replace(/[:\s]/g, ''),
});
console.log("🔥 readCFolder 返回结果:", res);
if (res.success && res.data) {
console.log("🔥 自动上传获取的文件:", res.data);
console.log("🔥 文件名:", res.data.fileName);
// 🔥
this.currentFile = res.data.fileName;
// 🔥
const newRecord = {
deviceId: device.code,
orderNumber: res.data.fileName.replace(/\.[^/.]+$/, ""),
deviceModel: device.codeType,
fileName: res.data.fileName,
analysisDate: "",
type: "auto",
date: this.getCurrentDateTime(),
uploadType: "自动上传",
uploading: true, //
};
console.log("🔥 准备插入新记录:", newRecord);
this.allSavedFileList.unshift(newRecord);
this.total = this.allSavedFileList.length;
this.updateCurrentPageData();
console.log("🔥 已插入列表,当前总数:", this.total);
//
await this.uploadFile(res.data, newRecord);
//
this.currentFile = null;
} else {
console.error("🔥 读取文件失败或无数据:", res.msg || "未知错误");
if (res.msg) {
this.lastUploadStatus = { title: res.msg, type: "error" };
}
}
} catch (err) {
console.error("🔥 自动上传失败:", err);
this.lastUploadStatus = { title: `上传失败:${err.message}`, type: "error" };
this.currentFile = null;
}
},
// 🔥
async uploadFile(file, record) {
try {
const device = this.configData.device;
// Blob
const fileBlob = new Blob([file.fileBuffer], {
type: "application/octet-stream"
});
// FormData
const formData = new FormData();
formData.append("file", fileBlob, file.fileName);
formData.append("token", device.username);
formData.append("deviceId", device.code);
formData.append("orderNumber", file.fileName.replace(/\.[^/.]+$/, ""));
formData.append("deviceModel", device.codeType);
console.log("上传参数:", {
fileName: file.fileName,
token: device.username,
deviceId: device.code,
orderNumber: file.fileName.replace(/\.[^/.]+$/, ""),
deviceModel: device.codeType,
uploadUrl: device.address + "/upper/send"
});
//
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);
const response = await fetch(device.address + "/upper/send", {
method: "POST",
body: formData,
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log("上传接口返回:", result);
if (result.code == 0) {
// 🔥
record.uploading = false;
record.analysisDate = JSON.stringify(result.data);
//
await window.api.saveFileInfo([{
deviceId: device.code,
orderNumber: file.fileName.replace(/\.[^/.]+$/, ""),
deviceModel: device.codeType,
fileName: file.fileName,
analysisDate: JSON.stringify(result.data),
type: "auto",
date: this.getCurrentDateTime(),
uploadType: "自动上传",
}]);
console.log("自动上传成功");
this.lastUploadStatus = { title: "上传成功", type: "success" };
} else {
// 🔥
record.uploading = false;
record.analysisDate = "上传失败: " + result.msg;
console.error("上传失败:", result.msg);
this.lastUploadStatus = { title: result.msg, type: "error" };
}
} catch (err) {
// 🔥
record.uploading = false;
if (err.name === "AbortError") {
console.error("请求超时,请检查网络或服务器状态");
record.analysisDate = "上传失败: 请求超时";
this.lastUploadStatus = { title: "请求超时", type: "error" };
} else {
console.error("上传异常:", err);
record.analysisDate = "上传失败: " + (err.message || "上传异常");
this.lastUploadStatus = { title: err.message || "上传异常", type: "error" };
}
}
},
//
async getSavedFileInfo() {
try {
this.tableLoading = true;
const res = await window.api.getSavedFileInfo();
if (res.success) {
//
this.allSavedFileList = res.data.filter(
(item) => item.uploadType === "自动上传"
);
this.total = this.allSavedFileList.length;
this.updateCurrentPageData();
console.log(`成功读取${this.total}条自动上传记录`);
} else {
console.error("读取文件信息失败:", res.msg);
}
} catch (err) {
console.error("读取本地数据失败:", err);
} finally {
this.tableLoading = false;
}
},
updateCurrentPageData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
this.savedFileList = this.allSavedFileList.slice(start, end);
},
handleSizeChange(val) {
this.pageSize = val;
this.currentPage = 1;
this.updateCurrentPageData();
},
handleCurrentChange(val) {
this.currentPage = val;
this.updateCurrentPageData();
},
getCurrentDateTime() {
const now = new Date();
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");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
},
beforeDestroy() {
//
if (this.isWatching) {
window.api.stopWatchFolder();
}
// 🔥
if (this.fileChangedCallback) {
window.api.removeFileChangedListener(this.fileChangedCallback);
console.log("🔥 已移除文件变化监听器");
}
},
};
</script>
<style scoped>
.auto-mode-container {
padding: 20px;
}
.header {
display: flex;
align-items: center;
margin-bottom: 30px;
}
.mode-title {
font-size: 20px;
font-weight: bold;
margin-left: 20px;
color: #333;
}
.auto-content {
max-width: 1200px;
margin: 0 auto;
}
.upload-status {
margin-bottom: 20px;
}
.current-file {
margin-bottom: 20px;
}
.upload-list {
background: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
.upload-list h3 {
margin: 0 0 20px 0;
font-size: 18px;
color: #333;
border-bottom: 2px solid #409eff;
padding-bottom: 10px;
}
</style>

@ -0,0 +1,147 @@
<template>
<div class="mode-select-container">
<div class="mode-select-card">
<h2 class="title">文件上传</h2>
<p class="subtitle">请选择操作模式</p>
<div class="mode-buttons">
<el-button type="primary" class="mode-btn" @click="selectMode('auto')">
<i class="el-icon-cpu"></i>
<span>自动模式</span>
</el-button>
<el-button type="success" class="mode-btn" @click="selectMode('manual')">
<i class="el-icon-edit"></i>
<span>手动模式</span>
</el-button>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ModeSelect",
data() {
return {
configData: null,
isWatching: false,
};
},
async mounted() {
//
try {
this.configData = await window.api.getConfig();
// 🔥
if (this.configData && this.configData.device && this.configData.device.searchMode === "auto") {
console.log("配置检测:自动检索模式,直接启动");
await this.selectMode('auto');
return; //
}
//
if (this.configData && this.configData.device && this.configData.device.searchMode === "manual") {
console.log("配置检测:手动检索模式,跳转到手动页面");
// this.$router.replace("/manual");
return;
}
//
window.api.onFileChanged((data) => {
console.log("收到文件变化通知:", data);
this.handleFileChanged(data);
});
} catch (err) {
console.error("读取配置失败:", err);
}
},
beforeDestroy() {
//
if (this.isWatching) {
window.api.stopWatchFolder();
}
},
methods: {
async selectMode(mode) {
try {
//
if (this.configData && this.configData.device) {
this.configData.device.searchMode = mode;
await window.api.updateConfig(this.configData);
console.log(`已保存模式配置: ${mode}`);
}
if (mode === "auto") {
console.log("选择自动模式");
// AutoMode.vue
this.$router.replace("/auto");
} else {
// -
this.$router.push("/manual");
}
} catch (err) {
console.error("保存配置失败:", err);
}
},
},
};
</script>
<style scoped>
.mode-select-container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.mode-select-card {
background: white;
padding: 60px 80px;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
text-align: center;
}
.title {
margin: 0 0 15px 0;
font-size: 32px;
color: #333;
font-weight: 600;
}
.subtitle {
margin: 0 0 40px 0;
font-size: 16px;
color: #666;
}
.mode-buttons {
display: flex;
gap: 30px;
justify-content: center;
}
.mode-btn {
width: 160px;
height: 160px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 16px;
border-radius: 12px;
transition: all 0.3s ease;
}
.mode-btn i {
font-size: 48px;
margin-bottom: 15px;
}
.mode-btn:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
</style>

@ -51,6 +51,11 @@
label-width="150px" label-width="150px"
style="margin-top: 20px" style="margin-top: 20px"
> >
<el-col :span="12">
<el-form-item label="token">
<el-input size="mini" v-model="device.username"></el-input>
</el-form-item>
</el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="设备编号"> <el-form-item label="设备编号">
<el-input size="mini" v-model="device.code"></el-input> <el-input size="mini" v-model="device.code"></el-input>
@ -90,6 +95,15 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24">
<el-form-item label="检索模式">
<!-- "auto" 自动检索 "manual" 手动检索 -->
<el-radio-group v-model="device.searchMode">
<el-radio label="auto">自动模式</el-radio>
<el-radio label="manual">手动模式</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<!-- <el-col :span="12"> <!-- <el-col :span="12">
<el-form-item label="文件未上传目录"> <el-form-item label="文件未上传目录">
<el-input size="mini" disabled v-model="device.no_report_path"></el-input> <el-input size="mini" disabled v-model="device.no_report_path"></el-input>
@ -107,6 +121,7 @@ export default {
return { return {
loading: false, loading: false,
device: { device: {
username:'',
code: "0P0123", code: "0P0123",
codeType: "ER-HUIN", // codeType: "ER-HUIN", //
reconnect_time: "10", reconnect_time: "10",
@ -114,6 +129,7 @@ export default {
filePathDisc: "C", filePathDisc: "C",
file_path: "检索目录", file_path: "检索目录",
no_report_path: "未上报目录", no_report_path: "未上报目录",
searchMode: "auto",
}, },
mqttInfo: { mqttInfo: {
address: "tcp://127.0.0.1:1883/", address: "tcp://127.0.0.1:1883/",
@ -132,25 +148,23 @@ export default {
async init() { async init() {
this.configData = await window.api.getConfig(); this.configData = await window.api.getConfig();
if (this.configData) { if (this.configData) {
this.device = this.configData.device; // device
const tmpData = {}; if (this.configData.device) {
Object.keys(this.device).forEach((key) => { Object.keys(this.device).forEach((key) => {
if (this.configData.device.hasOwnProperty(key)) { if (this.configData.device.hasOwnProperty(key)) {
tmpData[key] = this.configData.device[key]; this.device[key] = this.configData.device[key];
} }
}); });
// }
Object.assign(this.device, tmpData);
this.mqttInfo = this.configData.MQTT; // MQTT
const tmpDatas = {}; if (this.configData.MQTT) {
Object.keys(this.mqttInfo).forEach((key) => { Object.keys(this.mqttInfo).forEach((key) => {
if (this.configData.MQTT.hasOwnProperty(key)) { if (this.configData.MQTT.hasOwnProperty(key)) {
tmpDatas[key] = this.configData.MQTT[key]; this.mqttInfo[key] = this.configData.MQTT[key];
} }
}); });
// }
Object.assign(this.mqttInfo, tmpDatas);
} }
}, },
goBack() { goBack() {
@ -162,15 +176,28 @@ export default {
MQTT: this.mqttInfo, MQTT: this.mqttInfo,
device: this.device, device: this.device,
}; };
console.log('提交前的配置信息:', JSON.stringify(configInfo, null, 2));
console.log('device:', this.device);
console.log('mqttInfo:', this.mqttInfo);
this.loading = true; this.loading = true;
window.api.updateConfig(configInfo); window.api.updateConfig(configInfo);
setTimeout(() => { setTimeout(() => {
this.loading = false; this.loading = false;
this.$message({ this.$message({
message: "配置成功", message: "配置成功",
type: "success", type: "success",
}); });
}, 1000);
// 🔥
if (this.device.searchMode === "auto") {
console.log("配置为自动模式,返回主页并启动自动监控");
this.$router.push("/");
} else {
//
this.$router.push("/");
}
}, 500);
}, },
}, },
mounted() { mounted() {

@ -1,6 +1,9 @@
<template> <template>
<div class="hello" v-loading="tableLoading"> <div class="hello" v-loading="tableLoading">
<div> <div class="header-bar">
<el-button type="text" @click="goBack()">
<i class="el-icon-arrow-left"></i> 返回选择模式
</el-button>
<el-button type="text" @click="configPage()">配置文件</el-button> <el-button type="text" @click="configPage()">配置文件</el-button>
</div> </div>
<div style="height: 50px; margin-top: 20px"> <div style="height: 50px; margin-top: 20px">
@ -61,6 +64,13 @@
align="center" align="center"
> >
</el-table-column> </el-table-column>
<el-table-column
prop="fileName"
label="文件名"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column <el-table-column
prop="deviceId" prop="deviceId"
label="设备编号" label="设备编号"
@ -168,6 +178,9 @@ export default {
}, },
methods: { methods: {
goBack() {
this.$router.push("/");
},
// //
handleClick() { handleClick() {
this.fullscreenLoading = false; this.fullscreenLoading = false;
@ -259,7 +272,7 @@ export default {
try { try {
// AbortController // AbortController
const controller = new AbortController(); const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000); // 3 const timeoutId = setTimeout(() => controller.abort(), 5000); // 5
// 1. BufferFile<input type="file">File // 1. BufferFile<input type="file">File
const fileObj = new File([file.fileBuffer], file.fileName, { const fileObj = new File([file.fileBuffer], file.fileName, {
@ -269,6 +282,7 @@ export default {
// 2. FormData // 2. FormData
const formData = new FormData(); const formData = new FormData();
formData.append("file", fileObj); formData.append("file", fileObj);
formData.append("token", this.configData.device.username);
formData.append("deviceId", this.configData.device.code); formData.append("deviceId", this.configData.device.code);
formData.append("orderNumber", id); formData.append("orderNumber", id);
formData.append("deviceModel", this.configData.device.codeType); formData.append("deviceModel", this.configData.device.codeType);
@ -293,6 +307,7 @@ export default {
deviceId: this.configData.device.code, deviceId: this.configData.device.code,
orderNumber: id, orderNumber: id,
deviceModel: this.configData.device.codeType, deviceModel: this.configData.device.codeType,
fileName: file.fileName,
analysisDate: JSON.stringify(result.data), analysisDate: JSON.stringify(result.data),
type: this.activeName, type: this.activeName,
date: this.getCurrentDateTime(), date: this.getCurrentDateTime(),
@ -465,6 +480,11 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only --> <!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped> <style scoped>
.header-bar {
display: flex;
justify-content: space-between;
align-items: center;
}
.mark { .mark {
width: 100%; width: 100%;
height: 100%; height: 100%;

Loading…
Cancel
Save