Compare commits
22 Commits
6b8c6c8c7f
...
9f510187c0
Author | SHA1 | Date |
---|---|---|
朱浩 | 9f510187c0 | |
朱浩 | 3bcb0a2ef3 | |
朱浩 | 9018abb673 | |
朱浩 | a55a662ce9 | |
朱浩 | 528e7876a9 | |
朱浩 | 82456a7f96 | |
lyc | 74b0cf5fdb | |
lyc | df7658a17d | |
lyc | 8a9fa83c04 | |
lyc | 9a6f37528c | |
zhengdegang | d64b469ac8 | |
zdg | 19901d802f | |
zdg | 22a92ee84b | |
zdg | 8d558c47f5 | |
lyc | 9ab5f65409 | |
lyc | 95e9fc528a | |
lyc | e38235fd6b | |
lyc | 26c46e33c7 | |
lyc | ce274237dc | |
lyc | d46d312b37 | |
lyc | fb84977321 | |
朱浩 | 2ef129d5c1 |
|
@ -5,15 +5,15 @@ VITE_APP_TITLE = AIx数字平台
|
||||||
VITE_APP_ENV = 'production'
|
VITE_APP_ENV = 'production'
|
||||||
|
|
||||||
# AIx融合数字管理系统/生产环境
|
# AIx融合数字管理系统/生产环境
|
||||||
VITE_APP_BASE_API = 'https://file.ysaix.com:7868/prod-api'
|
VITE_APP_BASE_API = 'https://prev.ysaix.com:7868/prod-api'
|
||||||
|
|
||||||
VITE_APP_DOMAIN = 'file.ysaix.com'
|
VITE_APP_DOMAIN = 'prev.ysaix.com'
|
||||||
|
|
||||||
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
|
VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868/prod-api'
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||||
|
|
||||||
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
|
VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/'
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# 页面标题
|
||||||
|
VITE_APP_TITLE = AIx数字平台
|
||||||
|
|
||||||
|
# 生产环境配置
|
||||||
|
VITE_APP_ENV = 'production'
|
||||||
|
|
||||||
|
# AIx融合数字管理系统/生产环境
|
||||||
|
VITE_APP_BASE_API = 'https://file.ysaix.com:7868/prod-api'
|
||||||
|
|
||||||
|
VITE_APP_DOMAIN = 'file.ysaix.com'
|
||||||
|
|
||||||
|
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
|
||||||
|
|
||||||
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
|
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||||
|
|
||||||
|
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
|
|
@ -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: https://prev.ysaix.com:7868/src/assets/smarttalk/
|
||||||
|
electronDownload:
|
||||||
|
mirror: https://npmmirror.com/mirrors/electron/
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "aix-win",
|
"name": "aix-win",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"description": "An Electron application with Vue",
|
"description": "An Electron application with Vue",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "example.com",
|
"author": "example.com",
|
||||||
|
@ -14,7 +14,8 @@
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"postinstall": "electron-builder install-app-deps",
|
||||||
"build:unpack": "npm run build && electron-builder --dir",
|
"build:unpack": "npm run build && electron-builder --dir",
|
||||||
"build:dev": "npm run build && electron-builder --win --config ./electron-builder-test.yml",
|
"build:dev": "npm run build && electron-builder --win --config ./electron-builder-test.yml",
|
||||||
"build:test": "npm run build && electron-builder --win --config ./electron-builder.yml",
|
"build:test": "electron-vite build --mode test && electron-builder --win --config ./electron-builder.yml",
|
||||||
|
"build:prod": "electron-vite build --mode production && electron-builder --win --config ./electron-builder-prod.yml",
|
||||||
"build:mac": "npm run build && electron-builder --mac",
|
"build:mac": "npm run build && electron-builder --mac",
|
||||||
"build:linux": "npm run build && electron-builder --linux"
|
"build:linux": "npm run build && electron-builder --linux"
|
||||||
},
|
},
|
||||||
|
|
|
@ -77,10 +77,10 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
|
||||||
console.error('Error uploading file:', err)
|
console.error('Error uploading file:', err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, 5000)
|
}, 20000)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, 1000)
|
}, 10000)
|
||||||
})
|
})
|
||||||
|
|
||||||
function getFileMD5(path) {
|
function getFileMD5(path) {
|
||||||
|
|
|
@ -103,11 +103,12 @@ function createMainWindow() {
|
||||||
remote.enable(mainWindow.webContents)
|
remote.enable(mainWindow.webContents)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 作业窗口相关-开发中
|
// 打开外部链接窗口
|
||||||
let linkWindow
|
let linkWin = {}
|
||||||
async function createLinkWin(data) {
|
async function createLinkWin(data) {
|
||||||
if (linkWindow) return
|
if (linkWin[data.key]) return
|
||||||
linkWindow = new BrowserWindow({
|
|
||||||
|
linkWin[data.key] = new BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
frame: true,
|
frame: true,
|
||||||
maximizable: true,
|
maximizable: true,
|
||||||
|
@ -120,9 +121,10 @@ async function createLinkWin(data) {
|
||||||
contextIsolation: true
|
contextIsolation: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
linkWindow.type = 'link' // 唯一标识
|
linkWin[data.key].type = 'link' // 唯一标识
|
||||||
|
|
||||||
let cookieDetails = { ...data.cookieData }
|
let cookieDetails = { ...data.cookieData }
|
||||||
await linkWindow.webContents.session.cookies
|
await linkWin[data.key].webContents.session.cookies
|
||||||
.set(cookieDetails)
|
.set(cookieDetails)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('Cookie is successful')
|
console.log('Cookie is successful')
|
||||||
|
@ -131,14 +133,15 @@ async function createLinkWin(data) {
|
||||||
console.error('Cookie is error', error)
|
console.error('Cookie is error', error)
|
||||||
})
|
})
|
||||||
data.fullPath = data.fullPath.replaceAll('//', '/')
|
data.fullPath = data.fullPath.replaceAll('//', '/')
|
||||||
linkWindow.loadURL(data.fullPath)
|
linkWin[data.key].loadURL(data.fullPath)
|
||||||
|
|
||||||
linkWindow.once('ready-to-show', () => {
|
linkWin[data.key].once('ready-to-show', () => {
|
||||||
linkWindow.show()
|
linkWin[data.key].show()
|
||||||
linkWindow.maximize()
|
linkWin[data.key].maximize()
|
||||||
})
|
})
|
||||||
linkWindow.on('closed', () => {
|
linkWin[data.key].on('closed', () => {
|
||||||
linkWindow = null
|
linkWin[data.key] = null
|
||||||
|
delete linkWin[data.key]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,14 +205,8 @@ app.on('ready', () => {
|
||||||
ipcMain.on('openWindow', (e, data) => {
|
ipcMain.on('openWindow', (e, data) => {
|
||||||
createLinkWin(data)
|
createLinkWin(data)
|
||||||
})
|
})
|
||||||
// 新窗口创建-监听
|
// zdg: 消息监听
|
||||||
ipcMain.on('new-window', (e, data) => {
|
handleAll()
|
||||||
const { id, type } = data
|
|
||||||
const win = BrowserWindow.fromId(id)
|
|
||||||
win.type = type // 绑定独立标识
|
|
||||||
remote.enable(win.webContents) // 开启远程服务
|
|
||||||
})
|
|
||||||
|
|
||||||
// 打开-登录窗口
|
// 打开-登录窗口
|
||||||
createLoginWindow()
|
createLoginWindow()
|
||||||
|
|
||||||
|
@ -226,3 +223,24 @@ app.on('window-all-closed', () => {
|
||||||
app.quit()
|
app.quit()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听全局事件
|
||||||
|
function handleAll() {
|
||||||
|
// 新窗口创建-监听
|
||||||
|
ipcMain.on('new-window', (e, data) => {
|
||||||
|
const { id, type } = data
|
||||||
|
const win = BrowserWindow.fromId(id)
|
||||||
|
win.type = type // 绑定独立标识
|
||||||
|
remote.enable(win.webContents) // 开启远程服务
|
||||||
|
})
|
||||||
|
// 用于监听-状态管理变化-同步所有窗口
|
||||||
|
ipcMain.handle('pinia-state-change', (e, storeName, jsonStr) => {
|
||||||
|
for(const curWin of BrowserWindow.getAllWindows()){
|
||||||
|
const id = curWin.webContents.id
|
||||||
|
const bool = id !== e.sender.id && !curWin.isDestroyed()
|
||||||
|
if (bool) { // 除了消息发送窗口和销毁的窗口 其他都发送
|
||||||
|
curWin.webContents.send('pinia-state-set', storeName, jsonStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -18,6 +18,15 @@ export function listEntpcourse(query) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增entpcourse
|
||||||
|
export function addEntpcourse(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/entpcourse',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 布置作业
|
// 布置作业
|
||||||
export function saveByClassWorkArray(data) {
|
export function saveByClassWorkArray(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
<span>{{ curBookName }}</span>
|
<span>{{ curBookName }}</span>
|
||||||
<i class="iconfont icon-xiangyou"></i>
|
<i class="iconfont icon-xiangyou"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="book-list">
|
<div class="book-list" v-loading="treeLoading">
|
||||||
<el-tree ref="refTree" :data="treeData" :props="defaultProps" node-key="id"
|
<el-tree ref="refTree" :data="treeData" :props="defaultProps" node-key="id"
|
||||||
:default-expanded-keys="defaultExpandedKeys" :current-node-key="currentNode" highlight-current
|
:default-expanded-keys="defaultExpandedKeys" :current-node-key="currentNodeId" highlight-current
|
||||||
@node-click="handleNodeClick">
|
@node-click="handleNodeClick">
|
||||||
<template #default="{ node }">
|
<template #default="{ node }">
|
||||||
<span :title="node.label" class="tree-label">{{ node.label }}</span>
|
<span :title="node.label" class="tree-label">{{ node.label }}</span>
|
||||||
|
@ -30,7 +30,10 @@
|
||||||
<el-scrollbar height="450px">
|
<el-scrollbar height="450px">
|
||||||
<div class="textbook-item flex" v-for="item in subjectList" :class="curBookId == item.id ? 'active-item' : ''"
|
<div class="textbook-item flex" v-for="item in subjectList" :class="curBookId == item.id ? 'active-item' : ''"
|
||||||
:key="item.id" @click="changeBook(item)">
|
:key="item.id" @click="changeBook(item)">
|
||||||
<img :src="BaseUrl + item.avartar" class="textbook-img" alt="">
|
<img v-if="item.avartar" :src="BaseUrl + item.avartar" class="textbook-img" alt="">
|
||||||
|
<div v-else class="textbook-img">
|
||||||
|
<i class="iconfont icon-jiaocaixuanze" style="font-size: 40px;"></i>
|
||||||
|
</div>
|
||||||
<span class="book-name">{{ item.itemtitle }}</span>
|
<span class="book-name">{{ item.itemtitle }}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
@ -39,7 +42,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, nextTick, toRaw } from 'vue';
|
import { onMounted, ref, nextTick, toRaw, reactive } from 'vue';
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
import { listEvaluation } from '@/api/subject'
|
import { listEvaluation } from '@/api/subject'
|
||||||
|
|
||||||
|
@ -60,18 +63,26 @@ const defaultProps = {
|
||||||
label: 'label',
|
label: 'label',
|
||||||
class: 'textbook-tree'
|
class: 'textbook-tree'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const treeLoading = ref(false)
|
||||||
//当前教材ID
|
//当前教材ID
|
||||||
const curBookId = ref(-1)
|
const curBookId = ref(-1)
|
||||||
//当前教材名称
|
//当前教材名称
|
||||||
const curBookName = ref('')
|
const curBookName = ref('')
|
||||||
//当前教材封面图
|
//当前教材封面图
|
||||||
const curBookImg = ref('')
|
const curBookImg = ref('')
|
||||||
|
//当前教材文件路径
|
||||||
|
const curBookPath = ref('')
|
||||||
// 上册
|
// 上册
|
||||||
const volumeOne = ref([])
|
const volumeOne = ref([])
|
||||||
// 下册
|
// 下册
|
||||||
const volumeTwo = ref([])
|
const volumeTwo = ref([])
|
||||||
|
// 当前节点
|
||||||
|
const currentNode = reactive({
|
||||||
|
data:{}
|
||||||
|
})
|
||||||
// 当前选中的节点ID
|
// 当前选中的节点ID
|
||||||
const currentNode = ref(0)
|
const currentNodeId = ref(0)
|
||||||
// 当前选中的节点名称
|
// 当前选中的节点名称
|
||||||
const currentNodeName = ref('')
|
const currentNodeName = ref('')
|
||||||
// 默认展开的节点
|
// 默认展开的节点
|
||||||
|
@ -82,6 +93,7 @@ const refTree = ref(null)
|
||||||
|
|
||||||
//获取教材下面的单元内容
|
//获取教材下面的单元内容
|
||||||
const getSubjectContent = async () => {
|
const getSubjectContent = async () => {
|
||||||
|
treeLoading.value = true
|
||||||
const params = {
|
const params = {
|
||||||
edusubject,
|
edusubject,
|
||||||
edustage,
|
edustage,
|
||||||
|
@ -93,12 +105,17 @@ const getSubjectContent = async () => {
|
||||||
if (localStorage.getItem('evaluationList')) {
|
if (localStorage.getItem('evaluationList')) {
|
||||||
evaluationList.value = JSON.parse(localStorage.getItem('evaluationList'))
|
evaluationList.value = JSON.parse(localStorage.getItem('evaluationList'))
|
||||||
data = evaluationList.value
|
data = evaluationList.value
|
||||||
|
treeLoading.value = false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
try {
|
||||||
const { rows } = await listEvaluation(params)
|
const { rows } = await listEvaluation(params)
|
||||||
localStorage.setItem('evaluationList', JSON.stringify(rows))
|
localStorage.setItem('evaluationList', JSON.stringify(rows))
|
||||||
evaluationList.value = rows
|
evaluationList.value = rows
|
||||||
data = rows
|
data = rows
|
||||||
|
} finally {
|
||||||
|
treeLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取教材版本
|
//获取教材版本
|
||||||
|
@ -107,15 +124,15 @@ const getSubjectContent = async () => {
|
||||||
volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
|
volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
|
||||||
//下册
|
//下册
|
||||||
volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
|
volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
|
||||||
|
|
||||||
getTreeData()
|
getTreeData()
|
||||||
}
|
}
|
||||||
|
|
||||||
//选择教材
|
//选择教材
|
||||||
const changeBook = ({ id, itemtitle, avartar }) => {
|
const changeBook = ({ id, itemtitle, avartar, fileurl }) => {
|
||||||
curBookId.value = id
|
curBookId.value = id
|
||||||
curBookName.value = itemtitle
|
curBookName.value = itemtitle
|
||||||
curBookImg.value = BaseUrl + avartar
|
curBookImg.value = BaseUrl + avartar
|
||||||
|
curBookPath.value = fileurl
|
||||||
getTreeData()
|
getTreeData()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
|
@ -126,10 +143,20 @@ const getTreeData = () => {
|
||||||
//数据过滤
|
//数据过滤
|
||||||
let upData = transData(volumeOne.value)
|
let upData = transData(volumeOne.value)
|
||||||
let downData = transData(volumeTwo.value)
|
let downData = transData(volumeTwo.value)
|
||||||
|
if(upData.length && downData.length){
|
||||||
|
treeData.value = [...upData,...downData]
|
||||||
|
}
|
||||||
|
else if(upData.length || downData.length){
|
||||||
treeData.value = upData.length ? upData : downData
|
treeData.value = upData.length ? upData : downData
|
||||||
defaultExpandedKeys.value = [treeData.value[0].id]
|
}
|
||||||
|
else{
|
||||||
|
treeData.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
currentNode.value = getLastLevelData(treeData.value)[0].id
|
defaultExpandedKeys.value = [treeData.value[0].id]
|
||||||
|
currentNode.data = getLastLevelData(treeData.value)[0]
|
||||||
|
currentNodeId.value = getLastLevelData(treeData.value)[0].id
|
||||||
currentNodeName.value = getLastLevelData(treeData.value)[0].label
|
currentNodeName.value = getLastLevelData(treeData.value)[0].label
|
||||||
emitChangeBook()
|
emitChangeBook()
|
||||||
})
|
})
|
||||||
|
@ -138,17 +165,22 @@ const getTreeData = () => {
|
||||||
|
|
||||||
const emitChangeBook = () => {
|
const emitChangeBook = () => {
|
||||||
let curNode = {
|
let curNode = {
|
||||||
id: currentNode.value,
|
id: currentNodeId.value,
|
||||||
label: currentNodeName.value
|
label: currentNodeName.value,
|
||||||
|
itemtitle: currentNode.data.itemtitle,
|
||||||
|
edudegree: currentNode.data.edudegree,
|
||||||
|
edustage: currentNode.data.edustage,
|
||||||
|
edusubject: currentNode.data.edusubject,
|
||||||
}
|
}
|
||||||
let parentNode = findParentByChildId(treeData.value, currentNode.value)
|
let parentNode = findParentByChildId(treeData.value, currentNodeId.value)
|
||||||
curNode.parentNode = toRaw(parentNode)
|
curNode.parentNode = toRaw(parentNode)
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
textBook: {
|
textBook: {
|
||||||
curBookId: curBookId.value,
|
curBookId: curBookId.value,
|
||||||
curBookName: curBookName.value,
|
curBookName: curBookName.value,
|
||||||
curBookImg: curBookImg.value
|
curBookImg: curBookImg.value,
|
||||||
|
curBookPath: curBookPath.value
|
||||||
},
|
},
|
||||||
node: curNode
|
node: curNode
|
||||||
}
|
}
|
||||||
|
@ -201,20 +233,26 @@ const findParentByChildId = (treeData, targetNodeId) => {
|
||||||
|
|
||||||
const transData = (data) => {
|
const transData = (data) => {
|
||||||
let ary = []
|
let ary = []
|
||||||
|
|
||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
let obj = {}
|
let obj = {}
|
||||||
|
|
||||||
if (item.rootid == curBookId.value) {
|
if (item.rootid == curBookId.value) {
|
||||||
obj.label = item.itemtitle
|
obj.label = item.itemtitle
|
||||||
obj.id = item.id
|
obj.id = item.id
|
||||||
|
obj.itemtitle = item.itemtitle
|
||||||
|
obj.edudegree = item.edudegree
|
||||||
|
obj.edustage = item.edustage
|
||||||
|
obj.edusubject = item.edusubject
|
||||||
let ary2 = []
|
let ary2 = []
|
||||||
evaluationList.value.forEach(el => {
|
evaluationList.value.forEach(el => {
|
||||||
let obj2 = {}
|
let obj2 = {}
|
||||||
if (item.id == el.parentid) {
|
if (item.id == el.parentid) {
|
||||||
obj2 = {
|
obj2 = {
|
||||||
label: el.itemtitle,
|
label: el.itemtitle,
|
||||||
id: el.id
|
id: el.id,
|
||||||
|
itemtitle : el.itemtitle,
|
||||||
|
edudegree : el.edudegree,
|
||||||
|
edustage : el.edustage,
|
||||||
|
edusubject : el.edusubject,
|
||||||
}
|
}
|
||||||
ary2.push(obj2)
|
ary2.push(obj2)
|
||||||
}
|
}
|
||||||
|
@ -238,9 +276,11 @@ const getSubject = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认第一个
|
// 默认第一个
|
||||||
|
if(!subjectList.value.length) return
|
||||||
curBookName.value = subjectList.value[0].itemtitle
|
curBookName.value = subjectList.value[0].itemtitle
|
||||||
curBookId.value = subjectList.value[0].id
|
curBookId.value = subjectList.value[0].id
|
||||||
curBookImg.value = BaseUrl + subjectList.value[0].avartar
|
curBookImg.value = BaseUrl + subjectList.value[0].avartar
|
||||||
|
curBookPath.value = subjectList.value[0].fileurl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,25 +296,27 @@ const handleNodeClick = (data, node) => {
|
||||||
* data : 当前节点数据
|
* data : 当前节点数据
|
||||||
* node : 当前节点对象 包含当前节点所有数据 parent属性 指向父节点Node对象
|
* node : 当前节点对象 包含当前节点所有数据 parent属性 指向父节点Node对象
|
||||||
*/
|
*/
|
||||||
const currentNode = data;
|
|
||||||
|
const nodeData = data;
|
||||||
const parentNode = node.parent.data;
|
const parentNode = node.parent.data;
|
||||||
|
|
||||||
if (Array.isArray(parentNode)) {
|
if (Array.isArray(parentNode)) {
|
||||||
currentNode.parentNode = null
|
nodeData.parentNode = null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
currentNode.parentNode = parentNode
|
nodeData.parentNode = parentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
let curData = {
|
let curData = {
|
||||||
textBook: {
|
textBook: {
|
||||||
curBookId: curBookId.value,
|
curBookId: curBookId.value,
|
||||||
curBookName: curBookName.value,
|
curBookName: curBookName.value,
|
||||||
curBookImg: curBookImg.value
|
curBookImg: curBookImg.value,
|
||||||
|
curBookPath: curBookPath.value
|
||||||
},
|
},
|
||||||
node: toRaw(currentNode)
|
node: toRaw(nodeData)
|
||||||
}
|
}
|
||||||
|
currentNode.data = curData
|
||||||
emit('nodeClick', curData)
|
emit('nodeClick', curData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +407,9 @@ onMounted(() => {
|
||||||
.textbook-img {
|
.textbook-img {
|
||||||
width: 55px;
|
width: 55px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,6 @@ const getSubjectContent = async () => {
|
||||||
volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
|
volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
|
||||||
//下册
|
//下册
|
||||||
volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
|
volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
|
||||||
|
|
||||||
getTreeData()
|
getTreeData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +153,7 @@ const getSubject = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认第一个
|
// 默认第一个
|
||||||
|
if(!subjectList.value.length) return
|
||||||
curBookName.value = subjectList.value[0].itemtitle
|
curBookName.value = subjectList.value[0].itemtitle
|
||||||
curBookId.value = subjectList.value[0].id
|
curBookId.value = subjectList.value[0].id
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,17 @@ const getTreeData = () => {
|
||||||
//数据过滤
|
//数据过滤
|
||||||
let upData = transData(volumeOne.value)
|
let upData = transData(volumeOne.value)
|
||||||
let downData = transData(volumeTwo.value)
|
let downData = transData(volumeTwo.value)
|
||||||
|
|
||||||
|
if(upData.length && downData.length){
|
||||||
|
treeData.value = [...upData,...downData]
|
||||||
|
}
|
||||||
|
else if(upData.length || downData.length){
|
||||||
treeData.value = upData.length ? upData : downData
|
treeData.value = upData.length ? upData : downData
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
treeData.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
defaultExpandedKeys.value = [treeData.value[0].id]
|
defaultExpandedKeys.value = [treeData.value[0].id]
|
||||||
currentNodeId.value = getLastLevelData(treeData.value)[0].id
|
currentNodeId.value = getLastLevelData(treeData.value)[0].id
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" @click="editUserInfo">
|
<el-button type="primary" @click="editUserInfo" :loading="subjectLoading">
|
||||||
确定
|
确定
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { listEvaluation } from '@/api/subject'
|
import { listEvaluation } from '@/api/subject'
|
||||||
import { updateUserInfo } from '@/api/system/user'
|
import { updateUserInfo } from '@/api/system/user'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
|
@ -42,12 +42,20 @@ const userStore = useUserStore()
|
||||||
const { userId, userName } = userStore.user
|
const { userId, userName } = userStore.user
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
loginData: {
|
||||||
|
type: Object,
|
||||||
|
default(){
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const subjectLoading = ref(false)
|
||||||
|
|
||||||
// 定义要发送的emit事件
|
// 定义要发送的emit事件
|
||||||
const emit = defineEmits(['update:modelValue', 'onSuccess'])
|
const emit = defineEmits(['update:modelValue', 'onSuccess'])
|
||||||
|
|
||||||
|
@ -111,8 +119,18 @@ const editUserInfo = async () =>{
|
||||||
edustage: gradeVal.value,
|
edustage: gradeVal.value,
|
||||||
edusubject: subjectVal.value
|
edusubject: subjectVal.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 修改之后需要重新登录 查询用户信息,否则不登录 查询的用户信息是未修改之前的
|
||||||
|
// 接口如此,我也不知道为啥要这样
|
||||||
|
subjectLoading.value = true
|
||||||
|
try {
|
||||||
|
//修改用户信息
|
||||||
await updateUserInfo(data)
|
await updateUserInfo(data)
|
||||||
|
await userStore.login(props.loginData)
|
||||||
await userStore.getInfo()
|
await userStore.getInfo()
|
||||||
|
} finally {
|
||||||
|
subjectLoading.value = false
|
||||||
|
}
|
||||||
emit('onSuccess')
|
emit('onSuccess')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,5 +166,7 @@ watch(() => props.modelValue, (newVal) => {
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-select-dropdown__item{
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -98,7 +98,7 @@ const hanleFileChange = (file) => {
|
||||||
// 验证文件大小
|
// 验证文件大小
|
||||||
// B < KB < MB < GB
|
// B < KB < MB < GB
|
||||||
// file.raw.size 单位是B
|
// file.raw.size 单位是B
|
||||||
const fileSize = file.raw.size / 1024 / 1024 > 100
|
const fileSize = file.raw.size / 1024 / 1024 > 500
|
||||||
if (fileSize) {
|
if (fileSize) {
|
||||||
ElMessage.error('文件大小错误! 请上传小于100M的文件!')
|
ElMessage.error('文件大小错误! 请上传小于100M的文件!')
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -118,7 +118,7 @@ export default {
|
||||||
file.callback(res)
|
file.callback(res)
|
||||||
},
|
},
|
||||||
beforeUpload(file) {
|
beforeUpload(file) {
|
||||||
const MAX_SIZE = 100 * 1024 * 1024 // 2MB
|
const MAX_SIZE = 500 * 1024 * 1024 // 2MB
|
||||||
if (file.size > MAX_SIZE) {
|
if (file.size > MAX_SIZE) {
|
||||||
this.$message.error('文件大小不能超过 100MB!')
|
this.$message.error('文件大小不能超过 100MB!')
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* 共享数据状态-多窗口
|
||||||
|
*/
|
||||||
|
const { ipcRenderer } = require('electron') // app使用
|
||||||
|
export function shareStorePlugin({store}) {
|
||||||
|
store.$subscribe(() => { // 自动同步
|
||||||
|
// 在存储变化的时候执行
|
||||||
|
const storeName = store.$id
|
||||||
|
// 用于多窗口共享(需要共享的状态名称)
|
||||||
|
const names = ['tool']
|
||||||
|
if (names.includes(storeName)) stateSync(store) // 需要同步
|
||||||
|
})
|
||||||
|
// 暴露方法-手动同步
|
||||||
|
store.stateSync = () => stateSync(store)
|
||||||
|
// 监听主线程消息-同步数据
|
||||||
|
stateChange(store)
|
||||||
|
}
|
||||||
|
// 同步数据-发送给主线程
|
||||||
|
function stateSync(store) {
|
||||||
|
const storeName = store.$id
|
||||||
|
const jsonStr = JSON.stringify(store.$state)
|
||||||
|
// 通知主线程更新
|
||||||
|
ipcRenderer.invoke('pinia-state-change', storeName, jsonStr)
|
||||||
|
}
|
||||||
|
// 同步数据-接收主线程消息
|
||||||
|
function stateChange(store) {
|
||||||
|
const storeName = store.$id
|
||||||
|
ipcRenderer.on('pinia-state-set', (e, sName, jsonStr) => {
|
||||||
|
if (sName == storeName) { // 更新对应数据
|
||||||
|
console.log('state-set', jsonStr, sName)
|
||||||
|
const curJson = JSON.stringify(store.$state) // 当前数据
|
||||||
|
const isUp = curJson != jsonStr // 不同的时候才写入,不然会导致触发数据变化监听,导致死循环
|
||||||
|
if (!isUp) return
|
||||||
|
const stateJson = JSON.parse(jsonStr) // 新数据
|
||||||
|
// 更新状态
|
||||||
|
store.$patch(stateJson)
|
||||||
|
// 您可以通过将其 $state 属性设置为新对象来替换 Store 的整个状态
|
||||||
|
// store.$state = stateJson
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||||
|
import { shareStorePlugin } from '@/plugins/shareStore'
|
||||||
|
|
||||||
const pinia = createPinia() //创建pinia实例
|
const pinia = createPinia() //创建pinia实例
|
||||||
pinia.use(piniaPluginPersistedstate) //将插件添加到 pinia 实例上
|
pinia.use(piniaPluginPersistedstate) //将插件添加到 pinia 实例上
|
||||||
|
pinia.use(shareStorePlugin) // 多窗口数据状态共享
|
||||||
|
|
||||||
export const store = pinia
|
export const store = pinia
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* 工具类-窗口-状态管理
|
||||||
|
*/
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useToolState = defineStore('tool', {
|
||||||
|
state: () => ({
|
||||||
|
model: 'select', // 悬浮球-当前模式
|
||||||
|
showBoardAll: false, // 全屏画板-是否显示
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
}
|
||||||
|
})
|
|
@ -17,7 +17,7 @@ const uploaderStore = defineStore('uploader', {
|
||||||
pushFile(payload) {
|
pushFile(payload) {
|
||||||
let _this = this
|
let _this = this
|
||||||
let arr = payload.filter((item) => {
|
let arr = payload.filter((item) => {
|
||||||
const MAX_SIZE = 100 * 1024 * 1024; // 2MB
|
const MAX_SIZE = 500 * 1024 * 1024; // 2MB
|
||||||
if (item.size > MAX_SIZE) {
|
if (item.size > MAX_SIZE) {
|
||||||
ElMessage.error('文件大小不能超过 100MB!');
|
ElMessage.error('文件大小不能超过 100MB!');
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--选择学科-->
|
<!--选择学科-->
|
||||||
<SelectSubject v-model="isSubject" @onSuccess="successEditSubject" />
|
<SelectSubject v-model="isSubject" :loginData="loginForm" @onSuccess="successEditSubject"/>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
|
@ -35,7 +35,7 @@ import leftBg2 from '@/assets/images/login/left-bg2.png'
|
||||||
import WindowTools from '@/components/window-tools/index.vue'
|
import WindowTools from '@/components/window-tools/index.vue'
|
||||||
import SelectSubject from '@/components/select-subject/index.vue'
|
import SelectSubject from '@/components/select-subject/index.vue'
|
||||||
|
|
||||||
const { BrowserWindow, session } = require('@electron/remote')
|
const { session } = require('@electron/remote')
|
||||||
|
|
||||||
const { ipcRenderer } = window.electron || {}
|
const { ipcRenderer } = window.electron || {}
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
@ -48,13 +48,14 @@ const loginForm = reactive({
|
||||||
password: '',
|
password: '',
|
||||||
rememberMe: false
|
rememberMe: false
|
||||||
})
|
})
|
||||||
|
|
||||||
//表单规则
|
//表单规则
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
|
username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
|
||||||
password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }]
|
password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }]
|
||||||
})
|
})
|
||||||
|
|
||||||
let curWinUrl;
|
let curWinUrl = import.meta.env.VITE_APP_BUILD_BASE_PATH;
|
||||||
|
|
||||||
//登录
|
//登录
|
||||||
const submitForm = async (formEl) => {
|
const submitForm = async (formEl) => {
|
||||||
|
@ -131,9 +132,7 @@ const setCookie = (name, value) => {
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 当前窗口URL
|
localStorage.clear()
|
||||||
curWinUrl = BrowserWindow.getFocusedWindow().webContents.getURL()
|
|
||||||
|
|
||||||
getCookie()
|
getCookie()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="centerDialogVisible"
|
||||||
|
class="reserv-dialog"
|
||||||
|
title="预约课程"
|
||||||
|
destroy-on-close
|
||||||
|
width="600"
|
||||||
|
style="text-align: left"
|
||||||
|
>
|
||||||
|
<el-form :model="form" label-width="auto" style="max-width: 600px">
|
||||||
|
<el-form-item label="课程名称">
|
||||||
|
<el-input v-model="form.name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="课程类型" prop="location">
|
||||||
|
<el-segmented v-model="form.type" :block="false" :options="locationOptions" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label=" " prop="location">
|
||||||
|
<div>{{ locationMessage }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="上课时间">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.day"
|
||||||
|
type="date"
|
||||||
|
:editable="false"
|
||||||
|
class="reserv-date-pick"
|
||||||
|
placeholder="请选择日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2" class="text-center">
|
||||||
|
<span class="text-gray-500">-</span>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="11">
|
||||||
|
<el-time-picker
|
||||||
|
v-model="form.time"
|
||||||
|
is-range
|
||||||
|
:editable="false"
|
||||||
|
format="HH:mm"
|
||||||
|
class="reserv-time-pick"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="授课对象">
|
||||||
|
<el-radio-group v-model="form.resource">
|
||||||
|
<el-radio v-for="(item, index) in classList" :key="index" :value="item.id">{{item.caption}}({{item.classstudentcount}})人</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教室">
|
||||||
|
<el-input v-model="form.classRoom" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="centerDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="centerDialogVisible = false"> 提交 </el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose, onMounted, reactive, computed } from 'vue'
|
||||||
|
import { listClassmain } from '@/api/classManage'
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
const userStore = useUserStore().user
|
||||||
|
const centerDialogVisible = ref(false)
|
||||||
|
const form = reactive({
|
||||||
|
name: '',
|
||||||
|
type: '常规课',
|
||||||
|
delivery: false,
|
||||||
|
day:'',
|
||||||
|
time:'',
|
||||||
|
resource: '',
|
||||||
|
classRoom: ''
|
||||||
|
})
|
||||||
|
const locationOptions = [
|
||||||
|
{
|
||||||
|
label: '常规课',
|
||||||
|
value: '常规课',
|
||||||
|
disabled: false,
|
||||||
|
message: '现场公屏授课,学生无需长时间打开平板上。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '公开课',
|
||||||
|
value: '公开课',
|
||||||
|
disabled: true,
|
||||||
|
message: '现场公屏授课,学生需打开平开与老师进行互动,如点赞、互动作业。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '直播课',
|
||||||
|
value: '直播课',
|
||||||
|
disabled: true,
|
||||||
|
message: '远程直播授课,学生需打开平开观看实时直播教学,并与老师进行互动。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const locationMessage = computed(() => {
|
||||||
|
return locationOptions.find((item) => item.value === form.type).message
|
||||||
|
})
|
||||||
|
const openDialog = () => {
|
||||||
|
centerDialogVisible.value = true
|
||||||
|
}
|
||||||
|
const closeDialog = () => {
|
||||||
|
centerDialogVisible.value = false
|
||||||
|
}
|
||||||
|
const classList = ref([])
|
||||||
|
onMounted(() => {
|
||||||
|
listClassmain({ classuserid: userStore.userId, pageSize: 100, status: 'open' }).then(
|
||||||
|
(response) => {
|
||||||
|
classList.value = [...response.rows]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
defineExpose({
|
||||||
|
openDialog,
|
||||||
|
closeDialog
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.reserv-date-pick) {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
:deep(.reserv-time-pick) {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -3,18 +3,17 @@
|
||||||
<ChooseTextbook @change-book="nodeClick" @node-click="nodeClick" />
|
<ChooseTextbook @change-book="nodeClick" @node-click="nodeClick" />
|
||||||
<div class="page-right">
|
<div class="page-right">
|
||||||
<div class="header-top flex">
|
<div class="header-top flex">
|
||||||
<div class="textbook-img">
|
<div class="textbook-img" @click="navtoPdf">
|
||||||
<el-image style="width: 80px; height: 110px" :src="curBookImg" />
|
<el-image style="width: 80px; height: 110px" :src="curBookImg" />
|
||||||
</div>
|
</div>
|
||||||
<div class="top-item">
|
<div class="top-item">
|
||||||
<el-button class="btn" @click="handleOutLink('standard')">课标研读</el-button>
|
<el-button class="btn" @click="handleOutLink('standard')">课标研读</el-button>
|
||||||
<el-button class="btn" @click="navtoPdf">电子课本</el-button>
|
<el-button class="btn" @click="openReserv">预约课程</el-button>
|
||||||
<el-button class="btn" @click="handleOutLink('gk')">高考研读</el-button>
|
<el-button class="btn" @click="handleOutLink('gk')">高考研读</el-button>
|
||||||
<el-button class="btn" @click="handleOutLink('aiModel')">教学大模型</el-button>
|
<el-button class="btn" @click="handleOutLink('aiModel')">教学大模型</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="primary" class="to-class-btn" @click="openLesson">
|
<el-button type="primary" class="to-class-btn" @click="openLesson">
|
||||||
<i class="iconfont icon-lingdang"></i>上课</el-button
|
<i class="iconfont icon-lingdang"></i>上课</el-button>
|
||||||
>
|
|
||||||
<div class="top-zoom-style"></div>
|
<div class="top-zoom-style"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="prepare-body-header">
|
<div class="prepare-body-header">
|
||||||
|
@ -23,13 +22,7 @@
|
||||||
<el-popover placement="top-start" :width="250" trigger="hover">
|
<el-popover placement="top-start" :width="250" trigger="hover">
|
||||||
<template #default>
|
<template #default>
|
||||||
<div>
|
<div>
|
||||||
<el-button
|
<el-button v-if="lastAsyncAllTime" type="success" size="small" :icon="Check" circle />
|
||||||
v-if="lastAsyncAllTime"
|
|
||||||
type="success"
|
|
||||||
size="small"
|
|
||||||
:icon="Check"
|
|
||||||
circle
|
|
||||||
/>
|
|
||||||
{{ lastAsyncAllTime ? toTimeText(lastAsyncAllTime) + '同步成功' : '' }}
|
{{ lastAsyncAllTime ? toTimeText(lastAsyncAllTime) + '同步成功' : '' }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -47,49 +40,33 @@
|
||||||
<el-button @click="handleOutLink('feedback')">作业反馈</el-button>
|
<el-button @click="handleOutLink('feedback')">作业反馈</el-button>
|
||||||
<el-button @click="handleOutLink('homeWork')">布置作业</el-button>
|
<el-button @click="handleOutLink('homeWork')">布置作业</el-button>
|
||||||
<el-button @click="isDialogOpen = true">上传资料</el-button>
|
<el-button @click="isDialogOpen = true">上传资料</el-button>
|
||||||
<el-button type="primary" style="margin-left: 10px" @click="createFile"
|
<el-button type="primary" style="margin-left: 10px" @click="createFile">新建课件</el-button>
|
||||||
>新建课件</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-checkbox-group
|
<el-checkbox-group v-model="checkFileList" class="prepare-body-main"
|
||||||
v-model="checkFileList"
|
:style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }">
|
||||||
class="prepare-body-main"
|
<file-list-item v-for="(item, index) in currentFileList" :key="index" :item="item" :index="index"
|
||||||
:style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }"
|
@on-move="onMoveSingleFile" @on-delete="deleteTalk" @on-set="openSet" @on-delhomework="delhomework">
|
||||||
>
|
|
||||||
<file-list-item
|
|
||||||
v-for="(item, index) in currentFileList"
|
|
||||||
:key="index"
|
|
||||||
:item="item"
|
|
||||||
:index="index"
|
|
||||||
@on-move="onMoveSingleFile"
|
|
||||||
@on-delete="deleteTalk"
|
|
||||||
@on-set="openSet"
|
|
||||||
@on-delhomework="delhomework"
|
|
||||||
>
|
|
||||||
<el-checkbox label="" :value="item" v-if="!item.uniquekey" />
|
<el-checkbox label="" :value="item" v-if="!item.uniquekey" />
|
||||||
</file-list-item>
|
</file-list-item>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<file-oper-batch
|
<file-oper-batch v-show="checkFileList.length > 0"
|
||||||
v-show="checkFileList.length > 0"
|
|
||||||
:indeterminate="checkFileList.length > 0 && checkFileList.length < currentFileList.length"
|
:indeterminate="checkFileList.length > 0 && checkFileList.length < currentFileList.length"
|
||||||
:choose="checkFileList"
|
:choose="checkFileList" :check-all="isCheckAll" @click-delete="clickDelete" @click-move="clickMove"
|
||||||
:check-all="isCheckAll"
|
@cancel="checkFileList = []" @click-choose="clickChoose"></file-oper-batch>
|
||||||
@click-delete="clickDelete"
|
|
||||||
@click-move="clickMove"
|
|
||||||
@cancel="checkFileList = []"
|
|
||||||
@click-choose="clickChoose"
|
|
||||||
></file-oper-batch>
|
|
||||||
</div>
|
</div>
|
||||||
<MoveFile v-model="isMoveDialogOpen" @on-submit="chooseMoveCata" />
|
<MoveFile v-model="isMoveDialogOpen" @on-submit="chooseMoveCata" />
|
||||||
<uploadDialog v-model="isDialogOpen" @submit-file="submitFile" />
|
<uploadDialog v-model="isDialogOpen" @submit-file="submitFile" />
|
||||||
<SetHomework v-model="setDialog" :entpcourseid="entpcourseid" :row="row" @on-close="closeHomework" />
|
<SetHomework v-model="setDialog" :entpcourseid="entpcourseid" :row="row" @on-close="closeHomework" />
|
||||||
</div>
|
</div>
|
||||||
|
<reserv ref="reservDialog"></reserv>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Check } from '@element-plus/icons-vue'
|
import { Check } from '@element-plus/icons-vue'
|
||||||
|
import Reserv from '@/views/prepare/container/reserv.vue'
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
const Remote = require('@electron/remote')
|
||||||
import ChooseTextbook from '@/components/choose-textbook/index.vue'
|
import ChooseTextbook from '@/components/choose-textbook/index.vue'
|
||||||
import uploadDialog from '@/components/upload-dialog/index.vue'
|
import uploadDialog from '@/components/upload-dialog/index.vue'
|
||||||
import { Refresh } from '@element-plus/icons-vue'
|
import { Refresh } from '@element-plus/icons-vue'
|
||||||
|
@ -107,8 +84,8 @@ import SetHomework from './container/set-homework.vue'
|
||||||
import outLink from '@/utils/linkConfig'
|
import outLink from '@/utils/linkConfig'
|
||||||
import { createWindow } from '@/utils/tool'
|
import { createWindow } from '@/utils/tool'
|
||||||
import { uniqBy, cloneDeep } from 'lodash'
|
import { uniqBy, cloneDeep } from 'lodash'
|
||||||
import { delClasswork } from '@/api/teaching/classwork'
|
import { delClasswork, addEntpcourse } from '@/api/teaching/classwork'
|
||||||
|
const fs = require('fs');
|
||||||
const { ipcRenderer } = window.electron || {}
|
const { ipcRenderer } = window.electron || {}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -134,6 +111,7 @@ export default {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
currentNode: {},
|
currentNode: {},
|
||||||
currentFileList: [],
|
currentFileList: [],
|
||||||
|
curBookPath: '',
|
||||||
lastAsyncAllTime: '',
|
lastAsyncAllTime: '',
|
||||||
uploadData: {
|
uploadData: {
|
||||||
textbookId: null,
|
textbookId: null,
|
||||||
|
@ -170,6 +148,7 @@ export default {
|
||||||
created() {
|
created() {
|
||||||
this.userStore = useUserStore().user
|
this.userStore = useUserStore().user
|
||||||
ipcRenderer.removeAllListeners('copy-file-default-reply')
|
ipcRenderer.removeAllListeners('copy-file-default-reply')
|
||||||
|
|
||||||
ipcRenderer.on('copy-file-default-reply', (e, param) => {
|
ipcRenderer.on('copy-file-default-reply', (e, param) => {
|
||||||
this.callback(param)
|
this.callback(param)
|
||||||
})
|
})
|
||||||
|
@ -179,9 +158,42 @@ export default {
|
||||||
activated() {
|
activated() {
|
||||||
if (this.uploadData.textbookId !== null) {
|
if (this.uploadData.textbookId !== null) {
|
||||||
this.asyncAllFile()
|
this.asyncAllFile()
|
||||||
|
this.initHomeWork()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getBookPathFromServer() {
|
||||||
|
let fileName = this.curBookPath
|
||||||
|
if (!fileName) return
|
||||||
|
fileName = fileName.replace('.txt', '.pdf')
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
const userDataPath = Remote.app.getPath('userData')
|
||||||
|
const appRootFilePath = userDataPath + '\\selfFile\\'
|
||||||
|
let filePath = appRootFilePath + fileName
|
||||||
|
fs.access(filePath, fs.constants.F_OK, (err) => {
|
||||||
|
let filePath = import.meta.env.VITE_APP_RES_FILE_PATH + fileName
|
||||||
|
if (err) {
|
||||||
|
//从线上下载
|
||||||
|
ipcRenderer.send('download-file-default', {
|
||||||
|
url: filePath,
|
||||||
|
fileName: fileName
|
||||||
|
})
|
||||||
|
ipcRenderer.once('download-file-default' + fileName, (e, isSuccess) => {
|
||||||
|
if (isSuccess === true) {
|
||||||
|
resolve(appRootFilePath + fileName)
|
||||||
|
}else {
|
||||||
|
ElMessage({
|
||||||
|
type: 'info',
|
||||||
|
message: `下载教材失败!`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
resolve(appRootFilePath + fileName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
createFile() {
|
createFile() {
|
||||||
creatPPT(this.currentNode.label + '.pptx', this.uploadData).then((res) => {
|
creatPPT(this.currentNode.label + '.pptx', this.uploadData).then((res) => {
|
||||||
this.currentFileList.unshift(res.resData)
|
this.currentFileList.unshift(res.resData)
|
||||||
|
@ -301,8 +313,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async nodeClick(data) {
|
async nodeClick(data) {
|
||||||
|
console.log(data)
|
||||||
if (this.currentNode.id === data.node.id) return
|
if (this.currentNode.id === data.node.id) return
|
||||||
this.curBookImg = data.textBook.curBookImg
|
this.curBookImg = data.textBook.curBookImg
|
||||||
|
this.curBookPath = data.textBook.curBookPath
|
||||||
this.checkFileList = []
|
this.checkFileList = []
|
||||||
let cata = parseCataByNode(data.node)
|
let cata = parseCataByNode(data.node)
|
||||||
this.currentNode = data.node
|
this.currentNode = data.node
|
||||||
|
@ -310,17 +324,54 @@ export default {
|
||||||
this.uploadData.levelSecondId = cata[1]
|
this.uploadData.levelSecondId = cata[1]
|
||||||
this.uploadData.levelThirdId = cata[2]
|
this.uploadData.levelThirdId = cata[2]
|
||||||
this.uploadData.textbookId = data.textBook.curBookId
|
this.uploadData.textbookId = data.textBook.curBookId
|
||||||
|
this.initHomeWork()
|
||||||
await this.asyncAllFile()
|
await this.asyncAllFile()
|
||||||
|
|
||||||
|
},
|
||||||
|
async initHomeWork() {
|
||||||
|
if (this.timerId) {
|
||||||
|
clearInterval(this.timerId)
|
||||||
|
}
|
||||||
if (this.uploadData.levelSecondId) {
|
if (this.uploadData.levelSecondId) {
|
||||||
// 获取作业列表所需ID 可能存在没有
|
// 获取作业列表所需ID 可能存在没有
|
||||||
const { rows } = await this.getChapterId()
|
let { rows } = await this.getChapterId()
|
||||||
if(!rows.length) return
|
if (rows.length > 0) {
|
||||||
this.entpcourseid = rows[0].id
|
this.entpcourseid = rows[0].id
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
await this.createEntpcourse()
|
||||||
|
let { rows } = await this.getChapterId()
|
||||||
|
this.entpcourseid = rows[0].id
|
||||||
|
}
|
||||||
|
|
||||||
// 查询作业
|
// 查询作业
|
||||||
this.getHomeWorkList()
|
this.getHomeWorkList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 创建新的entpcourse
|
||||||
|
createEntpcourse() {
|
||||||
|
var cform = {};
|
||||||
|
cform.entpid = this.userStore.deptId;
|
||||||
|
cform.level = 1;
|
||||||
|
cform.parentid = 0;
|
||||||
|
cform.dictid = 0;
|
||||||
|
cform.evalid = this.currentNode.id;
|
||||||
|
cform.evalparentid = 0;
|
||||||
|
cform.edusubject = this.currentNode.edusubject;
|
||||||
|
cform.edudegree = this.currentNode.edudegree;
|
||||||
|
cform.edustage = this.currentNode.edustage;
|
||||||
|
cform.coursetype = '课标学科';
|
||||||
|
cform.coursetitle = this.currentNode.itemtitle;
|
||||||
|
cform.coursedesc = '';
|
||||||
|
cform.status = '';
|
||||||
|
cform.dflag = 0;
|
||||||
|
cform.edituserid = this.userStore.userId;
|
||||||
|
cform.createblankfile = 'yes';
|
||||||
|
return addEntpcourse(cform)
|
||||||
|
},
|
||||||
|
openReserv(){
|
||||||
|
// this.$refs['reservDialog'].openDialog()
|
||||||
|
},
|
||||||
// 打开外部链接
|
// 打开外部链接
|
||||||
handleOutLink(key) {
|
handleOutLink(key) {
|
||||||
if (key == 'homeWork') {
|
if (key == 'homeWork') {
|
||||||
|
@ -331,6 +382,7 @@ export default {
|
||||||
let configObj = outLink()[key]
|
let configObj = outLink()[key]
|
||||||
// 通知主进程
|
// 通知主进程
|
||||||
ipcRenderer.send('openWindow', {
|
ipcRenderer.send('openWindow', {
|
||||||
|
key,
|
||||||
fullPath: configObj.fullPath,
|
fullPath: configObj.fullPath,
|
||||||
cookieData: { ...configObj.data }
|
cookieData: { ...configObj.data }
|
||||||
})
|
})
|
||||||
|
@ -343,7 +395,7 @@ export default {
|
||||||
pageSize: 500
|
pageSize: 500
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 清除查询作业列表定时器
|
// 查询作业列表定时器
|
||||||
createTimer() {
|
createTimer() {
|
||||||
this.timerId = setInterval(() => {
|
this.timerId = setInterval(() => {
|
||||||
this.getHomeWorkList()
|
this.getHomeWorkList()
|
||||||
|
@ -435,8 +487,11 @@ export default {
|
||||||
closeHomework() {
|
closeHomework() {
|
||||||
this.setDialog = false
|
this.setDialog = false
|
||||||
},
|
},
|
||||||
|
|
||||||
// 打开PDF-课件
|
// 打开PDF-课件
|
||||||
navtoPdf() {
|
async navtoPdf() {
|
||||||
|
let path = await this.getBookPathFromServer()
|
||||||
|
console.log(path)
|
||||||
createWindow('open-PDF', { url: '/classBegins/index' })
|
createWindow('open-PDF', { url: '/classBegins/index' })
|
||||||
},
|
},
|
||||||
// 上课-工具类悬浮
|
// 上课-工具类悬浮
|
||||||
|
@ -516,6 +571,9 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-item {
|
.top-item {
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 上传弹窗 -->
|
<!-- 上传弹窗 -->
|
||||||
<uploadDialog v-model="isDialogOpen" @submit-file="submitFile" />
|
<uploadDialog v-model="isDialogOpen" @submit-file="submitFile" />
|
||||||
<!-- <el-button @click="testClick">测试</el-button> -->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
@ -35,22 +34,17 @@ import ResoureList from './container/resoure-list.vue'
|
||||||
import uploadDialog from '@/components/upload-dialog/index.vue'
|
import uploadDialog from '@/components/upload-dialog/index.vue'
|
||||||
import uploaderState from '@/store/modules/uploader'
|
import uploaderState from '@/store/modules/uploader'
|
||||||
import { createWindow } from '@/utils/tool'
|
import { createWindow } from '@/utils/tool'
|
||||||
//
|
import { useToolState } from '@/store/modules/tool'
|
||||||
const sourceStore = useResoureStore()
|
const sourceStore = useResoureStore()
|
||||||
const isDialogOpen = ref(false)
|
const isDialogOpen = ref(false)
|
||||||
|
const toolStore = useToolState()
|
||||||
const openDialog = () => {
|
const openDialog = () => {
|
||||||
isDialogOpen.value = true
|
isDialogOpen.value = true
|
||||||
}
|
}
|
||||||
onMounted(async () => {
|
// onMounted(async () => {
|
||||||
// const params = { url: '/tool/sphere' }
|
// console.log('toolStore: ', toolStore.windowState)
|
||||||
// const res = await ipcMsgSend('tool-sphere:create', params)
|
// })
|
||||||
// console.log('消息返回:', res)
|
|
||||||
})
|
|
||||||
const testClick = async () => {
|
|
||||||
const win = await createWindow('tool-sphere', { url: '/tool/sphere' })
|
|
||||||
console.log('消息返回:', win)
|
|
||||||
}
|
|
||||||
// 查询
|
// 查询
|
||||||
const getData = (data) => {
|
const getData = (data) => {
|
||||||
const { textBook, node } = data
|
const { textBook, node } = data
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
<canvas ref="canvasRef" />
|
<canvas ref="canvasRef" />
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
// 功能说明:画板
|
// 功能说明:画板
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="warp-all">
|
<div class="warp-all">
|
||||||
<board-vue v-model="tabActive"></board-vue>
|
<board-vue v-model="tabActive" v-show="isShow"></board-vue>
|
||||||
<!-- 底部工具栏 :style="dataPos.style"-->
|
<!-- 底部工具栏 :style="dataPos.style"-->
|
||||||
<div class="tool-bottom-all"
|
<div class="tool-bottom-all"
|
||||||
@mouseenter="mouseChange(0)" @mouseleave="mouseChange(1)">
|
@mouseenter="mouseChange(0)" @mouseleave="mouseChange(1)">
|
||||||
|
@ -27,18 +27,20 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
// 功能说明:electron 悬浮球
|
// 功能说明:electron 悬浮球
|
||||||
import { onMounted, ref, reactive } from 'vue'
|
import { onMounted, ref, reactive, watchEffect } from 'vue'
|
||||||
import logo from '@root/resources/icon.png' // logo
|
import logo from '@root/resources/icon.png' // logo
|
||||||
import boardVue from './components/board.vue' // 画板
|
import boardVue from './components/board.vue' // 画板
|
||||||
import vDrag from './directive/drag'
|
import vDrag from './directive/drag' // 自定义指令-拖拽
|
||||||
// const Remote = require('@electron/remote') // remote对象
|
import { useToolState } from '@/store/modules/tool'
|
||||||
const { ipcRenderer } = require('electron') // app使用
|
const { ipcRenderer } = require('electron') // app使用
|
||||||
// const ipcRenderer = { send: () => {} } // 网页测试使用
|
// const ipcRenderer = { send: () => {} } // 网页测试使用
|
||||||
|
|
||||||
const tabActive = ref('select') // 工具栏当前选中项
|
const tabActive = ref('select') // 工具栏当前选中项
|
||||||
const isFold = ref(false) // 折叠工具栏
|
const isFold = ref(false) // 折叠工具栏
|
||||||
const isDrag = ref(false) // 开始拖拽
|
const isDrag = ref(false) // 开始拖拽
|
||||||
const dragtime = ref(0)
|
const dragtime = ref(0) // 拖拽时间-计算点击还是拖动
|
||||||
|
const isShow = ref(false)
|
||||||
|
const toolStore = useToolState()
|
||||||
const btnList = [ // 工具栏按钮列表
|
const btnList = [ // 工具栏按钮列表
|
||||||
{ label: '选择', value: 'select', icon: 'icon-mouse' },
|
{ label: '选择', value: 'select', icon: 'icon-mouse' },
|
||||||
{ label: '画笔', value: 'brush', icon: 'icon-huabi' },
|
{ label: '画笔', value: 'brush', icon: 'icon-huabi' },
|
||||||
|
@ -48,9 +50,17 @@ const btnList = [ // 工具栏按钮列表
|
||||||
// { label: '聚焦', value: 'focus', icon: 'icon-jujiao' },
|
// { label: '聚焦', value: 'focus', icon: 'icon-jujiao' },
|
||||||
// { label: '更多', value: 'more', icon: 'icon-xiazai9' },
|
// { label: '更多', value: 'more', icon: 'icon-xiazai9' },
|
||||||
]
|
]
|
||||||
|
onMounted(() => {
|
||||||
|
// isShow.value = toolStore.showBoardAll // 是否显示-画板
|
||||||
|
// console.log('xxx: ', toolStore.model)
|
||||||
|
// setTimeout(() => {
|
||||||
|
// toolStore.windowState.test = '测试成功'
|
||||||
|
// }, 2000);
|
||||||
|
})
|
||||||
// ==== 方法 ===
|
// ==== 方法 ===
|
||||||
const tabChange = (val) => { // 切换tab-change
|
const tabChange = (val) => { // 切换tab-change
|
||||||
console.log(val)
|
// console.log('xxxx:', val)
|
||||||
|
toolStore.showBoardAll = true
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 'brush': // 画笔
|
case 'brush': // 画笔
|
||||||
break
|
break
|
||||||
|
@ -68,6 +78,7 @@ const tabChange = (val) => { // 切换tab-change
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
toolStore.model = val // 存储当前tab
|
||||||
}
|
}
|
||||||
const logoHandle = (e,t) => { // logo 点击-事件 折叠|展开
|
const logoHandle = (e,t) => { // logo 点击-事件 折叠|展开
|
||||||
if (Date.now() - dragtime.value < 200) {
|
if (Date.now() - dragtime.value < 200) {
|
||||||
|
@ -80,6 +91,9 @@ const mouseChange = (bool) => { // 鼠标移入工具栏 是否穿透
|
||||||
if (tabActive.value == 'select') resBool = !!bool
|
if (tabActive.value == 'select') resBool = !!bool
|
||||||
ipcRenderer.send('tool-sphere:set:ignore', resBool)
|
ipcRenderer.send('tool-sphere:set:ignore', resBool)
|
||||||
}
|
}
|
||||||
|
watchEffect(() => { // 监听
|
||||||
|
isShow.value = toolStore.showBoardAll // 是否显示-画板
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in New Issue