zdg #101

Merged
zhengdegang merged 3 commits from zdg into main 2024-08-05 17:49:45 +08:00
8 changed files with 164 additions and 93 deletions
Showing only changes of commit 22a92ee84b - Show all commits

View File

@ -1,6 +1,6 @@
{ {
"name": "electron-app", "name": "aix-win",
"version": "1.0.1", "version": "1.0.2",
"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",

View File

@ -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]
}) })
} }

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>Electron</title> <title>AIx智慧教育</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --> <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<!-- <meta <!-- <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"

View File

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

View File

@ -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,6 +63,8 @@ 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)
// //
@ -70,8 +75,12 @@ const curBookImg = 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 +91,7 @@ const refTree = ref(null)
// //
const getSubjectContent = async () => { const getSubjectContent = async () => {
treeLoading.value = true
const params = { const params = {
edusubject, edusubject,
edustage, edustage,
@ -93,12 +103,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 {
const { rows } = await listEvaluation(params) try {
localStorage.setItem('evaluationList', JSON.stringify(rows)) const { rows } = await listEvaluation(params)
evaluationList.value = rows localStorage.setItem('evaluationList', JSON.stringify(rows))
data = rows evaluationList.value = rows
data = rows
} finally {
treeLoading.value = false
}
} }
// //
@ -107,7 +122,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()
} }
@ -126,10 +140,20 @@ const getTreeData = () => {
// //
let upData = transData(volumeOne.value) let upData = transData(volumeOne.value)
let downData = transData(volumeTwo.value) let downData = transData(volumeTwo.value)
treeData.value = upData.length ? upData : downData if(upData.length && downData.length){
defaultExpandedKeys.value = [treeData.value[0].id] treeData.value = [...upData,...downData]
}
else if(upData.length || downData.length){
treeData.value = upData.length ? upData : downData
}
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,10 +162,14 @@ 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 = {
@ -201,20 +229,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,6 +272,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
curBookImg.value = BaseUrl + subjectList.value[0].avartar curBookImg.value = BaseUrl + subjectList.value[0].avartar
@ -256,14 +291,15 @@ 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 = {
@ -272,9 +308,9 @@ const handleNodeClick = (data, node) => {
curBookName: curBookName.value, curBookName: curBookName.value,
curBookImg: curBookImg.value curBookImg: curBookImg.value
}, },
node: toRaw(currentNode) node: toRaw(nodeData)
} }
currentNode.data = curData
emit('nodeClick', curData) emit('nodeClick', curData)
} }
@ -365,6 +401,9 @@ onMounted(() => {
.textbook-img { .textbook-img {
width: 55px; width: 55px;
height: 70px; height: 70px;
display: flex;
align-items: center;
justify-content: center;
} }
} }

View File

@ -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)
treeData.value = upData.length ? upData : downData
if(upData.length && downData.length){
treeData.value = [...upData,...downData]
}
else if(upData.length || downData.length){
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

View File

@ -54,7 +54,7 @@ const rules = reactive({
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 +131,7 @@ const setCookie = (name, value) => {
onMounted(() => { onMounted(() => {
// URL localStorage.clear()
curWinUrl = BrowserWindow.getFocusedWindow().webContents.getURL()
getCookie() getCookie()
}) })
</script> </script>

View File

@ -13,8 +13,7 @@
<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,39 +40,20 @@
<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">
> <el-checkbox label="" :value="item" v-if="!item.uniquekey" />
<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"/>
</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" />
@ -107,7 +81,7 @@ 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 { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
@ -170,15 +144,17 @@ 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)
}) })
this.lastAsyncAllTime = localStorage.getItem('lastAsyncAllTime') this.lastAsyncAllTime = localStorage.getItem('lastAsyncAllTime')
}, },
mounted() {}, mounted() { },
activated() { activated() {
if (this.uploadData.textbookId !== null) { if (this.uploadData.textbookId !== null) {
this.asyncAllFile() this.asyncAllFile()
this.initHomeWork()
} }
}, },
methods: { methods: {
@ -310,17 +286,51 @@ 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)
},
// //
handleOutLink(key) { handleOutLink(key) {
if (key == 'homeWork') { if (key == 'homeWork') {
@ -331,6 +341,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 +354,7 @@ export default {
pageSize: 500 pageSize: 500
}) })
}, },
// //
createTimer() { createTimer() {
this.timerId = setInterval(() => { this.timerId = setInterval(() => {
this.getHomeWorkList() this.getHomeWorkList()
@ -421,20 +432,21 @@ export default {
this.setDialog = true this.setDialog = true
}, },
// //
delhomework(item){ delhomework(item) {
this.isLoading = true this.isLoading = true
delClasswork(item.id).then( async res =>{ delClasswork(item.id).then(async res => {
ElMessage.success('操作成功') ElMessage.success('操作成功')
this.isLoading = false this.isLoading = false
await this.asyncAllFile() await this.asyncAllFile()
this.getHomeWorkList() this.getHomeWorkList()
}).catch(()=>{ }).catch(() => {
this.isLoading = false this.isLoading = false
}) })
}, },
closeHomework() { closeHomework() {
this.setDialog = false this.setDialog = false
}, },
// PDF- // PDF-
navtoPdf() { navtoPdf() {
createWindow('open-PDF', { url: '/classBegins/index' }) createWindow('open-PDF', { url: '/classBegins/index' })