diff --git a/docs/paper-question-independent-windows.md b/docs/paper-question-independent-windows.md new file mode 100644 index 0000000..0006b72 --- /dev/null +++ b/docs/paper-question-independent-windows.md @@ -0,0 +1,121 @@ +# Paper/Question 页面独立窗口功能使用说明 + +## 功能概述 + +完善了 paper/question 页面的独立窗口功能,支持编程题和表格题通过独立窗口进行新增、编辑和修改操作。 + +## 主要改进 + +### 1. 独立窗口支持 +- **编程题**: 点击新增/修改时会打开独立窗口 +- **表格题**: 点击新增/修改时会打开独立窗口 +- **其他题型**: 继续使用传统对话框模式 + +### 2. 路由配置 +添加了两个新的独立窗口路由: +- `/cdesign-independent` - 编程题独立窗口 +- `/excel-independent` - 表格题独立窗口 + +### 3. 事件通信 +使用 Tauri 事件系统进行窗口间通信: +- `init-cdesign-form` - 初始化编程题表单数据 +- `init-excel-form` - 初始化表格题表单数据 +- `cdesign-form-success` / `excel-form-success` - 表单提交成功 +- `cdesign-form-cancel` / `excel-form-cancel` - 表单取消 + +## 文件修改说明 + +### 1. 主要页面修改 +- `src/views/paper/question/index.vue`: 修改 openForm 函数,为编程题和表格题添加独立窗口支持 +- `src/views/paper/question/CdesignForm.vue`: 已支持独立窗口模式 +- `src/views/paper/question/WpsXlsxForm.vue`: 添加独立窗口模式支持 + +### 2. 新增独立窗口页面 +- `src/views/cdesign/independent.vue`: 编程题独立窗口页面 +- `src/views/excel/independent.vue`: 表格题独立窗口页面 + +### 3. 路由配置 +- `src/router/modules/remaining.ts`: 添加独立窗口路由配置 + +## 使用方法 + +### 在 paper/question 页面中 + +1. **选择题型**: 首先选择相应的专业和题型 +2. **新增操作**: + - 编程题:点击"新增"按钮,自动打开编程题独立窗口 + - 表格题:点击"新增"按钮,自动打开表格题独立窗口 + - 其他题型:使用传统对话框模式 + +3. **修改操作**: + - 在题目列表中点击"修改"按钮 + - 编程题和表格题会在独立窗口中打开 + - 其他题型继续使用对话框模式 + +### 独立窗口功能 + +1. **窗口大小**: 1200x800 像素,可调整大小 +2. **数据传递**: 通过 Tauri 事件系统自动传递初始化数据 +3. **表单提交**: 提交成功后自动关闭窗口并刷新主页面列表 +4. **取消操作**: 取消时自动关闭窗口 + +## 技术实现 + +### 1. 窗口管理 +```javascript +const { WebviewWindow } = await import('@tauri-apps/api/webviewWindow') +const webview = new WebviewWindow(windowLabel, { + url: '#/cdesign-independent', + title: '新增编程题', + width: 1200, + height: 800, + resizable: true, + center: true +}) +``` + +### 2. 事件通信 +```javascript +// 发送初始化数据 +import('@tauri-apps/api/event').then(({ emit }) => { + emit('init-cdesign-form', { + queryParams, + type, + id + }) +}) + +// 监听成功事件 +const { listen } = await import('@tauri-apps/api/event') +listen('cdesign-form-success', () => { + getList() // 刷新列表 +}) +``` + +### 3. 降级处理 +如果独立窗口创建失败,会自动降级到传统对话框模式,确保功能的稳定性。 + +## 优势特点 + +1. **用户体验好**: 独立窗口提供更大的操作空间 +2. **多任务处理**: 可以同时查看列表和编辑表单 +3. **兼容性强**: 保持其他题型的传统操作方式不变 +4. **容错机制**: 具备降级处理机制,保证功能稳定性 +5. **事件驱动**: 使用 Tauri 事件系统实现优雅的窗口间通信 + +## 注意事项 + +1. 确保 Tauri 环境正常运行 +2. 独立窗口需要相应的路由配置 +3. 表单组件需要支持 `isIndependent` 属性 +4. 事件名称需要保持一致以确保正常通信 + +## 扩展说明 + +如需为其他题型添加独立窗口支持: + +1. 在对应的 Form 组件中添加 `isIndependent` 属性支持 +2. 创建对应的独立窗口页面 +3. 在路由中添加相应配置 +4. 在 `openForm` 函数中添加相应的处理逻辑 +5. 定义相应的事件名称用于通信 diff --git a/docs/独立窗口系统使用说明.md b/docs/独立窗口系统使用说明.md new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index 94af1f6..ebd0a1c 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.10", "@zxcvbn-ts/core": "^3.0.4", + "ace-builds": "^1.43.2", "animate.css": "^4.1.1", "axios": "^1.6.8", "benz-amr-recorder": "^1.1.5", @@ -79,6 +80,7 @@ "vue-i18n": "9.10.2", "vue-router": "4.4.5", "vue-types": "^5.1.1", + "vue3-ace-editor": "^2.2.4", "vue3-signature": "^0.2.4", "vuedraggable": "^4.1.0", "web-storage-cache": "^1.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b864db..f87aa38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: '@zxcvbn-ts/core': specifier: ^3.0.4 version: 3.0.4 + ace-builds: + specifier: ^1.43.2 + version: 1.43.2 animate.css: specifier: ^4.1.1 version: 4.1.1 @@ -164,6 +167,9 @@ importers: vue-types: specifier: ^5.1.1 version: 5.1.3(vue@3.5.12(typescript@5.3.3)) + vue3-ace-editor: + specifier: ^2.2.4 + version: 2.2.4(ace-builds@1.43.2)(vue@3.5.12(typescript@5.3.3)) vue3-signature: specifier: ^0.2.4 version: 0.2.4(vue@3.5.12(typescript@5.3.3)) @@ -2420,8 +2426,8 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==, tarball: https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz} hasBin: true - ace-builds@1.39.1: - resolution: {integrity: sha512-HcJbBzx8qY66t9gZo/sQu7pi0wO/CFLdYn1LxQO1WQTfIkMfyc7LRnBpsp/oNCSSU/LL83jXHN1fqyOTuIhUjg==} + ace-builds@1.43.2: + resolution: {integrity: sha512-3wzJUJX0RpMc03jo0V8Q3bSb/cKPnS7Nqqw8fVHsCCHweKMiTIxT3fP46EhjmVy6MCuxwP801ere+RW245phGw==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, tarball: https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz} @@ -5159,6 +5165,12 @@ packages: vue: optional: true + vue3-ace-editor@2.2.4: + resolution: {integrity: sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==} + peerDependencies: + ace-builds: '*' + vue: ^3 + vue3-signature@0.2.4: resolution: {integrity: sha512-XFwwFVK9OG3F085pKIq2SlNVqx32WdFH+TXbGEWc5FfEKpx8oMmZuAwZZ50K/pH2FgmJSE8IRwU9DDhrLpd6iA==} peerDependencies: @@ -7788,7 +7800,7 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 - ace-builds@1.39.1: {} + ace-builds@1.43.2: {} acorn-jsx@5.3.2(acorn@8.14.0): dependencies: @@ -9253,7 +9265,7 @@ snapshots: jsoneditor@9.10.5: dependencies: - ace-builds: 1.39.1 + ace-builds: 1.43.2 ajv: 6.12.6 javascript-natural-sort: 0.7.1 jmespath: 0.16.0 @@ -10675,6 +10687,12 @@ snapshots: optionalDependencies: vue: 3.5.12(typescript@5.3.3) + vue3-ace-editor@2.2.4(ace-builds@1.43.2)(vue@3.5.12(typescript@5.3.3)): + dependencies: + ace-builds: 1.43.2 + resize-observer-polyfill: 1.5.1 + vue: 3.5.12(typescript@5.3.3) + vue3-signature@0.2.4(vue@3.5.12(typescript@5.3.3)): dependencies: default-passive-events: 2.0.0 diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 388023c..204b3b6 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -36,6 +36,9 @@ "core:window:allow-set-skip-taskbar", "core:webview:allow-set-webview-position", "core:webview:allow-set-webview-size", - "core:window:allow-create" + "core:window:allow-create", + "core:event:allow-emit", + "core:event:allow-listen", + "core:event:allow-unlisten" ] } diff --git a/src/layout/components/TagsView/src/TagsView.vue b/src/layout/components/TagsView/src/TagsView.vue index af492ba..6b6510b 100644 --- a/src/layout/components/TagsView/src/TagsView.vue +++ b/src/layout/components/TagsView/src/TagsView.vue @@ -273,7 +273,7 @@ watch(
{ `${prefixCls}-content-scrollbar`, { '!h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))] mt-[calc(var(--top-tool-height)+var(--tags-view-height))]': - fixedHeader.value && tagsView.value, + fixedHeader.value && (tagsView.value || !isDashboardPage.value), '!h-[calc(100%-var(--top-tool-height))] mt-[var(--top-tool-height)]': - fixedHeader.value && !tagsView.value + fixedHeader.value && !tagsView.value && isDashboardPage.value } ]} > diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 971e3c9..fd7277e 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -746,6 +746,27 @@ const remainingRouter: AppRouteRecordRaw[] = [ component: () => import('@/views/iot/plugin/detail/index.vue') } ] + }, + // 独立窗口路由 + { + path: '/cdesign-independent', + name: 'CdesignIndependent', + component: () => import('@/views/cdesign/independent.vue'), + meta: { + title: '编程题独立窗口', + hidden: true, + noTagsView: true + } + }, + { + path: '/excel-independent', + name: 'ExcelIndependent', + component: () => import('@/views/excel/independent.vue'), + meta: { + title: '表格题独立窗口', + hidden: true, + noTagsView: true + } } ] diff --git a/src/styles/index.scss b/src/styles/index.scss index 7607941..3fe017d 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -35,3 +35,20 @@ border-left-color: var(--el-color-primary); } } + +/* Layout border styles */ +.layout-border__top { + border-top: 1px solid var(--el-border-color); +} + +.layout-border__bottom { + border-bottom: 1px solid var(--el-border-color); +} + +.layout-border__left { + border-left: 1px solid var(--el-border-color); +} + +.layout-border__right { + border-right: 1px solid var(--el-border-color); +} diff --git a/src/utils/aceConfig.ts b/src/utils/aceConfig.ts new file mode 100644 index 0000000..81a76ad --- /dev/null +++ b/src/utils/aceConfig.ts @@ -0,0 +1,53 @@ +import ace from 'ace-builds' + +// ACE 编辑器配置 +export const configureAce = () => { + try { + // 设置基础路径 + ace.config.set('basePath', '/node_modules/ace-builds/src-noconflict/') + ace.config.set('workerPath', '/node_modules/ace-builds/src-noconflict/') + ace.config.set('modePath', '/node_modules/ace-builds/src-noconflict/') + ace.config.set('themePath', '/node_modules/ace-builds/src-noconflict/') + + // 禁用严格的CSP模式来避免worker问题 + ace.config.set('useStrictCSP', true) + + console.log('ACE Editor configured successfully') + } catch (error) { + console.warn('ACE Editor configuration warning:', error) + } +} + +// 默认编辑器选项 +export const defaultAceOptions = { + useWorker: false, // 禁用worker避免加载问题 + enableBasicAutocompletion: true, + enableSnippets: true, + enableLiveAutocompletion: true, + fontSize: 14, + showPrintMargin: false, + highlightActiveLine: true, + showGutter: true, + wrap: true, + autoScrollEditorIntoView: true +} + +// 初始化编辑器实例 +export const initAceEditor = (editor: any) => { + try { + // 禁用worker + editor.session.setUseWorker(false) + + // 设置样式 + editor.container.style.lineHeight = 1.5 + editor.renderer.updateFontSize() + + // 设置其他选项 + editor.setShowPrintMargin(false) + editor.setHighlightActiveLine(true) + + console.log('ACE Editor instance initialized successfully') + } catch (error) { + console.warn('ACE Editor instance initialization warning:', error) + } +} diff --git a/src/views/cdesign/independent.vue b/src/views/cdesign/independent.vue new file mode 100644 index 0000000..165e21b --- /dev/null +++ b/src/views/cdesign/independent.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/views/excel/independent.vue b/src/views/excel/independent.vue new file mode 100644 index 0000000..7c4cc49 --- /dev/null +++ b/src/views/excel/independent.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/src/views/paper/question/CdesignForm.vue b/src/views/paper/question/CdesignForm.vue index cade925..1edffeb 100644 --- a/src/views/paper/question/CdesignForm.vue +++ b/src/views/paper/question/CdesignForm.vue @@ -1,524 +1,733 @@