Compare commits

...

72 Commits

Author SHA1 Message Date
yangws d2f57fd18e add:班级管理; 2024-07-26 12:09:31 +08:00
lyc 03bcade299 Merge pull request 'lyc-dev' (#66) from lyc-dev into main 2024-07-26 11:06:46 +08:00
lyc 8c7468ef7f Merge branch 'main' into lyc-dev 2024-07-26 11:06:32 +08:00
lyc 7e3978d532 图标 2024-07-26 11:06:06 +08:00
lyc 01d972f18e Merge pull request '图标' (#65) from lyc-dev into main 2024-07-26 10:43:51 +08:00
lyc c0c3324d9d 图标 2024-07-26 10:43:46 +08:00
lyc daaddfaaf2 Merge pull request 'lyc-dev' (#64) from lyc-dev into main 2024-07-26 09:44:11 +08:00
lyc 5fea7e094d 资源-上传修改 2024-07-26 09:43:59 +08:00
lyc e221bedb81 Merge branch 'main' into lyc-dev 2024-07-25 16:45:36 +08:00
lyc 0ec1a7327a 更新 2024-07-25 16:45:17 +08:00
lyc ed9f3d4189 Merge pull request '教学模型跳转' (#63) from lyc-dev into main 2024-07-25 10:52:39 +08:00
lyc af20ff4931 教学模型跳转 2024-07-25 10:52:29 +08:00
lyc 08c365b0ed Merge pull request '资源模块-新建权限' (#62) from lyc-dev into main 2024-07-25 10:08:17 +08:00
lyc 212d5be4d4 资源模块-新建权限 2024-07-25 10:07:59 +08:00
朱浩 415a4c17c1 Merge pull request 'zhuhao_dev' (#61) from zhuhao_dev into main
Reviewed-on: #61
2024-07-25 09:20:57 +08:00
朱浩 88e306e8a2 Merge branch 'main' into zhuhao_dev 2024-07-25 09:19:56 +08:00
朱浩 e5c55cefda 二期:文件上传图标修复 2024-07-25 09:19:43 +08:00
lyc 78e666d6c1 Merge pull request 'lyc-dev' (#60) from lyc-dev into main 2024-07-25 09:15:03 +08:00
lyc 580ab2ee5b Merge branch 'main' into lyc-dev 2024-07-25 09:14:35 +08:00
lyc cda6e3e2c4 edit 2024-07-25 09:12:52 +08:00
lyc 75595562db Merge pull request 'lyc-dev' (#59) from lyc-dev into main 2024-07-24 15:27:57 +08:00
lyc ea5a069f85 Merge branch 'main' into lyc-dev 2024-07-24 15:24:03 +08:00
lyc bf9e7c96ff 平台资源管理员 2024-07-24 15:23:26 +08:00
朱浩 d0bf9c0768 Merge pull request 'zhuhao_dev' (#58) from zhuhao_dev into main
Reviewed-on: #58
2024-07-24 14:49:32 +08:00
朱浩 eff5688e42 Merge branch 'main' into zhuhao_dev 2024-07-24 14:48:36 +08:00
朱浩 4e9c93da15 二期:头像相关问题修复 2024-07-24 14:48:18 +08:00
lyc e6da6ef65f 打开外部链接 2024-07-24 14:03:59 +08:00
lyc a618032d25 Merge branch 'main' into lyc-dev 2024-07-23 16:04:16 +08:00
朱浩 a25be335e6 Merge pull request 'zhuhao_dev' (#57) from zhuhao_dev into main
Reviewed-on: #57
2024-07-23 16:02:27 +08:00
朱浩 62248dfafa Merge branch 'main' into zhuhao_dev
# Conflicts:
#	src/renderer/src/views/prepare/index.vue
2024-07-23 16:01:53 +08:00
朱浩 2926b4bd63 二期:自动同步功能开发 2024-07-23 15:59:52 +08:00
lyc ac5cafe1e8 Merge branch 'main' into lyc-dev 2024-07-23 14:33:18 +08:00
lyc 0086ce4236 open win cookie 2024-07-23 14:33:07 +08:00
朱浩 af941a22b7 Merge pull request '二期:自动同步功能开发' (#56) from zhuhao_dev into main
Reviewed-on: #56
2024-07-23 14:32:01 +08:00
朱浩 4dc180a26f 二期:自动同步功能开发 2024-07-23 14:31:33 +08:00
lyc 3487cabc02 Merge pull request 'lyc-dev' (#55) from lyc-dev into main 2024-07-23 14:08:22 +08:00
lyc 5712e77a29 openwindow 2024-07-23 14:08:00 +08:00
朱浩 7106d75964 Merge pull request '二期:自动同步功能开发' (#54) from zhuhao_dev into main
Reviewed-on: #54
2024-07-23 14:07:13 +08:00
朱浩 4c635e9fe3 二期:自动同步功能开发 2024-07-23 14:06:42 +08:00
lyc 4a5fb04362 Merge branch 'main' into lyc-dev 2024-07-23 13:46:32 +08:00
lyc d91f08d398 布置作业 2024-07-23 13:46:09 +08:00
朱浩 5afa31b8c3 Merge pull request 'zhuhao_dev' (#53) from zhuhao_dev into main
Reviewed-on: #53
2024-07-23 13:45:27 +08:00
朱浩 c8f1047124 Merge branch 'main' into zhuhao_dev
# Conflicts:
#	src/renderer/src/views/prepare/index.vue
2024-07-23 13:44:44 +08:00
朱浩 e1fc883870 二期:自动同步功能开发 2024-07-23 13:43:41 +08:00
lyc c81b74b9de Merge pull request 'lyc-dev' (#52) from lyc-dev into main 2024-07-23 10:23:45 +08:00
lyc 2fbc3e272b Merge branch 'main' into lyc-dev 2024-07-23 10:23:34 +08:00
lyc 125962b859 备课-增加头部布局 2024-07-23 10:23:18 +08:00
lyc 5f05ad8bea Merge pull request '打开新网页窗口' (#51) from lyc-dev into main 2024-07-22 16:25:13 +08:00
lyc 3dc478e724 打开新网页窗口 2024-07-22 16:24:32 +08:00
lyc d72d0ae956 Merge pull request '登录窗口/主窗口调整' (#50) from lyc-dev into main 2024-07-22 15:11:06 +08:00
lyc cefb6ae5a7 登录窗口/主窗口调整 2024-07-22 15:10:28 +08:00
lyc 7b09c8ec81 Merge pull request 'window-tools' (#49) from lyc-dev into main 2024-07-22 11:25:26 +08:00
lyc de1e0c5a2e window-tools 2024-07-22 11:24:36 +08:00
lyc 8ed27fc925 Merge pull request '退出 跳转' (#48) from lyc-dev into main 2024-07-19 11:10:12 +08:00
lyc e5e4359b5d 退出 跳转 2024-07-19 11:09:55 +08:00
lyc 1ce8fd1714 Merge pull request '请求地址修改' (#47) from lyc-dev into main 2024-07-19 10:31:59 +08:00
lyc 6dbe3c6202 请求地址修改 2024-07-19 10:31:41 +08:00
lyc 78b30feb13 Merge pull request '删除一些无用图片' (#46) from lyc-dev into main 2024-07-19 09:37:57 +08:00
lyc b16f067cee 删除一些无用图片 2024-07-19 09:33:52 +08:00
lyc 0228bc3084 Merge pull request 'lyc-dev' (#44) from lyc-dev into main 2024-07-18 17:54:03 +08:00
lyc be0a34f03e edit 2024-07-18 17:53:43 +08:00
朱浩 d5c1d08fa2 Merge pull request '基础文件上传核心开发' (#45) from zhuhao_dev into main
Reviewed-on: #45
2024-07-18 16:38:14 +08:00
朱浩 21ff546429 基础文件上传核心开发 2024-07-18 16:37:46 +08:00
lyc 7d80846e0c Merge branch 'main' into lyc-dev 2024-07-18 16:33:21 +08:00
朱浩 d262c87b60 Merge pull request 'zhuhao_dev' (#43) from zhuhao_dev into main
Reviewed-on: #43
2024-07-18 16:32:39 +08:00
朱浩 243561e656 Merge branch 'main' into zhuhao_dev 2024-07-18 16:28:21 +08:00
朱浩 6f18bf9344 基础文件上传核心开发 2024-07-18 16:28:00 +08:00
lyc 4b9b5c544f 合并冲突 2024-07-18 16:23:22 +08:00
lyc c8389645af 删除一些无用文件 2024-07-18 16:22:03 +08:00
yangws 1e0d0d18e0 Merge pull request 'fix: 更改图片的同时更改头像;' (#42) from yangws into main
Reviewed-on: #42
2024-07-18 16:01:17 +08:00
朱浩 e8d48d8bd9 Merge branch 'main' into zhuhao_dev 2024-07-18 15:17:45 +08:00
朱浩 a30d2945a0 基础文件上传核心开发 2024-07-18 15:17:15 +08:00
226 changed files with 2658 additions and 372 deletions

View File

@ -7,6 +7,8 @@ VITE_APP_ENV = 'development'
# AIx融合数字管理系统/开发环境
VITE_APP_BASE_API = '/dev-api'
VITE_APP_UPLOAD_API = 'http://192.168.2.52:7863'
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'

View File

@ -5,11 +5,13 @@ VITE_APP_TITLE = AIx数字平台
VITE_APP_ENV = 'production'
# AIx融合数字管理系统/生产环境
VITE_APP_BASE_API = 'http://192.168.2.52:7863'
VITE_APP_BASE_API = 'https://file.ysaix.com:7868/prod-api'
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip
VITE_APP_RES_FILE_PATH = 'https://prev.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://prev.ysaix.com:7868/'
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'

View File

@ -1,3 +1,3 @@
provider: generic
url: https://example.com/auto-updates
url: http://localhost:3000/
updaterCacheDirName: electron-app-updater

47
electron-builder-test.yml Normal file
View File

@ -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/logo2.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/

View File

@ -12,6 +12,7 @@ asarUnpack:
- resources/**
win:
executableName: AIx
icon: resources/logo2.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/

View File

@ -26,11 +26,6 @@ export default defineConfig({
target: 'http://192.168.2.52:7863',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
},
'/profile': {
// target: 'http://27.128.240.72:7865',
target: 'https://cqyy.ysaix.com:7868',
changeOrigin: true
}
},
},

View File

@ -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"
},
@ -21,17 +22,22 @@
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^3.0.0",
"@element-plus/icons-vue": "^2.3.1",
"@vitejs/plugin-vue-jsx": "^4.0.0",
"@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",
"js-cookie": "^3.0.5",
"jsencrypt": "^3.3.2",
"lodash": "^4.17.21",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"vue-cropper": "^1.0.3",
"vue-router": "^4.4.0"
"spark-md5": "^3.0.2",
"vue-cropper": "^1.1.4",
"vue-router": "^4.4.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@electron-toolkit/eslint-config": "^1.0.2",

BIN
resources/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

BIN
resources/logo2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View File

@ -1,25 +1,148 @@
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) => {
if (err) {
e.reply('is-have-local-file-reply'+fileNewName, false)
e.reply('is-have-local-file-reply' + fileNewName, false)
return
}
e.reply('is-have-local-file-reply'+fileNewName, true)
e.reply('is-have-local-file-reply' + fileNewName, true)
})
})
/*
* 判断是需要同步本地文件
* */
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
@ -35,6 +158,78 @@ 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 uploadFileByFS({ url, path, name, cookie, fileType, formData, success, error }) {
fs.readFile(path, (err, data) => {
if (err) {
return console.error(err)
}
// 配置上传的请求
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')
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])
}
}
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)
}
})
})
})
//获取应用文件目录
ipcMain.on('get-root-file-path', (e) => {
e.reply('get-root-file-path-reply', appRootFilePath)
@ -53,23 +248,22 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
onDownloadStarted: async ({ id, item, webContents }) => {
// Do something with the download id
},
onDownloadProgress: async ({ id, item, percentCompleted }) => {
},
onDownloadProgress: async ({ id, item, percentCompleted }) => {},
onDownloadCompleted: async ({ id, item }) => {
console.log('完成')
e.reply('download-file-default'+fileName,true)
e.reply('download-file-default' + fileName, true)
},
onDownloadCancelled: async () => {
console.log('取消')
e.reply('download-file-default'+fileName,false)
e.reply('download-file-default' + fileName, false)
},
onDownloadInterrupted: async () => {
console.log('中断')
e.reply('download-file-default'+fileName,false)
e.reply('download-file-default' + fileName, false)
},
onError: (err, data) => {
console.log(err.toString())
e.reply('download-file-default'+fileName,false)
e.reply('download-file-default' + fileName, false)
}
}
})
@ -124,6 +318,76 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
})
})
/*导出文件*/
function exportFile(list, callback) {
let win = BrowserWindow.getFocusedWindow()
//通过扩展名识别文件类型
let filePath = null //用户选择存放文件的路径
//1- 弹出另存为弹框,用于获取保存路径
dialog
.showOpenDialog(win, {
properties: ['openDirectory']
})
.then(async (result) => {
if (result.filePaths[0]) {
filePath = result.filePaths[0]
let res = []
for (let i = 0; i < list.length; i++) {
let item = list[i]
let source = appRootFilePath + item.id
let destination = filePath + '/' + item.name
await copyRelFile(source, filterCopyFile(destination), (error, path) => {
res.push({ error, path })
})
}
callback(res)
}
})
.catch(() => {
console.log('另存为--catch')
})
}
/*文件是否已经存在*/
function isHaveFile(path) {
return fs.existsSync(path)
}
/*判断是否已经存在这个名字的文件,如果已经存在则递增导出*/
function filterCopyFile(path, index = 0) {
if (isHaveFile(path) === true) {
index++
path = path.replaceAll('.', `(${index}).`)
return filterCopyFile(path, index)
} else {
return path
}
}
/*复制文件*/
function copyRelFile(source, destination, callback) {
return new Promise((resolve, reject) => {
const readStream = fs.createReadStream(source)
const writeStream = fs.createWriteStream(destination)
readStream.on('error', (error) => {
reject()
callback(error, null)
})
writeStream.on('error', (error) => {
reject()
callback(error, null)
})
writeStream.on('close', () => {
console.log('关闭写入流')
callback(null, destination)
resolve()
})
readStream.pipe(writeStream)
})
}
/*复制文件*/
function copyFile(source, destination, callback) {
let path = appRootFilePath + destination
createFolder('selfFile').then(() => {
@ -144,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)

View File

@ -1,18 +1,59 @@
import { app, shell, BrowserWindow, ipcMain } from 'electron'
import { app, shell, BrowserWindow, ipcMain, session } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import File from './file'
import updateInit from './update'
File({ app, shell, BrowserWindow, ipcMain })
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
let mainWindow, loginWindow
//登录窗口
function createLoginWindow() {
if (loginWindow) return
loginWindow = new BrowserWindow({
width: 888,
height: 520,
show: false,
frame: false,
autoHideMenuBar: true,
icon: join(__dirname, '../../resources/logo2.ico'),
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
nodeIntegration: true
}
})
// 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
})
}
//主窗口
function createMainWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 700,
show: false,
frame: false, // 无边框
autoHideMenuBar: true,
icon: join(__dirname, '../../resources/logo2.ico'),
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
@ -24,48 +65,119 @@ function createWindow() {
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.openDevTools()
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
mainWindow.webContents.openDevTools()
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
// mainWindow.loadURL('https://file.ysaix.com:7868/')
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] )
} else {
// mainWindow.loadURL('https://file.ysaix.com:7868/')
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
// Set app user model id for windows
// 作业窗口相关-开发中
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,
worldSafeExecuteJavaScript: true,
contextIsolation: true
}
})
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);
})
linkWindow.loadURL(data.fullPath)
linkWindow.once('ready-to-show', () => {
linkWindow.show()
linkWindow.maximize()
})
linkWindow.on('closed', () => {
linkWindow = null
})
}
// 初始化完成
app.on('ready', () => {
// 设置应用程序用户模型标识符
electronApp.setAppUserModelId('com.electron')
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
//一个新的browserWindow 被创建时触发
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
//窗口 最大、最小、关闭
ipcMain.on('minimize-window', () => {
if (loginWindow) {
loginWindow.minimize()
}
if (mainWindow) {
mainWindow.minimize()
}
})
ipcMain.on('maximize-window', () => {
mainWindow.isMaximized() ? mainWindow.unmaximize() : mainWindow.maximize()
})
createWindow()
ipcMain.on('close-window', () => {
if (loginWindow) {
loginWindow.destroy()
}
if (mainWindow) {
mainWindow.destroy()
}
})
// 打开主窗口
ipcMain.on('openMainWindow', () => {
if (!mainWindow) {
createMainWindow()
}
loginWindow.destroy()
loginWindow = null
})
// 打开登录窗口
ipcMain.on('openLoginWindow', () => {
if (!loginWindow) {
createLoginWindow()
}
mainWindow.destroy()
mainWindow = null
loginWindow.show()
loginWindow.focus()
})
//打开作业窗口
ipcMain.on('openWindow', (e, data) => {
createLinkWin(data)
})
createLoginWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
if (BrowserWindow.getAllWindows().length === 0) createLoginWindow()
})
})
@ -77,35 +189,3 @@ app.on('window-all-closed', () => {
app.quit()
}
})
ipcMain.on('toggle-top', (event) => {
const win = BrowserWindow.getFocusedWindow();
const isAlwaysOnTop = win.isAlwaysOnTop();
win.setAlwaysOnTop(!isAlwaysOnTop);
event.sender.send('top-status-changed', !isAlwaysOnTop);
})
ipcMain.on('minimize-window', () => {
const win = BrowserWindow.getFocusedWindow();
win.minimize();
});
ipcMain.on('maximize-window', () => {
const win = BrowserWindow.getFocusedWindow();
if (win.isMaximized()) {
win.unmaximize();
} else {
win.maximize();
}
});
ipcMain.on('close-window', () => {
const win = BrowserWindow.getFocusedWindow();
win.close();
});
ipcMain.on('set-winsize', (e, {x, y})=>{
const win = BrowserWindow.getFocusedWindow();
win.setSize(x,y);
win.center()
})

