zdg #72
|
@ -1,3 +1,3 @@
|
|||
provider: generic
|
||||
url: https://example.com/auto-updates
|
||||
url: http://localhost:3000/
|
||||
updaterCacheDirName: electron-app-updater
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
appId: com.electron.app
|
||||
productName: AIx
|
||||
directories:
|
||||
buildResources: build
|
||||
files:
|
||||
- '!**/.vscode/*'
|
||||
- '!src/*'
|
||||
- '!electron.vite.config.{js,ts,mjs,cjs}'
|
||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
|
||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
|
||||
asarUnpack:
|
||||
- resources/**
|
||||
win:
|
||||
executableName: AIx
|
||||
icon: resources/logo.ico
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
artifactName: ${name}-${version}-setup.${ext}
|
||||
shortcutName: ${productName}
|
||||
uninstallDisplayName: ${productName}
|
||||
createDesktopShortcut: always
|
||||
mac:
|
||||
entitlementsInherit: build/entitlements.mac.plist
|
||||
extendInfo:
|
||||
- NSCameraUsageDescription: Application requests access to the device's camera.
|
||||
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
|
||||
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
|
||||
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
|
||||
notarize: false
|
||||
dmg:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
linux:
|
||||
target:
|
||||
- AppImage
|
||||
- snap
|
||||
- deb
|
||||
maintainer: electronjs.org
|
||||
category: Utility
|
||||
appImage:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: http://localhost:3000
|
||||
electronDownload:
|
||||
mirror: https://npmmirror.com/mirrors/electron/
|
|
@ -12,6 +12,7 @@ asarUnpack:
|
|||
- resources/**
|
||||
win:
|
||||
executableName: AIx
|
||||
icon: resources/logo.ico
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
|
@ -41,6 +42,6 @@ appImage:
|
|||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: https://example.com/auto-updates
|
||||
url: https://file.ysaix.com:7868/src/assets/smarttalk/
|
||||
electronDownload:
|
||||
mirror: https://npmmirror.com/mirrors/electron/
|
||||
|
|
|
@ -26,12 +26,7 @@ export default defineConfig({
|
|||
// target: 'http://192.168.2.52:7863',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||
},
|
||||
'/profile': {
|
||||
target: 'http://192.168.2.52:7863',
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [vue(), WindiCSS()],
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
"build": "electron-vite build",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"build:unpack": "npm run build && electron-builder --dir",
|
||||
"build:win": "npm run build && electron-builder --win",
|
||||
"build:test": "npm run build && electron-builder --win --config ./electron-builder-test.yml",
|
||||
"build:prod": "npm run build && electron-builder --win --config ./electron-builder.yml",
|
||||
"build:mac": "npm run build && electron-builder --mac",
|
||||
"build:linux": "npm run build && electron-builder --linux"
|
||||
},
|
||||
|
@ -24,6 +25,7 @@
|
|||
"@vueuse/core": "^10.11.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"electron-dl-manager": "^3.0.0",
|
||||
"electron-log": "^5.1.7",
|
||||
"electron-updater": "^6.1.7",
|
||||
"element-plus": "^2.7.6",
|
||||
"fabric": "5.3.0",
|
||||
|
@ -33,6 +35,7 @@
|
|||
"pdfjs-dist": "^4.4.168",
|
||||
"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"
|
||||
},
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 264 KiB |
223
src/main/file.js
223
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,39 @@ 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)
|
||||
//如果线上时间大于线下时间,就需要从线上下载,否则则需要上传
|
||||
let time = new Date(lastModifyTime)
|
||||
if (time > stats.mtime.getTime()) {
|
||||
e.reply('is-async-local-file-reply' + fileNewName, { isAsync: true, type: 'down' })
|
||||
} else if (time < 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 +158,74 @@ 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
|
||||
})
|
||||
const stats = fs.statSync(path)
|
||||
formData.append('file', file)
|
||||
formData.append('md5', md5)
|
||||
formData.append('lastModifyTime', stats.mtime.toLocaleString())
|
||||
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 +318,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
})
|
||||
|
||||
/*导出文件*/
|
||||
function exportFile(list, callback) {
|
||||
let win = BrowserWindow.getFocusedWindow()
|
||||
//通过扩展名识别文件类型
|
||||
|
@ -220,10 +348,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 +364,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 +387,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
}
|
||||
|
||||
/*复制文件*/
|
||||
function copyFile(source, destination, callback) {
|
||||
let path = appRootFilePath + destination
|
||||
createFolder('selfFile').then(() => {
|
||||
|
@ -276,6 +408,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
|||
})
|
||||
}
|
||||
|
||||
/*创建文件夹*/
|
||||
function createFolder(folderName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const folderPath = path.join(userDataPath, folderName)
|
||||
|
|
|
@ -4,11 +4,10 @@ import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
|||
import icon from '../../resources/icon.png?asset'
|
||||
import File from './file'
|
||||
import Tool from './tool'
|
||||
import updateInit from './update'
|
||||
|
||||
File({ app, shell, BrowserWindow, ipcMain })
|
||||
|
||||
|
||||
|
||||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
|
||||
let mainWindow, loginWindow
|
||||
|
||||
//登录窗口
|
||||
|
@ -27,13 +26,21 @@ function createLoginWindow() {
|
|||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
const loginURL = is.dev ? `http://localhost:5173/#/login` : `file://${__dirname}/index.html/login`
|
||||
loginWindow.loadURL(loginURL)
|
||||
// handleUpdate(loginWindow,ipcMain)
|
||||
// const loginURL = is.dev ? `http://localhost:5173/#/login` : `file://${__dirname}/index.html/#/login`
|
||||
// loginWindow.loadURL(loginURL)
|
||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||
loginWindow.loadURL('http://localhost:5173/#/login')
|
||||
} else {
|
||||
loginWindow.loadFile(join(__dirname, '../renderer/index.html'), {hash: 'login'})
|
||||
updateInit(loginWindow)
|
||||
}
|
||||
|
||||
// loginWindow.webContents.openDevTools()
|
||||
loginWindow.once('ready-to-show', () => {
|
||||
loginWindow.show()
|
||||
})
|
||||
|
||||
|
||||
loginWindow.on('closed', () => {
|
||||
loginWindow = null
|
||||
})
|
||||
|
@ -44,7 +51,7 @@ function createMainWindow() {
|
|||
width: 1200,
|
||||
height: 700,
|
||||
show: false,
|
||||
frame: false,
|
||||
frame: false, // 无边框
|
||||
autoHideMenuBar: true,
|
||||
...(process.platform === 'linux' ? { icon } : {}),
|
||||
webPreferences: {
|
||||
|
@ -64,53 +71,47 @@ function createMainWindow() {
|
|||
mainWindow.webContents.openDevTools()
|
||||
|
||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
||||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] )
|
||||
} else {
|
||||
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 作业窗口相关-开发中
|
||||
let workWindow
|
||||
function createWork(data) {
|
||||
if (workWindow) return
|
||||
workWindow = new BrowserWindow({
|
||||
let linkWindow
|
||||
async function createLinkWin(data) {
|
||||
if (linkWindow) return
|
||||
linkWindow = new BrowserWindow({
|
||||
width: 650,
|
||||
height: 500,
|
||||
show: false,
|
||||
frame: true,
|
||||
|
||||
maximizable: true,
|
||||
autoHideMenuBar: true,
|
||||
...(process.platform === 'linux' ? { icon } : {}),
|
||||
webPreferences: {
|
||||
sandbox: false,
|
||||
nodeIntegration: true
|
||||
nodeIntegration: true,
|
||||
worldSafeExecuteJavaScript: true,
|
||||
contextIsolation: true
|
||||
}
|
||||
})
|
||||
|
||||
workWindow.webContents.session.cookies.set(
|
||||
{
|
||||
url: 'https://file.ysaix.com:7868',
|
||||
name: 'Admin-Token',
|
||||
value: data
|
||||
},
|
||||
function (error) {
|
||||
if (error) {
|
||||
console.error('Set cookie failed:', error)
|
||||
} else {
|
||||
console.log('Cookie set successfully.')
|
||||
}
|
||||
}
|
||||
)
|
||||
workWindow.loadURL(
|
||||
'https://file.ysaix.com:7868/teaching/classtaskassign?titleName=%E4%BD%9C%E4%B8%9A%E5%B8%83%E7%BD%AE'
|
||||
)
|
||||
|
||||
workWindow.once('ready-to-show', () => {
|
||||
workWindow.show()
|
||||
let cookieDetails = { ...data.cookieData }
|
||||
await linkWindow.webContents.session.cookies.set(cookieDetails).then(()=>{
|
||||
console.log('Cookie is successful');
|
||||
}).catch( error =>{
|
||||
console.error('Cookie is error', error);
|
||||
})
|
||||
workWindow.on('closed', () => {
|
||||
workWindow = null
|
||||
|
||||
linkWindow.loadURL(data.fullPath)
|
||||
|
||||
linkWindow.once('ready-to-show', () => {
|
||||
linkWindow.show()
|
||||
linkWindow.maximize()
|
||||
})
|
||||
linkWindow.on('closed', () => {
|
||||
linkWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -162,18 +163,18 @@ app.on('ready', () => {
|
|||
createLoginWindow()
|
||||
}
|
||||
mainWindow.destroy()
|
||||
mainWindow = null
|
||||
loginWindow.show()
|
||||
loginWindow.focus()
|
||||
})
|
||||
|
||||
//打开作业窗口
|
||||
ipcMain.on('openWork', (e, data) => {
|
||||
createWork(data)
|
||||
ipcMain.on('openWindow', (e, data) => {
|
||||
createLinkWin(data)
|
||||
})
|
||||
// zdg: 创建工具窗口-如 悬浮球
|
||||
Tool()
|
||||
// 打开-登录窗口
|
||||
|
||||
createLoginWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createLoginWindow()
|
||||
})
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import { dialog } from 'electron'
|
||||
import logger from 'electron-log'
|
||||
const updateURL = 'http://27.128.240.72:3000/zhuhao/AIx_Smarttalk/releases/tag/V1.0.0%28%E6%B5%8B%E8%AF%95%E7%89%88%29/'
|
||||
|
||||
// 主进程中的更新检查
|
||||
const { autoUpdater } = require('electron-updater')
|
||||
|
||||
const updateInit = (win) => {
|
||||
logger.info('进来了')
|
||||
// 检查更新
|
||||
autoUpdater.checkForUpdates()
|
||||
// 自动下载
|
||||
autoUpdater.autoDownload = false
|
||||
// 设置版本更新服务器地址
|
||||
// autoUpdater.setFeedURL(updateURL)
|
||||
|
||||
//监听更新事件
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
logger.info('发现新版本')
|
||||
dialog
|
||||
.showMessageBox(win,{
|
||||
type: 'info',
|
||||
title: '新版本可用',
|
||||
message: '有一个可用的新版本,要更新吗',
|
||||
buttons: ['是', '否']
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.response === 0) {
|
||||
// 用户选择更新,触发下载和安装
|
||||
autoUpdater.downloadUpdate()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 没有新版本
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
logger.info('没有新版本')
|
||||
})
|
||||
|
||||
// 更新发生错误
|
||||
autoUpdater.on('error', () => {
|
||||
logger.error('检查更新失败')
|
||||
})
|
||||
|
||||
// 跟新下载完毕
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
dialog
|
||||
.showMessageBox({
|
||||
type: 'info',
|
||||
title: '更新下载完成',
|
||||
message: '点击确定重启获取最新内容',
|
||||
buttons: ['确定']
|
||||
})
|
||||
.then(() => {
|
||||
// 调用 quitAndInstall 来安装更新
|
||||
autoUpdater.quitAndInstall()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default updateInit
|
|
@ -9,6 +9,13 @@ export const getSmarttalkPage = (params) => {
|
|||
})
|
||||
}
|
||||
|
||||
export const getPrepareById = (id) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteSmarttalk(id) {
|
||||
return request({
|
||||
url: '/smarttalk/file/' + id,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2794390 */
|
||||
src: url('iconfont.woff2?t=1721798279074') format('woff2'),
|
||||
url('iconfont.woff?t=1721798279074') format('woff'),
|
||||
url('iconfont.ttf?t=1721798279074') format('truetype'),
|
||||
url('iconfont.svg?t=1721798279074#iconfont') format('svg');
|
||||
src: url('iconfont.woff2?t=1721698955462') format('woff2'),
|
||||
url('iconfont.woff?t=1721698955462') format('woff'),
|
||||
url('iconfont.ttf?t=1721698955462') format('truetype'),
|
||||
url('iconfont.svg?t=1721698955462#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -14,22 +14,6 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-xiayiye:before {
|
||||
content: "\e68b";
|
||||
}
|
||||
|
||||
.icon-shangyiye:before {
|
||||
content: "\e68e";
|
||||
}
|
||||
|
||||
.icon-shuangye:before {
|
||||
content: "\e64e";
|
||||
}
|
||||
|
||||
.icon-danyemoban:before {
|
||||
content: "\e859";
|
||||
}
|
||||
|
||||
.icon-lingdang:before {
|
||||
content: "\e613";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,34 +5,6 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "694110",
|
||||
"name": "下一页",
|
||||
"font_class": "xiayiye",
|
||||
"unicode": "e68b",
|
||||
"unicode_decimal": 59019
|
||||
},
|
||||
{
|
||||
"icon_id": "694115",
|
||||
"name": "上一页",
|
||||
"font_class": "shangyiye",
|
||||
"unicode": "e68e",
|
||||
"unicode_decimal": 59022
|
||||
},
|
||||
{
|
||||
"icon_id": "930693",
|
||||
"name": "双页",
|
||||
"font_class": "shuangye",
|
||||
"unicode": "e64e",
|
||||
"unicode_decimal": 58958
|
||||
},
|
||||
{
|
||||
"icon_id": "2144697",
|
||||
"name": "单页模板",
|
||||
"font_class": "danyemoban",
|
||||
"unicode": "e859",
|
||||
"unicode_decimal": 59481
|
||||
},
|
||||
{
|
||||
"icon_id": "17990800",
|
||||
"name": "铃铛",
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="xiayiye" unicode="" d="M262.3386 833.6323 762.3127 383.6508 262.3386-66.3255Z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="shangyiye" unicode="" d="M779.704065 749.884155c0.082888 12.881378-1.100054 22.822798-9.91993 31.327496-1.528819 1.482771-3.160993 2.758834-4.880147 3.923356-5.882987 4.114714-13.130042 6.578836-20.979824 6.578836-10.750855 0-16.845667-4.072759-26.91193-11.800767L254.198469 437.507658c-7.198959-6.944156-10.700713-16.087397-10.559497-25.195845-0.14224-9.108448 3.360538-18.252713 10.559497-25.195845l464.578967-343.721389c17.667382-13.287631 36.927027-13.623275 51.006697 0 8.819876 8.516977 10.214642 19.716041 9.91993 31.331589L779.704065 749.884155z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="shuangye" unicode="" d="M848.266092 813.673993 175.733908 813.673993c-61.922305 0-112.089891-50.207495-112.089891-112.087844l0-635.169227c0-61.920258 50.167586-112.089891 112.089891-112.089891l672.532183 0c61.916165 0 112.087844 50.169633 112.087844 112.089891L960.353936 701.585125C960.353936 763.465474 910.182256 813.673993 848.266092 813.673993zM138.371976 66.415898 138.371976 701.585125c0 20.650319 16.744359 37.362956 37.362956 37.362956l298.903647 0 0-709.895139L175.733908 29.052942C155.116335 29.053965 138.371976 45.762509 138.371976 66.415898zM885.629048 66.415898c0-20.654412-16.748453-37.362956-37.362956-37.362956L549.363468 29.052942 549.363468 738.948081l298.903647 0c20.614503 0 37.362956-16.712637 37.362956-37.362956L885.630071 66.415898zM213.096864 552.133302l186.813756 0 0-37.362956-186.813756 0 0 37.362956ZM213.096864 402.682501l186.813756 0 0-37.362956-186.813756 0 0 37.362956ZM213.096864 253.229654l186.813756 0 0-37.362956-186.813756 0 0 37.362956ZM624.088356 552.133302l186.813756 0 0-37.362956-186.813756 0 0 37.362956ZM624.088356 402.682501l186.813756 0 0-37.362956-186.813756 0 0 37.362956ZM624.088356 253.229654l186.813756 0 0-37.362956-186.813756 0 0 37.362956Z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="danyemoban" unicode="" d="M801.757337 887.402181h-70.842465v-0.201591H145.744385c-36.021401 0-65.225537-29.196972-65.225537-65.214281v-876.16193c0-36.028565 29.204136-65.225537 65.225537-65.225537h732.507136c36.025495 0 65.22963 29.207206 65.229631 65.225537V745.714182L801.757337 887.402181z m69.313645-878.988302c0-30.886451-24.296359-55.916521-54.284347-55.91652H207.208249c-29.987988 0-54.284347 25.029046-54.284347 55.91652V759.395786c0 30.876218 24.296359 55.909357 54.284347 55.909357h523.706623v-140.42524h140.15611v-666.466024zM695.120644 599.797881H328.875263c-18.028609 0-32.624025-14.598486-32.624025-32.609699v-6.681166c0-18.011212 14.594393-32.616862 32.624025-32.616862h366.244358c18.011212 0 32.605605 14.605649 32.605605 32.616862v6.681166c0.001023 18.011212-14.594393 32.609699-32.604582 32.609699z m0-215.703737H328.875263c-18.028609 0-32.624025-14.598486-32.624025-32.598442v-6.691399c0-18.011212 14.594393-32.605605 32.624025-32.605606h366.244358c18.011212 0 32.605605 14.594393 32.605605 32.605606v6.691399c0.001023 17.999956-14.594393 32.598442-32.604582 32.598442z m0-215.694527H328.875263c-18.028609 0-32.624025-14.608719-32.624025-32.605605v-6.695493c0-18.007119 14.594393-32.605605 32.624025-32.605605h366.244358c18.011212 0 32.605605 14.598486 32.605605 32.605605v6.695493c0.001023 17.996886-14.594393 32.605605-32.604582 32.605605z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="lingdang" unicode="" d="M257.7 243.70000000000005h510.6c17.9 0 32.5 14.5 32.5 32.5V480.9c0 143.2-104.6 261.9-241.5 284 2.1 5.5 3.3 11.6 3.3 17.8 0 27.4-22.2 49.6-49.6 49.6s-49.6-22.2-49.6-49.6c0-6.3 1.2-12.3 3.3-17.8-136.9-22.1-241.5-140.9-241.5-284v-204.7c0-17.9 14.6-32.5 32.5-32.5zM513-63.60000000000002c44.4 0 80.3 36 80.3 80.3H432.7c0-44.4 35.9-80.3 80.3-80.3zM911.7 115L895 148.29999999999995c-14.8 29.7-47.7 52.1-74.5 52.1h-615c-26.8 0-59.7-22.4-74.5-52.1L114.3 115c-17.5-35.1-6.6-65.9 25.9-65.9h745.6c32.5 0 43.5 30.8 25.9 65.9z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="yidongdaozu" unicode="" d="M904.448 270.272 119.616 270.272c-23.68 0-44.736-14.656-52.48-36.48C65.024 227.968 64 221.952 64 216c0-16.32 7.616-32.192 21.184-42.688l293.248-225.728c24.128-18.56 59.008-14.464 78.016 9.088 18.944 23.552 14.848 57.664-9.28 76.224L288 156.544l616 0c30.72 0 56 29.44 56 59.456C960 246.016 935.168 270.272 904.448 270.272zM119.552 497.728l784.832 0c23.68 0 44.736 14.656 52.48 36.48C958.976 540.032 960 546.048 960 552c0 16.32-7.616 32.192-21.184 42.688l-293.248 225.728c-24.128 18.56-59.008 14.464-78.016-9.088C548.608 787.776 552.64 753.6 576.832 735.04L736 611.456 120 611.456C89.28 611.456 64 582.016 64 552 64 521.984 88.832 497.728 119.552 497.728z" horiz-adv-x="1024" />
|
||||
|
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -64,6 +64,8 @@ const defaultProps = {
|
|||
const curBookId = ref(-1)
|
||||
//当前教材名称
|
||||
const curBookName = ref('')
|
||||
//当前教材封面图
|
||||
const curBookImg = ref('')
|
||||
// 上册
|
||||
const volumeOne = ref([])
|
||||
// 下册
|
||||
|
@ -110,9 +112,10 @@ const getSubjectContent = async () => {
|
|||
}
|
||||
|
||||
//选择教材
|
||||
const changeBook = ({ id, itemtitle }) => {
|
||||
const changeBook = ({ id, itemtitle, avartar }) => {
|
||||
curBookId.value = id
|
||||
curBookName.value = itemtitle
|
||||
curBookImg.value = BaseUrl + avartar
|
||||
getTreeData()
|
||||
setTimeout(() => {
|
||||
dialogVisible.value = false
|
||||
|
@ -144,7 +147,8 @@ const emitChangeBook = () => {
|
|||
const data = {
|
||||
textBook: {
|
||||
curBookId: curBookId.value,
|
||||
curBookName: curBookName.value
|
||||
curBookName: curBookName.value,
|
||||
curBookImg: curBookImg.value
|
||||
},
|
||||
node: curNode
|
||||
}
|
||||
|
@ -236,6 +240,7 @@ const getSubject = async () => {
|
|||
// 默认第一个
|
||||
curBookName.value = subjectList.value[0].itemtitle
|
||||
curBookId.value = subjectList.value[0].id
|
||||
curBookImg.value = BaseUrl + subjectList.value[0].avartar
|
||||
}
|
||||
|
||||
|
||||
|
@ -264,7 +269,8 @@ const handleNodeClick = (data, node) => {
|
|||
let curData = {
|
||||
textBook: {
|
||||
curBookId: curBookId.value,
|
||||
curBookName: curBookName.value
|
||||
curBookName: curBookName.value,
|
||||
curBookImg: curBookImg.value
|
||||
},
|
||||
node: toRaw(currentNode)
|
||||
}
|
||||
|
|
|
@ -79,10 +79,6 @@ const subjectList = ref([])
|
|||
const allSubject = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
dialogVisible.value = newVal
|
||||
})
|
||||
|
||||
//切换年级
|
||||
const changeGrade = ()=>{
|
||||
// 切换年级 过滤出对应学科数据
|
||||
|
@ -120,8 +116,13 @@ const editUserInfo = async () =>{
|
|||
emit('onSuccess')
|
||||
}
|
||||
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
dialogVisible.value = newVal
|
||||
if(newVal){
|
||||
getSubject()
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(getSubject)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -138,11 +139,13 @@ onMounted(getSubject)
|
|||
|
||||
.dialog-content {
|
||||
padding: 30px 20px 10px 30px;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.dialog-footer{
|
||||
text-align: center;
|
||||
padding-bottom: 10px;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
<el-form>
|
||||
<el-form-item label="文件">
|
||||
<div class="create-item file-item flex">
|
||||
<el-upload :file-list="fileList" :show-file-list="false" :auto-upload="false" multiple
|
||||
<el-upload :file-list="fileList" :limit="limit" :show-file-list="false" :auto-upload="false" multiple
|
||||
:on-change="hanleFileChange">
|
||||
<el-button slot="trigger">选择文件</el-button>
|
||||
</el-upload>
|
||||
<span class="upload-desc">说明:一次最多上传5个文件,单个文件大小不能大于100M</span>
|
||||
<span class="upload-desc">说明:一次最多上传{{ limit }}个文件,单个文件大小不能大于100M</span>
|
||||
<span class="upload-desc">仅支持图片、音频、视频、word、ppt、pdf、txt、zip文件</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
|
@ -16,14 +17,15 @@
|
|||
<div class="file-list-item flex" v-for="(item, index) in fileList" :key="item.uid">
|
||||
<div class="file-name">
|
||||
<span class="name">标题:</span>
|
||||
<FileImage :fileName="item.name" :size="50"/>
|
||||
<el-input class="file-input" v-model="item.fileData.name" placeholder="请输入文件名" />
|
||||
<FileImage :fileName="item.name" :size="50" />
|
||||
<el-input class="file-input" v-model="item.fileData.name" placeholder="请输入文件名" />
|
||||
<span>.{{ getFileSuffix(item.name) }}</span>
|
||||
</div>
|
||||
<div class="flex-type flex">
|
||||
<span class="name">类别:</span>
|
||||
<el-select v-model="item.fileData.fileFlag" placeholder="Select" style="width: 100px">
|
||||
<el-option v-for="item in resourceType" :key="item.alue" :label="item.label" :value="item.value" />
|
||||
<el-option v-for="el in resourceType" :key="el.alue" :label="el.label" :value="el.value"
|
||||
:disabled="checkFile(el, item)" />
|
||||
</el-select>
|
||||
|
||||
</div>
|
||||
|
@ -58,6 +60,7 @@ const props = defineProps({
|
|||
},
|
||||
})
|
||||
const dialogValue = ref(false)
|
||||
const limit = ref(5)
|
||||
// 定义要发送的emit事件
|
||||
const emit = defineEmits(['update:modelValue', 'submitFile'])
|
||||
// 文件列表
|
||||
|
@ -68,7 +71,7 @@ watch(() => props.modelValue, (newVal) => {
|
|||
})
|
||||
|
||||
const hanleFileChange = (file) => {
|
||||
console.log(file)
|
||||
console.log(file)
|
||||
|
||||
//音频 类型
|
||||
const audioTypes = ['audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/aac']
|
||||
|
@ -81,9 +84,9 @@ const hanleFileChange = (file) => {
|
|||
// pdf 类型
|
||||
const pdfTypes = ['application/pdf']
|
||||
// zip 类型
|
||||
const zipTypes = ['application/x-zip-compressed','application/x-compressed']
|
||||
const zipTypes = ['application/x-zip-compressed', 'application/x-compressed']
|
||||
// 图片 类型
|
||||
const imgTypes = ['image/jpeg','image/gif', 'image/png']
|
||||
const imgTypes = ['image/jpeg', 'image/gif', 'image/png']
|
||||
// text 类型
|
||||
const textTypes = ['text/plain']
|
||||
|
||||
|
@ -93,22 +96,39 @@ const hanleFileChange = (file) => {
|
|||
return false
|
||||
}
|
||||
// 验证文件大小
|
||||
// B < KB < MB < GB
|
||||
// file.raw.size 单位是B
|
||||
const fileSize = file.raw.size / 1024 / 1024 > 100
|
||||
if (fileSize) {
|
||||
ElMessage.error('文件大小错误! 请上传小于100M的文件!')
|
||||
return false
|
||||
}
|
||||
if (file.status === 'ready') {
|
||||
|
||||
|
||||
// 给一个默认的fileData
|
||||
file.fileData = {
|
||||
fileFlag: '课件',
|
||||
fileFlag: '素材',
|
||||
name: getFileName(file.name),
|
||||
}
|
||||
fileList.value.push(file)
|
||||
console.log(fileList.value)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查文件类型
|
||||
const checkFile = (item, file) => {
|
||||
const type = file.raw.type
|
||||
const pptTypes = ['application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation']
|
||||
let isPpt = pptTypes.includes(type)
|
||||
if(!isPpt && item.value == '教案'){
|
||||
return true
|
||||
}
|
||||
else{
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 删除
|
||||
const delFile = (index) => {
|
||||
fileList.value.splice(index, 1)
|
||||
|
@ -133,7 +153,7 @@ const submitFile = () => {
|
|||
item.fileData.fileShowName = item.fileData.name + '.' + suffix
|
||||
delete item.fileData.name
|
||||
})
|
||||
emit('submitFile',fileList.value)
|
||||
emit('submitFile', fileList.value)
|
||||
closeDialog()
|
||||
}
|
||||
|
||||
|
@ -203,24 +223,28 @@ const submitFile = () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-input {
|
||||
border-bottom: solid #dfdfdf 1px;
|
||||
|
||||
&:hover {
|
||||
border-color: #409EFF;
|
||||
}
|
||||
&:focus{
|
||||
|
||||
&:focus {
|
||||
border-color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper){
|
||||
box-shadow: none
|
||||
}
|
||||
:deep(.el-input__wrapper.is-focus){
|
||||
box-shadow: none
|
||||
}
|
||||
:deep(.el-input__wrapper:hover){
|
||||
:deep(.el-input__wrapper) {
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper.is-focus) {
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper:hover) {
|
||||
box-shadow: none
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -113,9 +113,6 @@ const emits = defineEmits(['setLayout'])
|
|||
function setLayout() {
|
||||
emits('setLayout');
|
||||
}
|
||||
watch(()=> userStore.avatar,() => {
|
||||
userImg.value = userStore.avatar;
|
||||
},{deep:true})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
<div class="prepare-body-main-item">
|
||||
<div class="prepare-uploader-progress" :style="{ width: item.percentage + '%' }"></div>
|
||||
<div class="prepare-body-main-item-icon">
|
||||
<svg
|
||||
<FileImage :size="50" :file-name="item.raw.name" />
|
||||
<!-- <svg
|
||||
class="icon"
|
||||
aria-hidden="true"
|
||||
font-size="50px"
|
||||
|
@ -32,7 +33,7 @@
|
|||
style="margin: auto"
|
||||
>
|
||||
<use xlink:href="#icon-ppt"></use>
|
||||
</svg>
|
||||
</svg>-->
|
||||
</div>
|
||||
<div class="prepare-body-main-item-info">
|
||||
<div class="prepare-item-info-title">{{ item.raw.name }}</div>
|
||||
|
@ -59,12 +60,14 @@
|
|||
<script>
|
||||
import uploaderState from '@/store/modules/uploader'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import CryptoJS from 'crypto-js'
|
||||
// import CryptoJS from 'crypto-js/md5'
|
||||
import SparkMD5 from 'spark-md5'
|
||||
import { DeleteFilled } from '@element-plus/icons-vue'
|
||||
import FileImage from '@/components/file-image/index.vue'
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
export default {
|
||||
name: 'Uploader',
|
||||
components: { DeleteFilled },
|
||||
components: { DeleteFilled, FileImage },
|
||||
data() {
|
||||
return {
|
||||
timer: null,
|
||||
|
@ -147,13 +150,14 @@ export default {
|
|||
},
|
||||
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()
|
||||
let fileReader = new FileReader()
|
||||
let Spark = new SparkMD5.ArrayBuffer()
|
||||
fileReader.readAsArrayBuffer(file)
|
||||
fileReader.onload = function (e) {
|
||||
Spark.append(e.target.result)
|
||||
let md5 = Spark.end()
|
||||
resolve(md5)
|
||||
}
|
||||
fileReader.readAsArrayBuffer(file)
|
||||
})
|
||||
},
|
||||
removeUploadFile(uid) {
|
||||
|
|
|
@ -36,6 +36,7 @@ const useUserStore = defineStore(
|
|||
getInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getInfo().then(res => {
|
||||
res.user.avatar = import.meta.env.VITE_APP_BASE_API + res.user.avatar
|
||||
const user = res.user
|
||||
this.user = user
|
||||
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : user.avatar;
|
||||
|
@ -46,8 +47,8 @@ const useUserStore = defineStore(
|
|||
} else {
|
||||
this.roles = ['ROLE_DEFAULT']
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this.id = user.userId
|
||||
this.userName = user.userName
|
||||
this.nickName = user.nickName;
|
||||
|
@ -70,7 +71,7 @@ const useUserStore = defineStore(
|
|||
this.plainpwd = user.plainpwd;
|
||||
|
||||
this.roles = res.roles;
|
||||
|
||||
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
import array from 'lodash/array'
|
||||
export const hasPermission = (value, def = true) => {
|
||||
// 不传值,默认视为有权限,不做鉴权
|
||||
if (!value) {
|
||||
return def
|
||||
}
|
||||
|
||||
const allCodeList = useUserStore().roles
|
||||
// 如果不是数组,直接判断pinia里的权限数组有没有相同的元素即可
|
||||
if (!Array.isArray(value)) {
|
||||
return allCodeList.includes(value)
|
||||
}
|
||||
// intersection是lodash提供的一个方法,用于返回一个所有给定数组都存在的元素组成的数组
|
||||
return array.intersection(value, allCodeList).length > 0
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const baseConfig = {
|
||||
// Electron 设置cookie
|
||||
url: 'https://file.ysaix.com:7868',
|
||||
//cookie 名称 这里为 token
|
||||
name: 'Admin-Token',
|
||||
//cookie 值
|
||||
value: userStore.token,
|
||||
// 域名
|
||||
domain: 'file.ysaix.com',
|
||||
|
||||
}
|
||||
|
||||
// 作业
|
||||
const homeWork = {
|
||||
data: { ...baseConfig},
|
||||
// 完整路径
|
||||
fullPath: `${baseConfig.url}/teaching/classtaskassign?titleName=%E4%BD%9C%E4%B8%9A%E5%B8%83%E7%BD%AE`
|
||||
}
|
||||
|
||||
// 高考研读
|
||||
const gk = {
|
||||
data: { ...baseConfig},
|
||||
fullPath: `${baseConfig.url}/education/colentrance`
|
||||
}
|
||||
|
||||
// 课标研读
|
||||
const standard = {
|
||||
data: { ...baseConfig},
|
||||
fullPath: `${baseConfig.url}/teaching/chatwithstandard`
|
||||
}
|
||||
|
||||
// 教学大模型
|
||||
const aiModel = {
|
||||
data: { ...baseConfig},
|
||||
fullPath: `${baseConfig.url}/platofai`
|
||||
}
|
||||
|
||||
export default {
|
||||
homeWork,
|
||||
gk,
|
||||
standard,
|
||||
aiModel
|
||||
}
|
|
@ -1,5 +1,49 @@
|
|||
const { ipcRenderer } = window.electron || {}
|
||||
|
||||
export const asyncLocalFile = (item) => {
|
||||
return new Promise((resolve) => {
|
||||
//判断是否需要从线上拿新的文件
|
||||
isAsyncLocalFile(item.fileNewName, item.lastModifyTime, item.fileMd5).then(
|
||||
({ isAsync, type }) => {
|
||||
item.async = !isAsync
|
||||
if (isAsync === true) {
|
||||
item.async = 'on'
|
||||
if (type === 'down') {
|
||||
ipcRenderer.send('download-file-default', {
|
||||
url: item.fileFullPath,
|
||||
fileName: item.fileNewName
|
||||
})
|
||||
ipcRenderer.once('download-file-default' + item.fileNewName, (e, isSuccess) => {
|
||||
item.async = isSuccess
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
if (type === 'upload') {
|
||||
let cookie = localStorage.getItem('Admin-Token')
|
||||
ipcRenderer.send('upload-file-change', {
|
||||
id: item.id,
|
||||
fileNewName: item.fileNewName,
|
||||
cookie,
|
||||
fileType: item.fileType
|
||||
})
|
||||
ipcRenderer.once(
|
||||
'upload-file-change-success' + item.fileNewName,
|
||||
(e, { data, md5 }) => {
|
||||
item.fileSize = data.fileSize
|
||||
item.md5 = md5
|
||||
item.async = true
|
||||
resolve()
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export const isHaveLocalFile = async (fileNewName) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('is-have-local-file', fileNewName)
|
||||
|
@ -9,6 +53,15 @@ export const isHaveLocalFile = async (fileNewName) => {
|
|||
})
|
||||
}
|
||||
|
||||
export const isAsyncLocalFile = async (fileNewName, lastModifyTime, md5) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('is-async-local-file', { fileNewName, lastModifyTime, md5 })
|
||||
ipcRenderer.once('is-async-local-file-reply' + fileNewName, (e, { isAsync, type }) => {
|
||||
resolve({ isAsync, type })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const parseCataByNode = (node) => {
|
||||
if (node.parentNode) {
|
||||
let arr = parseCataByNode(node.parentNode)
|
||||
|
@ -31,9 +84,12 @@ export const exportFile = async (list) => {
|
|||
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 })
|
||||
let cookie = localStorage.getItem('Admin-Token')
|
||||
ipcRenderer.send('creat-file-default', {
|
||||
name,
|
||||
uploadData: JSON.parse(JSON.stringify(uploadData)),
|
||||
cookie
|
||||
})
|
||||
ipcRenderer.once('creat-file-default-reply', (e, res) => {
|
||||
resolve(res)
|
||||
})
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<!--选择学科-->
|
||||
<SelectSubject v-model="isSubject" v-if="isSubject" class="select-subject" @onSuccess="successEditSubject" />
|
||||
<SelectSubject v-model="isSubject" @onSuccess="successEditSubject" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
|
@ -202,7 +202,5 @@ onMounted(()=>{
|
|||
.el-form-item {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.select-subject{
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -100,10 +100,10 @@ import { Check, UploadFilled, Switch } from '@element-plus/icons-vue'
|
|||
</script>
|
||||
<script>
|
||||
import FileImage from '@/components/file-image/index.vue'
|
||||
import { isHaveLocalFile } from '@/utils/talkFile'
|
||||
import { asyncLocalFile } from '@/utils/talkFile'
|
||||
import { toTimeText } from '@/utils/date'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { deleteSmarttalk, updateSmarttalk } from '@/api/file'
|
||||
import { deleteSmarttalk, updateSmarttalk, getPrepareById } from '@/api/file'
|
||||
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
export default {
|
||||
|
@ -112,18 +112,23 @@ export default {
|
|||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
default: function () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: function() {
|
||||
default: function () {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
},
|
||||
emits: { 'on-move': null, 'on-delete': null },
|
||||
data() {
|
||||
return {
|
||||
listenList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editTalk(item) {
|
||||
ElMessageBox.prompt('请输入新的名称', '重命名', {
|
||||
|
@ -142,8 +147,7 @@ export default {
|
|||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
downloadFile(item) {
|
||||
ipcRenderer.send('save-as', item.fileFullPath, item.fileShowName)
|
||||
|
@ -156,7 +160,6 @@ export default {
|
|||
})
|
||||
},
|
||||
closePopver(index) {
|
||||
console.log(this.$refs['popover_' + index])
|
||||
this.$refs['popover_' + index].hide()
|
||||
},
|
||||
moveSmarttalkFun(item) {
|
||||
|
@ -179,20 +182,31 @@ export default {
|
|||
return temp + 'GB'
|
||||
}
|
||||
},
|
||||
openFileWin(item) {
|
||||
isHaveLocalFile(item.fileNewName).then((res) => {
|
||||
if (res === true) {
|
||||
openFileWin(items) {
|
||||
getPrepareById(items.id).then((item) => {
|
||||
Object.assign(items, item)
|
||||
asyncLocalFile(items).then(() => {
|
||||
ipcRenderer.send('open-path-app', item.fileNewName)
|
||||
} else {
|
||||
item.async = 'on'
|
||||
ipcRenderer.once('download-file-default' + item.fileNewName, (e, isSuccess) => {
|
||||
item.async = isSuccess
|
||||
})
|
||||
ipcRenderer.send('download-file-default', {
|
||||
url: item.fileFullPath,
|
||||
fileName: item.fileNewName
|
||||
})
|
||||
}
|
||||
if (this.listenList.indexOf(item.fileNewName) === -1) {
|
||||
this.listenList.push(item.fileNewName)
|
||||
let cookie = localStorage.getItem('Admin-Token')
|
||||
ipcRenderer.send('listen-file-change', {
|
||||
id: item.id,
|
||||
fileNewName: item.fileNewName,
|
||||
md5: item.fileMd5,
|
||||
cookie,
|
||||
fileType: item.fileType
|
||||
})
|
||||
ipcRenderer.on('listen-file-change-on' + item.fileNewName, () => {
|
||||
item.async = 'on'
|
||||
})
|
||||
ipcRenderer.on('listen-file-change-success' + item.fileNewName, (e, { data, md5 }) => {
|
||||
item.fileSize = data.fileSize
|
||||
item.md5 = md5
|
||||
item.async = true
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,27 @@
|
|||
<div v-loading="isLoading" class="page-resource flex">
|
||||
<ChooseTextbook @change-book="nodeClick" @node-click="nodeClick" />
|
||||
<div class="page-right">
|
||||
<div class="header-top flex">
|
||||
<div class="textbook-img">
|
||||
<el-image style="width: 80px; height: 110px" :src="curBookImg" />
|
||||
</div>
|
||||
<div class="top-item">
|
||||
<el-button class="btn" @click="handleOutLink('standard')">课标研读</el-button>
|
||||
<el-button class="btn" >电子课本</el-button>
|
||||
<el-button class="btn" @click="handleOutLink('gk')">高考研读</el-button>
|
||||
<el-button class="btn" @click="handleOutLink('aiModel')">教学大模型</el-button>
|
||||
</div>
|
||||
<el-button type="primary" class="to-class-btn">
|
||||
<i class="iconfont icon-lingdang"></i>上课</el-button>
|
||||
</div>
|
||||
<div class="prepare-body-header">
|
||||
|
||||
<div>
|
||||
<label style="font-size: 15px">共{{ currentFileList.length }}个文件</label>
|
||||
<el-popover placement="top-start" :width="250" trigger="hover">
|
||||
<template #default>
|
||||
<div>
|
||||
<el-button
|
||||
v-if="lastAsyncAllTime"
|
||||
type="success"
|
||||
size="small"
|
||||
:icon="Check"
|
||||
circle
|
||||
/>
|
||||
<el-button v-if="lastAsyncAllTime" type="success" size="small" :icon="Check" circle />
|
||||
{{ lastAsyncAllTime ? toTimeText(lastAsyncAllTime) + '同步成功' : '' }}
|
||||
</div>
|
||||
</template>
|
||||
|
@ -29,38 +37,22 @@
|
|||
</el-popover>
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<el-button @click="handleOutLink('homeWork')">布置作业</el-button>
|
||||
<el-button @click="isDialogOpen = true">上传资料</el-button>
|
||||
<el-button type="primary" style="margin-left: 10px" @click="createFile"
|
||||
>新建课件</el-button
|
||||
>
|
||||
<el-button type="primary" style="margin-left: 10px" @click="createFile">新建课件</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-checkbox-group
|
||||
v-model="checkFileList"
|
||||
class="prepare-body-main"
|
||||
:style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }"
|
||||
>
|
||||
<file-list-item
|
||||
v-for="(item, index) in currentFileList"
|
||||
:key="index"
|
||||
:item="item"
|
||||
:index="index"
|
||||
@on-move="onMoveSingleFile"
|
||||
@on-delete="deleteTalk"
|
||||
>
|
||||
<el-checkbox-group v-model="checkFileList" class="prepare-body-main"
|
||||
:style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }">
|
||||
<file-list-item v-for="(item, index) in currentFileList" :key="index" :item="item" :index="index"
|
||||
@on-move="onMoveSingleFile" @on-delete="deleteTalk">
|
||||
<el-checkbox label="" :value="item" />
|
||||
</file-list-item>
|
||||
</el-checkbox-group>
|
||||
<file-oper-batch
|
||||
v-show="checkFileList.length > 0"
|
||||
<file-oper-batch v-show="checkFileList.length > 0"
|
||||
:indeterminate="checkFileList.length > 0 && checkFileList.length < currentFileList.length"
|
||||
:choose="checkFileList"
|
||||
:check-all="isCheckAll"
|
||||
@click-delete="clickDelete"
|
||||
@click-move="clickMove"
|
||||
@cancel="checkFileList = []"
|
||||
@click-choose="clickChoose"
|
||||
></file-oper-batch>
|
||||
:choose="checkFileList" :check-all="isCheckAll" @click-delete="clickDelete" @click-move="clickMove"
|
||||
@cancel="checkFileList = []" @click-choose="clickChoose"></file-oper-batch>
|
||||
</div>
|
||||
<MoveFile v-model="isMoveDialogOpen" @on-submit="chooseMoveCata" />
|
||||
<uploadDialog v-model="isDialogOpen" @submit-file="submitFile" />
|
||||
|
@ -79,9 +71,12 @@ import FileListItem from '@/views/prepare/container/file-list-item.vue'
|
|||
import { getSmarttalkPage, moveSmarttalk } from '@/api/file'
|
||||
import { toTimeText } from '@/utils/date'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { isHaveLocalFile, parseCataByNode, creatPPT } from '@/utils/talkFile'
|
||||
import { parseCataByNode, creatPPT, asyncLocalFile } from '@/utils/talkFile'
|
||||
import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue'
|
||||
import outLink from '@/utils/linkConfig'
|
||||
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
|
||||
export default {
|
||||
name: 'Prepare',
|
||||
components: { ChooseTextbook, Refresh, uploadDialog, FileListItem, FileOperBatch, MoveFile },
|
||||
|
@ -104,7 +99,9 @@ export default {
|
|||
levelSecondId: null,
|
||||
fileSource: '个人',
|
||||
fileRoot: '备课'
|
||||
}
|
||||
},
|
||||
// 当前教材封面图
|
||||
curBookImg: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -120,21 +117,13 @@ export default {
|
|||
this.callback(param)
|
||||
})
|
||||
this.lastAsyncAllTime = localStorage.getItem('lastAsyncAllTime')
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// const destination = '0901高一【数学(人教A版)】集合的概念-PPT课件.pptx'
|
||||
// ipcRenderer.send('open-path-app',this.filePath)
|
||||
// const source = 'D:\\edufile\\0901高一【数学(人教A版)】集合的概念-PPT课件.pptx'
|
||||
// ipcRenderer.send('copy-file-default',{ source, destination })
|
||||
// ipcRenderer.send('download-file-default',this.fileUrl)
|
||||
// getSmarttalkPage({nowPage:1,pageSize:2}).then(res=>{
|
||||
// console.log(res)
|
||||
// })
|
||||
// let filePath = window.rootTalkFilePath + item.fileNewName
|
||||
},
|
||||
methods: {
|
||||
createFile() {
|
||||
creatPPT('新建ppt文档.pptx',this.uploadData).then((res) => {
|
||||
creatPPT(this.currentNode.label + '.pptx', this.uploadData).then((res) => {
|
||||
this.currentFileList.unshift(res.resData)
|
||||
})
|
||||
},
|
||||
|
@ -160,35 +149,6 @@ export default {
|
|||
clickChoose(value) {
|
||||
this.checkFileList = value ? this.currentFileList : []
|
||||
},
|
||||
async asyncAllFile() {
|
||||
this.lastAsyncAllTime = new Date()
|
||||
localStorage.setItem('lastAsyncAllTime', this.lastAsyncAllTime)
|
||||
this.asyncAllFileVisiable = true
|
||||
const test = (item) => {
|
||||
return new Promise((resolve) => {
|
||||
isHaveLocalFile(item.fileNewName).then((res) => {
|
||||
item.async = res
|
||||
if (res === false) {
|
||||
ipcRenderer.send('download-file-default', {
|
||||
url: item.fileFullPath,
|
||||
fileName: item.fileNewName
|
||||
})
|
||||
item.async = 'on'
|
||||
ipcRenderer.once('download-file-default' + item.fileNewName, (e, isSuccess) => {
|
||||
item.async = isSuccess
|
||||
resolve()
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
for (let i = 0; i < this.currentFileList.length; i++) {
|
||||
await test(this.currentFileList[i])
|
||||
}
|
||||
this.asyncAllFileVisiable = false
|
||||
},
|
||||
deleteTalk(item) {
|
||||
let index = this.currentFileList.indexOf(item)
|
||||
this.currentFileList.splice(index, 1)
|
||||
|
@ -254,15 +214,7 @@ export default {
|
|||
}
|
||||
console.log('File copied to:', filePath)
|
||||
},
|
||||
nodeClick(data) {
|
||||
if (this.currentNode.id === data.node.id) return
|
||||
this.checkFileList = []
|
||||
let cata = parseCataByNode(data.node)
|
||||
this.currentNode = data.node
|
||||
this.uploadData.levelFirstId = cata[0]
|
||||
this.uploadData.levelSecondId = cata[1]
|
||||
this.uploadData.levelThirdId = cata[2]
|
||||
this.uploadData.textbookId = data.textBook.curBookId
|
||||
asyncAllFile() {
|
||||
this.isLoading = true
|
||||
getSmarttalkPage({
|
||||
...this.uploadData,
|
||||
|
@ -270,20 +222,44 @@ export default {
|
|||
isAsc: 'desc',
|
||||
pageSize: 500
|
||||
})
|
||||
.then((res) => {
|
||||
.then(async (res) => {
|
||||
this.currentFileList = [...res.rows]
|
||||
this.isLoading = false
|
||||
this.currentFileList.filter((item) => {
|
||||
isHaveLocalFile(item.fileNewName).then((res) => {
|
||||
item.async = res
|
||||
})
|
||||
})
|
||||
this.lastAsyncAllTime = new Date()
|
||||
localStorage.setItem('lastAsyncAllTime', this.lastAsyncAllTime)
|
||||
this.asyncAllFileVisiable = true
|
||||
for (let i = 0; i < this.currentFileList.length; i++) {
|
||||
let item = this.currentFileList[i]
|
||||
await asyncLocalFile(item)
|
||||
}
|
||||
this.asyncAllFileVisiable = false
|
||||
})
|
||||
.catch((res) => {
|
||||
console.log(res)
|
||||
.catch(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
nodeClick(data) {
|
||||
if (this.currentNode.id === data.node.id) return
|
||||
this.curBookImg = data.textBook.curBookImg
|
||||
this.checkFileList = []
|
||||
let cata = parseCataByNode(data.node)
|
||||
this.currentNode = data.node
|
||||
this.uploadData.levelFirstId = cata[0]
|
||||
this.uploadData.levelSecondId = cata[1]
|
||||
this.uploadData.levelThirdId = cata[2]
|
||||
this.uploadData.textbookId = data.textBook.curBookId
|
||||
this.asyncAllFile()
|
||||
},
|
||||
// 打开外部链接
|
||||
handleOutLink(key){
|
||||
// key 对应的 linkConfig.js 外部链接配置
|
||||
let configObj = outLink[key]
|
||||
// 通知主进程
|
||||
ipcRenderer.send('openWindow', {
|
||||
fullPath: configObj.fullPath,
|
||||
cookieData: {...(configObj.data)}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -321,6 +297,7 @@ export default {
|
|||
height: 100%;
|
||||
|
||||
.page-right {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
|
@ -332,6 +309,55 @@ export default {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.header-top {
|
||||
height: 150px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(#97c4ed, #7aa8e5);
|
||||
padding-right: 20px;
|
||||
.textbook-img{
|
||||
height: 120px;
|
||||
background-color: #ffffff;
|
||||
padding: 5px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.top-item{
|
||||
width: 230px;
|
||||
|
||||
flex-wrap: wrap;
|
||||
.btn{
|
||||
width: 102px;
|
||||
background: none;
|
||||
color: #ffffff;
|
||||
border-width: 2px;
|
||||
border-color: #ffffff;
|
||||
&:hover{
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
&:first-child{
|
||||
margin-left: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
&:nth-child(2){
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.to-class-btn{
|
||||
width: 130px;
|
||||
height: 80px;
|
||||
margin-left: 25px;
|
||||
font-size: 18px;
|
||||
.icon-lingdang{
|
||||
margin-right: 5px;
|
||||
color: #ffffff;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.prepare-body-header {
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
|
@ -340,6 +366,7 @@ export default {
|
|||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
|
||||
}
|
||||
|
||||
.prepare-body-main {
|
||||
|
|
|
@ -99,6 +99,7 @@ const state = reactive({
|
|||
|
||||
function getUser() {
|
||||
getUserProfile().then((response) => {
|
||||
response.data.avatar = import.meta.env.VITE_APP_BASE_API + response.data.avatar
|
||||
state.user = response.data
|
||||
state.roleGroup = response.roleGroup
|
||||
state.postGroup = response.postGroup
|
||||
|
|
|
@ -84,7 +84,7 @@ const title = ref('修改头像')
|
|||
|
||||
//图片裁剪数据
|
||||
const options = reactive({
|
||||
img: userStore.avatar, // 裁剪图片的地址
|
||||
img: userStore.user.avatar, // 裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: 200, // 默认生成截图框宽度
|
||||
autoCropHeight: 200, // 默认生成截图框高度
|
||||
|
@ -155,7 +155,7 @@ function uploadImg() {
|
|||
uploadAvatar(formData).then((response) => {
|
||||
open.value = false
|
||||
options.img = import.meta.env.VITE_APP_BASE_API + response.imgUrl
|
||||
userStore.avatar = options.img
|
||||
userStore.user.avatar = options.img
|
||||
ElMessage({
|
||||
message: '上传成功',
|
||||
type: 'success',
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
}}</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12" class="search-box flex">
|
||||
<el-input v-model="sourceStore.query.fileName" @input="sourceStore.changeName" style="width: 240px" placeholder="请输入关键词" />
|
||||
<el-input v-model="sourceStore.query.fileName" @input="sourceStore.changeName" style="width: 240px"
|
||||
placeholder="请输入关键词" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="resoure-btns">
|
||||
<el-col :span="24" class="query-row flex">
|
||||
<div class="flex row-left"> <el-select v-model="sourceStore.query.fileSuffix" @change="sourceStore.changeSuffix"
|
||||
<div class="flex row-left"> <el-select v-model="sourceStore.query.fileSuffix" @change="sourceStore.changeSuffix"
|
||||
style="width: 110px">
|
||||
<el-option v-for="item in sourceStore.resourceFormatList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
|
@ -22,7 +23,7 @@
|
|||
<el-button v-for="item in sourceStore.resourceTypeList" :key="item.id"
|
||||
:type="sourceStore.query.fileFlag == item.value ? 'primary' : ''" round
|
||||
@click="sourceStore.changeType(item.value)">{{
|
||||
item.label }}</el-button>
|
||||
item.label }}</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<slot name="add" />
|
||||
|
@ -58,7 +59,8 @@ const sourceStore = useResoureStore()
|
|||
|
||||
.query-row {
|
||||
justify-content: space-between;
|
||||
.row-left{
|
||||
|
||||
.row-left {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
@ -70,11 +72,12 @@ const sourceStore = useResoureStore()
|
|||
margin: 0 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
.el-button.is-round{
|
||||
|
||||
.el-button.is-round {
|
||||
padding: 3px 15px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="page-right">
|
||||
<!-- 搜索 -->
|
||||
<ResoureSearch #add>
|
||||
<el-button type="primary" round @click="openDialog" class="create-btn">
|
||||
<el-button v-if="sourceStore.isCreate" type="primary" round @click="openDialog" class="create-btn">
|
||||
<i class="iconfont icon-jiahao"></i>
|
||||
新建资源</el-button>
|
||||
</ResoureSearch>
|
||||
|
@ -27,7 +27,8 @@ import ResoureList from './container/resoure-list.vue'
|
|||
import uploadDialog from '@/components/upload-dialog/index.vue'
|
||||
import uploaderState from '@/store/modules/uploader'
|
||||
import { createTools } from '@/utils/tool'
|
||||
|
||||
import { hasPermission } from '@/utils/hasPermission'
|
||||
//
|
||||
const sourceStore = useResoureStore()
|
||||
const isDialogOpen = ref(false)
|
||||
|
||||
|
@ -75,17 +76,20 @@ const submitFile = (data) => {
|
|||
item.fileData = fileData
|
||||
item.callback = fileCallBack
|
||||
})
|
||||
// console.log(fileList)
|
||||
uploaderState().pushFile(fileList)
|
||||
}
|
||||
|
||||
|
||||
const fileCallBack = (res) => {
|
||||
console.log(res)
|
||||
if (res.code == 200) {
|
||||
sourceStore.handleQuery()
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
sourceStore.getCreate()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
|
|||
import { getSmarttalkPage } from '@/api/file/index'
|
||||
import { tabs, resourceType, resourceFormat } from '@/utils/resourceDict'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { hasPermission } from '@/utils/hasPermission'
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
|
@ -21,10 +22,10 @@ const resourceFormatList = [
|
|||
]
|
||||
|
||||
// 校本资源为学校ID
|
||||
tabs.forEach(item =>{
|
||||
if( item.label == "校本资源"){
|
||||
item.value = userStore.user.deptId
|
||||
}
|
||||
tabs.forEach((item) => {
|
||||
if (item.label == '校本资源') {
|
||||
item.value = userStore.user.deptId
|
||||
}
|
||||
})
|
||||
|
||||
const structQuery = {
|
||||
|
@ -39,14 +40,16 @@ export default defineStore('resource', {
|
|||
resourceFormatList,
|
||||
|
||||
searchKey: '',
|
||||
|
||||
|
||||
//节点数据
|
||||
nodeData:{},
|
||||
nodeData: {},
|
||||
loading: false,
|
||||
//
|
||||
isCreate: true,
|
||||
//查询条件
|
||||
query: {
|
||||
textbookId: '',
|
||||
fileSource: '平台',
|
||||
fileSource: tabs[0].value,
|
||||
//资源格式 mp3 ppt ...
|
||||
fileSuffix: -1,
|
||||
// 资源类型 课件 素材 教案
|
||||
|
@ -66,8 +69,8 @@ export default defineStore('resource', {
|
|||
handleQuery() {
|
||||
try {
|
||||
this.loading = true
|
||||
let data = {...this.query}
|
||||
if(data.fileSuffix == -1){
|
||||
let data = { ...this.query }
|
||||
if (data.fileSuffix == -1) {
|
||||
data.fileSuffix = ''
|
||||
}
|
||||
getSmarttalkPage(data).then((res) => {
|
||||
|
@ -80,20 +83,28 @@ export default defineStore('resource', {
|
|||
},
|
||||
changeTab(val) {
|
||||
this.query.fileSource = val
|
||||
this.getCreate()
|
||||
this.handleQuery()
|
||||
},
|
||||
changeType(val) {
|
||||
this.query.fileFlag = val
|
||||
this.handleQuery()
|
||||
},
|
||||
changeSuffix(val){
|
||||
changeSuffix(val) {
|
||||
this.query.fileSuffix = val
|
||||
this.handleQuery()
|
||||
},
|
||||
// 关键词搜索
|
||||
changeName(){
|
||||
console.log(this.query.fileName)
|
||||
changeName() {
|
||||
this.handleQuery()
|
||||
},
|
||||
getCreate(){
|
||||
if(this.query.fileSource == '平台'){
|
||||
this.isCreate = hasPermission(['platformmanager'])
|
||||
}
|
||||
else{
|
||||
this.isCreate = hasPermission(['schoolteacher','headmaster'])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue