diff --git a/.env.yc b/.env.yc new file mode 100644 index 0000000..c3b1489 --- /dev/null +++ b/.env.yc @@ -0,0 +1,25 @@ +# 页面标题 +VITE_APP_TITLE = 文枢课堂 + +# 生产环境配置 +VITE_APP_ENV = 'production' + +# AIx融合数字管理系统/生产环境 +VITE_APP_BASE_API = 'https://prev.ysaix.com:7868/prod-api' + +VITE_APP_DOMAIN = 'prev.ysaix.com' + +VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868/prod-api' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip + +VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/' + +VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/' + +# websocket 地址 +VITE_APP_WS_URL = 'wss://prev.ysaix.com:7868' + +# 是否显示开发工具 +VITE_SHOW_DEV_TOOLS = 'false' diff --git a/.env.yc2 b/.env.yc2 new file mode 100644 index 0000000..c4a88ef --- /dev/null +++ b/.env.yc2 @@ -0,0 +1,25 @@ +# 页面标题 +VITE_APP_TITLE = 实训教学 + +# 生产环境配置 +VITE_APP_ENV = 'production' + +# AIx融合数字管理系统/生产环境 +VITE_APP_BASE_API = 'https://prev.ysaix.com:7868/prod-api' + +VITE_APP_DOMAIN = 'prev.ysaix.com' + +VITE_APP_UPLOAD_API = 'https://prev.ysaix.com:7868/prod-api' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip + +VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/' + +VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/' + +# websocket 地址 +VITE_APP_WS_URL = 'wss://prev.ysaix.com:7868' + +# 是否显示开发工具 +VITE_SHOW_DEV_TOOLS = 'false' diff --git a/electron-builder-yc.yml b/electron-builder-yc.yml new file mode 100644 index 0000000..385b578 --- /dev/null +++ b/electron-builder-yc.yml @@ -0,0 +1,54 @@ +appId: com.electron.app.yc +productName: 文枢课堂 +directories: + output: dist + buildResources: build +win: + executableName: 文枢课堂 + icon: resources/yc-logo.png +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/** +nsis: + oneClick: false + allowToChangeInstallationDirectory: true + artifactName: ${name}-yc-${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/smarttalkyc/ +electronDownload: + mirror: https://npmmirror.com/mirrors/electron/ +# 额外依赖打包到输出目录 +extraFiles: + - from: ./node_modules/im_electron_sdk/lib/ + to: ./resources + filter: + - '**/*' diff --git a/electron-builder-yc2.yml b/electron-builder-yc2.yml new file mode 100644 index 0000000..a7bfd2f --- /dev/null +++ b/electron-builder-yc2.yml @@ -0,0 +1,54 @@ +appId: com.electron.app.yc2 +productName: 实训教学 +directories: + output: dist + buildResources: build +win: + executableName: 实训教学 + icon: resources/yc-logo.png +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/** +nsis: + oneClick: false + allowToChangeInstallationDirectory: true + artifactName: ${name}-ycsx-${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/smarttalkycsx/ +electronDownload: + mirror: https://npmmirror.com/mirrors/electron/ +# 额外依赖打包到输出目录 +extraFiles: + - from: ./node_modules/im_electron_sdk/lib/ + to: ./resources + filter: + - '**/*' diff --git a/package.json b/package.json index e8adfd8..9c9774e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aix-win-ws", - "version": "2.5.7", + "version": "2.5.8", "description": "", "main": "./out/main/index.js", "author": "上海交大重庆人工智能研究院", @@ -16,6 +16,8 @@ "build:dev": "npm run build && electron-builder --win --config ./electron-builder-test.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:yc": "electron-vite build --mode yc && electron-builder --win --config ./electron-builder-yc.yml", + "build:yc2": "electron-vite build --mode yc2 && electron-builder --win --config ./electron-builder-yc2.yml", "build:lt": "electron-vite build --mode lt && electron-builder --win --config ./electron-builder-lt.yml", "build:mac": "electron-vite build --mode production && electron-builder --mac --config ./electron-builder-prod.yml", "build:linux": "npm run build && electron-builder --linux" diff --git a/resources/yc-logo.png b/resources/yc-logo.png new file mode 100644 index 0000000..59db44e Binary files /dev/null and b/resources/yc-logo.png differ diff --git a/src/main/index.js b/src/main/index.js index c223604..f43c571 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -7,6 +7,7 @@ import Logger from './logger' // 日志封装 import chat from './chat' // chat封装 import Store from './store' // Store封装 import updateInit from './update' + // 代理 electron/remote // 第一步:引入remote import remote from '@electron/remote/main' @@ -41,19 +42,19 @@ if(!gotTheLock){ } }) } - +let logoIco = import.meta.env.MODE==='yc'||import.meta.env.MODE==='yc2'?'../../resources/yc-logo.png':'../../resources/logo2.ico' //登录窗口 function createLoginWindow() { if (loginWindow) return loginWindow = new BrowserWindow({ - width: 888, + width: import.meta.env.MODE==='yc'||import.meta.env.MODE==='yc2'?1060:888, height: 520, show: false, frame: false, autoHideMenuBar: true, maximizable: false, resizable: false, - icon: join(__dirname, '../../resources/logo2.ico'), + icon: join(__dirname, logoIco), ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { defaultEncoding: 'utf-8', @@ -95,7 +96,7 @@ function createMainWindow() { frame: false, // 无边框 autoHideMenuBar: true, maximizable: false, - icon: join(__dirname, '../../resources/logo2.ico'), + icon: join(__dirname, logoIco), ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { defaultEncoding: 'utf-8', diff --git a/src/renderer/src/AixPPTist/src/App.vue b/src/renderer/src/AixPPTist/src/App.vue index 74c4b73..7fe9cd8 100644 --- a/src/renderer/src/AixPPTist/src/App.vue +++ b/src/renderer/src/AixPPTist/src/App.vue @@ -74,8 +74,6 @@ const initLoad: Function = () => { !!(opt.ratio??null) && slidesStore.setViewportRatio(opt.ratio)// 有比例配置项 } return PPTApi.getSlideList(resource.id) - // PPTApi.updateWorkList() - // return Promise.resolve() } return Promise.resolve() } diff --git a/src/renderer/src/AixPPTist/src/api/index.ts b/src/renderer/src/AixPPTist/src/api/index.ts index a82ffc4..5e5bcb6 100644 --- a/src/renderer/src/AixPPTist/src/api/index.ts +++ b/src/renderer/src/AixPPTist/src/api/index.ts @@ -50,6 +50,8 @@ export class Utils { }, delay) } } + // 延时 + static sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) } /** ppt相关后端接口处理 */ @@ -84,6 +86,12 @@ export class PPTApi { slidesStore.setWorkItem(workItem) // 没有上课时调用-作业列表 if(!classcourse) this.updateWorkList() + // 没有上课时调用-批量更新缩略图 + if(!classcourse) { + Utils.sleep(1500).then(() => { + this.batchUpdateThumUrl() + }) + } resolve(true) } else msgUtils.msgError(res.msg || '获取数据失败');resolve(false) }) @@ -233,13 +241,20 @@ export class PPTApi { // 批量更新缩略图-异步 static batchUpdateThumUrl() { - return new Promise(async resolve => { + return nextTick().then(async () => { const list = slidesStore.workItem || [] - if (!list.length) return resolve() + if (!list.length) return const upList = [] for (const [ind,o] of list.entries()) { - const thumUrl = await this.getSlideThumUrl(ind) + const isCreate = !o.fileurl // 是否创建 + if (isCreate) { + const thumUrl = await this.getSlideThumUrl(ind) + upList.push({ id: o.id, fileurl: thumUrl }) + } } + if (!upList.length) return + // 批量更新 + return await API_entpcoursefile.batchUpdateNew(upList) }) } diff --git a/src/renderer/src/AixPPTist/src/api/types.ts b/src/renderer/src/AixPPTist/src/api/types.ts index 3678ed4..0beb5ef 100644 --- a/src/renderer/src/AixPPTist/src/api/types.ts +++ b/src/renderer/src/AixPPTist/src/api/types.ts @@ -126,6 +126,8 @@ export class MsgEnum { MSG_homework : 'HOMEWORK', /** @desc: 公屏 - 课堂作业|活动 */ MSG_pushSreen_work : 'pushSreen_work', + /** @desc: 公屏 - 实验 */ + MSG_pushSreen_experiment : 'pushSreen_experiment', /** @desc: 点赞 */ MSG_dz : 'dz', /** @desc: 疑惑 */ diff --git a/src/renderer/src/AixPPTist/src/api/watcher.ts b/src/renderer/src/AixPPTist/src/api/watcher.ts index 34c3294..005aef2 100644 --- a/src/renderer/src/AixPPTist/src/api/watcher.ts +++ b/src/renderer/src/AixPPTist/src/api/watcher.ts @@ -10,6 +10,7 @@ import { MsgEnum } from './types' // 消息枚举 import ChatWs from '@/plugins/socket' // 聊天socket import Classcourse from './classcourse' // 课程相关 import msgUtils from '@/plugins/modal' // 消息工具 +import * as dialogUtils from '@/utils/dialog' // 弹窗-函数 import { Homework } from './index' // api-作业相关 // import emitter from '@/utils/mitt' //mitt 事件总线 import useExecPlay from '../views/Screen/hooks/useExecPlay' // 播放控制 @@ -114,6 +115,10 @@ export default () => { if (!content.id) return Homework.showHomework(content.id) break + case MsgEnum.HEADS.MSG_pushSreen_experiment: // 打开实验: + if (!content.url) return + dialogUtils.openLink(content.url) + break case MsgEnum.HEADS.MSG_closed: // 下课: close() break @@ -137,4 +142,4 @@ export default () => { window.close() // 关闭窗口 }, 1000) } -} +} \ No newline at end of file diff --git a/src/renderer/src/assets/images/login/yc-logo.png b/src/renderer/src/assets/images/login/yc-logo.png new file mode 100644 index 0000000..59db44e Binary files /dev/null and b/src/renderer/src/assets/images/login/yc-logo.png differ diff --git a/src/renderer/src/assets/images/login/ycpeitu.png b/src/renderer/src/assets/images/login/ycpeitu.png new file mode 100644 index 0000000..433a296 Binary files /dev/null and b/src/renderer/src/assets/images/login/ycpeitu.png differ diff --git a/src/renderer/src/assets/images/login/ycpeitu2.jpg b/src/renderer/src/assets/images/login/ycpeitu2.jpg new file mode 100644 index 0000000..4cc2f71 Binary files /dev/null and b/src/renderer/src/assets/images/login/ycpeitu2.jpg differ diff --git a/src/renderer/src/components/template-study/container/right.vue b/src/renderer/src/components/template-study/container/right.vue index 2f4b93c..a452139 100644 --- a/src/renderer/src/components/template-study/container/right.vue +++ b/src/renderer/src/components/template-study/container/right.vue @@ -83,7 +83,7 @@ - + - + \ No newline at end of file + diff --git a/src/renderer/src/plugins/imChat/msgEnum.js b/src/renderer/src/plugins/imChat/msgEnum.js index a83fed7..42458a2 100644 --- a/src/renderer/src/plugins/imChat/msgEnum.js +++ b/src/renderer/src/plugins/imChat/msgEnum.js @@ -100,6 +100,8 @@ export class MsgEnum { MSG_homework : 'HOMEWORK', /** @desc: 公屏 - 课堂作业|活动 */ MSG_pushSreen_work : 'pushSreen_work', + /** @desc: 公屏 - 实验 */ + MSG_pushSreen_experiment : 'pushSreen_experiment', /** @desc: 点赞 */ MSG_dz : 'dz', /** @desc: 疑惑 */ diff --git a/src/renderer/src/utils/comm.js b/src/renderer/src/utils/comm.js index b7d3035..1f7aa7f 100644 --- a/src/renderer/src/utils/comm.js +++ b/src/renderer/src/utils/comm.js @@ -49,10 +49,10 @@ export function blobToFile(blob, fileName, contentType) { /** * @description 计算两点直线距离 (获取直径) * (欧几里得距离公式): [ \text{distance} = \sqrt{(x2 - x1)^2 + (y2 - y1)^2} ] - * @param {*} x1 - * @param {*} y1 - * @param {*} x2 - * @param {*} y2 + * @param {*} x1 + * @param {*} y1 + * @param {*} x2 + * @param {*} y2 */ export function getDistance(x1,y1,x2,y2) { return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)) @@ -62,10 +62,10 @@ export function getRadius(x1,y1,x2,y2) { return getDistance(x1,y1,x2,y2) / 2 } /** * 计算某个值在总数中所占的百分比。 - * + * * 此函数用于根据给定的值和总数,计算该值占总数的百分比。它还支持指定百分比的小数位数。 * 如果计算结果小于0,则返回0;如果大于100,则返回100,以确保百分比的合理范围。 - * + * * @param {number} v - 待计算的值。 * @param {number} total - 总数。 * @param {number} [step=2] - 百分比的小数位数,默认为2。 @@ -76,7 +76,7 @@ export function getPercent(v, total, step=2) { !total && (total = 1) // 计算百分比,保留指定的小数位,并转换为数字类型 let res = (v / total * 100).toFixed(step)-0 - + // 确保百分比在0到100之间 return res < 0 ? 0 : res > 100 ? 100 : res } @@ -89,7 +89,7 @@ export function getPercent(v, total, step=2) { * @param {*} start 前面保留几位 默认 3位 * @param {*} end 后面保留几位 默认 3位 * @param {*} rstr 替换字符 默认 **** - * @returns + * @returns */ export function phoneHideFormat(phone, start = 3, end = 4, rstr = '****') { // const reg = /^(\d{3})\d*(\d{4})$/ @@ -101,8 +101,8 @@ export function phoneHideFormat(phone, start = 3, end = 4, rstr = '****') { // ============= 习题工具--相关 =================== /** * @description 将字符串转换为数组 - * @param {*} str - * @returns + * @param {*} str + * @returns */ export function quizStrToList(str = '') { if (!str) return [] @@ -175,8 +175,8 @@ export const validateUrl = (url) => { /** * @description 时间 秒 转化 时分秒 - * @param {*} seconds - * @returns + * @param {*} seconds + * @returns */ export function formatTime(seconds) { seconds = parseInt(seconds) // 转换整数 @@ -188,9 +188,9 @@ export function formatTime(seconds) { /** * @description 时间格式化 - * @param {*} time - * @param {*} fmt - * @returns + * @param {*} time + * @param {*} fmt + * @returns */ export function formatDate(time, fmt = 'yyyy-MM-dd') { let date @@ -300,7 +300,7 @@ export function getDateStr1(num, fmt = 'yyyy-MM-dd hh:mm:ss') { } /** * 获取当前 0:0:0:0 时间 - * @param {*} [fmt] 格式 'yyyy-MM-dd hh:mm:ss' + * @param {*} [fmt] 格式 'yyyy-MM-dd hh:mm:ss' */ export function getDateNow(fmt) { const date = new Date() @@ -339,9 +339,9 @@ export function timeToStr(time,str = '时分秒', isPad = false) { * debounce(() => { console.log('Input event handled'); }, 300); - * @param {*} func - * @param {*} wait - * @returns + * @param {*} func + * @param {*} wait + * @returns */ export function debounce(func, wait) { let timeout; @@ -358,9 +358,9 @@ export function debounce(func, wait) { * throttle(() => { console.log('Scroll event handled'); }, 300); - * @param {*} func - * @param {*} wait - * @returns + * @param {*} func + * @param {*} wait + * @returns */ export function throttle(func, wait) { let lastTime = 0; @@ -376,7 +376,7 @@ export function throttle(func, wait) { } /** - * + * * 大模型对话dataset_id */ export const dataSetJson = { @@ -403,5 +403,11 @@ export const dataSetJson = { "教材-高中-数学": "e03aa4fe9fd011ef91270242ac140006", "教材-高中-地理": "270516829fd111efb13c0242ac140006", "教材-高中-政治": "a2f0b247b85d11ef84290242ac140005", + "课标-小学-科学": "935cfec8bf6a11ef98950242ac140006", + "课标-小学-数学": "3c4e298fbf7911ef8e8b0242ac140002", + "课标-小学-语文": "f76f1aa5bf7111ef90c80242ac140002", + "教材-小学-科学": "935cfec8bf6a11ef98950242ac140006", + "教材-小学-数学": "3c4e298fbf7911ef8e8b0242ac140002", + "教材-小学-语文": "f76f1aa5bf7111ef90c80242ac140002", "鉴权": "ragflow-IwMDI1MGU2YTU3NjExZWZiNWEzMDI0Mm" -} \ No newline at end of file +} diff --git a/src/renderer/src/utils/dialog.js b/src/renderer/src/utils/dialog.js new file mode 100644 index 0000000..66b41d3 --- /dev/null +++ b/src/renderer/src/utils/dialog.js @@ -0,0 +1,49 @@ +/** + * 弹窗-函数 + */ +import { h, render } from 'vue' +import { ElDialog } from 'element-plus' + +// 打开弹窗-函数 +export const openDialog = (option, content) => { + let vNode + const body = document.body + const dOpts = { + modelValue: true, + width: 800, + height: 600, + title: '添加-超连接', + draggable: true, + 'onUpdate:modelValue': val => { + if (vNode && !val) render(null, body) + }, + ...option + } + vNode = h(ElDialog, dOpts, { + default: typeof content == 'function' ? content(h) : content + }) + render(vNode, body) +} + +// 打开链接 +export const openLink = (option, title) => { + // https://phet.colorado.edu/sims/html/number-play/latest/number-play_zh_CN.html + const isStr = typeof option == 'string' + const opt = isStr ? {} : option + const url = isStr ? option : option?.url || option?.src || option?.href + const titleNew = isStr? title||'实验室' : option?.title || '添加-超连接' + openDialog({ + title: titleNew, + ...opt + }, (h) => { + return h('iframe', { + src: url, + width: '100%', + style: { + height: 'calc(80vh - 75px)', + }, + scrolling: 'no', + frameborder: '0', + }) + }) +} \ No newline at end of file diff --git a/src/renderer/src/utils/talkFile/index.js b/src/renderer/src/utils/talkFile/index.js index ae5dfbb..fa56bb2 100644 --- a/src/renderer/src/utils/talkFile/index.js +++ b/src/renderer/src/utils/talkFile/index.js @@ -9,7 +9,7 @@ export const asyncLocalFile = (item) => { if (isAsync === true) { item.async = 'on' if (type === 'down') { - console.log(item) + // console.log(item) ipcRenderer.send('download-file-default', { url: item.fileFullPath, fileName: item.fileNewName diff --git a/src/renderer/src/utils/tool.js b/src/renderer/src/utils/tool.js index 1dbc2be..a83cbd1 100644 --- a/src/renderer/src/utils/tool.js +++ b/src/renderer/src/utils/tool.js @@ -248,10 +248,11 @@ export function toolWindow(type, {url, isConsole, isWeb=true, option={}}) { const devUrl = `${BaseUrl}${url}` const buildUrl = path.join(__dirname, 'index.html') const urlAll = isDev ? devUrl : buildUrl + let logoIco = import.meta.env.MODE==='yc'||import.meta.env.MODE==='yc2'?'/resources/yc-logo.png':'/resources/logo2.ico' return new Promise(async(resolve) => { const config = { width, height, - icon: path.join(appPath, '/resources/logo2.ico'), + icon: path.join(appPath, logoIco), webPreferences: { preload: path.join(API.preloadPath, '/index.js'), sandbox: false, diff --git a/src/renderer/src/views/classTask/teachClassTask.vue b/src/renderer/src/views/classTask/teachClassTask.vue index 83b5ec9..0d1afe6 100644 --- a/src/renderer/src/views/classTask/teachClassTask.vue +++ b/src/renderer/src/views/classTask/teachClassTask.vue @@ -721,19 +721,23 @@ const msgHandle = (msg) => { const { head, content, ...other } = msg switch(head) { case MsgEnum.HEADS.MSG_closed: // 下课: - Homework.win = null - window.close() // 关闭窗口 - break + Homework.win = null + window.close() // 关闭窗口 + break case MsgEnum.HEADS.MSG_finishHomework: // 跟新作业: console.log('更新作业', head, content) const data = JSON.parse(localStorage.getItem('teachClassWorkItem')); openDialog(data, false); - break + break case MsgEnum.HEADS.MSG_slideFlapping: // 切换页面 console.log('切换页面-关闭窗口') Homework.win = null window.close() // 关闭窗口 - break + break + case MsgEnum.HEADS.MSG_pushSreen_experiment: // 实验: + Homework.win = null + window.close() // 关闭窗口 + break // case 'TIMAddRecvNewMsgCallback': // 收到新消息 data=[] // { // (data||[]).forEach(o => { diff --git a/src/renderer/src/views/login/defult-login.vue b/src/renderer/src/views/login/defult-login.vue new file mode 100644 index 0000000..9b506aa --- /dev/null +++ b/src/renderer/src/views/login/defult-login.vue @@ -0,0 +1,427 @@ + + + diff --git a/src/renderer/src/views/login/index.vue b/src/renderer/src/views/login/index.vue index 9b506aa..290f79d 100644 --- a/src/renderer/src/views/login/index.vue +++ b/src/renderer/src/views/login/index.vue @@ -1,427 +1,13 @@ diff --git a/src/renderer/src/views/login/yc-login.vue b/src/renderer/src/views/login/yc-login.vue new file mode 100644 index 0000000..32ecf38 --- /dev/null +++ b/src/renderer/src/views/login/yc-login.vue @@ -0,0 +1,463 @@ + + + diff --git a/src/renderer/src/views/prepare/container/file-list-item.vue b/src/renderer/src/views/prepare/container/file-list-item.vue index c2e3e90..7f28cdb 100644 --- a/src/renderer/src/views/prepare/container/file-list-item.vue +++ b/src/renderer/src/views/prepare/container/file-list-item.vue @@ -126,11 +126,17 @@ 下载 -
+ +
+ + + 导入PPT +
@@ -181,7 +187,7 @@ export default { } } }, - emits: { 'on-move': null, 'on-delete': null, 'on-set': null, 'on-reSet': null, 'on-delhomework': null,'on-filearg': null }, + emits: { 'on-move': null, 'on-delete': null, 'on-set': null, 'on-reSet': null, 'on-delhomework': null,'on-filearg': null,'on-importPPT': null }, data() { return { listenList: [], @@ -217,6 +223,9 @@ export default { }) .catch(() => {}) }, + importPPT(item) { + this.$emit('on-importPPT', item) + }, downloadFile(item) { ipcRenderer.send('save-as', item.fileFullPath, item.fileShowName) }, diff --git a/src/renderer/src/views/prepare/index.vue b/src/renderer/src/views/prepare/index.vue index 2196474..bd0b57b 100644 --- a/src/renderer/src/views/prepare/index.vue +++ b/src/renderer/src/views/prepare/index.vue @@ -99,6 +99,7 @@ @on-delete="deleteTalk" @on-set="openSet" @on-delhomework="delhomework" + @on-importPPT="importPPT" @on-filearg="isOpenHomework = true" > @@ -555,6 +556,15 @@ export default { progDownFile(e, num) { this.downloadNum = num }, + importPPT(item) { + let _this = this; + fetch(item.fileFullPath) + .then(res => res.arrayBuffer()) + .then(buffer => { + let name = item.fileShowName.substring(0, item.fileShowName.lastIndexOf('.')) + '.aippt' + _this.createAIPPTByFile(buffer, name) + }) + }, createFile() { creatPPT(this.currentNode.itemtitle + '.pptx', this.uploadData).then((res) => { this.currentFileList.unshift(res.resData) @@ -573,7 +583,7 @@ export default { console.log('文件名:', file.name); console.log('文件类型:', file.type); console.log('文件大小:', file.size); - this.createAIPPTByFile(file) + this.createAIPPTByFile(file, this.currentNode.itemtitle + '.aippt') } }, async toRousrceUrl(o) { @@ -619,7 +629,7 @@ export default { } } }, - async createAIPPTByFile(file) { + async createAIPPTByFile(file,fileShowName) { this.pgDialog.visible = true this.pgDialog.pg.percentage = 0 const resPptJson = await PPTXFileToJson(file) @@ -665,7 +675,7 @@ export default { ...this.uploadData, fileId: slideid, fileFlag: 'aippt', - fileShowName: this.currentNode.itemtitle + '.aippt' + fileShowName: fileShowName }).then(async (res) => { const resSlides = slides.map(({id, ...slide}) => JSON.stringify(slide)) diff --git a/src/renderer/src/views/teachingDesign/container/right.vue b/src/renderer/src/views/teachingDesign/container/right.vue index c69a22b..f829f3b 100644 --- a/src/renderer/src/views/teachingDesign/container/right.vue +++ b/src/renderer/src/views/teachingDesign/container/right.vue @@ -92,7 +92,9 @@ import * as API_entpcourse from '@/api/education/entpcourse' // 相关api import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api import * as Api_server from '@/api/apiService' // 相关api import * as API_smarttalk from '@/api/file' // 文件相关api -import msgUtils from '@/plugins/modal' // 消息工具 +import msgUtils from '@/plugins/modal' +import { getEntpcoursefile } from '@/api/education/entpcoursefile' +import { createWindow } from '@/utils/tool' // 消息工具 const userStore = useUserStore() const pptDialog = ref(false) @@ -117,7 +119,7 @@ const pgDialog = reactive({ // 弹窗-进度条 } }) -const curMode = ref(1) +const curMode = ref(2) const modeOptions = ref([ { label: '教学大模型', @@ -223,7 +225,7 @@ const editKeyWord = (item, val) => { const removeItem = async (item, isChild) => { /** * item: 当前操作的模板 - * isChild: 子模板中的移除为 true + * isChild: 子模板中的移除为 true */ if (item.ex3 != '1') { ElMessageBox.confirm( @@ -280,7 +282,7 @@ const scrollToBottom = (height, index) => { let listDom = listRef.value.children if (index == 0) { - // 220 去掉头部 + // 220 去掉头部 let screenHeight = window.innerHeight - 220 if (height > screenHeight) { listRef.value.scrollTop = (height - screenHeight + 50) @@ -346,13 +348,20 @@ const addAiPPT = async (res) => { const parentid = await HTTP_SERVER_API('addEntpcoursefile', p_params) if (!!parentid ?? null) { // 生成内容幻灯片 // 生成备课资源-Smarttalk - HTTP_SERVER_API('addSmarttalk', { fileId: parentid }) + const smarttalk = await HTTP_SERVER_API('addSmarttalk', { fileId: parentid }) if (slides.length > 0) { const resSlides = slides.map(({ id, ...slide }) => JSON.stringify(slide)) const params = { parentid, filetype: 'slide', title: '', slides: resSlides } const res_3 = await HTTP_SERVER_API('batchAddNew', params) if (res_3 && res_3.code == 200) { msgUtils.msgSuccess('生成PPT课件成功') + //TODO 打开生成的课件 + const res = await getEntpcoursefile(parentid) + if (res && res.code === 200) { + openPublicScreen('edit', res.data, smarttalk.resData) // 打开公屏-窗口 + } else { + ElMessage.warning(res.msg||'文件获取异常!') + } } else { msgUtils.msgWarning('生成PPT课件失败') } @@ -361,7 +370,20 @@ const addAiPPT = async (res) => { }) } - +const openPublicScreen = (type, resource, currData)=> { + sessionStore.set('curr.resource', resource) // 缓存当前资源信息 + if (type=='edit') sessionStore.set('curr.smarttalk', currData) // 缓存当前文件smarttalk + else sessionStore.set('curr.classcourse', currData) // 缓存当前当前上课 + createWindow('open-win', { + url: '/pptist', // 窗口关闭时,清除缓存 + close: () => { + sessionStore.set('curr.resource', null) // 清除缓存 + if (type=='edit') { + sessionStore.set('curr.smarttalk', null) // 清除缓存 + } else sessionStore.set('curr.classcourse', null) // 清除缓存 + } + }) +} const isEdit = ref(false) // 当前操作的索引 const curIndex = ref(-1) @@ -735,4 +757,4 @@ onUnmounted(() => { width: 110px !important; min-width: 110px !important; } - \ No newline at end of file +