61
src/main/update.js Normal file
View File

@ -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

View File

@ -8,7 +8,7 @@
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
/> -->
<meta http-equiv="Content-Security-Policy" content="connect-src *; default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:" />
<meta http-equiv="Content-Security-Policy" content="connect-src *; default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src * 'self' data: blob:" />
</head>

View File

@ -0,0 +1,132 @@
// 查询evaluation列表
import request from '@/utils/request'
// 查询班级列表
export function listClassmain(query) {
return request({
url: '/education/classmain/list',
method: 'get',
params: query
})
}
// 查询学生列表
export function listClassuser(query) {
return request({
url: '/education/classuser/list',
method: 'get',
params: query
})
}
// 新增班级
export function addClassmain(data) {
return request({
url: '/education/classmain',
method: 'post',
data: data
})
}
// 查询所有学科的列表
export function listEvaluation(query) {
return request({
url: '/education/evaluation/list',
method: 'get',
params: query
})
}
// 新增小组
export function addClassgroup(data) {
return request({
url: '/education/classgroup',
method: 'post',
data: data
})
}
//班级详情
export function getClassmain(id) {
return request({
url: '/education/classmain/' + id,
method: 'get'
})
}
// 获取小组列表
export function listClassgroup(query) {
return request({
url: '/education/classgroup/list',
method: 'get',
params: query
})
}
//删除小组
export function delClassgroup(id) {
return request({
url: '/education/classgroup/' + id,
method: 'delete'
})
}
//查询小组信息
export function getClassgroup(id) {
return request({
url: '/education/classgroup/' + id,
method: 'get'
})
}
//修改小组信息
export function updateClassgroup(data) {
return request({
url: '/education/classgroup',
method: 'put',
data: data
})
}
//新增学生
export function addStudentmain(data) {
return request({
url: '/education/studentmain',
method: 'post',
data: data
})
}
//修改学生信息
export function updateStudentmain(data) {
return request({
url: '/education/studentmain',
method: 'put',
data: data
})
}
//获取学生信息
export function getStudentmain(id) {
return request({
url: '/education/studentmain/' + id,
method: 'get'
})
}
//删除学生
export function leaveClass(data) {
return request({
url: '/education/classuser/leaveClass',
method: 'post',
data: data
})
}
//删除学生所有数据
export function removeStudentDataAll(id) {
return request({
url: '/education/studentmain/removeStudent/' + id,
method: 'post'
})
}
//删除教室
export function delClassroom(id) {
return request({
url: '/education/classroom/' + id,
method: 'delete'
})
}
//导入学生
export function addStudentmainByNameArray(data) {
return request({
url: '/education/studentmain/addByNameArray',
method: 'post',
data: data
})
}

