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..5955e9f 100644 --- a/package.json +++ b/package.json @@ -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..7f7eee1 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -46,7 +46,7 @@ if(!gotTheLock){ 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, 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..9343418 100644 --- a/src/renderer/src/components/template-study/container/right.vue +++ b/src/renderer/src/components/template-study/container/right.vue @@ -104,7 +104,7 @@ import { cloneDeep } from 'lodash' const props = defineProps(['type']) const { user } = useUserStore() -const curMode = ref(1) +const curMode = ref(2) const modeOptions = ref([ { label: '教学大模型', @@ -205,7 +205,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) @@ -240,7 +240,7 @@ const changeTemplate = (val) => { const removeItem = async (item, isChild) => { /** * item: 当前操作的模板 - * isChild: 子模板中的移除为 true + * isChild: 子模板中的移除为 true */ if (item.ex3 != '1') { ElMessageBox.confirm( @@ -320,7 +320,7 @@ const againResult = async (index, item) => { str = str.replace('{模板内容}',item.prompt) params.prompt = str params.template = item.prompt - + let data = null; // 教学大模型 if (curMode.value == 1) { @@ -606,4 +606,4 @@ onUnmounted(() => { width: 110px !important; min-width: 110px !important; } - \ No newline at end of file + 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/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/teachingDesign/container/right.vue b/src/renderer/src/views/teachingDesign/container/right.vue index a56bca2..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) @@ -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)