基础文件上传核心开发

This commit is contained in:
朱浩 2024-07-18 15:17:15 +08:00
parent 6d394eb94e
commit a30d2945a0
5 changed files with 203 additions and 21 deletions

View File

@ -2,18 +2,22 @@ const fs = require('fs')
const path = require('path') const path = require('path')
import { ElectronDownloadManager } from 'electron-dl-manager' import { ElectronDownloadManager } from 'electron-dl-manager'
import { dialog } from 'electron' import { dialog } from 'electron'
import axios from 'axios'
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/smarttalk/file/upload'
console.log(uploadUrl)
const manager = new ElectronDownloadManager() const manager = new ElectronDownloadManager()
export default async function ({ app, shell, BrowserWindow, ipcMain }) { export default async function ({ app, shell, BrowserWindow, ipcMain }) {
const userDataPath = app.getPath('userData') const userDataPath = app.getPath('userData')
const appRootFilePath = userDataPath + '\\selfFile\\' const appRootFilePath = userDataPath + '\\selfFile\\'
const appTempFilePath = userDataPath + '\\tempFile\\'
ipcMain.on('is-have-local-file', (e, fileNewName) => { ipcMain.on('is-have-local-file', (e, fileNewName) => {
let filePath = appRootFilePath + fileNewName let filePath = appRootFilePath + fileNewName
fs.access(filePath, fs.constants.F_OK, (err) => { fs.access(filePath, fs.constants.F_OK, (err) => {
if (err) { if (err) {
e.reply('is-have-local-file-reply'+fileNewName, false) e.reply('is-have-local-file-reply' + fileNewName, false)
return return
} }
e.reply('is-have-local-file-reply'+fileNewName, true) e.reply('is-have-local-file-reply' + fileNewName, true)
}) })
}) })
//默认浏览器打开url //默认浏览器打开url
@ -35,6 +39,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)
})
})
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)
}
console.log(cookie)
// 配置上传的请求
// const uploadUrl = 'http://192.168.2.52:7863/smarttalk/file/upload' // 你的上传服务URL
const config = {
headers: {
'Content-Type': 'application/octet-stream', // 或者其他适合上传文件的Content-Type
Authorization: 'Bearer ' + cookie
}
}
// 使用axios上传文件
axios
.post(uploadUrl, { ...uploadData, data }, config)
.then((response) => {
console.log('File uploaded successfully:', response.data)
})
.catch((error) => {
console.error('Error uploading file:', error)
})
})
/*fs.readFile(path, (err, data) => {
if (err) {
return console.error(err)
}
let file = new File([data], '111.pptx', {
type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
})
const headers = {
'Content-Type': 'multipart/form-data',
Authorization: 'Bearer ' + cookie
}
axios
.post(
import.meta.env.VITE_APP_BASE_API + '/smarttalk/file/upload',
{
file
},
{ headers }
)
.then((res) => {
console.log(res)
})
// e.reply('creat-file-default-reply', res)
})*/
})
})
//获取应用文件目录 //获取应用文件目录
ipcMain.on('get-root-file-path', (e) => { ipcMain.on('get-root-file-path', (e) => {
e.reply('get-root-file-path-reply', appRootFilePath) e.reply('get-root-file-path-reply', appRootFilePath)
@ -53,23 +120,22 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
onDownloadStarted: async ({ id, item, webContents }) => { onDownloadStarted: async ({ id, item, webContents }) => {
// Do something with the download id // Do something with the download id
}, },
onDownloadProgress: async ({ id, item, percentCompleted }) => { onDownloadProgress: async ({ id, item, percentCompleted }) => {},
},
onDownloadCompleted: async ({ id, item }) => { onDownloadCompleted: async ({ id, item }) => {
console.log('完成') console.log('完成')
e.reply('download-file-default'+fileName,true) e.reply('download-file-default' + fileName, true)
}, },
onDownloadCancelled: async () => { onDownloadCancelled: async () => {
console.log('取消') console.log('取消')
e.reply('download-file-default'+fileName,false) e.reply('download-file-default' + fileName, false)
}, },
onDownloadInterrupted: async () => { onDownloadInterrupted: async () => {
console.log('中断') console.log('中断')
e.reply('download-file-default'+fileName,false) e.reply('download-file-default' + fileName, false)
}, },
onError: (err, data) => { onError: (err, data) => {
console.log(err.toString()) console.log(err.toString())
e.reply('download-file-default'+fileName,false) e.reply('download-file-default' + fileName, false)
} }
} }
}) })
@ -124,6 +190,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) { function copyFile(source, destination, callback) {
let path = appRootFilePath + destination let path = appRootFilePath + destination
createFolder('selfFile').then(() => { createFolder('selfFile').then(() => {

View File

@ -1,10 +1,10 @@
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
export const isHaveLocalFile = async (fileNewName)=>{ export const isHaveLocalFile = async (fileNewName) => {
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject) => {
ipcRenderer.send('is-have-local-file', fileNewName); ipcRenderer.send('is-have-local-file', fileNewName)
ipcRenderer.once('is-have-local-file-reply'+fileNewName,(e, isHave)=>{ ipcRenderer.once('is-have-local-file-reply' + fileNewName, (e, isHave) => {
resolve(isHave); resolve(isHave)
}) })
}) })
} }
@ -18,3 +18,24 @@ export const parseCataByNode = (node) => {
return [node.id] 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)
})
})
}