View File

@ -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,

View File

@ -1,9 +1,9 @@
@font-face {
font-family: "iconfont"; /* Project id 2794390 */
src: url('iconfont.woff2?t=1721179711733') format('woff2'),
url('iconfont.woff?t=1721179711733') format('woff'),
url('iconfont.ttf?t=1721179711733') format('truetype'),
url('iconfont.svg?t=1721179711733#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,6 +14,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-lingdang:before {
content: "\e613";
}
.icon-yidongdaozu:before {
content: "\e67d";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "17990800",
"name": "铃铛",
"font_class": "lingdang",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "1207918",
"name": "移动到组",

View File

@ -14,6 +14,8 @@
/>
<missing-glyph />
<glyph glyph-name="lingdang" unicode="&#58899;" 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="&#59005;" 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" />
<glyph glyph-name="shanchu" unicode="&#59474;" d="M736.653061-33.959184H287.346939c-45.97551 0-83.591837 37.616327-83.591837 83.591837V540.734694h616.489796v-491.102041c0-45.97551-37.616327-83.591837-83.591837-83.591837zM245.55102 498.938776v-449.306123c0-22.987755 18.808163-41.795918 41.795919-41.795918h449.306122c22.987755 0 41.795918 18.808163 41.795919 41.795918V498.938776H245.55102zM407.510204 101.877551c-11.493878 0-20.897959 9.404082-20.897959 20.897959V384c0 11.493878 9.404082 20.897959 20.897959 20.897959s20.897959-9.404082 20.897959-20.897959v-261.22449c0-11.493878-9.404082-20.897959-20.897959-20.897959zM616.489796 101.877551c-11.493878 0-20.897959 9.404082-20.897959 20.897959V384c0 11.493878 9.404082 20.897959 20.897959 20.897959s20.897959-9.404082 20.897959-20.897959v-261.22449c0-11.493878-9.404082-20.897959-20.897959-20.897959zM846.367347 498.938776H177.632653c-45.97551 0-83.591837 37.616327-83.591837 83.591836v31.346939c0 45.97551 37.616327 83.591837 83.591837 83.591837h668.734694c45.97551 0 83.591837-37.616327 83.591837-83.591837v-31.346939c0-45.97551-37.616327-83.591837-83.591837-83.591836zM177.632653 655.673469c-22.987755 0-41.795918-18.808163-41.795918-41.795918v-31.346939c0-22.987755 18.808163-41.795918 41.795918-41.795918h668.734694c22.987755 0 41.795918 18.808163 41.795918 41.795918v31.346939c0 22.987755-18.808163 41.795918-41.795918 41.795918H177.632653zM650.44898 655.673469h-276.89796c-28.734694 0-52.244898 23.510204-52.244898 52.244898v41.795919c0 28.734694 23.510204 52.244898 52.244898 52.244898h276.89796c28.734694 0 52.244898-23.510204 52.244898-52.244898v-41.795919c0-28.734694-23.510204-52.244898-52.244898-52.244898z m-276.89796 104.489796c-5.746939 0-10.44898-4.702041-10.448979-10.448979v-41.795919c0-5.746939 4.702041-10.44898 10.448979-10.448979h276.89796c5.746939 0 10.44898 4.702041 10.448979 10.448979v41.795919c0 5.746939-4.702041 10.44898-10.448979 10.448979h-276.89796z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Some files were not shown because too many files have changed in this diff Show More