From e1fc883870de60fa0aa1586355616a1d9dcef598 Mon Sep 17 00:00:00 2001 From: zhuhao <979263092@qq.com> Date: Tue, 23 Jul 2024 13:43:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8C=E6=9C=9F=EF=BC=9A=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/main/file.js | 220 ++++++++++++++---- .../src/layout/components/Uploader.vue | 14 +- src/renderer/src/utils/talkFile/index.js | 18 +- .../prepare/container/file-list-item.vue | 32 ++- src/renderer/src/views/prepare/index.vue | 52 +++-- 6 files changed, 262 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index 7ae26ab..99c4ada 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "jsencrypt": "^3.3.2", "pinia": "^2.1.7", "pinia-plugin-persistedstate": "^3.2.1", + "spark-md5": "^3.0.2", "vue-cropper": "^1.0.3", "vue-router": "^4.4.0" }, diff --git a/src/main/file.js b/src/main/file.js index 7580c8f..920ecec 100644 --- a/src/main/file.js +++ b/src/main/file.js @@ -1,16 +1,105 @@ -import CryptoJS from 'crypto-js' - +import SparkMD5 from 'spark-md5' const fs = require('fs') const path = require('path') import { ElectronDownloadManager } from 'electron-dl-manager' import { dialog } from 'electron' import axios from 'axios' const uploadUrl = import.meta.env.VITE_APP_UPLOAD_API + '/smarttalk/file/upload' +const asyncUploadUrl = import.meta.env.VITE_APP_UPLOAD_API + '/smarttalk/file/asyncUpload' const manager = new ElectronDownloadManager() export default async function ({ app, shell, BrowserWindow, ipcMain }) { const userDataPath = app.getPath('userData') const appRootFilePath = userDataPath + '\\selfFile\\' const appTempFilePath = userDataPath + '\\tempFile\\' + let Spark = new SparkMD5.ArrayBuffer() + + ipcMain.on('upload-file-change', (e, { id, fileNewName, cookie, fileType }) => { + let filePath = appRootFilePath + fileNewName + //执行更新,上传文件 + let formData = new FormData() + formData.append('id', id) + uploadFileByFS({ + url: asyncUploadUrl, + path: filePath, + name: fileNewName, + cookie, + fileType, + formData, + success: (response) => { + e.reply('upload-file-change-success' + fileNewName, { + data: response.data, + md5: formData.md5 + }) + }, + error: (err) => { + console.error('Error uploading file:', err) + } + }) + }) + + /*监听文件改变,如果有改变则返回触发*/ + ipcMain.on('listen-file-change', (e, { id, fileNewName, md5, cookie, fileType }) => { + let filePath = appRootFilePath + fileNewName + let uploadId = null + let isOn = false + setInterval(() => { + getFileMD5(filePath).then((md5New) => { + if (md5New !== md5) { + md5 = md5New + if (uploadId) { + clearTimeout(uploadId) + } + if (isOn === false) { + e.reply('listen-file-change-on' + fileNewName) + isOn = true + } + //倒数十秒提交更改,十秒之内有继续修改则重置倒数 + uploadId = setTimeout(() => { + //执行更新,上传文件 + let formData = new FormData() + formData.append('id', id) + uploadFileByFS({ + url: asyncUploadUrl, + path: filePath, + name: fileNewName, + cookie, + fileType, + formData, + success: (response) => { + e.reply('listen-file-change-success' + fileNewName, { + data: response.data, + md5: formData.md5 + }) + clearTimeout(uploadId) + isOn = false + }, + error: (err) => { + console.error('Error uploading file:', err) + } + }) + }, 5000) + } + }) + }, 1000) + }) + + function getFileMD5(path) { + return new Promise((resolve, reject) => { + fs.readFile(path, (err, dataFile) => { + if (err) { + reject(err) + return console.error(err) + } + Spark.append(dataFile) + let md5 = Spark.end() + resolve(md5) + }) + }) + } + + /* + * 判断是否有本地文件 + * */ ipcMain.on('is-have-local-file', (e, fileNewName) => { let filePath = appRootFilePath + fileNewName fs.access(filePath, fs.constants.F_OK, (err) => { @@ -21,10 +110,38 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { e.reply('is-have-local-file-reply' + fileNewName, true) }) }) + + /* + * 判断是需要同步本地文件 + * */ + ipcMain.on('is-async-local-file', (e, { fileNewName, lastModifyTime, md5 }) => { + let filePath = appRootFilePath + fileNewName + fs.access(filePath, fs.constants.F_OK, (err) => { + if (err) { + e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'down' }) + return + } + getFileMD5(filePath).then((localMd5) => { + if (localMd5 === md5) { + e.reply('is-async-local-file-reply' + fileNewName, { isAsync: false, type: '' }) + } else { + const stats = fs.statSync(filePath) + //如果线上时间大于线下时间,就需要从线上下载,否则则需要上传 + if (lastModifyTime > stats.mtime.getTime()) { + e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'down' }) + } else if (lastModifyTime < stats.mtime.getTime()) { + e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'upload' }) + } + } + }) + }) + }) + //默认浏览器打开url ipcMain.on('open-url-browser', (e, url) => { shell.openPath(url) }) + //使用默认应用打开本地文件 ipcMain.on('open-path-app', (e, destination) => { let path = appRootFilePath + destination @@ -40,65 +157,72 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { }) }) - //复制文件 + //导出文件 ipcMain.on('export-file-default', (e, list) => { exportFile(list, (res) => { e.reply('export-file-default-reply', res) }) }) - function getFileMD5(file) { - return new Promise((resolve, reject) => { - const fileReader = new FileReader() - fileReader.onload = (e) => { - const buffer = e.target.result - let md5 = CryptoJS.MD5(buffer).toString() - resolve(md5) + function uploadFileByFS({ url, path, name, cookie, fileType, formData, success, error }) { + fs.readFile(path, (err, data) => { + if (err) { + return console.error(err) } - fileReader.readAsArrayBuffer(file) + // 配置上传的请求 + const config = { + headers: { + 'Content-Type': 'multipart/form-data', // 或者其他适合上传文件的Content-Type + Authorization: 'Bearer ' + cookie + } + } + Spark.append(data) + let md5 = Spark.end() + // 使用axios上传文件 + let file = new File([data], name, { + type: fileType + }) + formData.append('file', file) + formData.append('md5', md5) + axios + .post(url, formData, config) + .then((response) => { + success(response) + }) + .catch((errorMsg) => { + error(errorMsg) + }) }) } + /*创建新的ppt文件*/ ipcMain.on('creat-file-default', (e, { name, uploadData, cookie }) => { createFolder('tempFile').then(() => { let path = appTempFilePath + name fs.writeFileSync(path, '', 'utf-8') - // 读取文件 - fs.readFile(path, (err, data) => { - if (err) { - return console.error(err) + let fileType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + let formData = new FormData() + for (let key in uploadData) { + if (Object.prototype.hasOwnProperty.call(uploadData, key)) { + // 检查是否是对象自身的属性 + formData.append(key, uploadData[key]) } - // 配置上传的请求 - const config = { - headers: { - 'Content-Type': 'multipart/form-data', // 或者其他适合上传文件的Content-Type - Authorization: 'Bearer ' + cookie - } + } + formData.append('fileFlag', '教案') + uploadFileByFS({ + url: uploadUrl, + path, + name, + cookie, + fileType, + formData, + success: (response) => { + e.reply('creat-file-default-reply', response.data) + console.log('File uploaded successfully:', response.data) + }, + error: (err) => { + console.error('Error uploading file:', err) } - let md5 = CryptoJS.MD5(data).toString() - let formData = new FormData() - // 使用axios上传文件 - let file = new File([data], name, { - type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' - }) - formData.append('file', file) - formData.append('md5',md5) - - for (let key in uploadData) { - if (uploadData.hasOwnProperty(key)) { // 检查是否是对象自身的属性 - formData.append(key,uploadData[key]) - } - } - formData.append("fileFlag","教案") - axios - .post(uploadUrl, formData, config) - .then((response) => { - e.reply('creat-file-default-reply', response.data) - console.log('File uploaded successfully:', response.data) - }) - .catch((error) => { - console.error('Error uploading file:', error) - }) }) }) }) @@ -191,6 +315,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { }) }) + /*导出文件*/ function exportFile(list, callback) { let win = BrowserWindow.getFocusedWindow() //通过扩展名识别文件类型 @@ -220,10 +345,12 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { }) } + /*文件是否已经存在*/ function isHaveFile(path) { return fs.existsSync(path) } + /*判断是否已经存在这个名字的文件,如果已经存在则递增导出*/ function filterCopyFile(path, index = 0) { if (isHaveFile(path) === true) { index++ @@ -234,6 +361,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { } } + /*复制文件*/ function copyRelFile(source, destination, callback) { return new Promise((resolve, reject) => { const readStream = fs.createReadStream(source) @@ -256,6 +384,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { }) } + /*复制文件*/ function copyFile(source, destination, callback) { let path = appRootFilePath + destination createFolder('selfFile').then(() => { @@ -276,6 +405,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { }) } + /*创建文件夹*/ function createFolder(folderName) { return new Promise((resolve, reject) => { const folderPath = path.join(userDataPath, folderName) diff --git a/src/renderer/src/layout/components/Uploader.vue b/src/renderer/src/layout/components/Uploader.vue index e094b35..2309338 100644 --- a/src/renderer/src/layout/components/Uploader.vue +++ b/src/renderer/src/layout/components/Uploader.vue @@ -59,7 +59,8 @@