diff --git a/.env.development b/.env.development index 6da57b4..c581825 100644 --- a/.env.development +++ b/.env.development @@ -7,6 +7,8 @@ VITE_APP_ENV = 'development' # AIx融合数字管理系统/开发环境 VITE_APP_BASE_API = '/dev-api' +VITE_APP_UPLOAD_API = 'http://192.168.2.52:7863' + VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/' -VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/' \ No newline at end of file +VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/' diff --git a/.env.production b/.env.production index 5929a05..51d777c 100644 --- a/.env.production +++ b/.env.production @@ -7,9 +7,11 @@ VITE_APP_ENV = 'production' # AIx融合数字管理系统/生产环境 VITE_APP_BASE_API = 'http://192.168.2.52:7863' +VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868' + # 是否在打包时开启压缩,支持 gzip 和 brotli VITE_BUILD_COMPRESS = gzip VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/' -VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/' \ No newline at end of file +VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/' diff --git a/src/main/file.js b/src/main/file.js index eecd08c..7580c8f 100644 --- a/src/main/file.js +++ b/src/main/file.js @@ -1,19 +1,24 @@ +import CryptoJS from 'crypto-js' + 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 manager = new ElectronDownloadManager() export default async function ({ app, shell, BrowserWindow, ipcMain }) { const userDataPath = app.getPath('userData') const appRootFilePath = userDataPath + '\\selfFile\\' + const appTempFilePath = userDataPath + '\\tempFile\\' ipcMain.on('is-have-local-file', (e, fileNewName) => { let filePath = appRootFilePath + fileNewName fs.access(filePath, fs.constants.F_OK, (err) => { if (err) { - e.reply('is-have-local-file-reply'+fileNewName, false) + e.reply('is-have-local-file-reply' + fileNewName, false) return } - e.reply('is-have-local-file-reply'+fileNewName, true) + e.reply('is-have-local-file-reply' + fileNewName, true) }) }) //默认浏览器打开url @@ -35,6 +40,69 @@ 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) + } + fileReader.readAsArrayBuffer(file) + }) + } + + 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) + } + // 配置上传的请求 + const config = { + headers: { + 'Content-Type': 'multipart/form-data', // 或者其他适合上传文件的Content-Type + Authorization: 'Bearer ' + cookie + } + } + 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) + }) + }) + }) + }) + //获取应用文件目录 ipcMain.on('get-root-file-path', (e) => { e.reply('get-root-file-path-reply', appRootFilePath) @@ -53,23 +121,22 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { onDownloadStarted: async ({ id, item, webContents }) => { // Do something with the download id }, - onDownloadProgress: async ({ id, item, percentCompleted }) => { - }, + onDownloadProgress: async ({ id, item, percentCompleted }) => {}, onDownloadCompleted: async ({ id, item }) => { console.log('完成') - e.reply('download-file-default'+fileName,true) + e.reply('download-file-default' + fileName, true) }, onDownloadCancelled: async () => { console.log('取消') - e.reply('download-file-default'+fileName,false) + e.reply('download-file-default' + fileName, false) }, onDownloadInterrupted: async () => { console.log('中断') - e.reply('download-file-default'+fileName,false) + e.reply('download-file-default' + fileName, false) }, onError: (err, data) => { console.log(err.toString()) - e.reply('download-file-default'+fileName,false) + e.reply('download-file-default' + fileName, false) } } }) @@ -124,6 +191,71 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) { }) }) + function exportFile(list, callback) { + let win = BrowserWindow.getFocusedWindow() + //通过扩展名识别文件类型 + let filePath = null //用户选择存放文件的路径 + //1- 弹出另存为弹框,用于获取保存路径 + dialog + .showOpenDialog(win, { + properties: ['openDirectory'] + }) + .then(async (result) => { + if (result.filePaths[0]) { + filePath = result.filePaths[0] + let res = [] + for (let i = 0; i < list.length; i++) { + let item = list[i] + let source = appRootFilePath + item.id + let destination = filePath + '/' + item.name + await copyRelFile(source, filterCopyFile(destination), (error, path) => { + res.push({ error, path }) + }) + } + callback(res) + } + }) + .catch(() => { + console.log('另存为--catch') + }) + } + + function isHaveFile(path) { + return fs.existsSync(path) + } + + function filterCopyFile(path, index = 0) { + if (isHaveFile(path) === true) { + index++ + path = path.replaceAll('.', `(${index}).`) + return filterCopyFile(path, index) + } else { + return path + } + } + + function copyRelFile(source, destination, callback) { + return new Promise((resolve, reject) => { + const readStream = fs.createReadStream(source) + const writeStream = fs.createWriteStream(destination) + + readStream.on('error', (error) => { + reject() + callback(error, null) + }) + writeStream.on('error', (error) => { + reject() + callback(error, null) + }) + writeStream.on('close', () => { + console.log('关闭写入流') + callback(null, destination) + resolve() + }) + readStream.pipe(writeStream) + }) + } + function copyFile(source, destination, callback) { let path = appRootFilePath + destination createFolder('selfFile').then(() => { diff --git a/src/renderer/src/layout/components/Uploader.vue b/src/renderer/src/layout/components/Uploader.vue index 1dc7d9d..e094b35 100644 --- a/src/renderer/src/layout/components/Uploader.vue +++ b/src/renderer/src/layout/components/Uploader.vue @@ -69,7 +69,7 @@ export default { return { timer: null, uploadDatas: {}, - uploadUrl: import.meta.env.VITE_APP_BASE_API + '/smarttalk/file/upload', + uploadUrl: import.meta.env.VITE_APP_UPLOAD_API + '/smarttalk/file/upload', headers: { Authorization: 'Bearer ' + getToken() }, diff --git a/src/renderer/src/utils/talkFile/index.js b/src/renderer/src/utils/talkFile/index.js index 23495ce..eaea024 100644 --- a/src/renderer/src/utils/talkFile/index.js +++ b/src/renderer/src/utils/talkFile/index.js @@ -1,10 +1,10 @@ const { ipcRenderer } = window.electron || {} -export const isHaveLocalFile = async (fileNewName)=>{ - return new Promise((resolve, reject)=>{ - ipcRenderer.send('is-have-local-file', fileNewName); - ipcRenderer.once('is-have-local-file-reply'+fileNewName,(e, isHave)=>{ - resolve(isHave); +export const isHaveLocalFile = async (fileNewName) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('is-have-local-file', fileNewName) + ipcRenderer.once('is-have-local-file-reply' + fileNewName, (e, isHave) => { + resolve(isHave) }) }) } @@ -18,3 +18,24 @@ export const parseCataByNode = (node) => { return [node.id] } } + +export const exportFile = async (list) => { + return new Promise((resolve, reject) => { + ipcRenderer.send('export-file-default', list) + ipcRenderer.once('export-file-default-reply', (e, res) => { + resolve(res) + }) + }) +} + +export const creatPPT = (name, uploadData) => { + JSON.parse(JSON.stringify(uploadData)) + return new Promise((resolve, reject) => { + let cookie = localStorage.getItem('Admin-Token'); + console.log(cookie) + ipcRenderer.send('creat-file-default', { name, uploadData:JSON.parse(JSON.stringify(uploadData)), cookie }) + ipcRenderer.once('creat-file-default-reply', (e, res) => { + resolve(res) + }) + }) +} diff --git a/src/renderer/src/views/prepare/container/file-list-item.vue b/src/renderer/src/views/prepare/container/file-list-item.vue index b87212a..55c4124 100644 --- a/src/renderer/src/views/prepare/container/file-list-item.vue +++ b/src/renderer/src/views/prepare/container/file-list-item.vue @@ -4,11 +4,11 @@ -
+
{{ item.fileShowName }}
-
+
 已选{{ choose.length }}个
- 导出 + 导出 移动 删除  | 取消 @@ -15,7 +15,8 @@