# Conflicts:
#	src/renderer/src/utils/tool.js
#	src/renderer/src/views/prepare/index.vue
#	src/renderer/src/views/tool/components/side.vue
This commit is contained in:
zhangxuelin 2024-08-14 17:48:32 +08:00
commit b520858f3f
25 changed files with 373 additions and 154 deletions

View File

@ -9,7 +9,7 @@ VITE_APP_BASE_API = '/dev-api'
VITE_APP_DOMAIN = 'file.ysaix.com' VITE_APP_DOMAIN = 'file.ysaix.com'
VITE_APP_UPLOAD_API = 'http://192.168.2.52:7863' VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/' VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'

View File

@ -1,6 +1,6 @@
{ {
"name": "aix-win", "name": "aix-win",
"version": "1.0.7", "version": "1.1.0",
"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

@ -146,7 +146,7 @@ export default async function ({ app, shell, BrowserWindow, ipcMain }) {
//使用默认应用打开本地文件 //使用默认应用打开本地文件
ipcMain.on('open-path-app', (e, destination) => { ipcMain.on('open-path-app', (e, destination) => {
let path = appRootFilePath + destination let path = appRootFilePath + destination
shell.openExternal(path).catch((error) => { shell.openPath(path).catch((error) => {
console.log(error) console.log(error)
}) })
}) })

View File

@ -28,6 +28,7 @@ function createLoginWindow() {
icon: join(__dirname, '../../resources/logo2.ico'), icon: join(__dirname, '../../resources/logo2.ico'),
...(process.platform === 'linux' ? { icon } : {}), ...(process.platform === 'linux' ? { icon } : {}),
webPreferences: { webPreferences: {
defaultEncoding: 'utf-8',
preload: join(__dirname, '../preload/index.js'), preload: join(__dirname, '../preload/index.js'),
sandbox: false, sandbox: false,
nodeIntegration: true, nodeIntegration: true,
@ -67,6 +68,7 @@ function createMainWindow() {
icon: join(__dirname, '../../resources/logo2.ico'), icon: join(__dirname, '../../resources/logo2.ico'),
...(process.platform === 'linux' ? { icon } : {}), ...(process.platform === 'linux' ? { icon } : {}),
webPreferences: { webPreferences: {
defaultEncoding: 'utf-8',
preload: join(__dirname, '../preload/index.js'), preload: join(__dirname, '../preload/index.js'),
sandbox: false, sandbox: false,
// nodeIntegration: true, // nodeIntegration: true,
@ -115,6 +117,7 @@ async function createLinkWin(data) {
autoHideMenuBar: true, autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}), ...(process.platform === 'linux' ? { icon } : {}),
webPreferences: { webPreferences: {
defaultEncoding: 'utf-8',
sandbox: false, sandbox: false,
nodeIntegration: true, nodeIntegration: true,
worldSafeExecuteJavaScript: true, worldSafeExecuteJavaScript: true,
@ -126,12 +129,8 @@ async function createLinkWin(data) {
let cookieDetails = { ...data.cookieData } let cookieDetails = { ...data.cookieData }
await linkWin[data.key].webContents.session.cookies await linkWin[data.key].webContents.session.cookies
.set(cookieDetails) .set(cookieDetails)
.then(() => { .then(() => {})
console.log('Cookie is successful') .catch((error) => {})
})
.catch((error) => {
console.error('Cookie is error', error)
})
data.fullPath = data.fullPath.replaceAll('//', '/') data.fullPath = data.fullPath.replaceAll('//', '/')
linkWin[data.key].loadURL(data.fullPath) linkWin[data.key].loadURL(data.fullPath)
@ -147,6 +146,8 @@ async function createLinkWin(data) {
// 初始化完成 // 初始化完成
app.on('ready', () => { app.on('ready', () => {
process.env.LANG = 'en_US.UTF-8'
process.env['ELECTRON_DISABLE_SANDBOX'] = true;
// 设置应用程序用户模型标识符 // 设置应用程序用户模型标识符
electronApp.setAppUserModelId('com.electron') electronApp.setAppUserModelId('com.electron')

View File

@ -159,11 +159,11 @@ export function deleteSmartReserv(id) {
method: 'delete' method: 'delete'
}) })
} }
export function startClass(id) { export function startClass(id, ex3) {
return request({ return request({
url: '/smarttalk/classReserv/startClass', url: '/smarttalk/classReserv/startClass',
method: 'get', method: 'get',
params: {id} params: {id, ex3}
}) })
} }
export function endClass(id) { export function endClass(id) {

View File

@ -1,9 +1,9 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 2794390 */ font-family: "iconfont"; /* Project id 2794390 */
src: url('iconfont.woff2?t=1723452423265') format('woff2'), src: url('iconfont.woff2?t=1723453634574') format('woff2'),
url('iconfont.woff?t=1723452423265') format('woff'), url('iconfont.woff?t=1723453634574') format('woff'),
url('iconfont.ttf?t=1723452423265') format('truetype'), url('iconfont.ttf?t=1723453634574') format('truetype'),
url('iconfont.svg?t=1723452423265#iconfont') format('svg'); url('iconfont.svg?t=1723453634574#iconfont') format('svg');
} }
.iconfont { .iconfont {
@ -14,6 +14,10 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-arrangement:before {
content: "\e656";
}
.icon-zanwushuju:before { .icon-zanwushuju:before {
content: "\e655"; content: "\e655";
} }

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "4978988",
"name": "作业-布置作业",
"font_class": "arrangement",
"unicode": "e656",
"unicode_decimal": 58966
},
{ {
"icon_id": "9689424", "icon_id": "9689424",
"name": "暂无数据", "name": "暂无数据",

View File

@ -14,6 +14,8 @@
/> />
<missing-glyph /> <missing-glyph />
<glyph glyph-name="arrangement" unicode="&#58966;" d="M939.52 199.67999999999995c-10.24 10.24-25.6 10.24-35.84 0l-184.32-184.32-81.92 81.92c-10.24 10.24-25.6 10.24-35.84 0s-10.24-25.6 0-35.84l102.4-102.4c5.12-5.12 10.24-5.12 20.48-5.12s15.36 0 20.48 5.12l204.8 204.8c-5.12 5.12-5.12 25.6-10.24 35.84zM688.64 537.6c0 15.36-10.24 25.6-25.6 25.6h-409.6c-15.36 0-25.6-10.24-25.6-25.6s10.24-25.6 25.6-25.6h409.6c15.36 0 25.6 10.24 25.6 25.6zM458.24 153.60000000000002h-204.8c-15.36 0-25.6-10.24-25.6-25.6s10.24-25.6 25.6-25.6h204.8c15.36 0 25.6 10.24 25.6 25.6s-10.24 25.6-25.6 25.6zM611.84-76.79999999999995h-460.8c-15.36 0-25.6 10.24-25.6 25.6V742.4c0 15.36 10.24 25.6 25.6 25.6H227.84C227.84 727.04 263.68 691.2 304.64 691.2h307.2c40.96 0 76.8 35.84 76.8 76.8h76.8c15.36 0 25.6-10.24 25.6-25.6v-460.8c0-15.36 10.24-25.6 25.6-25.6s25.6 10.24 25.6 25.6V742.4c0 40.96-35.84 76.8-76.8 76.8H688.64c0 40.96-35.84 76.8-76.8 76.8h-307.2C263.68 896 227.84 860.16 227.84 819.2H151.04C110.08 819.2 74.24 783.36 74.24 742.4v-793.6c0-40.96 35.84-76.8 76.8-76.8h460.8c15.36 0 25.6 10.24 25.6 25.6s-10.24 25.6-25.6 25.6zM279.04 819.2c0 15.36 10.24 25.6 25.6 25.6h307.2c15.36 0 25.6-10.24 25.6-25.6v-51.2c0-15.36-10.24-25.6-25.6-25.6h-307.2c-15.36 0-25.6 10.24-25.6 25.6v51.2zM458.24 358.4h-204.8c-15.36 0-25.6-10.24-25.6-25.6s10.24-25.6 25.6-25.6h204.8c15.36 0 25.6 10.24 25.6 25.6s-10.24 25.6-25.6 25.6z" horiz-adv-x="1024" />
<glyph glyph-name="zanwushuju" unicode="&#58965;" d="M876.202667 543.445333H147.882667L0 282.752V-42.666667h1024v325.376l-147.797333 260.736z m-234.112-263.637333c0-70.485333-58.197333-127.658667-130.090667-127.658667-71.893333 0-130.133333 57.173333-130.133333 127.658667H61.098667L179.541333 501.76H844.373333l118.442667-221.952H642.133333zM500.138667 810.666667h44.629333v-157.610667h-44.629333V810.666667zM197.290667 732.416l31.573333 31.018667L342.272 651.946667l-31.573333-31.018667-113.493334 111.445333z m491.52-80.512l113.493333 111.445333 31.573333-30.976-113.493333-111.445333-31.573333 30.976z" horiz-adv-x="1024" /> <glyph glyph-name="zanwushuju" unicode="&#58965;" d="M876.202667 543.445333H147.882667L0 282.752V-42.666667h1024v325.376l-147.797333 260.736z m-234.112-263.637333c0-70.485333-58.197333-127.658667-130.090667-127.658667-71.893333 0-130.133333 57.173333-130.133333 127.658667H61.098667L179.541333 501.76H844.373333l118.442667-221.952H642.133333zM500.138667 810.666667h44.629333v-157.610667h-44.629333V810.666667zM197.290667 732.416l31.573333 31.018667L342.272 651.946667l-31.573333-31.018667-113.493334 111.445333z m491.52-80.512l113.493333 111.445333 31.573333-30.976-113.493333-111.445333-31.573333 30.976z" horiz-adv-x="1024" />
<glyph glyph-name="xiangzuo" unicode="&#58957;" d="M774.89 725L399.08 380.75l375.81-344.21a39.28 39.28 0 0 0 13.11-29c0-36.51-48.19-54.79-76.38-29L335.8 322.8c-34.94 32-34.94 83.9 0 115.9l375.82 344.22c28.19 25.81 76.38 7.53 76.38-29A39.3 39.3 0 0 0 774.89 725z" horiz-adv-x="1024" /> <glyph glyph-name="xiangzuo" unicode="&#58957;" d="M774.89 725L399.08 380.75l375.81-344.21a39.28 39.28 0 0 0 13.11-29c0-36.51-48.19-54.79-76.38-29L335.8 322.8c-34.94 32-34.94 83.9 0 115.9l375.82 344.22c28.19 25.81 76.38 7.53 76.38-29A39.3 39.3 0 0 0 774.89 725z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 264 KiB

View File

@ -42,7 +42,7 @@
</template> </template>
<script setup> <script setup>
import { onMounted, ref, nextTick, toRaw, reactive,watch } 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'
@ -258,7 +258,7 @@ const transData = (data) => {
const getSubject = async () => { const getSubject = async () => {
const { rows } = await listEvaluation({ itemkey: "version", pageSize: 500 }) const { rows } = await listEvaluation({ itemkey: "version", pageSize: 500 })
subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject) subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject && isHaveUnit(item.id))
localStorage.setItem('subjectList', JSON.stringify(subjectList.value)) localStorage.setItem('subjectList', JSON.stringify(subjectList.value))
// //
@ -270,11 +270,11 @@ const getSubject = async () => {
} }
// const isHaveUnit = (id) => { const isHaveUnit = (id) => {
// return evaluationList.value.some(item => { return evaluationList.value.some(item => {
// return item.rootid == id return item.rootid == id
// }) })
// } }
const handleNodeClick = (data, node) => { const handleNodeClick = (data, node) => {
@ -305,9 +305,6 @@ const handleNodeClick = (data, node) => {
currentNode.data = curData currentNode.data = curData
emit('nodeClick', curData) emit('nodeClick', curData)
} }
watch(() => userStore.edusubject, () => {
console.log(userStore.edusubject,'userStore.edusubject')
})
onMounted(() => { onMounted(() => {
getSubjectContent() getSubjectContent()
}) })

View File

@ -45,7 +45,6 @@ function stateSync(storeName, key, value) {
function stateSyncAll(store) { function stateSyncAll(store) {
const storeName = store.$id const storeName = store.$id
const jsonStr = circularSafeStringify(store.$state) const jsonStr = circularSafeStringify(store.$state)
console.log('state-change', jsonStr, storeName)
// 通知主线程更新 // 通知主线程更新
ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr) ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr)
} }

View File

@ -47,6 +47,12 @@ export default () => {
data: { ...baseConfig() }, data: { ...baseConfig() },
fullPath: `${baseConfig().url}/platofai` fullPath: `${baseConfig().url}/platofai`
}, },
// 文件资源 布置作业
filehomework: {
data: { ...baseConfig() },
fullPath: `${baseConfig().url}/teaching/classtaskassign?titleName=作业布置`
},
getBaseData: () => { getBaseData: () => {
return { return {

View File

@ -85,7 +85,9 @@ export function ipcHandle(fn,key, cb) {
* @returns * @returns
*/ */
let winPdf=null let winPdf=null
let wins_tool = null
export const createWindow = async (type, data) => { export const createWindow = async (type, data) => {
if (wins_tool) return console.error('createWindow: win is have')
if (!type) return console.error('createWindow: type is null') if (!type) return console.error('createWindow: type is null')
switch(type) { switch(type) {
case 'tool-sphere': { // 创建-悬浮球 case 'tool-sphere': { // 创建-悬浮球
@ -100,16 +102,16 @@ export const createWindow = async (type, data) => {
} }
data.isConsole = true // 是否开启控制台 data.isConsole = true // 是否开启控制台
data.option = {...defOption, ...option} data.option = {...defOption, ...option}
const win = await toolWindow(data) wins_tool = await toolWindow(data)
win.type = type // 唯一标识 wins_tool.type = type // 唯一标识
win.show() wins_tool.show()
win.setFullScreen(true) // 设置窗口为全屏 wins_tool.setFullScreen(true) // 设置窗口为全屏
win.setIgnoreMouseEvents(true, {forward: true}) // 忽略鼠标事件但是事件继续传递给窗口 wins_tool.setIgnoreMouseEvents(true, {forward: true}) // 忽略鼠标事件但是事件继续传递给窗口
win.setAlwaysOnTop(true,'screen-saver') // 将窗口设置为顶层窗口 wins_tool.setAlwaysOnTop(true,'screen-saver') // 将窗口设置为顶层窗口
win.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见 wins_tool.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见
// win.webContents.openDevTools() // 打开调试工具 // win.webContents.openDevTools() // 打开调试工具
eventHandles(type, win) // 事件监听处理 eventHandles(type, wins_tool) // 事件监听处理
return win return wins_tool
} }
case 'open-PDF': { //课本展示-pdf case 'open-PDF': { //课本展示-pdf
const option = data.option||{} const option = data.option||{}
@ -209,6 +211,7 @@ const eventHandles = (type, win) => {
win.on('closed', () => { win.on('closed', () => {
if(onClosed) onClosed() // 自定义关闭事件 if(onClosed) onClosed() // 自定义关闭事件
win = null win = null
wins_tool = null
}) })
// 新窗口-创建事件(如:主进程加载远程服务) // 新窗口-创建事件(如:主进程加载远程服务)

View File

@ -17,6 +17,8 @@
v-show="tabActive === '已结束'" v-show="tabActive === '已结束'"
:key="index" :key="index"
:item="item" :item="item"
@open-edit="reservDialog.openDialog(item)"
@delete-reserv="deleteReserv(item)"
></reserv-item> ></reserv-item>
</div> </div>
<reserv ref="reservDialog"></reserv> <reserv ref="reservDialog"></reserv>
@ -51,8 +53,8 @@ const doneDataList = computed(() => {
}) })
const toolStore = useToolState() const toolStore = useToolState()
watch( watch(
() => toolStore.isToolWin, () => [dataList,toolStore.isToolWin],
(newD, oldD) => { () => {
getSelfReserv().then((res) => { getSelfReserv().then((res) => {
dataList.value = [...res.data] dataList.value = [...res.data]
}) })

View File

@ -68,18 +68,18 @@ const startClassR = (item) => {
} }
}) })
} }
const toolStore = useToolState() // const toolStore = useToolState()
let wins = null;
// - // -
const openLesson = () => { const openLesson = () => {
if (toolStore.isToolWin) return ElMessage.error('您当前已开始上课,请勿重复操作')
startClass(props.item.id) startClass(props.item.id)
listEntpcourse({ listEntpcourse({
evalid: props.item.ex2, evalid: props.item.ex2,
edituserid: useUserStore().user.userId, edituserid: useUserStore().user.userId,
pageSize: 500 pageSize: 500
}).then(res=>{ }).then(async res=>{
if (res.rows[0].id) { if (res.rows[0].id) {
createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res.rows[0].id + "&reservId=" + props.item.id }) wins = await createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res.rows[0].id + "&reservId=" + props.item.id })
} }
}) })
} }

View File

@ -95,6 +95,12 @@
</template> </template>
<template v-else> <template v-else>
<!-- 判断是不是自己创建的课件--> <!-- 判断是不是自己创建的课件-->
<div class="item-popover-item">
<el-button text @click="openFileLink(item)">
<i class="iconfont icon-arrangement"></i>
<span>布置</span>
</el-button>
</div>
<div class="item-popover-item" v-if="userInfo.userId === Number(item.createUserId)"> <div class="item-popover-item" v-if="userInfo.userId === Number(item.createUserId)">
<el-button text @click="editTalk(item, index)"> <el-button text @click="editTalk(item, index)">
<i class="iconfont icon-bianji"></i> <i class="iconfont icon-bianji"></i>
@ -142,6 +148,7 @@ import { toTimeText } from '@/utils/date'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { deleteSmarttalk, updateSmarttalk, getPrepareById } from '@/api/file' import { deleteSmarttalk, updateSmarttalk, getPrepareById } from '@/api/file'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import outLink from '@/utils/linkConfig'
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
export default { export default {
@ -161,7 +168,7 @@ export default {
} }
} }
}, },
emits: { 'on-move': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null }, emits: { 'on-move': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null,'on-filearg': null },
data() { data() {
return { return {
listenList: [], listenList: [],
@ -223,6 +230,7 @@ export default {
} }
}, },
openFileWin(items) { openFileWin(items) {
if (!items||!items.fileSuffix) return;
getPrepareById(items.id).then((item) => { getPrepareById(items.id).then((item) => {
Object.assign(items, item) Object.assign(items, item)
asyncLocalFile(items).then(() => { asyncLocalFile(items).then(() => {
@ -256,6 +264,21 @@ export default {
// //
deleteHomework(item){ deleteHomework(item){
this.$emit('on-delhomework', item) this.$emit('on-delhomework', item)
},
// web AIX
openFileLink(item){
let unitId = item.levelSecondId ? item.levelSecondId : item.levelFirstId
// key linkConfig.js
let key = 'filehomework'
let configObj = outLink()[key]
//
ipcRenderer.send('openWindow', {
key,
fullPath: configObj.fullPath + `&fileShowName=${item.fileShowName}&fileFullPath=${item.fileFullPath}&unitId=${unitId}`,
cookieData: { ...configObj.data }
})
this.$emit('on-filearg', item)
} }
}, },
mounted() { mounted() {

View File

@ -3,8 +3,14 @@
<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" @click="navtoPdf"> <div class="textbook-img">
<el-image style="width: 80px; height: 110px" :src="curBookImg" /> <el-image style="width: 80px; height: 110px" :src="curBookImg" @click="navtoPdf" />
<el-progress
v-if="downloadNum > 0 && downloadNum < 100"
style="position: absolute; left: 0; z-index: 999"
type="circle"
:percentage="downloadNum"
/>
</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>
@ -12,9 +18,16 @@
<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
<i class="iconfont icon-lingdang"></i>上课</el-button :type="!curClassReserv.id ? 'info' : 'primary'"
:disabled="!curClassReserv.id"
class="to-class-btn"
@click="openLesson"
> >
<label><i class="iconfont icon-lingdang"></i>上课</label>
<label>{{ curClassReserv.classDay }} {{ getWeekday1(curClassReserv.classDay) }}</label>
<label>{{ curClassReserv.startTime }}-{{ curClassReserv.endTime }}</label>
</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,7 +36,13 @@
<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 v-if="lastAsyncAllTime" type="success" size="small" :icon="Check" circle /> <el-button
v-if="lastAsyncAllTime"
type="success"
size="small"
:icon="Check"
circle
/>
{{ lastAsyncAllTime ? toTimeText(lastAsyncAllTime) + '同步成功' : '' }} {{ lastAsyncAllTime ? toTimeText(lastAsyncAllTime) + '同步成功' : '' }}
</div> </div>
</template> </template>
@ -41,26 +60,69 @@
<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> <el-button type="primary" style="margin-left: 10px" @click="createFile"
>新建课件</el-button
>
</div> </div>
</div> </div>
<el-checkbox-group v-model="checkFileList" class="prepare-body-main" <el-checkbox-group
:style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }"> v-model="checkFileList"
<file-list-item v-for="(item, index) in currentFileList" :key="index" :item="item" :index="index" class="prepare-body-main"
@on-move="onMoveSingleFile" @on-delete="deleteTalk" @on-set="openSet" @on-delhomework="delhomework"> :style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }"
<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"
@on-filearg="isOpenHomework = true"
>
<el-checkbox v-if="!item.uniquekey" label="" :value="item" />
</file-list-item>
<file-list-item
v-for="(item, index) in currentWorkList"
:key="index"
:item="item"
:index="index"
@on-move="onMoveSingleFile"
@on-delete="deleteTalk"
@on-set="openSet"
@on-delhomework="delhomework"
>
<el-checkbox v-if="!item.uniquekey" label="" :value="item" />
</file-list-item> </file-list-item>
</el-checkbox-group> </el-checkbox-group>
<file-oper-batch v-show="checkFileList.length > 0" <file-oper-batch
v-show="checkFileList.length > 0"
:indeterminate="checkFileList.length > 0 && checkFileList.length < currentFileList.length" :indeterminate="checkFileList.length > 0 && checkFileList.length < currentFileList.length"
:choose="checkFileList" :check-all="isCheckAll" @click-delete="clickDelete" @click-move="clickMove" :choose="checkFileList"
@cancel="checkFileList = []" @click-choose="clickChoose"></file-oper-batch> :check-all="isCheckAll"
@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> <reserv
ref="reservDialog"
:current-node="currentNode"
:book-id="uploadData.textbookId"
@add-success="initReserv"
></reserv>
</template> </template>
<script setup> <script setup>
import { Check } from '@element-plus/icons-vue' import { Check } from '@element-plus/icons-vue'
@ -85,9 +147,11 @@ import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue'
import SetHomework from './container/set-homework.vue' 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 { cloneDeep } from 'lodash'
import { delClasswork, addEntpcourse } from '@/api/teaching/classwork' import { delClasswork, addEntpcourse } from '@/api/teaching/classwork'
const fs = require('fs'); import { getSelfReserv, startClass } from '@/api/classManage'
const toolStore = useToolState()
const fs = require('fs')
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
export default { export default {
@ -113,7 +177,10 @@ export default {
fileList: [], fileList: [],
currentNode: {}, currentNode: {},
currentFileList: [], currentFileList: [],
currentWorkList: [],
curBookPath: '', curBookPath: '',
curClassReserv: {},
downloadNum: 0,
lastAsyncAllTime: '', lastAsyncAllTime: '',
uploadData: { uploadData: {
textbookId: null, textbookId: null,
@ -127,10 +194,10 @@ export default {
// //
userStore: '', userStore: '',
entpcourseid: '', entpcourseid: '',
timerId: null,
// //
setDialog: false, setDialog: false,
row: '', row: '',
isOpenHomework: false
} }
}, },
computed: { computed: {
@ -140,13 +207,7 @@ export default {
) )
} }
}, },
watch: {
$route(to) {
if (to.path != '/prepare' && this.timerId) {
clearInterval(this.timerId)
}
}
},
created() { created() {
this.userStore = useUserStore().user this.userStore = useUserStore().user
ipcRenderer.removeAllListeners('copy-file-default-reply') ipcRenderer.removeAllListeners('copy-file-default-reply')
@ -155,20 +216,51 @@ export default {
this.callback(param) this.callback(param)
}) })
this.lastAsyncAllTime = localStorage.getItem('lastAsyncAllTime') this.lastAsyncAllTime = localStorage.getItem('lastAsyncAllTime')
this.initReserv()
}, },
mounted() { }, mounted() {
activated() { this.$watch(
if (this.uploadData.textbookId !== null) { () => toolStore.isToolWin,
this.asyncAllFile() (newD, oldD) => {
setTimeout(this.initReserv, 500)
}
)
// electron
const curWin = Remote.getCurrentWindow()
curWin.on('focus', ()=>{
if(!this.isOpenHomework) return
this.initHomeWork() this.initHomeWork()
} this.asyncAllFile()
this.isOpenHomework = false
})
}, },
// activated() {
// if (this.uploadData.textbookId !== null) {
// this.asyncAllFile()
// this.initHomeWork()
// this.initReserv()
// }
// },
methods: { methods: {
initReserv() {
getSelfReserv().then((res) => {
let list = res.data.filter((item) => {
return item.status !== '已结束'
})
if (list.length > 0) {
this.curClassReserv = list[list.length - 1]
} else {
this.curClassReserv = {}
}
})
},
getBookPathFromServer() { getBookPathFromServer() {
let fileName = this.curBookPath let fileName = this.curBookPath
if (!fileName) return if (!fileName) return
fileName = fileName.replace('.txt', '.pdf') fileName = fileName.replace('.txt', '.pdf')
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject) => {
const userDataPath = Remote.app.getPath('userData') const userDataPath = Remote.app.getPath('userData')
const appRootFilePath = userDataPath + '\\selfFile\\' const appRootFilePath = userDataPath + '\\selfFile\\'
let filePath = appRootFilePath + fileName let filePath = appRootFilePath + fileName
@ -180,22 +272,27 @@ export default {
url: filePath, url: filePath,
fileName: fileName fileName: fileName
}) })
ipcRenderer.removeListener('download-file-default-prog' + fileName, this.progDownFile)
ipcRenderer.on('download-file-default-prog' + fileName, this.progDownFile)
ipcRenderer.once('download-file-default' + fileName, (e, isSuccess) => { ipcRenderer.once('download-file-default' + fileName, (e, isSuccess) => {
if (isSuccess === true) { if (isSuccess === true) {
resolve(appRootFilePath + fileName) resolve(fileName)
}else { } else {
ElMessage({ ElMessage({
type: 'info', type: 'info',
message: `下载教材失败!` message: `下载教材失败!`
}) })
} }
}) })
}else { } else {
resolve(appRootFilePath + fileName) resolve(fileName)
} }
}) })
}) })
}, },
progDownFile(e, num) {
this.downloadNum = num
},
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)
@ -319,30 +416,30 @@ export default {
this.curBookImg = data.textBook.curBookImg this.curBookImg = data.textBook.curBookImg
this.curBookPath = data.textBook.curBookPath this.curBookPath = data.textBook.curBookPath
this.checkFileList = [] this.checkFileList = []
this.currentWorkList = []
let cata = parseCataByNode(data.node) let cata = parseCataByNode(data.node)
this.currentNode = data.node this.currentNode = data.node
this.uploadData.levelFirstId = cata[0] this.uploadData.levelFirstId = cata[0]
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
const toolStore = useToolState()
toolStore.curSubjectNode.data = data
toolStore.curSubjectNode.querySearch = this.uploadData
this.initHomeWork() this.initHomeWork()
await this.asyncAllFile() await this.asyncAllFile()
}, },
async initHomeWork() { async initHomeWork() {
if (this.timerId) {
clearInterval(this.timerId)
}
if (this.uploadData.levelSecondId) { if (this.uploadData.levelSecondId) {
// ID // ID
let { rows } = await this.getChapterId() let { rows } = await this.getChapterId()
if (rows.length > 0) { if (rows.length > 0) {
this.entpcourseid = rows[0].id this.entpcourseid = rows[0].id
} } else {
else{ await this.createEntpcourse()
await this.createEntpcourse() let { rows } = await this.getChapterId()
let { rows } = await this.getChapterId() this.entpcourseid = rows[0].id
this.entpcourseid = rows[0].id
} }
// //
@ -352,40 +449,50 @@ export default {
// entpcourse // entpcourse
createEntpcourse() { createEntpcourse() {
// web AIx // web AIx
var cform = {}; var cform = {}
cform.entpid = this.userStore.deptId; cform.entpid = this.userStore.deptId
cform.level = 1; cform.level = 1
cform.parentid = 0; cform.parentid = 0
cform.dictid = 0; cform.dictid = 0
cform.evalid = this.currentNode.id; cform.evalid = this.currentNode.id
cform.evalparentid = 0; cform.evalparentid = 0
cform.edusubject = this.currentNode.edusubject; cform.edusubject = this.currentNode.edusubject
cform.edudegree = this.currentNode.edudegree; cform.edudegree = this.currentNode.edudegree
cform.edustage = this.currentNode.edustage; cform.edustage = this.currentNode.edustage
cform.coursetype = '课标学科'; cform.coursetype = '课标学科'
cform.coursetitle = this.currentNode.itemtitle; cform.coursetitle = this.currentNode.itemtitle
cform.coursedesc = ''; cform.coursedesc = ''
cform.status = ''; cform.status = ''
cform.dflag = 0; cform.dflag = 0
cform.edituserid = this.userStore.userId; cform.edituserid = this.userStore.userId
cform.createblankfile = 'yes'; cform.createblankfile = 'yes'
return addEntpcourse(cform) return addEntpcourse(cform)
}, },
openReserv(){ openReserv() {
// this.$refs['reservDialog'].openDialog() this.$refs['reservDialog'].openDialog()
}, },
// //
handleOutLink(key) { handleOutLink(key) {
if (key == 'homeWork') { if(key == 'homeWork'){
// this.isOpenHomework = true
this.createTimer()
} }
// key linkConfig.js // key linkConfig.js
let configObj = outLink()[key] let configObj = outLink()[key]
let fullPath = configObj.fullPath
// urlunitId ID
if(key != 'standard' && key != 'aiModel'){
let unitId = this.uploadData.levelSecondId ? this.uploadData.levelSecondId : this.uploadData.levelFirstId
if(key == 'gk'){
fullPath += `?unitId=${unitId}`
}
else{
fullPath += `&unitId=${unitId}`
}
}
// //
ipcRenderer.send('openWindow', { ipcRenderer.send('openWindow', {
key, key,
fullPath: configObj.fullPath, fullPath: fullPath,
cookieData: { ...configObj.data } cookieData: { ...configObj.data }
}) })
}, },
@ -397,12 +504,7 @@ export default {
pageSize: 500 pageSize: 500
}) })
}, },
//
createTimer() {
this.timerId = setInterval(() => {
this.getHomeWorkList()
}, 1500)
},
// //
getHomeWorkList() { getHomeWorkList() {
homeworklist({ homeworklist({
@ -463,12 +565,15 @@ export default {
res.rows[i].entpcourseworklistarray = [] res.rows[i].entpcourseworklistarray = []
} }
} }
//
let ary = uniqBy([...this.currentFileList, ...list], 'id')
// //
this.currentFileList = cloneDeep(ary) this.currentWorkList = cloneDeep(list)
}) })
}, },
getWeekday1(date) {
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
const weekday = new Date(date).getDay()
return weekdays[weekday]
},
// //
openSet(row) { openSet(row) {
this.row = row this.row = row
@ -477,14 +582,16 @@ export default {
// //
delhomework(item) { delhomework(item) {
this.isLoading = true this.isLoading = true
delClasswork(item.id).then(async res => { delClasswork(item.id)
ElMessage.success('操作成功') .then(async (res) => {
this.isLoading = false ElMessage.success('操作成功')
await this.asyncAllFile() this.isLoading = false
this.getHomeWorkList() await this.asyncAllFile()
}).catch(() => { this.getHomeWorkList()
this.isLoading = false })
}) .catch(() => {
this.isLoading = false
})
}, },
closeHomework() { closeHomework() {
this.setDialog = false this.setDialog = false
@ -492,18 +599,24 @@ export default {
// PDF- // PDF-
async navtoPdf() { async navtoPdf() {
// if (toolStore.isPdfWin) return this.$message.error('') if (toolStore.isPdfWin) return this.$message.error('您当前已打开课本,请勿重复操作')
let path = await this.getBookPathFromServer() let path = await this.getBookPathFromServer()
// path=path.replace(/^.*[\\\/]/, ''); createWindow('open-PDF', {
// console.log(path) url: '/classBegins/index?textbookId=' + this.uploadData.textbookId + '&path=' + path
// console.log(this.uploadData.textbookId) })
createWindow('open-PDF', { url: '/classBegins/index?textbookId='+this.uploadData.textbookId+'&path='+ path })
}, },
// - // -
openLesson() { async openLesson() {
const toolStore = useToolState() await startClass(this.curClassReserv.id)
if (toolStore.isToolWin) return this.$message.error('您当前已开始上课,请勿重复操作') createWindow('tool-sphere', {
createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + this.entpcourseid +'&label=' + this.currentNode.label }) url:
'/tool/sphere?entpcourseid=' +
this.entpcourseid +
'&label=' +
this.currentNode.label +
'&reservId=' +
this.curClassReserv.id
})
} }
} }
} }
@ -578,9 +691,14 @@ export default {
overflow: hidden; overflow: hidden;
margin-right: 20px; margin-right: 20px;
z-index: 1; z-index: 1;
position: relative;
&:hover { &:hover {
cursor: pointer; cursor: pointer;
} }
:deep(.el-progress-circle) {
width: 90px !important;
background-color: white;
}
} }
.top-item { .top-item {
@ -617,7 +735,13 @@ export default {
margin-left: 25px; margin-left: 25px;
font-size: 18px; font-size: 18px;
z-index: 1; z-index: 1;
& label:hover {
cursor: pointer !important;
}
& > :deep(span) {
flex-direction: column !important;
font-size: 12px;
}
.icon-lingdang { .icon-lingdang {
margin-right: 5px; margin-right: 5px;
color: #ffffff; color: #ffffff;

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-row :gutter="20"> <el-row :gutter="20" style="display: flex;flex-wrap: nowrap;justify-content: start">
<el-col :span="6" :xs="24"> <el-col :xs="24" style="min-width: 260px;max-width: 260px">
<el-card class="box-card"> <el-card class="box-card">
<template v-slot:header> <template v-slot:header>
<div class="clearfix"> <div class="clearfix">

View File

@ -15,6 +15,15 @@
<el-radio value="1"></el-radio> <el-radio value="1"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="学段">
<el-radio-group v-model="user.edustage" @change="semeterChange">
<template v-for="(item,index) in semesterList" :key="index">
<el-radio :value="item.title">
{{item.title }}
</el-radio>
</template>
</el-radio-group>
</el-form-item>
<el-form-item label="任教学科"> <el-form-item label="任教学科">
<el-radio-group v-model="user.edusubject"> <el-radio-group v-model="user.edusubject">
<template v-for="(item,index) in subjectList" :key="index"> <template v-for="(item,index) in subjectList" :key="index">
@ -32,7 +41,7 @@
<script setup> <script setup>
import { ref, getCurrentInstance } from 'vue' import { ref, getCurrentInstance } from 'vue'
import { updateUserProfile } from '@/api/system/user' import {updateUserInfo } from '@/api/system/user'
import { listEvaluation } from '@/api/subject/index' import { listEvaluation } from '@/api/subject/index'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import {ElMessage} from 'element-plus' import {ElMessage} from 'element-plus'
@ -46,6 +55,26 @@ const props = defineProps({
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const userStore = useUserStore() const userStore = useUserStore()
//
const semesterList = ref([
{
id:1,
title:'幼儿园'
},
{
id:2,
title:'小学'
},
{
id:3,
title:'初中'
},
{
id:4,
title:'高中'
},
])
const rules = ref({ const rules = ref({
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }], nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
email: [ email: [
@ -97,15 +126,17 @@ setTimeout(() => {
function submit() { function submit() {
proxy.$refs.userRef.validate((valid) => { proxy.$refs.userRef.validate((valid) => {
if (valid) { if (valid) {
console.log(props.user) props.user.avatar = userStore.user.avatar
updateUserProfile(props.user).then((response) => { updateUserInfo(props.user).then((response) => {
if(response.code == 200){ if(response.code == 200){
userStore.getInfo().then(res => { userStore.login({username:props.user.phonenumber,password:props.user.plainpwd}).then(() => {
if(res.code === 200){ userStore.getInfo().then(res => {
ElMessage.success('修改成功') if(res.code === 200){
}else{ ElMessage.success('修改成功')
ElMessage.error(response.msg) }else{
} ElMessage.error(response.msg)
}
})
}) })
}else{ }else{
ElMessage.error(response.msg) ElMessage.error(response.msg)
@ -114,4 +145,9 @@ function submit() {
} }
}) })
} }
const semeterChange = (item) => {
if(item === '幼儿园'){
props.user.edusubject = ''
}
}
</script> </script>

View File

@ -25,6 +25,7 @@
</div> </div>
</div> </div>
</div> </div>
<el-button color="#349d44" @click="openFileLink(item)">推送</el-button>
</li> </li>
<!--作业--> <!--作业-->
<li class="item flex" v-for="item in dataList" :key="item.id"> <li class="item flex" v-for="item in dataList" :key="item.id">
@ -82,8 +83,9 @@ import { useToolState } from '@/store/modules/tool'
import { asyncLocalFile } from '@/utils/talkFile' import { asyncLocalFile } from '@/utils/talkFile'
import Lesson from './lesson.vue'; import Lesson from './lesson.vue';
import { parseCataByNode } from '@/utils/talkFile' import { parseCataByNode } from '@/utils/talkFile'
import outLink from '@/utils/linkConfig'
const { ipcRenderer } = window.electron || {} import { ipcMsgSend2 } from '@/utils/tool'
const route = useRoute(); const route = useRoute();
const usertore = useUserStore().user const usertore = useUserStore().user
const toolStore = useToolState() const toolStore = useToolState()
@ -127,6 +129,19 @@ const changeChapter = async (data)=>{
getResource() getResource()
} }
// web AIX
const openFileLink = (item) =>{
// key linkConfig.js
let key = 'filehomework'
let configObj = outLink()[key]
ipcMsgSend2('openWindow', {
key,
fullPath: configObj.fullPath + `&fileShowName=${item.fileShowName}&fileFullPath=${item.fileFullPath}`,
cookieData: { ...configObj.data }
})
}
// //
const getResource = () => { const getResource = () => {
let querySearch = toRaw(toolStore.curSubjectNode).querySearch let querySearch = toRaw(toolStore.curSubjectNode).querySearch
@ -233,7 +248,7 @@ onMounted(() => {
getHomework() getHomework()
setTimeout(()=>{ setTimeout(()=>{
getResource() getResource()
},5000) },1000)
}) })
</script> </script>

View File

@ -116,7 +116,7 @@ const sideMouse = e => {
mouseChange(type == 'mouseleave') mouseChange(type == 'mouseleave')
} }
// : // :
const sideChange = o => { const sideChange = async o => {
// console.log(o) // console.log(o)
switch(o.prop) { switch(o.prop) {
case 'resource': // case 'resource': //
@ -127,7 +127,7 @@ const sideChange = o => {
break break
case 'over': // case 'over': //
toolStore.isToolWin = false toolStore.isToolWin = false
endClass(route.query.reservId) await endClass(route.query.reservId)
ipcMsgSend('tool-sphere:close') ipcMsgSend('tool-sphere:close')
break break
} }