lyc-dev #44
|
@ -7,6 +7,8 @@ VITE_APP_ENV = 'development'
|
||||||
# AIx融合数字管理系统/开发环境
|
# AIx融合数字管理系统/开发环境
|
||||||
VITE_APP_BASE_API = '/dev-api'
|
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_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||||
|
|
||||||
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
|
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
|
|
@ -7,6 +7,8 @@ VITE_APP_ENV = 'production'
|
||||||
# AIx融合数字管理系统/生产环境
|
# AIx融合数字管理系统/生产环境
|
||||||
VITE_APP_BASE_API = 'http://192.168.2.52:7863'
|
VITE_APP_BASE_API = 'http://192.168.2.52:7863'
|
||||||
|
|
||||||
|
VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868'
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
|
|
148
src/main/file.js
148
src/main/file.js
|
@ -1,19 +1,24 @@
|
||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
|
||||||
const fs = require('fs')
|
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_UPLOAD_API + '/smarttalk/file/upload'
|
||||||
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 +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) => {
|
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 +121,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 +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) {
|
function copyFile(source, destination, callback) {
|
||||||
let path = appRootFilePath + destination
|
let path = appRootFilePath + destination
|
||||||
createFolder('selfFile').then(() => {
|
createFolder('selfFile').then(() => {
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
timer: null,
|
timer: null,
|
||||||
uploadDatas: {},
|
uploadDatas: {},
|
||||||
uploadUrl: import.meta.env.VITE_APP_BASE_API + '/smarttalk/file/upload',
|
uploadUrl: import.meta.env.VITE_APP_UPLOAD_API + '/smarttalk/file/upload',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: 'Bearer ' + getToken()
|
Authorization: 'Bearer ' + getToken()
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -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'"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
@change="handleCheckAllChange"
|
@change="handleCheckAllChange"
|
||||||
/> 已选{{ choose.length }}个
|
/> 已选{{ 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> |
|
<el-button @click="deleteFile">删除</el-button> |
|
||||||
<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,26 @@ 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 }
|
||||||
|
})
|
||||||
|
exportFile(ids).then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,7 +79,7 @@ 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'
|
||||||
const { ipcRenderer } = window.electron || {}
|
const { ipcRenderer } = window.electron || {}
|
||||||
export default {
|
export default {
|
||||||
|
@ -131,6 +133,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) => {
|
||||||
|
this.currentFileList.unshift(res.resData)
|
||||||
|
})
|
||||||
|
},
|
||||||
onMoveSingleFile(item) {
|
onMoveSingleFile(item) {
|
||||||
this.moveFile = [item]
|
this.moveFile = [item]
|
||||||
this.isMoveDialogOpen = true
|
this.isMoveDialogOpen = true
|
||||||
|
@ -142,7 +149,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 +217,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)
|
||||||
|
|
Loading…
Reference in New Issue