View File

@ -4,11 +4,11 @@
<slot name="default"></slot> <slot name="default"></slot>
<FileImage :size="50" :file-name="item.fileShowName" @click="openFileWin(item)" /> <FileImage :size="50" :file-name="item.fileShowName" @click="openFileWin(item)" />
</div> </div>
<div class="prepare-body-main-item-info"> <div class="prepare-body-main-item-info" @click="openFileWin(item)">
<div class="prepare-item-info-title" :title="item.fileShowName"> <div class="prepare-item-info-title" :title="item.fileShowName">
{{ item.fileShowName }} {{ item.fileShowName }}
</div> </div>
<div class="prepare-item-info-message" @click="openFileWin(item)"> <div class="prepare-item-info-message">
<div style="width: 60px"> <div style="width: 60px">
<el-icon <el-icon
v-loading="item.async === 'on'" v-loading="item.async === 'on'"

View File

@ -7,7 +7,7 @@
@change="handleCheckAllChange" @change="handleCheckAllChange"
/>&nbsp;{{ choose.length }} />&nbsp;{{ choose.length }}
</div> </div>
<el-button>导出</el-button> <el-button @click="exportFile">导出</el-button>
<el-button @click="moveFile">移动</el-button> <el-button @click="moveFile">移动</el-button>
<el-button @click="deleteFile">删除</el-button>&nbsp;&nbsp;| <el-button @click="deleteFile">删除</el-button>&nbsp;&nbsp;|
<el-button @click="cancel">取消</el-button> <el-button @click="cancel">取消</el-button>
@ -15,7 +15,8 @@
</template> </template>
<script> <script>
import { deleteSmarttalkBatch } from '@/api/file' import { deleteSmarttalkBatch } from '@/api/file'
import { ElMessage, ElMessageBox } from 'element-plus'
import { exportFile } from '@/utils/talkFile'
export default { export default {
name: 'FileOperBatch', name: 'FileOperBatch',
props: { props: {
@ -62,6 +63,27 @@ export default {
}, },
moveFile() { moveFile() {
this.$emit('click-move') this.$emit('click-move')
},
exportFile() {
let isPass = 0
this.choose.filter((item) => {
if (item.async !== true) {
ElMessage({
type: 'info',
message: `请先同步${item.fileShowName}`
})
isPass++
}
})
if (isPass === 0) {
let ids = this.choose.map((item) => {
return { id: item.fileNewName, name: item.fileShowName }
})
console.log(ids)
exportFile(ids).then((res) => {
console.log(res)
})
}
} }
} }
} }

View File

@ -30,7 +30,9 @@
</div> </div>
<div style="display: flex"> <div style="display: flex">
<el-button @click="isDialogOpen = true">上传资料</el-button> <el-button @click="isDialogOpen = true">上传资料</el-button>
<el-button type="primary" style="margin-left: 10px">新建课件</el-button> <el-button type="primary" style="margin-left: 10px" @click="createFile"
>新建课件</el-button
>
</div> </div>
</div> </div>
<el-checkbox-group <el-checkbox-group
@ -77,8 +79,9 @@ import FileListItem from '@/views/prepare/container/file-list-item.vue'
import { getSmarttalkPage, moveSmarttalk } from '@/api/file' import { getSmarttalkPage, moveSmarttalk } from '@/api/file'
import { toTimeText } from '@/utils/date' import { toTimeText } from '@/utils/date'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { isHaveLocalFile, parseCataByNode } from '@/utils/talkFile' import { isHaveLocalFile, parseCataByNode, creatPPT } from '@/utils/talkFile'
import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue' import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue'
import fs from 'fs'
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
export default { export default {
name: 'Prepare', name: 'Prepare',
@ -131,6 +134,11 @@ export default {
// let filePath = window.rootTalkFilePath + item.fileNewName // let filePath = window.rootTalkFilePath + item.fileNewName
}, },
methods: { methods: {
createFile() {
creatPPT('新建ppt文档.pptx',this.uploadData).then((res) => {
console.log(res)
})
},
onMoveSingleFile(item) { onMoveSingleFile(item) {
this.moveFile = [item] this.moveFile = [item]
this.isMoveDialogOpen = true this.isMoveDialogOpen = true
@ -142,7 +150,7 @@ export default {
clickDelete(res, ids) { clickDelete(res, ids) {
if (res.data === true) { if (res.data === true) {
ids.filter((id) => { ids.filter((id) => {
let index = this.currentFileList.findIndex(item=>{ let index = this.currentFileList.findIndex((item) => {
return item.id === id return item.id === id
}) })
this.currentFileList.splice(index, 1) this.currentFileList.splice(index, 1)
@ -210,7 +218,7 @@ export default {
moveSmarttalk(params).then((res) => { moveSmarttalk(params).then((res) => {
if (res.data === true) { if (res.data === true) {
ids.filter((id) => { ids.filter((id) => {
let index = this.currentFileList.findIndex((item)=>{ let index = this.currentFileList.findIndex((item) => {
return item.id === id return item.id === id
}) })
this.currentFileList.splice(index, 1) this.currentFileList.splice(index, 1)