diff --git a/.vscode/settings.json b/.vscode/settings.json index f145f38..2db1f3d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -62,7 +62,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { - "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescriptreact]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" diff --git a/package.json b/package.json index d2d8b31..e19830a 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,9 @@ "@form-create/designer": "^3.2.6", "@form-create/element-ui": "^3.2.11", "@iconify/iconify": "^3.1.1", + "@iconify/vue": "^4.3.0", "@microsoft/fetch-event-source": "^2.0.1", + "@traptitech/markdown-it-katex": "^3.6.0", "@videojs-player/vue": "^1.0.0", "@vueuse/core": "^10.9.0", "@wangeditor/editor": "^5.1.23", @@ -53,6 +55,7 @@ "jsencrypt": "^3.3.2", "lodash-es": "^4.17.21", "markdown-it": "^14.1.0", + "markdown-it-link-attributes": "^4.0.1", "markmap-common": "^0.16.0", "markmap-lib": "^0.16.1", "markmap-toolbar": "^0.17.0", @@ -67,6 +70,7 @@ "sortablejs": "^1.15.3", "steady-xml": "^0.1.0", "url": "^0.11.3", + "uuid": "^11.1.0", "video.js": "^7.21.5", "vue": "3.5.12", "vue-dompurify-html": "^4.1.4", @@ -88,6 +92,7 @@ "@types/nprogress": "^0.2.3", "@types/qrcode": "^1.5.5", "@types/qs": "^6.9.12", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "@unocss/eslint-config": "^0.57.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f4b94b..da0aeb6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,31 +10,37 @@ importers: dependencies: '@element-plus/icons-vue': specifier: ^2.1.0 - version: 2.3.1(vue@3.5.12) + version: 2.3.1(vue@3.5.12(typescript@5.3.3)) '@form-create/designer': specifier: ^3.2.6 - version: 3.2.8(vue@3.5.12) + version: 3.2.8(vue@3.5.12(typescript@5.3.3)) '@form-create/element-ui': specifier: ^3.2.11 - version: 3.2.14(vue@3.5.12) + version: 3.2.14(vue@3.5.12(typescript@5.3.3)) '@iconify/iconify': specifier: ^3.1.1 version: 3.1.1 + '@iconify/vue': + specifier: ^4.3.0 + version: 4.3.0(vue@3.5.12(typescript@5.3.3)) '@microsoft/fetch-event-source': specifier: ^2.0.1 version: 2.0.1 + '@traptitech/markdown-it-katex': + specifier: ^3.6.0 + version: 3.6.0 '@videojs-player/vue': specifier: ^1.0.0 - version: 1.0.0(@types/video.js@7.3.58)(video.js@7.21.6)(vue@3.5.12) + version: 1.0.0(@types/video.js@7.3.58)(video.js@7.21.6)(vue@3.5.12(typescript@5.3.3)) '@vueuse/core': specifier: ^10.9.0 - version: 10.11.1(vue@3.5.12) + version: 10.11.1(vue@3.5.12(typescript@5.3.3)) '@wangeditor/editor': specifier: ^5.1.23 version: 5.1.23 '@wangeditor/editor-for-vue': specifier: ^5.1.10 - version: 5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.12) + version: 5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.12(typescript@5.3.3)) '@zxcvbn-ts/core': specifier: ^3.0.4 version: 3.0.4 @@ -76,7 +82,7 @@ importers: version: 2.1.0(echarts@5.5.1) element-plus: specifier: 2.8.4 - version: 2.8.4(vue@3.5.12) + version: 2.8.4(vue@3.5.12(typescript@5.3.3)) fast-xml-parser: specifier: ^4.3.2 version: 4.5.0 @@ -92,6 +98,9 @@ importers: markdown-it: specifier: ^14.1.0 version: 14.1.0 + markdown-it-link-attributes: + specifier: ^4.0.1 + version: 4.0.1 markmap-common: specifier: ^0.16.0 version: 0.16.0 @@ -115,10 +124,10 @@ importers: version: 0.2.0 pinia: specifier: ^2.1.7 - version: 2.2.8(typescript@5.3.3)(vue@3.5.12) + version: 2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3)) pinia-plugin-persistedstate: specifier: ^3.2.1 - version: 3.2.3(pinia@2.2.8) + version: 3.2.3(pinia@2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3))) qrcode: specifier: ^1.5.3 version: 1.5.4 @@ -134,6 +143,9 @@ importers: url: specifier: ^0.11.3 version: 0.11.4 + uuid: + specifier: ^11.1.0 + version: 11.1.0 video.js: specifier: ^7.21.5 version: 7.21.6 @@ -142,19 +154,19 @@ importers: version: 3.5.12(typescript@5.3.3) vue-dompurify-html: specifier: ^4.1.4 - version: 4.1.4(vue@3.5.12) + version: 4.1.4(vue@3.5.12(typescript@5.3.3)) vue-i18n: specifier: 9.10.2 - version: 9.10.2(vue@3.5.12) + version: 9.10.2(vue@3.5.12(typescript@5.3.3)) vue-router: specifier: 4.4.5 - version: 4.4.5(vue@3.5.12) + version: 4.4.5(vue@3.5.12(typescript@5.3.3)) vue-types: specifier: ^5.1.1 - version: 5.1.3(vue@3.5.12) + version: 5.1.3(vue@3.5.12(typescript@5.3.3)) vuedraggable: specifier: ^4.1.0 - version: 4.1.0(vue@3.5.12) + version: 4.1.0(vue@3.5.12(typescript@5.3.3)) web-storage-cache: specifier: ^1.1.1 version: 1.1.1 @@ -173,7 +185,7 @@ importers: version: 2.2.277 '@intlify/unplugin-vue-i18n': specifier: ^2.0.0 - version: 2.0.0(rollup@4.27.4)(vue-i18n@9.10.2) + version: 2.0.0(rollup@4.27.4)(vue-i18n@9.10.2(vue@3.5.12(typescript@5.3.3))) '@purge-icons/generated': specifier: ^0.9.0 version: 0.9.0 @@ -192,9 +204,12 @@ importers: '@types/qs': specifier: ^6.9.12 version: 6.9.17 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 '@typescript-eslint/eslint-plugin': specifier: ^7.1.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0)(eslint@8.57.1)(typescript@5.3.3) + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3) '@typescript-eslint/parser': specifier: ^7.1.0 version: 7.18.0(eslint@8.57.1)(typescript@5.3.3) @@ -206,13 +221,13 @@ importers: version: 0.58.9 '@vitejs/plugin-legacy': specifier: ^5.3.1 - version: 5.4.3(terser@5.36.0)(vite@5.1.4) + version: 5.4.3(terser@5.36.0)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) '@vitejs/plugin-vue': specifier: ^5.0.4 - version: 5.2.1(vite@5.1.4)(vue@3.5.12) + version: 5.2.1(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))(vue@3.5.12(typescript@5.3.3)) '@vitejs/plugin-vue-jsx': specifier: ^3.1.0 - version: 3.1.0(vite@5.1.4)(vue@3.5.12) + version: 3.1.0(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))(vue@3.5.12(typescript@5.3.3)) autoprefixer: specifier: ^10.4.17 version: 10.4.20(postcss@8.4.49) @@ -221,7 +236,7 @@ importers: version: 17.11.1 bpmn-js-properties-panel: specifier: 5.23.0 - version: 5.23.0(@bpmn-io/properties-panel@3.25.0)(bpmn-js@17.11.1)(camunda-bpmn-js-behaviors@1.7.2)(diagram-js@12.8.1) + version: 5.23.0(@bpmn-io/properties-panel@3.25.0(@lezer/common@1.2.3))(bpmn-js@17.11.1)(camunda-bpmn-js-behaviors@1.7.2(bpmn-js@17.11.1)(camunda-bpmn-moddle@7.0.1)(zeebe-bpmn-moddle@1.7.0))(diagram-js@12.8.1) consola: specifier: ^3.2.3 version: 3.2.3 @@ -236,7 +251,7 @@ importers: version: 2.1.0 eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.1)(prettier@3.4.1) + version: 5.2.1(@types/eslint@8.56.12)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.4.1) eslint-plugin-vue: specifier: ^9.22.0 version: 9.31.0(eslint@8.57.1) @@ -272,16 +287,16 @@ importers: version: 16.11.0(typescript@5.3.3) stylelint-config-html: specifier: ^1.1.0 - version: 1.1.0(postcss-html@1.7.0)(stylelint@16.11.0) + version: 1.1.0(postcss-html@1.7.0)(stylelint@16.11.0(typescript@5.3.3)) stylelint-config-recommended: specifier: ^14.0.0 - version: 14.0.1(stylelint@16.11.0) + version: 14.0.1(stylelint@16.11.0(typescript@5.3.3)) stylelint-config-standard: specifier: ^36.0.0 - version: 36.0.1(stylelint@16.11.0) + version: 36.0.1(stylelint@16.11.0(typescript@5.3.3)) stylelint-order: specifier: ^6.0.4 - version: 6.0.4(stylelint@16.11.0) + version: 6.0.4(stylelint@16.11.0(typescript@5.3.3)) terser: specifier: ^5.28.1 version: 5.36.0 @@ -290,40 +305,40 @@ importers: version: 5.3.3 unocss: specifier: ^0.58.5 - version: 0.58.9(postcss@8.4.49)(rollup@4.27.4)(vite@5.1.4) + version: 0.58.9(postcss@8.4.49)(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) unplugin-auto-import: specifier: ^0.16.7 - version: 0.16.7(@vueuse/core@10.11.1)(rollup@4.27.4) + version: 0.16.7(@vueuse/core@10.11.1(vue@3.5.12(typescript@5.3.3)))(rollup@4.27.4) unplugin-element-plus: specifier: ^0.8.0 version: 0.8.0(rollup@4.27.4) unplugin-vue-components: specifier: ^0.25.2 - version: 0.25.2(rollup@4.27.4)(vue@3.5.12) + version: 0.25.2(@babel/parser@7.26.2)(rollup@4.27.4)(vue@3.5.12(typescript@5.3.3)) vite: specifier: 5.1.4 version: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) vite-plugin-compression: specifier: ^0.5.1 - version: 0.5.1(vite@5.1.4) + version: 0.5.1(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vite-plugin-ejs: specifier: ^1.7.0 - version: 1.7.0(vite@5.1.4) + version: 1.7.0(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.1.4) + version: 1.8.1(eslint@8.57.1)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vite-plugin-progress: specifier: ^0.0.7 - version: 0.0.7(vite@5.1.4) + version: 0.0.7(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vite-plugin-purge-icons: specifier: ^0.10.0 - version: 0.10.0(vite@5.1.4) + version: 0.10.0(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vite-plugin-svg-icons: specifier: ^2.0.1 - version: 2.0.1(vite@5.1.4) + version: 2.0.1(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vite-plugin-top-level-await: specifier: ^1.4.4 - version: 1.4.4(rollup@4.27.4)(vite@5.1.4) + version: 1.4.4(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) vue-eslint-parser: specifier: ^9.3.2 version: 9.4.3(eslint@8.57.1) @@ -1253,6 +1268,11 @@ packages: '@iconify/utils@2.1.33': resolution: {integrity: sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==, tarball: https://registry.npmmirror.com/@iconify/utils/-/utils-2.1.33.tgz} + '@iconify/vue@4.3.0': + resolution: {integrity: sha512-Xq0h6zMrHBbrW8jXJ9fISi+x8oDQllg5hTDkDuxnWiskJ63rpJu9CvJshj8VniHVTbsxCg9fVoPAaNp3RQI5OQ==, tarball: https://registry.npmmirror.com/@iconify/vue/-/vue-4.3.0.tgz} + peerDependencies: + vue: '>=3' + '@intlify/bundle-utils@7.5.1': resolution: {integrity: sha512-UovJl10oBIlmYEcWw+VIHdKY5Uv5sdPG0b/b6bOYxGLln3UwB75+2dlc0F3Fsa0RhoznQ5Rp589/BZpABpE4Xw==, tarball: https://registry.npmmirror.com/@intlify/bundle-utils/-/bundle-utils-7.5.1.tgz} engines: {node: '>= 14.16'} @@ -1673,6 +1693,9 @@ packages: '@transloadit/prettier-bytes@0.0.7': resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==, tarball: https://registry.npmmirror.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz} + '@traptitech/markdown-it-katex@3.6.0': + resolution: {integrity: sha512-CnJzTWxsgLGXFdSrWRaGz7GZ1kUUi8g3E9HzJmeveX1YwVJavrKYqysktfHZQsujdnRqV5O7g8FPKEA/aeTkOQ==, tarball: https://registry.npmmirror.com/@traptitech/markdown-it-katex/-/markdown-it-katex-3.6.0.tgz} + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==, tarball: https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz} engines: {node: '>=10.13.0'} @@ -1818,6 +1841,9 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==, tarball: https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz} + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==, tarball: https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz} + '@types/video.js@7.3.58': resolution: {integrity: sha512-1CQjuSrgbv1/dhmcfQ83eVyYbvGyqhTvb2Opxr0QCV+iJ4J6/J+XWQ3Om59WiwCd1MN3rDUHasx5XRrpUtewYQ==, tarball: https://registry.npmmirror.com/@types/video.js/-/video.js-7.3.58.tgz} @@ -4200,6 +4226,9 @@ packages: resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==, tarball: https://registry.npmmirror.com/map-visit/-/map-visit-1.0.0.tgz} engines: {node: '>=0.10.0'} + markdown-it-link-attributes@4.0.1: + resolution: {integrity: sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==, tarball: https://registry.npmmirror.com/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz} + markdown-it@14.1.0: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==, tarball: https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz} hasBin: true @@ -5479,6 +5508,10 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, tarball: https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz} hasBin: true + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==, tarball: https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz} + hasBin: true + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, tarball: https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz} engines: {node: '>= 0.8'} @@ -6610,7 +6643,7 @@ snapshots: '@commitlint/types': 19.5.0 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@5.3.3) - cosmiconfig-typescript-loader: 5.1.0(@types/node@20.17.9)(cosmiconfig@9.0.0)(typescript@5.3.3) + cosmiconfig-typescript-loader: 5.1.0(@types/node@20.17.9)(cosmiconfig@9.0.0(typescript@5.3.3))(typescript@5.3.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -6667,7 +6700,7 @@ snapshots: '@csstools/css-tokenizer@3.0.3': {} - '@csstools/media-query-list-parser@4.0.2(@csstools/css-parser-algorithms@3.0.4)(@csstools/css-tokenizer@3.0.3)': + '@csstools/media-query-list-parser@4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) '@csstools/css-tokenizer': 3.0.3 @@ -6680,7 +6713,7 @@ snapshots: '@dual-bundle/import-meta-resolve@4.1.0': {} - '@element-plus/icons-vue@2.3.1(vue@3.5.12)': + '@element-plus/icons-vue@2.3.1(vue@3.5.12(typescript@5.3.3))': dependencies: vue: 3.5.12(typescript@5.3.3) @@ -6821,24 +6854,24 @@ snapshots: dependencies: wangeditor: 4.7.15 - '@form-create/core@3.2.14(vue@3.5.12)': + '@form-create/core@3.2.14(vue@3.5.12(typescript@5.3.3))': dependencies: '@form-create/utils': 3.2.14 vue: 3.5.12(typescript@5.3.3) - '@form-create/designer@3.2.8(vue@3.5.12)': + '@form-create/designer@3.2.8(vue@3.5.12(typescript@5.3.3))': dependencies: '@form-create/component-wangeditor': 3.2.14 - '@form-create/element-ui': 3.2.14(vue@3.5.12) + '@form-create/element-ui': 3.2.14(vue@3.5.12(typescript@5.3.3)) '@form-create/utils': 3.2.14 codemirror: 6.65.7 - element-plus: 2.8.4(vue@3.5.12) + element-plus: 2.8.4(vue@3.5.12(typescript@5.3.3)) vue: 3.5.12(typescript@5.3.3) - vuedraggable: 4.1.0(vue@3.5.12) + vuedraggable: 4.1.0(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - '@vue/composition-api' - '@form-create/element-ui@3.2.14(vue@3.5.12)': + '@form-create/element-ui@3.2.14(vue@3.5.12(typescript@5.3.3))': dependencies: '@form-create/component-elm-checkbox': 3.2.14 '@form-create/component-elm-frame': 3.2.14 @@ -6848,7 +6881,7 @@ snapshots: '@form-create/component-elm-tree': 3.2.14 '@form-create/component-elm-upload': 3.2.14 '@form-create/component-subform': 3.1.34 - '@form-create/core': 3.2.14(vue@3.5.12) + '@form-create/core': 3.2.14(vue@3.5.12(typescript@5.3.3)) '@form-create/utils': 3.2.14 vue: 3.5.12(typescript@5.3.3) @@ -6899,7 +6932,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@intlify/bundle-utils@7.5.1(vue-i18n@9.10.2)': + '@iconify/vue@4.3.0(vue@3.5.12(typescript@5.3.3))': + dependencies: + '@iconify/types': 2.0.0 + vue: 3.5.12(typescript@5.3.3) + + '@intlify/bundle-utils@7.5.1(vue-i18n@9.10.2(vue@3.5.12(typescript@5.3.3)))': dependencies: '@intlify/message-compiler': 9.14.2 '@intlify/shared': 9.14.2 @@ -6910,8 +6948,9 @@ snapshots: magic-string: 0.30.14 mlly: 1.7.3 source-map-js: 1.2.1 - vue-i18n: 9.10.2(vue@3.5.12) yaml-eslint-parser: 1.2.3 + optionalDependencies: + vue-i18n: 9.10.2(vue@3.5.12(typescript@5.3.3)) '@intlify/core-base@9.10.2': dependencies: @@ -6932,9 +6971,9 @@ snapshots: '@intlify/shared@9.14.2': {} - '@intlify/unplugin-vue-i18n@2.0.0(rollup@4.27.4)(vue-i18n@9.10.2)': + '@intlify/unplugin-vue-i18n@2.0.0(rollup@4.27.4)(vue-i18n@9.10.2(vue@3.5.12(typescript@5.3.3)))': dependencies: - '@intlify/bundle-utils': 7.5.1(vue-i18n@9.10.2) + '@intlify/bundle-utils': 7.5.1(vue-i18n@9.10.2(vue@3.5.12(typescript@5.3.3))) '@intlify/shared': 9.14.2 '@rollup/pluginutils': 5.1.3(rollup@4.27.4) '@vue/compiler-sfc': 3.5.13 @@ -6946,7 +6985,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 unplugin: 1.16.0 - vue-i18n: 9.10.2(vue@3.5.12) + optionalDependencies: + vue-i18n: 9.10.2(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - rollup - supports-color @@ -7103,7 +7143,7 @@ snapshots: '@iconify/iconify': 3.1.1 '@rollup/plugin-virtual@3.0.2(rollup@4.27.4)': - dependencies: + optionalDependencies: rollup: 4.27.4 '@rollup/pluginutils@4.2.1': @@ -7116,6 +7156,7 @@ snapshots: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 4.0.2 + optionalDependencies: rollup: 4.27.4 '@rollup/rollup-android-arm-eabi@4.27.4': @@ -7230,6 +7271,10 @@ snapshots: '@transloadit/prettier-bytes@0.0.7': {} + '@traptitech/markdown-it-katex@3.6.0': + dependencies: + katex: 0.16.11 + '@trysound/sax@0.2.0': {} '@types/conventional-commits-parser@5.0.1': @@ -7395,13 +7440,15 @@ snapshots: '@types/trusted-types@2.0.7': optional: true + '@types/uuid@10.0.0': {} + '@types/video.js@7.3.58': {} '@types/web-bluetooth@0.0.16': {} '@types/web-bluetooth@0.0.20': {} - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0)(eslint@8.57.1)(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.12.1 '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.3.3) @@ -7414,6 +7461,7 @@ snapshots: ignore: 5.3.2 natural-compare: 1.4.0 ts-api-utils: 1.4.3(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -7426,6 +7474,7 @@ snapshots: '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.7 eslint: 8.57.1 + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -7438,6 +7487,7 @@ snapshots: '@typescript-eslint/visitor-keys': 7.18.0 debug: 4.3.7 eslint: 8.57.1 + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -7459,6 +7509,7 @@ snapshots: debug: 4.3.7 eslint: 8.57.1 ts-api-utils: 1.4.3(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -7477,6 +7528,7 @@ snapshots: minimatch: 9.0.3 semver: 7.6.3 ts-api-utils: 1.4.3(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -7491,6 +7543,7 @@ snapshots: minimatch: 9.0.5 semver: 7.6.3 ts-api-utils: 1.4.3(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -7532,11 +7585,12 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@unocss/astro@0.58.9(rollup@4.27.4)(vite@5.1.4)': + '@unocss/astro@0.58.9(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))': dependencies: '@unocss/core': 0.58.9 '@unocss/reset': 0.58.9 - '@unocss/vite': 0.58.9(rollup@4.27.4)(vite@5.1.4) + '@unocss/vite': 0.58.9(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) + optionalDependencies: vite: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) transitivePeerDependencies: - rollup @@ -7695,7 +7749,7 @@ snapshots: dependencies: '@unocss/core': 0.58.9 - '@unocss/vite@0.58.9(rollup@4.27.4)(vite@5.1.4)': + '@unocss/vite@0.58.9(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))': dependencies: '@ampproject/remapping': 2.3.0 '@rollup/pluginutils': 5.1.3(rollup@4.27.4) @@ -7740,7 +7794,7 @@ snapshots: '@uppy/utils': 4.1.3 nanoid: 3.3.8 - '@videojs-player/vue@1.0.0(@types/video.js@7.3.58)(video.js@7.21.6)(vue@3.5.12)': + '@videojs-player/vue@1.0.0(@types/video.js@7.3.58)(video.js@7.21.6)(vue@3.5.12(typescript@5.3.3))': dependencies: '@types/video.js': 7.3.58 video.js: 7.21.6 @@ -7769,7 +7823,7 @@ snapshots: global: 4.4.0 is-function: 1.0.2 - '@vitejs/plugin-legacy@5.4.3(terser@5.36.0)(vite@5.1.4)': + '@vitejs/plugin-legacy@5.4.3(terser@5.36.0)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))': dependencies: '@babel/core': 7.26.0 '@babel/preset-env': 7.26.0(@babel/core@7.26.0) @@ -7784,7 +7838,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@3.1.0(vite@5.1.4)(vue@3.5.12)': + '@vitejs/plugin-vue-jsx@3.1.0(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))(vue@3.5.12(typescript@5.3.3))': dependencies: '@babel/core': 7.26.0 '@babel/plugin-transform-typescript': 7.25.9(@babel/core@7.26.0) @@ -7794,7 +7848,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.1(vite@5.1.4)(vue@3.5.12)': + '@vitejs/plugin-vue@5.2.1(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0))(vue@3.5.12(typescript@5.3.3))': dependencies: vite: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) vue: 3.5.12(typescript@5.3.3) @@ -7816,7 +7870,6 @@ snapshots: '@vue/babel-plugin-jsx@1.2.5(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) @@ -7827,6 +7880,8 @@ snapshots: '@vue/babel-plugin-resolve-type': 1.2.5(@babel/core@7.26.0) html-tags: 3.3.1 svg-tags: 1.0.0 + optionalDependencies: + '@babel/core': 7.26.0 transitivePeerDependencies: - supports-color @@ -7913,8 +7968,9 @@ snapshots: minimatch: 9.0.5 muggle-string: 0.3.1 path-browserify: 1.0.1 - typescript: 5.3.3 vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.3.3 '@vue/reactivity@3.5.12': dependencies: @@ -7932,7 +7988,7 @@ snapshots: '@vue/shared': 3.5.12 csstype: 3.1.3 - '@vue/server-renderer@3.5.12(vue@3.5.12)': + '@vue/server-renderer@3.5.12(vue@3.5.12(typescript@5.3.3))': dependencies: '@vue/compiler-ssr': 3.5.12 '@vue/shared': 3.5.12 @@ -7942,22 +7998,22 @@ snapshots: '@vue/shared@3.5.13': {} - '@vueuse/core@10.11.1(vue@3.5.12)': + '@vueuse/core@10.11.1(vue@3.5.12(typescript@5.3.3))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.12) - vue-demi: 0.14.10(vue@3.5.12) + '@vueuse/shared': 10.11.1(vue@3.5.12(typescript@5.3.3)) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/core@9.13.0(vue@3.5.12)': + '@vueuse/core@9.13.0(vue@3.5.12(typescript@5.3.3))': dependencies: '@types/web-bluetooth': 0.0.16 '@vueuse/metadata': 9.13.0 - '@vueuse/shared': 9.13.0(vue@3.5.12) - vue-demi: 0.14.10(vue@3.5.12) + '@vueuse/shared': 9.13.0(vue@3.5.12(typescript@5.3.3)) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -7966,23 +8022,23 @@ snapshots: '@vueuse/metadata@9.13.0': {} - '@vueuse/shared@10.11.1(vue@3.5.12)': + '@vueuse/shared@10.11.1(vue@3.5.12(typescript@5.3.3))': dependencies: - vue-demi: 0.14.10(vue@3.5.12) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/shared@9.13.0(vue@3.5.12)': + '@vueuse/shared@9.13.0(vue@3.5.12(typescript@5.3.3))': dependencies: - vue-demi: 0.14.10(vue@3.5.12) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 is-url: 1.2.4 lodash.throttle: 4.1.1 @@ -7990,15 +8046,15 @@ snapshots: slate: 0.72.8 snabbdom: 3.6.2 - '@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 prismjs: 1.29.0 slate: 0.72.8 snabbdom: 3.6.2 - '@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: '@types/event-emitter': 0.3.5 '@uppy/core': 2.3.4 @@ -8021,7 +8077,7 @@ snapshots: slate-history: 0.66.0(slate@0.72.8) snabbdom: 3.6.2 - '@wangeditor/editor-for-vue@5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.12)': + '@wangeditor/editor-for-vue@5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.12(typescript@5.3.3))': dependencies: '@wangeditor/editor': 5.1.23 vue: 3.5.12(typescript@5.3.3) @@ -8030,13 +8086,13 @@ snapshots: dependencies: '@uppy/core': 2.3.4 '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) - '@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 is-hotkey: 0.2.0 lodash.camelcase: 4.3.0 @@ -8050,16 +8106,16 @@ snapshots: slate: 0.72.8 snabbdom: 3.6.2 - '@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 slate: 0.72.8 snabbdom: 3.6.2 - '@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 lodash.isequal: 4.5.0 lodash.throttle: 4.1.1 @@ -8067,22 +8123,22 @@ snapshots: slate: 0.72.8 snabbdom: 3.6.2 - '@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: '@uppy/core': 2.3.4 '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) - '@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 lodash.foreach: 4.5.0 slate: 0.72.8 snabbdom: 3.6.2 - '@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': + '@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2))(dom7@3.0.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2)': dependencies: '@uppy/core': 2.3.4 '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) - '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.8)(slate@0.72.8)(snabbdom@3.6.2) dom7: 3.0.0 nanoid: 3.3.8 slate: 0.72.8 @@ -8285,7 +8341,7 @@ snapshots: boolbase@1.0.0: {} - bpmn-js-properties-panel@5.23.0(@bpmn-io/properties-panel@3.25.0)(bpmn-js@17.11.1)(camunda-bpmn-js-behaviors@1.7.2)(diagram-js@12.8.1): + bpmn-js-properties-panel@5.23.0(@bpmn-io/properties-panel@3.25.0(@lezer/common@1.2.3))(bpmn-js@17.11.1)(camunda-bpmn-js-behaviors@1.7.2(bpmn-js@17.11.1)(camunda-bpmn-moddle@7.0.1)(zeebe-bpmn-moddle@1.7.0))(diagram-js@12.8.1): dependencies: '@bpmn-io/extract-process-variables': 0.8.0 '@bpmn-io/properties-panel': 3.25.0(@lezer/common@1.2.3) @@ -8590,7 +8646,7 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@5.1.0(@types/node@20.17.9)(cosmiconfig@9.0.0)(typescript@5.3.3): + cosmiconfig-typescript-loader@5.1.0(@types/node@20.17.9)(cosmiconfig@9.0.0(typescript@5.3.3))(typescript@5.3.3): dependencies: '@types/node': 20.17.9 cosmiconfig: 9.0.0(typescript@5.3.3) @@ -8603,6 +8659,7 @@ snapshots: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 + optionalDependencies: typescript: 5.3.3 crelt@1.0.6: {} @@ -9041,15 +9098,15 @@ snapshots: electron-to-chromium@1.5.67: {} - element-plus@2.8.4(vue@3.5.12): + element-plus@2.8.4(vue@3.5.12(typescript@5.3.3)): dependencies: '@ctrl/tinycolor': 3.6.1 - '@element-plus/icons-vue': 2.3.1(vue@3.5.12) + '@element-plus/icons-vue': 2.3.1(vue@3.5.12(typescript@5.3.3)) '@floating-ui/dom': 1.6.12 '@popperjs/core': '@sxzz/popperjs-es@2.11.7' '@types/lodash': 4.17.13 '@types/lodash-es': 4.17.12 - '@vueuse/core': 9.13.0(vue@3.5.12) + '@vueuse/core': 9.13.0(vue@3.5.12(typescript@5.3.3)) async-validator: 4.2.5 dayjs: 1.11.13 escape-html: 1.0.3 @@ -9225,13 +9282,15 @@ snapshots: eslint-define-config@2.1.0: {} - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.1)(prettier@3.4.1): + eslint-plugin-prettier@5.2.1(@types/eslint@8.56.12)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.4.1): dependencies: eslint: 8.57.1 - eslint-config-prettier: 9.1.0(eslint@8.57.1) prettier: 3.4.1 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 + optionalDependencies: + '@types/eslint': 8.56.12 + eslint-config-prettier: 9.1.0(eslint@8.57.1) eslint-plugin-vue@9.31.0(eslint@8.57.1): dependencies: @@ -9418,7 +9477,7 @@ snapshots: reusify: 1.0.4 fdir@6.4.2(picomatch@4.0.2): - dependencies: + optionalDependencies: picomatch: 4.0.2 feelers@1.4.0: @@ -9502,7 +9561,7 @@ snapshots: tabbable: 6.2.0 follow-redirects@1.15.9(debug@4.3.7): - dependencies: + optionalDependencies: debug: 4.3.7 for-each@0.3.3: @@ -10206,6 +10265,8 @@ snapshots: dependencies: object-visit: 1.0.1 + markdown-it-link-attributes@4.0.1: {} + markdown-it@14.1.0: dependencies: argparse: 2.0.1 @@ -10611,16 +10672,17 @@ snapshots: pidtree@0.6.0: {} - pinia-plugin-persistedstate@3.2.3(pinia@2.2.8): + pinia-plugin-persistedstate@3.2.3(pinia@2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3))): dependencies: - pinia: 2.2.8(typescript@5.3.3)(vue@3.5.12) + pinia: 2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3)) - pinia@2.2.8(typescript@5.3.3)(vue@3.5.12): + pinia@2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3)): dependencies: '@vue/devtools-api': 6.6.4 - typescript: 5.3.3 vue: 3.5.12(typescript@5.3.3) - vue-demi: 0.14.10(vue@3.5.12) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.3.3)) + optionalDependencies: + typescript: 5.3.3 pkcs7@1.0.4: dependencies: @@ -11204,21 +11266,21 @@ snapshots: style-mod@4.1.2: {} - stylelint-config-html@1.1.0(postcss-html@1.7.0)(stylelint@16.11.0): + stylelint-config-html@1.1.0(postcss-html@1.7.0)(stylelint@16.11.0(typescript@5.3.3)): dependencies: postcss-html: 1.7.0 stylelint: 16.11.0(typescript@5.3.3) - stylelint-config-recommended@14.0.1(stylelint@16.11.0): + stylelint-config-recommended@14.0.1(stylelint@16.11.0(typescript@5.3.3)): dependencies: stylelint: 16.11.0(typescript@5.3.3) - stylelint-config-standard@36.0.1(stylelint@16.11.0): + stylelint-config-standard@36.0.1(stylelint@16.11.0(typescript@5.3.3)): dependencies: stylelint: 16.11.0(typescript@5.3.3) - stylelint-config-recommended: 14.0.1(stylelint@16.11.0) + stylelint-config-recommended: 14.0.1(stylelint@16.11.0(typescript@5.3.3)) - stylelint-order@6.0.4(stylelint@16.11.0): + stylelint-order@6.0.4(stylelint@16.11.0(typescript@5.3.3)): dependencies: postcss: 8.4.49 postcss-sorting: 8.0.2(postcss@8.4.49) @@ -11228,7 +11290,7 @@ snapshots: dependencies: '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) '@csstools/css-tokenizer': 3.0.3 - '@csstools/media-query-list-parser': 4.0.2(@csstools/css-parser-algorithms@3.0.4)(@csstools/css-tokenizer@3.0.3) + '@csstools/media-query-list-parser': 4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.0.0) '@dual-bundle/import-meta-resolve': 4.1.0 balanced-match: 2.0.0 @@ -11513,9 +11575,9 @@ snapshots: universalify@2.0.1: {} - unocss@0.58.9(postcss@8.4.49)(rollup@4.27.4)(vite@5.1.4): + unocss@0.58.9(postcss@8.4.49)(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: - '@unocss/astro': 0.58.9(rollup@4.27.4)(vite@5.1.4) + '@unocss/astro': 0.58.9(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) '@unocss/cli': 0.58.9(rollup@4.27.4) '@unocss/core': 0.58.9 '@unocss/extractor-arbitrary-variants': 0.58.9 @@ -11534,24 +11596,26 @@ snapshots: '@unocss/transformer-compile-class': 0.58.9 '@unocss/transformer-directives': 0.58.9 '@unocss/transformer-variant-group': 0.58.9 - '@unocss/vite': 0.58.9(rollup@4.27.4)(vite@5.1.4) + '@unocss/vite': 0.58.9(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)) + optionalDependencies: vite: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) transitivePeerDependencies: - postcss - rollup - supports-color - unplugin-auto-import@0.16.7(@vueuse/core@10.11.1)(rollup@4.27.4): + unplugin-auto-import@0.16.7(@vueuse/core@10.11.1(vue@3.5.12(typescript@5.3.3)))(rollup@4.27.4): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.3(rollup@4.27.4) - '@vueuse/core': 10.11.1(vue@3.5.12) fast-glob: 3.3.2 local-pkg: 0.5.1 magic-string: 0.30.14 minimatch: 9.0.5 unimport: 3.14.2(rollup@4.27.4) unplugin: 1.16.0 + optionalDependencies: + '@vueuse/core': 10.11.1(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - rollup @@ -11564,7 +11628,7 @@ snapshots: transitivePeerDependencies: - rollup - unplugin-vue-components@0.25.2(rollup@4.27.4)(vue@3.5.12): + unplugin-vue-components@0.25.2(@babel/parser@7.26.2)(rollup@4.27.4)(vue@3.5.12(typescript@5.3.3)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.3(rollup@4.27.4) @@ -11577,6 +11641,8 @@ snapshots: resolve: 1.22.8 unplugin: 1.16.0 vue: 3.5.12(typescript@5.3.3) + optionalDependencies: + '@babel/parser': 7.26.2 transitivePeerDependencies: - rollup - supports-color @@ -11616,6 +11682,8 @@ snapshots: uuid@10.0.0: {} + uuid@11.1.0: {} + vary@1.1.2: {} video.js@7.21.6: @@ -11640,7 +11708,7 @@ snapshots: dependencies: global: 4.4.0 - vite-plugin-compression@0.5.1(vite@5.1.4): + vite-plugin-compression@0.5.1(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: chalk: 4.1.2 debug: 4.3.7 @@ -11649,12 +11717,12 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-ejs@1.7.0(vite@5.1.4): + vite-plugin-ejs@1.7.0(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: ejs: 3.1.10 vite: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) - vite-plugin-eslint@1.8.1(eslint@8.57.1)(vite@5.1.4): + vite-plugin-eslint@1.8.1(eslint@8.57.1)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: '@rollup/pluginutils': 4.2.1 '@types/eslint': 8.56.12 @@ -11662,14 +11730,14 @@ snapshots: rollup: 2.79.2 vite: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) - vite-plugin-progress@0.0.7(vite@5.1.4): + vite-plugin-progress@0.0.7(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: picocolors: 1.1.1 progress: 2.0.3 rd: 2.0.1 vite: 5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0) - vite-plugin-purge-icons@0.10.0(vite@5.1.4): + vite-plugin-purge-icons@0.10.0(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: '@purge-icons/core': 0.10.0 '@purge-icons/generated': 0.10.0 @@ -11679,7 +11747,7 @@ snapshots: - encoding - supports-color - vite-plugin-svg-icons@2.0.1(vite@5.1.4): + vite-plugin-svg-icons@2.0.1(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: '@types/svgo': 2.6.4 cors: 2.8.5 @@ -11693,7 +11761,7 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-top-level-await@1.4.4(rollup@4.27.4)(vite@5.1.4): + vite-plugin-top-level-await@1.4.4(rollup@4.27.4)(vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0)): dependencies: '@rollup/plugin-virtual': 3.0.2(rollup@4.27.4) '@swc/core': 1.9.3 @@ -11705,24 +11773,24 @@ snapshots: vite@5.1.4(@types/node@20.17.9)(sass@1.81.0)(terser@5.36.0): dependencies: - '@types/node': 20.17.9 esbuild: 0.19.12 postcss: 8.4.49 rollup: 4.27.4 + optionalDependencies: + '@types/node': 20.17.9 + fsevents: 2.3.3 sass: 1.81.0 terser: 5.36.0 - optionalDependencies: - fsevents: 2.3.3 - vue-demi@0.14.10(vue@3.5.12): + vue-demi@0.14.10(vue@3.5.12(typescript@5.3.3)): dependencies: vue: 3.5.12(typescript@5.3.3) - vue-dompurify-html@4.1.4(vue@3.5.12): + vue-dompurify-html@4.1.4(vue@3.5.12(typescript@5.3.3)): dependencies: dompurify: 3.2.1 vue: 3.5.12(typescript@5.3.3) - vue-demi: 0.14.10(vue@3.5.12) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.3.3)) transitivePeerDependencies: - '@vue/composition-api' @@ -11739,14 +11807,14 @@ snapshots: transitivePeerDependencies: - supports-color - vue-i18n@9.10.2(vue@3.5.12): + vue-i18n@9.10.2(vue@3.5.12(typescript@5.3.3)): dependencies: '@intlify/core-base': 9.10.2 '@intlify/shared': 9.10.2 '@vue/devtools-api': 6.6.4 vue: 3.5.12(typescript@5.3.3) - vue-router@4.4.5(vue@3.5.12): + vue-router@4.4.5(vue@3.5.12(typescript@5.3.3)): dependencies: '@vue/devtools-api': 6.6.4 vue: 3.5.12(typescript@5.3.3) @@ -11763,9 +11831,10 @@ snapshots: semver: 7.6.3 typescript: 5.3.3 - vue-types@5.1.3(vue@3.5.12): + vue-types@5.1.3(vue@3.5.12(typescript@5.3.3)): dependencies: is-plain-object: 5.0.0 + optionalDependencies: vue: 3.5.12(typescript@5.3.3) vue@3.5.12(typescript@5.3.3): @@ -11773,11 +11842,12 @@ snapshots: '@vue/compiler-dom': 3.5.12 '@vue/compiler-sfc': 3.5.12 '@vue/runtime-dom': 3.5.12 - '@vue/server-renderer': 3.5.12(vue@3.5.12) + '@vue/server-renderer': 3.5.12(vue@3.5.12(typescript@5.3.3)) '@vue/shared': 3.5.12 + optionalDependencies: typescript: 5.3.3 - vuedraggable@4.1.0(vue@3.5.12): + vuedraggable@4.1.0(vue@3.5.12(typescript@5.3.3)): dependencies: sortablejs: 1.14.0 vue: 3.5.12(typescript@5.3.3) diff --git a/src/api/models/index.ts b/src/api/models/index.ts new file mode 100644 index 0000000..0708645 --- /dev/null +++ b/src/api/models/index.ts @@ -0,0 +1,20 @@ +export enum ModelTypeEnum { + CHAT = 'CHAT', + EMBEDDING = 'EMBEDDING', + TEXT_IMAGE = 'TEXT_IMAGE', + WEB_SEARCH = 'WEB_SEARCH', +} + +/** + * 隐藏API密钥中间部分 + * @param key API密钥 + * @returns 隐藏处理后的密钥 + */ +export function hideKey(key: string): string { + if (!key) return '' + const length = key.length + if (length <= 8) return key + const start = key.slice(0, 4) + const end = key.slice(-4) + return `${start}****${end}` +} diff --git a/src/api/new-ai/app.ts b/src/api/new-ai/app.ts new file mode 100644 index 0000000..8788e4e --- /dev/null +++ b/src/api/new-ai/app.ts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import request from '@/config/axios' + +// AI 应用 API +export const AppApi = { + // 获取应用列表 + getAppList: async (params: any) => { + return await request.get({ url: '/chat/aigc/app/list', params }) + }, + + // 获取应用分页数据 + getAppPage: async (params: any) => { + return await request.get({ url: '/chat/aigc/app/page', params }) + }, + + // 获取应用详情 + getApp: async (id: string) => { + return await request.get({ url: `/chat/aigc/app/${id}` }) + }, + + // 根据模型ID获取应用 + getAppByModelId: async (id: string) => { + return await request.get({ url: `/chat/aigc/app/byModelId/${id}` }) + }, + + // 获取应用API通道 + getAppApiChannel: async (appId: string) => { + return await request.get({ url: `/chat/aigc/app/channel/api/${appId}` }) + }, + + // 新增应用 + createApp: async (data: any) => { + return await request.post({ url: '/chat/aigc/app', data }) + }, + + // 更新应用 + updateApp: async (data: any) => { + return await request.put({ url: '/chat/aigc/app', data }) + }, + + // 删除应用 + deleteApp: async (id: string) => { + return await request.delete({ url: `/chat/aigc/app/${id}` }) + } +} diff --git a/src/api/new-ai/appApi.ts b/src/api/new-ai/appApi.ts new file mode 100644 index 0000000..9b3793f --- /dev/null +++ b/src/api/new-ai/appApi.ts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import request from '@/config/axios' + +// AI 应用管理 API +export const AppApiManagement = { + // 获取API列表 + getApiList: async (params: any) => { + return await request.get({ url: '/chat/aigc/app/api/list', params }) + }, + + // 获取API分页数据 + getApiPage: async (params: any) => { + return await request.get({ url: '/chat/aigc/app/api/page', params }) + }, + + // 获取API详情 + getApi: async (id: string) => { + return await request.get({ url: `/chat/aigc/app/api/${id}` }) + }, + + // 新增API + createApi: async (data: any) => { + return await request.post({ url: '/chat/aigc/app/api', data }) + }, + + // 更新API + updateApi: async (data: any) => { + return await request.put({ url: '/chat/aigc/app/api', data }) + }, + + // 删除API + deleteApi: async (id: string) => { + return await request.delete({ url: `/chat/aigc/app/api/${id}` }) + }, + + // 发布API + publishApi: async (id: string) => { + return await request.put({ url: `/chat/aigc/app/api/publish/${id}` }) + }, + + // 下线API + offlineApi: async (id: string) => { + return await request.put({ url: `/chat/aigc/app/api/offline/${id}` }) + } +} diff --git a/src/api/new-ai/chat.ts b/src/api/new-ai/chat.ts new file mode 100644 index 0000000..5072b61 --- /dev/null +++ b/src/api/new-ai/chat.ts @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import request from '@/config/axios' +import { AxiosProgressEvent } from 'axios' + +export function chat( + data: any, + controller: AbortController, + onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void +) { + return request.post({ + url: '/chat/aigc/chat/completions', + data, + signal: controller.signal, + onDownloadProgress, + isReturnNativeResponse: true + }) +} + +export function clean(conversationId: string | null) { + return request.delete({ + url: `/chat/aigc/chat/messages/clean/${conversationId}` + }) +} + +export function getMessages(conversationId?: string | number) { + return request.get({ + url: `/chat/aigc/chat/messages/${conversationId}` + }) +} + +export function getAppInfo(params: any) { + return request.get({ + url: `/chat/aigc/app/info`, + params + }) +} + +export function getImageModels() { + return request.get({ + url: '/chat/aigc/chat/getImageModels' + }) +} + +/** + * @description 生成图片 + */ +export function genImage(data: any) { + return request.post({ + url: '/chat/aigc/chat/image', + data + }) +} + +/** + * @description: 生成思维导图 + */ +export function genMindMap(data: any) { + return request.post({ + url: '/chat/aigc/chat/mindmap', + data + }) +} diff --git a/src/api/new-ai/conversation.ts b/src/api/new-ai/conversation.ts new file mode 100644 index 0000000..ef7a12a --- /dev/null +++ b/src/api/new-ai/conversation.ts @@ -0,0 +1,23 @@ + + + +import request from '@/config/axios' + +export function page(params: any) { + return request.get({ + url: '/chat/aigc/conversation/page', + params, + }); +} + +export function del(id: string) { + return request.delete({ + url: `/chat/aigc/conversation/${id}`, + }); +} + +export function getMessages(conversationId: string) { + return request.get({ + url: `/chat/aigc/conversation/messages/${conversationId}`, + }); +} diff --git a/src/api/new-ai/docs.ts b/src/api/new-ai/docs.ts new file mode 100644 index 0000000..4f88eaf --- /dev/null +++ b/src/api/new-ai/docs.ts @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import request from '@/config/axios' + +// AI 文档 VO +export interface DocsVO { + id: string + // TODO: Add other fields based on your data model +} + +// AI 文档 API +export const DocsApi = { + // 获得文档分页 + async getDocsPage(params: any) { + return await request.get({ url: '/chat/aigc/docs/page', params }) + }, + + // 获得文档列表 + async getDocsList(params: any) { + return await request.get({ url: '/chat/aigc/docs/list', params }) + }, + + // 获得文档详情 + async getDocsById(id: string) { + return await request.get({ url: `/chat/aigc/docs/${id}` }) + }, + + // 创建文档 + async addDocs(data: any) { + return await request.post({ url: '/chat/aigc/docs', data }) + }, + + // 更新文档 + async updateDocs(data: any) { + return await request.put({ url: '/chat/aigc/docs', data }) + }, + + // 删除文档 + async deleteDocs(id: string) { + return await request.delete({ url: `/chat/aigc/docs/${id}` }) + }, + + // 重新向量化 + async reEmbedDocs(id: string) { + return await request.get({ url: `/chat/aigc/embedding/re-embed/${id}` }) + } +} diff --git a/src/api/new-ai/embed-store.ts b/src/api/new-ai/embed-store.ts new file mode 100644 index 0000000..735112e --- /dev/null +++ b/src/api/new-ai/embed-store.ts @@ -0,0 +1,87 @@ + + +import request from '@/config/axios' + +// AI 嵌入存储 VO +export interface EmbedStoreVO { + id: string + // TODO: Add other fields based on your data model +} + +// AI 嵌入存储 API +export const EmbedStoreApi = { + // 获得嵌入存储列表 + getEmbedStoreList: async (params: any) => { + return await request.get({ url: '/chat/aigc/embed-store/list', params }) + }, + + // 获得嵌入存储分页 + getEmbedStorePage: async (params: any) => { + return await request.get({ url: '/chat/aigc/embed-store/page', params }) + }, + + // 获得嵌入存储详情 + getEmbedStore: async (id: string) => { + return await request.get({ url: `/chat/aigc/embed-store/${id}` }) + }, + + // 创建嵌入存储 + createEmbedStore: async (data: any) => { + return await request.post({ url: '/chat/aigc/embed-store', data }) + }, + + // 更新嵌入存储 + updateEmbedStore: async (data: any) => { + return await request.put({ url: '/chat/aigc/embed-store', data }) + }, + + // 删除嵌入存储 + deleteEmbedStore: async (id: string) => { + return await request.delete({ url: `/chat/aigc/embed-store/${id}` }) + } +} +// export function list(params: any) { +// return http.request({ +// url: '/aigc/embed-store/list', +// method: 'get', +// params, +// }); +// } + +// export function page(params: any) { +// return http.request({ +// url: '/aigc/embed-store/page', +// method: 'get', +// params, +// }); +// } + +// export function getById(id: string) { +// return http.request({ +// url: `/aigc/embed-store/${id}`, +// method: 'get', +// }); +// } + +// export function add(params: any) { +// return http.request({ +// url: '/aigc/embed-store', +// method: 'post', +// params, +// }); +// } + +// export function update(params: any) { +// return http.request({ +// url: '/aigc/embed-store', +// method: 'put', +// params, +// }); +// } + +// export function del(id?: string) { +// return http.request({ +// url: `/aigc/embed-store/${id}`, +// method: 'delete', +// }); +// } diff --git a/src/api/new-ai/embedding.ts b/src/api/new-ai/embedding.ts new file mode 100644 index 0000000..b0b064e --- /dev/null +++ b/src/api/new-ai/embedding.ts @@ -0,0 +1,81 @@ +import request from '@/config/axios' +import { AxiosProgressEvent } from 'axios' + +// AI 嵌入 API +export const EmbeddingApi = { + // 文本嵌入 + embeddingText: async (params: any) => { + return await request.post({ url: '/chat/aigc/embedding/text', params }) + }, + + // 嵌入搜索 + embeddingSearch: async (data: any) => { + return await request.post({ url: '/chat/aigc/embedding/search', data }) + }, + + // 文档嵌入 + embeddingDocs: async ( + knowledgeId: string, + data: any, + onUploadProgress?: (progressEvent: AxiosProgressEvent) => void + ) => { + return await request.post({ + url: `/chat/aigc/embedding/docs/${knowledgeId}`, + data, + headers: { + 'Content-Type': 'multipart/form-data' + }, + onUploadProgress + }) + } +} +// /* +// * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. +// * +// * Licensed under the GNU Affero General Public License, Version 3 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * https://www.gnu.org/licenses/agpl-3.0.html +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +// import { http } from '@/utils/http/axios'; +// import { AxiosProgressEvent } from 'axios'; + +// export function embeddingText(params: any) { +// return http.request({ +// url: '/aigc/embedding/text', +// method: 'post', +// params, +// }); +// } + +// export function embeddingSearch(data: any) { +// return http.request({ +// url: '/aigc/embedding/search', +// method: 'post', +// data, +// }); +// } + +// export function embeddingDocs( +// knowledgeId: string, +// data: any, +// onUploadProgress?: (progressEvent: AxiosProgressEvent) => void +// ) { +// return http.request({ +// url: `/aigc/embedding/docs/${knowledgeId}`, +// method: 'post', +// data, +// headers: { +// 'Content-Type': 'multipart/form-data', +// }, +// onUploadProgress, +// }); +// } diff --git a/src/api/new-ai/knowledge.ts b/src/api/new-ai/knowledge.ts new file mode 100644 index 0000000..9a52ad2 --- /dev/null +++ b/src/api/new-ai/knowledge.ts @@ -0,0 +1,40 @@ +import request from '@/config/axios' + +// AI 知识库 VO +export interface KnowledgeVO { + id: string + // TODO: Add other fields based on your data model +} + +// AI 知识库 API +export const KnowledgeApi = { + // 获得知识库列表 + getKnowledgeList: async (params: any) => { + return await request.get({ url: '/chat/aigc/knowledge/list', params }) + }, + + // 获得知识库分页 + getKnowledgePage: async (params: any) => { + return await request.get({ url: '/chat/aigc/knowledge/page', params }) + }, + + // 获得知识库详情 + getKnowledge: async (id: string) => { + return await request.get({ url: `/chat/aigc/knowledge/${id}` }) + }, + + // 创建知识库 + createKnowledge: async (data: any) => { + return await request.post({ url: '/chat/aigc/knowledge', data }) + }, + + // 更新知识库 + updateKnowledge: async (data: any) => { + return await request.put({ url: '/chat/aigc/knowledge', data }) + }, + + // 删除知识库 + deleteKnowledge: async (id: string) => { + return await request.delete({ url: `/chat/aigc/knowledge/${id}` }) + } +} \ No newline at end of file diff --git a/src/api/new-ai/message.ts b/src/api/new-ai/message.ts new file mode 100644 index 0000000..a7ebdf8 --- /dev/null +++ b/src/api/new-ai/message.ts @@ -0,0 +1,63 @@ + + +import request from '@/config/axios' + +/** + * 消息列表接口参数 + */ +export interface MessageParams { + text?: string; + username?: string; + role?: string; + pageNum?: number; + pageSize?: number; +} + +/** + * 获取消息列表 + */ +export function list(params: MessageParams) { + return request.get({ + url: '/chat/aigc/message/list', + params + }) +} + +/** + * 分页获取消息列表 + */ +export function page(params: MessageParams) { + return request.get({ + url: '/chat/aigc/message/page', + params + }) +} + +/** + * 添加消息 + */ +export function add(data: any) { + return request.post({ + url: '/chat/aigc/message', + data + }) +} + +/** + * 更新消息 + */ +export function update(data: any) { + return request.put({ + url: '/chat/aigc/message', + data + }) +} + +/** + * 删除消息 + */ +export function del(id: string) { + return request.delete({ + url: `/chat/aigc/message/${id}` + }) +} diff --git a/src/api/new-ai/model.ts b/src/api/new-ai/model.ts new file mode 100644 index 0000000..2aefc33 --- /dev/null +++ b/src/api/new-ai/model.ts @@ -0,0 +1,40 @@ +import request from '@/config/axios' + +// AI 模型 VO +export interface ModelVO { + id: string + // TODO: Add other fields based on your data model +} + +// AI 模型 API +export const ModelApi = { + // 获得模型分页 + getModelPage: async (params: any) => { + return await request.get({ url: '/chat/aigc/model/page', params }) + }, + + // 获得模型列表 + getModelList: async (params: any) => { + return await request.get({ url: '/chat/aigc/model/list', params }) + }, + + // 获得模型详情 + getModel: async (id: string) => { + return await request.get({ url: `/chat/aigc/model/${id}` }) + }, + + // 创建模型 + createModel: async (data: any) => { + return await request.post({ url: '/chat/aigc/model', data }) + }, + + // 更新模型 + updateModel: async (data: any) => { + return await request.put({ url: '/chat/aigc/model', data }) + }, + + // 删除模型 + deleteModel: async (id: string) => { + return await request.delete({ url: `/chat/aigc/model/${id}` }) + } +} \ No newline at end of file diff --git a/src/api/new-ai/oss.ts b/src/api/new-ai/oss.ts new file mode 100644 index 0000000..199e015 --- /dev/null +++ b/src/api/new-ai/oss.ts @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import request from '@/config/axios' + +/** + * OSS对象存储服务接口 + */ +export class OssApi { + /** + * 获取OSS上传策略 + */ + static policy() { + return request.get({ + url: '/chat/oss/policy' + }) + } + + /** + * 获取文件列表 + */ + static list(params: any) { + return request.get({ + url: '/chat/oss/list', + params + }) + } + + /** + * 删除文件 + */ + static del(objectName: string) { + return request.delete({ + url: `/chat/oss/${objectName}` + }) + } + + /** + * 上传文件 + */ + static uploadUrl = '/chat/aigc/oss/upload' + + static upload(data: any) { + return request.upload({ + url: '/chat/aigc/oss/upload', + data + }) + } + + /** + * 获取文件访问URL + */ + static getUrl(objectName: string) { + return request.get({ + url: `/chat/oss/url/${objectName}` + }) + } +} diff --git a/src/api/new-ai/slice.ts b/src/api/new-ai/slice.ts new file mode 100644 index 0000000..3680b99 --- /dev/null +++ b/src/api/new-ai/slice.ts @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import request from '@/config/axios' + +// AI 文档切片 VO +export interface SliceVO { + id: string + // TODO: Add other fields based on your data model +} + +// AI 文档切片 API +export const SliceApi = { + // 获得切片分页 + getSlicePage: async (params: any) => { + return await request.get({ url: '/chat/aigc/docs/slice/page', params }) + }, + + // 获得切片列表 + getSliceList: async (params: any) => { + return await request.get({ url: '/chat/aigc/docs/slice/list', params }) + }, + + // 获得切片详情 + getSlice: async (id: string) => { + return await request.get({ url: `/chat/aigc/docs/slice/${id}` }) + }, + + // 创建切片 + createSlice: async (data: any) => { + return await request.post({ url: '/chat/aigc/docs/slice', data }) + }, + + // 更新切片 + updateSlice: async (data: any) => { + return await request.put({ url: '/chat/aigc/docs/slice', data }) + }, + + // 删除切片 + deleteSlice: async (id: string) => { + return await request.delete({ url: `/chat/aigc/docs/slice/${id}` }) + } +} diff --git a/src/api/new-ai/statictic.ts b/src/api/new-ai/statictic.ts new file mode 100644 index 0000000..3ed400b --- /dev/null +++ b/src/api/new-ai/statictic.ts @@ -0,0 +1,33 @@ + + +import request from '@/config/axios' + +export function getReqChartBy30() { + return request.get({ + url: `/chat/aigc/statistic/requestBy30`, + }); +} + +export function getReqChart() { + return request.get({ + url: `/chat/aigc/statistic/request`, + }); +} + +export function getTokenChartBy30() { + return request.get({ + url: `/chat/aigc/statistic/tokenBy30`, + }); +} + +export function getTokenChart() { + return request.get({ + url: `/chat/aigc/statistic/token`, + }); +} + +export function getHomeData() { + return request.get({ + url: `/chat/aigc/statistic/home`, + }); +} diff --git a/src/components/Error/src/Error.vue b/src/components/Error/src/Error.vue index 3fd7a17..2bfab24 100644 --- a/src/components/Error/src/Error.vue +++ b/src/components/Error/src/Error.vue @@ -3,7 +3,7 @@ import pageError from '@/assets/svgs/404.svg' import networkError from '@/assets/svgs/500.svg' import noPermission from '@/assets/svgs/403.svg' import { propTypes } from '@/utils/propTypes' - +import { onBeforeRouteUpdate } from 'vue-router' defineOptions({ name: 'Error' }) interface ErrorMap { diff --git a/src/components/Form/src/Form.vue b/src/components/Form/src/Form.vue index 3acc10a..f23e103 100644 --- a/src/components/Form/src/Form.vue +++ b/src/components/Form/src/Form.vue @@ -113,11 +113,16 @@ export default defineComponent({ } } } - + const setValue = (key: string, value: any) => { + formModel.value[key] = value + } const getElFormRef = (): ComponentRef => { return unref(elFormRef) as ComponentRef } - + const clearForm = () => { + formModel.value = {} + getElFormRef().resetFields() + } expose({ setValues, formModel, @@ -125,7 +130,9 @@ export default defineComponent({ delSchema, addSchema, setSchema, - getElFormRef + getElFormRef, + clearForm, + setValue }) // 监听表单结构化数组,重新生成formModel @@ -187,7 +194,7 @@ export default defineComponent({ ) { slotsMap.default = () => renderOptions(item) } - + const formItemSlots: Recordable = setFormItemSlots(slots, item.field) // 如果有 labelMessage,自动使用插槽渲染 if (item?.labelMessage) { @@ -226,6 +233,7 @@ export default defineComponent({ return slots[item.field] ? ( getSlot(slots, item.field, formModel.value) ) : ( + <> {{ ...slotsMap }} + + ) } }} diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..5b89fb4 --- /dev/null +++ b/src/components/SvgIcon/index.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/components/UploadFile/src/UploadFile.vue b/src/components/UploadFile/src/UploadFile.vue index 9d0a904..10cfda8 100644 --- a/src/components/UploadFile/src/UploadFile.vue +++ b/src/components/UploadFile/src/UploadFile.vue @@ -22,13 +22,13 @@ > - 选取文件 + {{ props.drag ? '拖拽或' : ''}}选取文件 diff --git a/src/components/UploadFile/src/UploadImg.vue b/src/components/UploadFile/src/UploadImg.vue index ac0c162..f152e2b 100644 --- a/src/components/UploadFile/src/UploadImg.vue +++ b/src/components/UploadFile/src/UploadImg.vue @@ -79,7 +79,9 @@ const props = defineProps({ width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px) borderradius: propTypes.string.def('8px'), // 组件边框圆角 ==> 非必传(默认为 8px) showDelete: propTypes.bool.def(true), // 是否显示删除按钮 - showBtnText: propTypes.bool.def(true) // 是否显示按钮文字 + showBtnText: propTypes.bool.def(true), // 是否显示按钮文字 + customApi: propTypes.func.def(() => undefined), // 上传接口地址 ==> 非必传(默认为 '') + successBefore: propTypes.func.def(() => undefined), // 上传成功之前的钩子 ==> 非必传(默认为 undefined) }) const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 @@ -99,7 +101,7 @@ const deleteImg = () => { emit('update:modelValue', '') } -const { uploadUrl, httpRequest } = useUpload() +const { uploadUrl, httpRequest } = useUpload({ customApi: props.customApi }) const editImg = () => { const dom = document.querySelector(`#${uuid.value} .el-upload__input`) @@ -117,8 +119,12 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => { // 图片上传成功提示 const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { + let params = res + if (props.successBefore) { + params = props.successBefore(res) + } message.success('上传成功') - emit('update:modelValue', res.data) + emit('update:modelValue', params.data) } // 图片上传错误提示 diff --git a/src/components/UploadFile/src/useUpload.ts b/src/components/UploadFile/src/useUpload.ts index 2981e12..f718888 100644 --- a/src/components/UploadFile/src/useUpload.ts +++ b/src/components/UploadFile/src/useUpload.ts @@ -10,7 +10,7 @@ export const getUploadUrl = (): string => { return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload' } -export const useUpload = () => { +export const useUpload = (defaultParams?: { customApi: any }) => { // 后端上传地址 const uploadUrl = getUploadUrl() // 是否使用前端直连上传 @@ -40,7 +40,8 @@ export const useUpload = () => { // 模式二:后端上传 // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子 return new Promise((resolve, reject) => { - FileApi.updateFile({ file: options.file }) + const Api = defaultParams?.customApi || FileApi.updateFile + Api({ file: options.file }) .then((res) => { if (res.code === 0) { resolve(res) diff --git a/src/config/axios/service.ts b/src/config/axios/service.ts index 618f14a..d64f755 100644 --- a/src/config/axios/service.ts +++ b/src/config/axios/service.ts @@ -149,7 +149,7 @@ service.interceptors.response.use( }) } } else if (code === 500) { - ElMessage.error(t('sys.api.errMsg500')) + ElMessage.error(msg || t('sys.api.errMsg500')) return Promise.reject(new Error(msg)) } else if (code === 901) { ElMessage.error({ diff --git a/src/hooks/setting/index.ts b/src/hooks/setting/index.ts new file mode 100644 index 0000000..76003b2 --- /dev/null +++ b/src/hooks/setting/index.ts @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { GlobConfig } from '/#/config'; + +import { warn } from '@/utils/log'; +import { getAppEnvConfig } from '@/utils/env'; + +export const useGlobSetting = (): Readonly => { + const { + VITE_GLOB_APP_TITLE, + VITE_GLOB_API_URL, + VITE_GLOB_APP_SHORT_NAME, + VITE_GLOB_API_URL_PREFIX, + VITE_GLOB_UPLOAD_URL, + VITE_GLOB_IMG_URL, + } = getAppEnvConfig(); + + if (!/[a-zA-Z\_]*/.test(VITE_GLOB_APP_SHORT_NAME)) { + warn( + `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` + ); + } + + // Take global configuration + const glob: Readonly = { + title: VITE_GLOB_APP_TITLE, + apiUrl: VITE_GLOB_API_URL, + shortName: VITE_GLOB_APP_SHORT_NAME, + urlPrefix: VITE_GLOB_API_URL_PREFIX, + uploadUrl: VITE_GLOB_UPLOAD_URL, + imgUrl: VITE_GLOB_IMG_URL, + }; + return glob as Readonly; +}; diff --git a/src/hooks/setting/useDesignSetting.ts b/src/hooks/setting/useDesignSetting.ts new file mode 100644 index 0000000..d93dec1 --- /dev/null +++ b/src/hooks/setting/useDesignSetting.ts @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { computed } from 'vue'; +import { useDesignSettingStore } from '@/store/modules/designSetting'; + +export function useDesignSetting() { + const designStore = useDesignSettingStore(); + + const getDarkTheme = computed(() => designStore.darkTheme); + + const getAppTheme = computed(() => designStore.appTheme); + + const getAppThemeList = computed(() => designStore.appThemeList); + + return { + getDarkTheme, + getAppTheme, + getAppThemeList, + }; +} diff --git a/src/hooks/setting/useProjectSetting.ts b/src/hooks/setting/useProjectSetting.ts new file mode 100644 index 0000000..32a13da --- /dev/null +++ b/src/hooks/setting/useProjectSetting.ts @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { computed } from 'vue'; +import { useProjectSettingStore } from '@/store/modules/projectSetting'; + +export function useProjectSetting() { + const projectStore = useProjectSettingStore(); + + const navMode = computed(() => projectStore.navMode); + + const navTheme = computed(() => projectStore.navTheme); + + const isMobile = computed(() => projectStore.isMobile); + + const headerSetting = computed(() => projectStore.headerSetting); + + const multiTabsSetting = computed(() => projectStore.multiTabsSetting); + + const menuSetting = computed(() => projectStore.menuSetting); + + const crumbsSetting = computed(() => projectStore.crumbsSetting); + + const permissionMode = computed(() => projectStore.permissionMode); + + const showFooter = computed(() => projectStore.showFooter); + + const isPageAnimate = computed(() => projectStore.isPageAnimate); + + const pageAnimateType = computed(() => projectStore.pageAnimateType); + + return { + navMode, + navTheme, + isMobile, + headerSetting, + multiTabsSetting, + menuSetting, + crumbsSetting, + permissionMode, + showFooter, + isPageAnimate, + pageAnimateType, + }; +} diff --git a/src/settings/projectSetting.ts b/src/settings/projectSetting.ts new file mode 100644 index 0000000..b91faa1 --- /dev/null +++ b/src/settings/projectSetting.ts @@ -0,0 +1,59 @@ + + +const setting = { + //导航模式 vertical 左侧菜单模式 horizontal 顶部菜单模式 + navMode: 'vertical', + //导航风格 dark 暗色侧边栏 light 白色侧边栏 header-dark 暗色顶栏 + navTheme: 'dark', + // 是否处于移动端模式 + isMobile: false, + //顶部 + headerSetting: { + //背景色 + bgColor: '#fff', + //固定顶部 + fixed: true, + //显示重载按钮 + isReload: true, + }, + //页脚 + showFooter: false, + //多标签 + multiTabsSetting: { + //背景色 + bgColor: '#fff', + //是否显示 + show: true, + //固定多标签 + fixed: true, + }, + //菜单 + menuSetting: { + //最小宽度 + minMenuWidth: 64, + //菜单宽度 + menuWidth: 200, + //固定菜单 + fixed: true, + //分割菜单 + mixMenu: false, + //触发移动端侧边栏的宽度 + mobileWidth: 800, + // 折叠菜单 + collapsed: false, + }, + //面包屑 + crumbsSetting: { + //是否显示 + show: false, + //显示图标 + showIcon: false, + }, + //菜单权限模式 FIXED 前端固定路由 BACK 动态获取 + permissionMode: 'BACK', + //是否开启路由动画 + isPageAnimate: true, + //路由动画类型 + pageAnimateType: 'fade-slide', +}; +export default setting; diff --git a/src/store/modules/projectSetting.ts b/src/store/modules/projectSetting.ts new file mode 100644 index 0000000..067449c --- /dev/null +++ b/src/store/modules/projectSetting.ts @@ -0,0 +1,94 @@ +import { defineStore } from 'pinia'; +import projectSetting from '@/settings/projectSetting'; +import type { ICrumbsSetting, IHeaderSetting, IMenuSetting, IMultiTabsSetting } from '/#/config'; + +const { + navMode, + navTheme, + isMobile, + headerSetting, + showFooter, + menuSetting, + multiTabsSetting, + crumbsSetting, + permissionMode, + isPageAnimate, + pageAnimateType, +} = projectSetting; + +interface ProjectSettingState { + navMode: string; //导航模式 + navTheme: string; //导航风格 + headerSetting: IHeaderSetting; //顶部设置 + showFooter: boolean; //页脚 + menuSetting: IMenuSetting; //多标签 + multiTabsSetting: IMultiTabsSetting; //多标签 + crumbsSetting: ICrumbsSetting; //面包屑 + permissionMode: string; //权限模式 + isPageAnimate: boolean; //是否开启路由动画 + pageAnimateType: string; //路由动画类型 + isMobile: boolean; // 是否处于移动端模式 +} + +export const useProjectSettingStore = defineStore({ + id: 'app-project-setting', + state: (): ProjectSettingState => ({ + navMode: navMode, + navTheme, + isMobile, + headerSetting, + showFooter, + menuSetting, + multiTabsSetting, + crumbsSetting, + permissionMode, + isPageAnimate, + pageAnimateType, + }), + getters: { + getNavMode(): string { + return this.navMode; + }, + getNavTheme(): string { + return this.navTheme; + }, + getIsMobile(): boolean { + return this.isMobile; + }, + getHeaderSetting(): object { + return this.headerSetting; + }, + getShowFooter(): boolean { + return this.showFooter; + }, + getMenuSetting(): object { + return this.menuSetting; + }, + getMultiTabsSetting(): object { + return this.multiTabsSetting; + }, + getCrumbsSetting(): object { + return this.crumbsSetting; + }, + getPermissionMode(): string { + return this.permissionMode; + }, + getIsPageAnimate(): boolean { + return this.isPageAnimate; + }, + getPageAnimateType(): string { + return this.pageAnimateType; + }, + }, + actions: { + setNavTheme(value: string): void { + this.navTheme = value; + }, + setIsMobile(value: boolean): void { + this.isMobile = value; + }, + setMenuCollapse() { + this.menuSetting.collapsed = true; + }, + }, +}); diff --git a/src/styles/highligt.css b/src/styles/highligt.css new file mode 100644 index 0000000..f0d9740 --- /dev/null +++ b/src/styles/highligt.css @@ -0,0 +1,142 @@ +/* VSCode Dark+ Theme for highlight.js */ + +.hljs { + background: #1e1e1e !important; + color: #d4d4d4 !important; + --el-scrollbar-opacity: 0.3; + --el-scrollbar-bg-color: var(--el-text-color-secondary); + --el-scrollbar-hover-opacity: 0.5; + --el-scrollbar-hover-bg-color: var(--el-text-color-secondary); +} + +/* 滚动条样式 */ +.hljs::-webkit-scrollbar { + width: 6px !important; +} + +.hljs::-webkit-scrollbar-thumb { + background-color: var(--el-scrollbar-bg-color) !important; + opacity: var(--el-scrollbar-opacity) !important; + border-radius: 3px !important; +} + +.hljs::-webkit-scrollbar-thumb:hover { + background-color: var(--el-scrollbar-hover-bg-color) !important; + opacity: var(--el-scrollbar-hover-opacity) !important; +} + +.hljs::-webkit-scrollbar-track { + background-color: transparent !important; +} + +.hljs-keyword { + color: #569cd6 !important; +} + +.hljs-built_in { + color: #4ec9b0 !important; +} + +.hljs-type { + color: #4ec9b0 !important; +} + +.hljs-literal { + color: #569cd6 !important; +} + +.hljs-number { + color: #b5cea8 !important; +} + +.hljs-regexp { + color: #d16969 !important; +} + +.hljs-string { + color: #ce9178 !important; +} + +.hljs-subst { + color: #d4d4d4 !important; +} + +.hljs-symbol { + color: #d4d4d4 !important; +} + +.hljs-class { + color: #4ec9b0 !important; +} + +.hljs-function { + color: #dcdcaa !important; +} + +.hljs-title { + color: #dcdcaa !important; +} + +.hljs-params { + color: #d4d4d4 !important; +} + +.hljs-comment { + color: #6a9955 !important; +} + +.hljs-doctag { + color: #608b4e !important; +} + +.hljs-meta, +.hljs-meta .hljs-keyword { + color: #9b9b9b !important; +} + +.hljs-meta .hljs-string { + color: #ce9178 !important; +} + +.hljs-attr { + color: #9cdcfe !important; +} + +.hljs-attribute { + color: #9cdcfe !important; +} + +.hljs-name { + color: #569cd6 !important; +} + +.hljs-section { + color: #d4d4d4 !important; +} + +.hljs-tag { + color: #569cd6 !important; +} + +.hljs-variable { + color: #9cdcfe !important; +} + +.hljs-template-variable { + color: #9cdcfe !important; +} + +.hljs-template-tag { + color: #569cd6 !important; +} + +/* 添加代码块样式 */ +pre code.hljs { + display: block !important; + padding: 1em !important; + overflow-x: auto !important; + border-radius: 6px !important; + font-family: 'Consolas', 'Monaco', 'Courier New', monospace !important; + font-size: 14px !important; + line-height: 1.5 !important; +} diff --git a/src/styles/index.scss b/src/styles/index.scss index 7607941..b6988e8 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -2,7 +2,7 @@ @use './FormCreate/index.scss'; @use './theme.scss'; @use 'element-plus/theme-chalk/dark/css-vars.css'; - +@import './highligt.css'; .reset-margin [class*='el-icon'] + span { margin-left: 2px !important; } diff --git a/src/utils/copy.ts b/src/utils/copy.ts new file mode 100644 index 0000000..c1be43b --- /dev/null +++ b/src/utils/copy.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function copyToClip(text: string) { + return navigator.clipboard + .writeText(text) + .then(() => { + return Promise.resolve(text); + }) + .catch((error) => { + return Promise.reject(error); + }); +} diff --git a/src/utils/is.ts b/src/utils/is.ts index 24d7191..b825013 100644 --- a/src/utils/is.ts +++ b/src/utils/is.ts @@ -116,3 +116,9 @@ export const isImgPath = (path: string): boolean => { export const isEmptyVal = (val: any): boolean => { return val === '' || val === null || val === undefined } +export function isWhitespace(val: unknown) { + return val === ''; +} +export function isNullOrWhitespace(val: unknown) { + return isNullOrUnDef(val) || isWhitespace(val); +} diff --git a/src/utils/log.ts b/src/utils/log.ts new file mode 100644 index 0000000..501715e --- /dev/null +++ b/src/utils/log.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const projectName = import.meta.env.VITE_GLOB_APP_TITLE; + +export function warn(message: string) { + console.warn(`[${projectName} warn]:${message}`); +} + +export function error(message: string) { + throw new Error(`[${projectName} error]:${message}`); +} diff --git a/src/views/ai/app/ApiTable.vue b/src/views/ai/app/ApiTable.vue new file mode 100644 index 0000000..78645f4 --- /dev/null +++ b/src/views/ai/app/ApiTable.vue @@ -0,0 +1,132 @@ + + + + + + diff --git a/src/views/ai/app/base/index.vue b/src/views/ai/app/base/index.vue new file mode 100644 index 0000000..b4c6879 --- /dev/null +++ b/src/views/ai/app/base/index.vue @@ -0,0 +1,104 @@ + + + + + + + diff --git a/src/views/ai/app/base/prompt/index.vue b/src/views/ai/app/base/prompt/index.vue new file mode 100644 index 0000000..19c67be --- /dev/null +++ b/src/views/ai/app/base/prompt/index.vue @@ -0,0 +1,35 @@ + + + + + + + diff --git a/src/views/ai/app/base/settings/KnowledgeList.vue b/src/views/ai/app/base/settings/KnowledgeList.vue new file mode 100644 index 0000000..b8ee9d3 --- /dev/null +++ b/src/views/ai/app/base/settings/KnowledgeList.vue @@ -0,0 +1,102 @@ + + + + + + + diff --git a/src/views/ai/app/base/settings/index.vue b/src/views/ai/app/base/settings/index.vue new file mode 100644 index 0000000..41f2b67 --- /dev/null +++ b/src/views/ai/app/base/settings/index.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/views/ai/app/channel-api/components/docs.vue b/src/views/ai/app/channel-api/components/docs.vue new file mode 100644 index 0000000..4fb4a54 --- /dev/null +++ b/src/views/ai/app/channel-api/components/docs.vue @@ -0,0 +1,148 @@ + + + + + + + diff --git a/src/views/ai/app/channel-api/index.vue b/src/views/ai/app/channel-api/index.vue new file mode 100644 index 0000000..e7ccb0e --- /dev/null +++ b/src/views/ai/app/channel-api/index.vue @@ -0,0 +1,33 @@ + + + + + + + diff --git a/src/views/ai/app/columns.ts b/src/views/ai/app/columns.ts new file mode 100644 index 0000000..fcbf7cc --- /dev/null +++ b/src/views/ai/app/columns.ts @@ -0,0 +1,64 @@ + + +import { FormSchema } from '@/types/form'; + +export const CHANNEL = { + API: 'CHANNEL_API', + WEB: 'CHANNEL_WEB', +}; + +export const searchSchemas: FormSchema[] = [ + { + field: 'title', + component: 'Input', + label: '标题', + componentProps: { + placeholder: '请输入Prompt标题查询', + }, + }, +]; + +export const formSchemas: FormSchema[] = [ + // { + // field: 'id', + // label: 'ID', + // component: 'Input', + // isHidden: true, + // }, + { + field: 'name', + label: '应用名称', + component: 'Input', + formItemProps: { + rules: [{ required: true, message: '请输入应用名称', trigger: ['blur'] }] + }, + }, + { + field: 'modelId', + label: '关联模型', + component: 'Input', + formItemProps: { + rules: [{ required: true, message: '请选择关联模型', trigger: ['blur'] }] + }, + }, + { + field: 'cover', + label: '应用封面', + component: 'Input', + }, + { + field: 'des', + label: '应用描述', + component: 'Input', + componentProps: { + isFull: true, + placeholder: '请输入应用描述', + type: 'textarea', + autosize: { + minRows: 5, + maxRows: 8, + }, + }, + // rules: [{ required: true, message: '请输入应用描述', trigger: ['blur'] }], + }, +]; diff --git a/src/views/ai/app/edit.vue b/src/views/ai/app/edit.vue new file mode 100644 index 0000000..d865b66 --- /dev/null +++ b/src/views/ai/app/edit.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/views/ai/app/index.vue b/src/views/ai/app/index.vue new file mode 100644 index 0000000..92eced3 --- /dev/null +++ b/src/views/ai/app/index.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/src/views/ai/app/info.vue b/src/views/ai/app/info.vue new file mode 100644 index 0000000..c029183 --- /dev/null +++ b/src/views/ai/app/info.vue @@ -0,0 +1,96 @@ + + + + + + + diff --git a/src/views/ai/app/store/index.ts b/src/views/ai/app/store/index.ts new file mode 100644 index 0000000..75d71ce --- /dev/null +++ b/src/views/ai/app/store/index.ts @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineStore } from 'pinia'; +import { AppApi } from '@/api/new-ai/app'; + +export interface AppState { + activeMenu: string; + info: any; + modelId: string | null; + knowledgeIds: any[]; + knowledges: any[]; +} + +export const useAppStore = defineStore('app-store', { + state: (): AppState => + { + activeMenu: 'setting', + info: {}, + modelId: '', + knowledgeIds: [], + knowledges: [], + }, + + getters: {}, + + actions: { + setActiveMenu(active: string) { + this.activeMenu = active; + }, + addKnowledge(item: any) { + this.knowledgeIds.push(item.id); + this.knowledges.push(item); + this.updateInfo(); + }, + + removeKnowledge(item: any) { + this.knowledgeIds = this.knowledgeIds.filter((i) => i !== item.id); + this.knowledges = this.knowledges.filter((i) => i.id !== item.id); + this.updateInfo(); + }, + + async updateInfo() { + this.info.modelId = this.modelId; + this.info.knowledgeIds = this.knowledgeIds; + this.info.knowledges = this.knowledges; + await AppApi.updateApp({ ...this.info }); + }, + }, +}); diff --git a/src/views/ai/chat/new-chat/Chat.vue b/src/views/ai/chat/new-chat/Chat.vue new file mode 100644 index 0000000..767a718 --- /dev/null +++ b/src/views/ai/chat/new-chat/Chat.vue @@ -0,0 +1,244 @@ + + + + + + + diff --git a/src/views/ai/chat/new-chat/Header.vue b/src/views/ai/chat/new-chat/Header.vue new file mode 100644 index 0000000..bc25578 --- /dev/null +++ b/src/views/ai/chat/new-chat/Header.vue @@ -0,0 +1,60 @@ + + + + + + diff --git a/src/views/ai/chat/new-chat/index.vue b/src/views/ai/chat/new-chat/index.vue new file mode 100644 index 0000000..b1238b9 --- /dev/null +++ b/src/views/ai/chat/new-chat/index.vue @@ -0,0 +1,45 @@ + + + + + + + diff --git a/src/views/ai/chat/new-chat/message/Message.vue b/src/views/ai/chat/new-chat/message/Message.vue new file mode 100644 index 0000000..9584608 --- /dev/null +++ b/src/views/ai/chat/new-chat/message/Message.vue @@ -0,0 +1,129 @@ + + + + + + + diff --git a/src/views/ai/chat/new-chat/message/TextComponent.vue b/src/views/ai/chat/new-chat/message/TextComponent.vue new file mode 100644 index 0000000..954fc2f --- /dev/null +++ b/src/views/ai/chat/new-chat/message/TextComponent.vue @@ -0,0 +1,124 @@ + + + + + + diff --git a/src/views/ai/chat/new-chat/message/styles/github-markdown.scss b/src/views/ai/chat/new-chat/message/styles/github-markdown.scss new file mode 100644 index 0000000..41861d5 --- /dev/null +++ b/src/views/ai/chat/new-chat/message/styles/github-markdown.scss @@ -0,0 +1,1102 @@ +html.dark { + .markdown-body { + color-scheme: dark; + --color-prettylights-syntax-comment: #8b949e; + --color-prettylights-syntax-constant: #79c0ff; + --color-prettylights-syntax-entity: #d2a8ff; + --color-prettylights-syntax-storage-modifier-import: #c9d1d9; + --color-prettylights-syntax-entity-tag: #7ee787; + --color-prettylights-syntax-keyword: #ff7b72; + --color-prettylights-syntax-string: #a5d6ff; + --color-prettylights-syntax-variable: #ffa657; + --color-prettylights-syntax-brackethighlighter-unmatched: #f85149; + --color-prettylights-syntax-invalid-illegal-text: #f0f6fc; + --color-prettylights-syntax-invalid-illegal-bg: #8e1519; + --color-prettylights-syntax-carriage-return-text: #f0f6fc; + --color-prettylights-syntax-carriage-return-bg: #b62324; + --color-prettylights-syntax-string-regexp: #7ee787; + --color-prettylights-syntax-markup-list: #f2cc60; + --color-prettylights-syntax-markup-heading: #1f6feb; + --color-prettylights-syntax-markup-italic: #c9d1d9; + --color-prettylights-syntax-markup-bold: #c9d1d9; + --color-prettylights-syntax-markup-deleted-text: #ffdcd7; + --color-prettylights-syntax-markup-deleted-bg: #67060c; + --color-prettylights-syntax-markup-inserted-text: #aff5b4; + --color-prettylights-syntax-markup-inserted-bg: #033a16; + --color-prettylights-syntax-markup-changed-text: #ffdfb6; + --color-prettylights-syntax-markup-changed-bg: #5a1e02; + --color-prettylights-syntax-markup-ignored-text: #c9d1d9; + --color-prettylights-syntax-markup-ignored-bg: #1158c7; + --color-prettylights-syntax-meta-diff-range: #d2a8ff; + --color-prettylights-syntax-brackethighlighter-angle: #8b949e; + --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58; + --color-prettylights-syntax-constant-other-reference-link: #a5d6ff; + --color-fg-default: #c9d1d9; + --color-fg-muted: #8b949e; + --color-fg-subtle: #6e7681; + --color-canvas-default: #0d1117; + --color-canvas-subtle: #161b22; + --color-border-default: #30363d; + --color-border-muted: #21262d; + --color-neutral-muted: rgba(110,118,129,0.4); + --color-accent-fg: #58a6ff; + --color-accent-emphasis: #1f6feb; + --color-attention-subtle: rgba(187,128,9,0.15); + --color-danger-fg: #f85149; + } +} + +html { + .markdown-body { + color-scheme: light; + --color-prettylights-syntax-comment: #6e7781; + --color-prettylights-syntax-constant: #0550ae; + --color-prettylights-syntax-entity: #8250df; + --color-prettylights-syntax-storage-modifier-import: #24292f; + --color-prettylights-syntax-entity-tag: #116329; + --color-prettylights-syntax-keyword: #cf222e; + --color-prettylights-syntax-string: #0a3069; + --color-prettylights-syntax-variable: #953800; + --color-prettylights-syntax-brackethighlighter-unmatched: #82071e; + --color-prettylights-syntax-invalid-illegal-text: #f6f8fa; + --color-prettylights-syntax-invalid-illegal-bg: #82071e; + --color-prettylights-syntax-carriage-return-text: #f6f8fa; + --color-prettylights-syntax-carriage-return-bg: #cf222e; + --color-prettylights-syntax-string-regexp: #116329; + --color-prettylights-syntax-markup-list: #3b2300; + --color-prettylights-syntax-markup-heading: #0550ae; + --color-prettylights-syntax-markup-italic: #24292f; + --color-prettylights-syntax-markup-bold: #24292f; + --color-prettylights-syntax-markup-deleted-text: #82071e; + --color-prettylights-syntax-markup-deleted-bg: #ffebe9; + --color-prettylights-syntax-markup-inserted-text: #116329; + --color-prettylights-syntax-markup-inserted-bg: #dafbe1; + --color-prettylights-syntax-markup-changed-text: #953800; + --color-prettylights-syntax-markup-changed-bg: #ffd8b5; + --color-prettylights-syntax-markup-ignored-text: #eaeef2; + --color-prettylights-syntax-markup-ignored-bg: #0550ae; + --color-prettylights-syntax-meta-diff-range: #8250df; + --color-prettylights-syntax-brackethighlighter-angle: #57606a; + --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f; + --color-prettylights-syntax-constant-other-reference-link: #0a3069; + --color-fg-default: #24292f; + --color-fg-muted: #57606a; + --color-fg-subtle: #6e7781; + --color-canvas-default: #ffffff; + --color-canvas-subtle: #f6f8fa; + --color-border-default: #d0d7de; + --color-border-muted: hsla(210,18%,87%,1); + --color-neutral-muted: rgba(175,184,193,0.2); + --color-accent-fg: #0969da; + --color-accent-emphasis: #0969da; + --color-attention-subtle: #fff8c5; + --color-danger-fg: #cf222e; + } +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + margin: 0; + //color: var(--color-fg-default); + background-color: var(--color-canvas-default); + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; + font-size: 16px; + line-height: 1.5; + word-wrap: break-word; +} + +.markdown-body .octicon { + display: inline-block; + fill: currentColor; + vertical-align: text-bottom; +} + +.markdown-body h1:hover .anchor .octicon-link:before, +.markdown-body h2:hover .anchor .octicon-link:before, +.markdown-body h3:hover .anchor .octicon-link:before, +.markdown-body h4:hover .anchor .octicon-link:before, +.markdown-body h5:hover .anchor .octicon-link:before, +.markdown-body h6:hover .anchor .octicon-link:before { + width: 16px; + height: 16px; + content: ' '; + display: inline-block; + background-color: currentColor; + -webkit-mask-image: url("data:image/svg+xml,"); + mask-image: url("data:image/svg+xml,"); +} + +.markdown-body details, +.markdown-body figcaption, +.markdown-body figure { + display: block; +} + +.markdown-body summary { + display: list-item; +} + +.markdown-body [hidden] { + display: none !important; +} + +.markdown-body a { + background-color: transparent; + color: var(--color-accent-fg); + text-decoration: none; +} + +.markdown-body abbr[title] { + border-bottom: none; + text-decoration: underline dotted; +} + +.markdown-body b, +.markdown-body strong { + font-weight: var(--base-text-weight-semibold, 600); +} + +.markdown-body dfn { + font-style: italic; +} + +.markdown-body h1 { + margin: .67em 0; + font-weight: var(--base-text-weight-semibold, 600); + padding-bottom: .3em; + font-size: 2em; + border-bottom: 1px solid var(--color-border-muted); +} + +.markdown-body mark { + background-color: var(--color-attention-subtle); + color: var(--color-fg-default); +} + +.markdown-body small { + font-size: 90%; +} + +.markdown-body sub, +.markdown-body sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +.markdown-body sub { + bottom: -0.25em; +} + +.markdown-body sup { + top: -0.5em; +} + +.markdown-body img { + border-style: none; + max-width: 100%; + box-sizing: content-box; + background-color: var(--color-canvas-default); +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre, +.markdown-body samp { + font-family: monospace; + font-size: 1em; +} + +.markdown-body figure { + margin: 1em 40px; +} + +.markdown-body hr { + box-sizing: content-box; + overflow: hidden; + background: transparent; + border-bottom: 1px solid var(--color-border-muted); + height: .25em; + padding: 0; + margin: 24px 0; + background-color: var(--color-border-default); + border: 0; +} + +.markdown-body input { + font: inherit; + margin: 0; + overflow: visible; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +.markdown-body [type=button], +.markdown-body [type=reset], +.markdown-body [type=submit] { + -webkit-appearance: button; +} + +.markdown-body [type=checkbox], +.markdown-body [type=radio] { + box-sizing: border-box; + padding: 0; +} + +.markdown-body [type=number]::-webkit-inner-spin-button, +.markdown-body [type=number]::-webkit-outer-spin-button { + height: auto; +} + +.markdown-body [type=search]::-webkit-search-cancel-button, +.markdown-body [type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +.markdown-body ::-webkit-input-placeholder { + color: inherit; + opacity: .54; +} + +.markdown-body ::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +.markdown-body a:hover { + text-decoration: underline; +} + +.markdown-body ::placeholder { + color: var(--color-fg-subtle); + opacity: 1; +} + +.markdown-body hr::before { + display: table; + content: ""; +} + +.markdown-body hr::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body table { + border-spacing: 0; + border-collapse: collapse; + display: block; + width: max-content; + max-width: 100%; + overflow: auto; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body details summary { + cursor: pointer; +} + +.markdown-body details:not([open])>*:not(summary) { + display: none !important; +} + +.markdown-body a:focus, +.markdown-body [role=button]:focus, +.markdown-body input[type=radio]:focus, +.markdown-body input[type=checkbox]:focus { + outline: 2px solid var(--color-accent-fg); + outline-offset: -2px; + box-shadow: none; +} + +.markdown-body a:focus:not(:focus-visible), +.markdown-body [role=button]:focus:not(:focus-visible), +.markdown-body input[type=radio]:focus:not(:focus-visible), +.markdown-body input[type=checkbox]:focus:not(:focus-visible) { + outline: solid 1px transparent; +} + +.markdown-body a:focus-visible, +.markdown-body [role=button]:focus-visible, +.markdown-body input[type=radio]:focus-visible, +.markdown-body input[type=checkbox]:focus-visible { + outline: 2px solid var(--color-accent-fg); + outline-offset: -2px; + box-shadow: none; +} + +.markdown-body a:not([class]):focus, +.markdown-body a:not([class]):focus-visible, +.markdown-body input[type=radio]:focus, +.markdown-body input[type=radio]:focus-visible, +.markdown-body input[type=checkbox]:focus, +.markdown-body input[type=checkbox]:focus-visible { + outline-offset: 0; +} + +.markdown-body kbd { + display: inline-block; + padding: 3px 5px; + font: 11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + line-height: 10px; + color: var(--color-fg-default); + vertical-align: middle; + background-color: var(--color-canvas-subtle); + border: solid 1px var(--color-neutral-muted); + border-bottom-color: var(--color-neutral-muted); + border-radius: 6px; + box-shadow: inset 0 -1px 0 var(--color-neutral-muted); +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 24px; + margin-bottom: 16px; + font-weight: var(--base-text-weight-semibold, 600); + line-height: 1.25; +} + +.markdown-body h2 { + font-weight: var(--base-text-weight-semibold, 600); + padding-bottom: .3em; + font-size: 1.5em; + border-bottom: 1px solid var(--color-border-muted); +} + +.markdown-body h3 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: 1.25em; +} + +.markdown-body h4 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: 1em; +} + +.markdown-body h5 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: .875em; +} + +.markdown-body h6 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: .85em; + color: var(--color-fg-muted); +} + +.markdown-body p { + margin-top: 0; + margin-bottom: 10px; +} + +.markdown-body blockquote { + margin: 0; + padding: 0 1em; + color: var(--color-fg-muted); + border-left: .25em solid var(--color-border-default); +} + +.markdown-body ul, +.markdown-body ol { + margin-top: 0; + margin-bottom: 0; + padding-left: 2em; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body tt, +.markdown-body code, +.markdown-body samp { + font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + font-size: 12px; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + font-size: 12px; + word-wrap: normal; +} + +.markdown-body .octicon { + display: inline-block; + overflow: visible !important; + vertical-align: text-bottom; + fill: currentColor; +} + +.markdown-body input::-webkit-outer-spin-button, +.markdown-body input::-webkit-inner-spin-button { + margin: 0; + -webkit-appearance: none; + appearance: none; +} + +.markdown-body::before { + display: table; + content: ""; +} + +.markdown-body::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body a:not([href]) { + color: inherit; + text-decoration: none; +} + +.markdown-body .absent { + color: var(--color-danger-fg); +} + +.markdown-body .anchor { + float: left; + padding-right: 4px; + margin-left: -20px; + line-height: 1; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre, +.markdown-body details { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + color: var(--color-fg-default); + vertical-align: middle; + visibility: hidden; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + visibility: visible; +} + +.markdown-body h1 tt, +.markdown-body h1 code, +.markdown-body h2 tt, +.markdown-body h2 code, +.markdown-body h3 tt, +.markdown-body h3 code, +.markdown-body h4 tt, +.markdown-body h4 code, +.markdown-body h5 tt, +.markdown-body h5 code, +.markdown-body h6 tt, +.markdown-body h6 code { + padding: 0 .2em; + font-size: inherit; +} + +.markdown-body summary h1, +.markdown-body summary h2, +.markdown-body summary h3, +.markdown-body summary h4, +.markdown-body summary h5, +.markdown-body summary h6 { + display: inline-block; +} + +.markdown-body summary h1 .anchor, +.markdown-body summary h2 .anchor, +.markdown-body summary h3 .anchor, +.markdown-body summary h4 .anchor, +.markdown-body summary h5 .anchor, +.markdown-body summary h6 .anchor { + margin-left: -40px; +} + +.markdown-body summary h1, +.markdown-body summary h2 { + padding-bottom: 0; + border-bottom: 0; +} + +.markdown-body ul.no-list, +.markdown-body ol.no-list { + padding: 0; + list-style-type: none; +} + +.markdown-body ol[type=a] { + list-style-type: lower-alpha; +} + +.markdown-body ol[type=A] { + list-style-type: upper-alpha; +} + +.markdown-body ol[type=i] { + list-style-type: lower-roman; +} + +.markdown-body ol[type=I] { + list-style-type: upper-roman; +} + +.markdown-body ol[type="1"] { + list-style-type: decimal; +} + +.markdown-body div>ol:not([type]) { + list-style-type: decimal; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body li+li { + margin-top: .25em; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: var(--base-text-weight-semibold, 600); +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body table th { + font-weight: var(--base-text-weight-semibold, 600); +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid var(--color-border-default); +} + +.markdown-body table tr { + background-color: var(--color-canvas-default); + border-top: 1px solid var(--color-border-muted); +} + +.markdown-body table tr:nth-child(2n) { + background-color: var(--color-canvas-subtle); +} + +.markdown-body table img { + background-color: transparent; +} + +.markdown-body img[align=right] { + padding-left: 20px; +} + +.markdown-body img[align=left] { + padding-right: 20px; +} + +.markdown-body .emoji { + max-width: none; + vertical-align: text-top; + background-color: transparent; +} + +.markdown-body span.frame { + display: block; + overflow: hidden; +} + +.markdown-body span.frame>span { + display: block; + float: left; + width: auto; + padding: 7px; + margin: 13px 0 0; + overflow: hidden; + border: 1px solid var(--color-border-default); +} + +.markdown-body span.frame span img { + display: block; + float: left; +} + +.markdown-body span.frame span span { + display: block; + padding: 5px 0 0; + clear: both; + color: var(--color-fg-default); +} + +.markdown-body span.align-center { + display: block; + overflow: hidden; + clear: both; +} + +.markdown-body span.align-center>span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: center; +} + +.markdown-body span.align-center span img { + margin: 0 auto; + text-align: center; +} + +.markdown-body span.align-right { + display: block; + overflow: hidden; + clear: both; +} + +.markdown-body span.align-right>span { + display: block; + margin: 13px 0 0; + overflow: hidden; + text-align: right; +} + +.markdown-body span.align-right span img { + margin: 0; + text-align: right; +} + +.markdown-body span.float-left { + display: block; + float: left; + margin-right: 13px; + overflow: hidden; +} + +.markdown-body span.float-left span { + margin: 13px 0 0; +} + +.markdown-body span.float-right { + display: block; + float: right; + margin-left: 13px; + overflow: hidden; +} + +.markdown-body span.float-right>span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: right; +} + +.markdown-body code, +.markdown-body tt { + padding: .2em .4em; + margin: 0; + font-size: 85%; + white-space: break-spaces; + background-color: var(--color-neutral-muted); + border-radius: 6px; +} + +.markdown-body code br, +.markdown-body tt br { + display: none; +} + +.markdown-body del code { + text-decoration: inherit; +} + +.markdown-body samp { + font-size: 85%; +} + +.markdown-body pre code { + font-size: 100%; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: var(--color-canvas-subtle); + border-radius: 6px; +} + +.markdown-body pre code, +.markdown-body pre tt { + display: inline; + max-width: auto; + padding: 0; + margin: 0; + overflow: visible; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body .csv-data td, +.markdown-body .csv-data th { + padding: 5px; + overflow: hidden; + font-size: 12px; + line-height: 1; + text-align: left; + white-space: nowrap; +} + +.markdown-body .csv-data .blob-num { + padding: 10px 8px 9px; + text-align: right; + background: var(--color-canvas-default); + border: 0; +} + +.markdown-body .csv-data tr { + border-top: 0; +} + +.markdown-body .csv-data th { + font-weight: var(--base-text-weight-semibold, 600); + background: var(--color-canvas-subtle); + border-top: 0; +} + +.markdown-body [data-footnote-ref]::before { + content: "["; +} + +.markdown-body [data-footnote-ref]::after { + content: "]"; +} + +.markdown-body .footnotes { + font-size: 12px; + color: var(--color-fg-muted); + border-top: 1px solid var(--color-border-default); +} + +.markdown-body .footnotes ol { + padding-left: 16px; +} + +.markdown-body .footnotes ol ul { + display: inline-block; + padding-left: 16px; + margin-top: 16px; +} + +.markdown-body .footnotes li { + position: relative; +} + +.markdown-body .footnotes li:target::before { + position: absolute; + top: -8px; + right: -8px; + bottom: -8px; + left: -24px; + pointer-events: none; + content: ""; + border: 2px solid var(--color-accent-emphasis); + border-radius: 6px; +} + +.markdown-body .footnotes li:target { + color: var(--color-fg-default); +} + +.markdown-body .footnotes .data-footnote-backref g-emoji { + font-family: monospace; +} + +.markdown-body .pl-c { + color: var(--color-prettylights-syntax-comment); +} + +.markdown-body .pl-c1, +.markdown-body .pl-s .pl-v { + color: var(--color-prettylights-syntax-constant); +} + +.markdown-body .pl-e, +.markdown-body .pl-en { + color: var(--color-prettylights-syntax-entity); +} + +.markdown-body .pl-smi, +.markdown-body .pl-s .pl-s1 { + color: var(--color-prettylights-syntax-storage-modifier-import); +} + +.markdown-body .pl-ent { + color: var(--color-prettylights-syntax-entity-tag); +} + +.markdown-body .pl-k { + color: var(--color-prettylights-syntax-keyword); +} + +.markdown-body .pl-s, +.markdown-body .pl-pds, +.markdown-body .pl-s .pl-pse .pl-s1, +.markdown-body .pl-sr, +.markdown-body .pl-sr .pl-cce, +.markdown-body .pl-sr .pl-sre, +.markdown-body .pl-sr .pl-sra { + color: var(--color-prettylights-syntax-string); +} + +.markdown-body .pl-v, +.markdown-body .pl-smw { + color: var(--color-prettylights-syntax-variable); +} + +.markdown-body .pl-bu { + color: var(--color-prettylights-syntax-brackethighlighter-unmatched); +} + +.markdown-body .pl-ii { + color: var(--color-prettylights-syntax-invalid-illegal-text); + background-color: var(--color-prettylights-syntax-invalid-illegal-bg); +} + +.markdown-body .pl-c2 { + color: var(--color-prettylights-syntax-carriage-return-text); + background-color: var(--color-prettylights-syntax-carriage-return-bg); +} + +.markdown-body .pl-sr .pl-cce { + font-weight: bold; + color: var(--color-prettylights-syntax-string-regexp); +} + +.markdown-body .pl-ml { + color: var(--color-prettylights-syntax-markup-list); +} + +.markdown-body .pl-mh, +.markdown-body .pl-mh .pl-en, +.markdown-body .pl-ms { + font-weight: bold; + color: var(--color-prettylights-syntax-markup-heading); +} + +.markdown-body .pl-mi { + font-style: italic; + color: var(--color-prettylights-syntax-markup-italic); +} + +.markdown-body .pl-mb { + font-weight: bold; + color: var(--color-prettylights-syntax-markup-bold); +} + +.markdown-body .pl-md { + color: var(--color-prettylights-syntax-markup-deleted-text); + background-color: var(--color-prettylights-syntax-markup-deleted-bg); +} + +.markdown-body .pl-mi1 { + color: var(--color-prettylights-syntax-markup-inserted-text); + background-color: var(--color-prettylights-syntax-markup-inserted-bg); +} + +.markdown-body .pl-mc { + color: var(--color-prettylights-syntax-markup-changed-text); + background-color: var(--color-prettylights-syntax-markup-changed-bg); +} + +.markdown-body .pl-mi2 { + color: var(--color-prettylights-syntax-markup-ignored-text); + background-color: var(--color-prettylights-syntax-markup-ignored-bg); +} + +.markdown-body .pl-mdr { + font-weight: bold; + color: var(--color-prettylights-syntax-meta-diff-range); +} + +.markdown-body .pl-ba { + color: var(--color-prettylights-syntax-brackethighlighter-angle); +} + +.markdown-body .pl-sg { + color: var(--color-prettylights-syntax-sublimelinter-gutter-mark); +} + +.markdown-body .pl-corl { + text-decoration: underline; + color: var(--color-prettylights-syntax-constant-other-reference-link); +} + +.markdown-body g-emoji { + display: inline-block; + min-width: 1ch; + font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + font-size: 1em; + font-style: normal !important; + font-weight: var(--base-text-weight-normal, 400); + line-height: 1; + vertical-align: -0.075em; +} + +.markdown-body g-emoji img { + width: 1em; + height: 1em; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item label { + font-weight: var(--base-text-weight-normal, 400); +} + +.markdown-body .task-list-item.enabled label { + cursor: pointer; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 4px; +} + +.markdown-body .task-list-item .handle { + display: none; +} + +.markdown-body .task-list-item-checkbox { + margin: 0 .2em .25em -1.4em; + vertical-align: middle; +} + +.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox { + margin: 0 -1.6em .25em .2em; +} + +.markdown-body .contains-task-list { + position: relative; +} + +.markdown-body .contains-task-list:hover .task-list-item-convert-container, +.markdown-body .contains-task-list:focus-within .task-list-item-convert-container { + display: block; + width: auto; + height: 24px; + overflow: visible; + clip: auto; +} + +.markdown-body ::-webkit-calendar-picker-indicator { + filter: invert(50%); +} diff --git a/src/views/ai/chat/new-chat/message/styles/highlight.scss b/src/views/ai/chat/new-chat/message/styles/highlight.scss new file mode 100644 index 0000000..98423b0 --- /dev/null +++ b/src/views/ai/chat/new-chat/message/styles/highlight.scss @@ -0,0 +1,208 @@ + + +html.dark { + pre code.hljs { + display: block; + overflow-x: auto; + padding: 1em; + } + + code.hljs { + padding: 3px 5px; + } + + .hljs { + color: #abb2bf; + background: #282c34; + } + + .hljs-keyword, + .hljs-operator, + .hljs-pattern-match { + color: #f92672; + } + + .hljs-function, + .hljs-pattern-match .hljs-constructor { + color: #61aeee; + } + + .hljs-function .hljs-params { + color: #a6e22e; + } + + .hljs-function .hljs-params .hljs-typing { + color: #fd971f; + } + + .hljs-module-access .hljs-module { + color: #7e57c2; + } + + .hljs-constructor { + color: #e2b93d; + } + + .hljs-constructor .hljs-string { + color: #9ccc65; + } + + .hljs-comment, + .hljs-quote { + color: #b18eb1; + font-style: italic; + } + + .hljs-doctag, + .hljs-formula { + color: #c678dd; + } + + .hljs-deletion, + .hljs-name, + .hljs-section, + .hljs-selector-tag, + .hljs-subst { + color: #e06c75; + } + + .hljs-literal { + color: #56b6c2; + } + + .hljs-addition, + .hljs-attribute, + .hljs-meta .hljs-string, + .hljs-regexp, + .hljs-string { + color: #98c379; + } + + .hljs-built_in, + .hljs-class .hljs-title, + .hljs-title.class_ { + color: #e6c07b; + } + + .hljs-attr, + .hljs-number, + .hljs-selector-attr, + .hljs-selector-class, + .hljs-selector-pseudo, + .hljs-template-variable, + .hljs-type, + .hljs-variable { + color: #d19a66; + } + + .hljs-bullet, + .hljs-link, + .hljs-meta, + .hljs-selector-id, + .hljs-symbol, + .hljs-title { + color: #61aeee; + } + + .hljs-emphasis { + font-style: italic; + } + + .hljs-strong { + font-weight: 700; + } + + .hljs-link { + text-decoration: underline; + } +} + +html { + pre code.hljs { + display: block; + overflow-x: auto; + padding: 1em; + } + + code.hljs { + padding: 3px 5px; + &::-webkit-scrollbar { + height: 4px; + } + } + + .hljs { + color: #383a42; + background: #fafafa; + } + + .hljs-comment, + .hljs-quote { + color: #a0a1a7; + font-style: italic; + } + + .hljs-doctag, + .hljs-formula, + .hljs-keyword { + color: #a626a4; + } + + .hljs-deletion, + .hljs-name, + .hljs-section, + .hljs-selector-tag, + .hljs-subst { + color: #e45649; + } + + .hljs-literal { + color: #0184bb; + } + + .hljs-addition, + .hljs-attribute, + .hljs-meta .hljs-string, + .hljs-regexp, + .hljs-string { + color: #50a14f; + } + + .hljs-attr, + .hljs-number, + .hljs-selector-attr, + .hljs-selector-class, + .hljs-selector-pseudo, + .hljs-template-variable, + .hljs-type, + .hljs-variable { + color: #986801; + } + + .hljs-bullet, + .hljs-link, + .hljs-meta, + .hljs-selector-id, + .hljs-symbol, + .hljs-title { + color: #4078f2; + } + + .hljs-built_in, + .hljs-class .hljs-title, + .hljs-title.class_ { + color: #c18401; + } + + .hljs-emphasis { + font-style: italic; + } + + .hljs-strong { + font-weight: 700; + } + + .hljs-link { + text-decoration: underline; + } +} diff --git a/src/views/ai/chat/new-chat/message/styles/index.scss b/src/views/ai/chat/new-chat/message/styles/index.scss new file mode 100644 index 0000000..0f5ccac --- /dev/null +++ b/src/views/ai/chat/new-chat/message/styles/index.scss @@ -0,0 +1,3 @@ +@import "github-markdown"; +@import "highlight"; +@import "style"; diff --git a/src/views/ai/chat/new-chat/message/styles/style.scss b/src/views/ai/chat/new-chat/message/styles/style.scss new file mode 100644 index 0000000..d41142f --- /dev/null +++ b/src/views/ai/chat/new-chat/message/styles/style.scss @@ -0,0 +1,89 @@ + + +.markdown-body { + background-color: transparent; + font-size: 14px; + + p { + white-space: pre-wrap; + } + + ol { + list-style-type: decimal; + } + + ul { + list-style-type: disc; + } + + pre code, + pre tt { + line-height: 1.65; + } + + .highlight pre, + pre { + background-color: #fff; + } + + code.hljs { + padding: 0; + } + + .code-block { + &-wrapper { + position: relative; + padding-top: 24px; + margin-top: 10px; + } + + &-header { + position: absolute; + top: 5px; + right: 0; + width: 100%; + padding: 0 1rem; + display: flex; + justify-content: flex-end; + align-items: center; + color: #b3b3b3; + + &__copy { + cursor: pointer; + margin-left: 0.5rem; + user-select: none; + + &:hover { + color: #65a665; + } + } + } + } +} + +html.dark { + .message-reply { + .whitespace-pre-wrap { + white-space: pre-wrap; + color: var(--n-text-color); + } + } + + .highlight pre, + pre { + background-color: #282c34; + } +} + +@keyframes blink { + 0%, to { + background-color: currentColor; + } + 50% { + background-color: transparent; + } +} + +.animate-blink { + animation: blink 1.2s infinite steps(1, start); +} diff --git a/src/views/ai/chat/new-chat/store/chat.d.ts b/src/views/ai/chat/new-chat/store/chat.d.ts new file mode 100644 index 0000000..ff5e8ed --- /dev/null +++ b/src/views/ai/chat/new-chat/store/chat.d.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface ChatState { + messages: any[]; + modelId: string | null; + modelName: string | null; + modelProvider: string | null; + conversationId: string | null; + appId: any; +} diff --git a/src/views/ai/chat/new-chat/store/useBasicLayout.ts b/src/views/ai/chat/new-chat/store/useBasicLayout.ts new file mode 100644 index 0000000..0e52551 --- /dev/null +++ b/src/views/ai/chat/new-chat/store/useBasicLayout.ts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'; + +export const useBasicLayout = () => { + const breakpoints = useBreakpoints(breakpointsTailwind); + const isMobile = breakpoints.smaller('sm'); + return { isMobile }; +}; diff --git a/src/views/ai/chat/new-chat/store/useChatStore.ts b/src/views/ai/chat/new-chat/store/useChatStore.ts new file mode 100644 index 0000000..8c8d9fa --- /dev/null +++ b/src/views/ai/chat/new-chat/store/useChatStore.ts @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineStore } from 'pinia'; +import { formatToDateTime } from '@/utils/dateUtil'; +import type { ChatState } from '@/views/ai/chat/new-chat/store/chat'; + +export const useChatStore = defineStore('chat-store', { + state: (): ChatState => + { + modelId: null, + modelName: '', + modelProvider: '', + conversationId: null, + messages: [], + appId: null, + }, + + getters: {}, + + actions: { + /** + * 新增消息 + */ + async addMessage( + message: string, + role: 'user' | 'assistant' | 'system', + chatId: string + ): Promise { + this.messages.push({ + chatId, + role: role, + message: message, + createTime: formatToDateTime(new Date()), + }); + return true; + }, + + /** + * 更新消息 + * chatId 仅仅用于更新流式消息内容 + */ + async updateMessage(chatId: string, message: string, isError?: boolean) { + const index = this.messages.findIndex((item) => item?.chatId == chatId); + if (index !== -1) { + this.messages[index].message = message; + this.messages[index].isError = isError; + } + }, + + /** + * 删除消息 + */ + async delMessage(item: any) { + this.messages = this.messages.filter((i) => i.promptId !== item.promptId); + }, + }, +}); diff --git a/src/views/ai/chat/new-chat/store/useIconRender.ts b/src/views/ai/chat/new-chat/store/useIconRender.ts new file mode 100644 index 0000000..400fb44 --- /dev/null +++ b/src/views/ai/chat/new-chat/store/useIconRender.ts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { h } from 'vue'; +import SvgIcon from '@/components/SvgIcon/index.vue'; + +export const useIconRender = () => { + interface IconConfig { + icon?: string; + color?: string; + fontSize?: number; + } + + interface IconStyle { + color?: string; + fontSize?: string; + } + + const iconRender = (config: IconConfig) => { + const { color, fontSize, icon } = config; + + const style: IconStyle = {}; + + if (color) { + style.color = color; + } + + if (fontSize) { + style.fontSize = `${fontSize}px`; + } + + if (!icon) { + window.console.warn('iconRender: icon is required'); + } + + return () => h(SvgIcon, { icon, style }); + }; + + return { + iconRender, + }; +}; diff --git a/src/views/ai/chat/new-chat/store/useScroll.ts b/src/views/ai/chat/new-chat/store/useScroll.ts new file mode 100644 index 0000000..3d2fd06 --- /dev/null +++ b/src/views/ai/chat/new-chat/store/useScroll.ts @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Ref } from 'vue' +import { nextTick, ref } from 'vue' + +type ScrollElement = HTMLDivElement | null + +interface ScrollReturn { + contentRef: Ref + scrollRef: Ref + scrollToBottom: () => Promise + scrollToTop: () => Promise + scrollToBottomIfAtBottom: () => Promise +} + +export function useScroll(): ScrollReturn { + const scrollRef = ref(null) + const contentRef = ref(null) + + const scrollToBottom = async () => { + await nextTick() + if (contentRef.value) { + contentRef.value.scrollTo({ top: contentRef.value.scrollHeight, behavior: 'smooth' }) + } + } + + const scrollToTop = async () => { + await nextTick() + if (contentRef.value) { + contentRef.value.scrollTo({ top: 0, behavior: 'smooth' }) + } + } + + const scrollToBottomIfAtBottom = async () => { + await nextTick() + if (contentRef.value) { + const threshold = 100 // 阈值,表示滚动条到底部的距离阈值 + const distanceToBottom = + contentRef.value.scrollHeight - contentRef.value.scrollTop - contentRef.value.clientHeight + if (distanceToBottom <= threshold) { + contentRef.value.scrollTo({ top: contentRef.value.scrollHeight, behavior: 'smooth' }) + } + } + } + + return { + scrollRef, + contentRef, + scrollToBottom, + scrollToTop, + scrollToBottomIfAtBottom, + } +} diff --git a/src/views/ai/message/columns.ts b/src/views/ai/message/columns.ts new file mode 100644 index 0000000..6a7e8cc --- /dev/null +++ b/src/views/ai/message/columns.ts @@ -0,0 +1,107 @@ + + +import { TableColumnCtx } from 'element-plus'; +import { ElTag } from 'element-plus'; +import { h } from 'vue'; +import type { FormSchema } from '@/types/form'; +export const columns: Partial>[] = [ + { + label: '用户名', + prop: 'username', + align: 'center', + width: 120, + }, + { + label: '请求ip', + prop: 'ip', + align: 'center', + width: 120, + }, + { + label: '对话角色', + prop: 'role', + align: 'center', + width: 100, + formatter: (row: any) => { + return h( + ElTag, + { + type: row.role === 'user' ? 'success' : 'danger', + size: 'small', + }, + { default: () => row.role } + ); + }, + }, + { + label: '模型名称', + prop: 'model', + align: 'center', + width: 100, + }, + { + label: 'Token消耗', + prop: 'tokens', + align: 'center', + width: 100, + }, + { + label: '提示词Token消耗', + prop: 'promptTokens', + align: 'center', + width: 120, + }, + { + label: '消息内容', + prop: 'message', + formatter: (row: any) => { + return String(row.message).replace(/```|\n/g, ''); + }, + }, + { + label: '会话时间', + prop: 'createTime', + width: 180, + align: 'center', + }, +]; + +export const searchSchemas: FormSchema[] = [ + { + field: 'text', + component: 'Input', + label: '内容', + componentProps: { + placeholder: '请输入内容查询', + }, + }, + { + field: 'username', + component: 'Input', + label: '用户名', + componentProps: { + placeholder: '请输入用户名查询', + }, + }, + { + field: 'role', + component: 'Select', + label: '对话角色', + componentProps: { + placeholder: '请选择对话角色查询', + style: { + width: '140px', + }, + options: [ + { + label: 'user', + value: 'user', + }, + { + label: 'assistant', + value: 'assistant', + }, + ], + }, + }, +]; diff --git a/src/views/ai/message/composables/index.ts b/src/views/ai/message/composables/index.ts new file mode 100644 index 0000000..89aeb1e --- /dev/null +++ b/src/views/ai/message/composables/index.ts @@ -0,0 +1,165 @@ +import { ref, computed } from 'vue' +import type { FormSchema } from '@/types/form' +import type { TableColumn } from '@/types/table' +import { useTable } from '@/hooks/web/useTable' +import { ElTag, dayjs } from 'element-plus' +import { h } from 'vue' +import * as MessageApi from '@/api/new-ai/message' + +export default function () { + const searchParams = ref({}) + + const schema = ref([ + { + field: 'text', + component: 'Input', + label: '内容', + componentProps: { + placeholder: '请输入内容查询' + }, + colProps: { + span: 6 + } + }, + { + field: 'username', + component: 'Input', + label: '用户名', + componentProps: { + placeholder: '请输入用户名查询' + }, + colProps: { + span: 6 + } + }, + { + field: 'role', + component: 'Select', + label: '对话角色', + componentProps: { + placeholder: '请选择对话角色查询', + options: [ + { + label: 'user', + value: 'user' + }, + { + label: 'assistant', + value: 'assistant' + } + ] + }, + colProps: { + span: 6 + } + } + ]) + + const columns = ref([ + { + label: '用户名', + field: 'username', + align: 'center', + width: 120 + }, + { + label: '请求ip', + field: 'ip', + align: 'center', + width: 120 + }, + { + label: '对话角色', + field: 'role', + align: 'center', + width: 100, + formatter(row) { + return h( + ElTag, + { + type: row.role === 'user' ? 'success' : 'danger', + size: 'small' + }, + { + default: () => row.role + } + ) + } + }, + { + label: '模型名称', + field: 'model', + align: 'center', + width: 100 + }, + { + label: 'Token消耗', + field: 'tokens', + align: 'center', + width: 100 + }, + { + label: '提示词Token消耗', + field: 'promptTokens', + align: 'center', + width: 120 + }, + { + label: '消息内容', + field: 'message', + formatter: (row: any) => { + return String(row.message).replace(/```|\n/g, '') + } + }, + { + label: '会话时间', + field: 'createTime', + width: 180, + align: 'center', + formatter: (row: any) => { + return dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') + } + }, + + ]) + + const { register, tableObject, methods } = useTable({ + getListApi: MessageApi.page, + defaultParams: searchParams.value, + delListApi: MessageApi.del + }) + + const handleSearch = (values: any) => { + methods.setSearchParams(values) + // methods.getList() + } + + const pagination = computed(() => { + return { + total: tableObject.total, + pageSize: tableObject.pageSize, + currentPage: tableObject.currentPage + } + }) + + const handleDel = async (id: string | number) => { + try { + await methods.delList(id, false) + } catch (error) { + console.error('Failed to delete message:', error) + } + } + onMounted(() => { + methods.getList() + }) + return { + schema, + columns, + register, + handleSearch, + methods, + tableObject, + pagination, + handleDel + } +} diff --git a/src/views/ai/message/conversation/columns.ts b/src/views/ai/message/conversation/columns.ts new file mode 100644 index 0000000..861cafe --- /dev/null +++ b/src/views/ai/message/conversation/columns.ts @@ -0,0 +1,12 @@ +import type { FormSchema } from '@/types/form' + +export const searchSchemas: FormSchema[] = [ + { + field: 'text', + component: 'Input', + label: '内容', + componentProps: { + placeholder: '请输入内容' + } + } +] diff --git a/src/views/ai/message/conversation/components/InfoList.vue b/src/views/ai/message/conversation/components/InfoList.vue new file mode 100644 index 0000000..925d34b --- /dev/null +++ b/src/views/ai/message/conversation/components/InfoList.vue @@ -0,0 +1,68 @@ + + + + + + + diff --git a/src/views/ai/message/conversation/composables/index.ts b/src/views/ai/message/conversation/composables/index.ts new file mode 100644 index 0000000..47326c7 --- /dev/null +++ b/src/views/ai/message/conversation/composables/index.ts @@ -0,0 +1,107 @@ +import { ref, computed, onMounted } from 'vue' +import type { FormSchema } from '@/types/form' +import type { TableColumn } from '@/types/table' +import { useTable } from '@/hooks/web/useTable' +import { ElTag, dayjs } from 'element-plus' +import { h } from 'vue' +import * as ConversationApi from '@/api/new-ai/conversation' + +export default function () { + const searchParams = ref({}) + const infoRef = ref() + + const schema = ref([ + { + field: 'text', + component: 'Input', + label: '内容', + componentProps: { + placeholder: '请输入内容' + }, + colProps: { + span: 6 + } + } + ]) + + const columns = ref([ + { + label: '用户名', + field: 'username', + align: 'center' + }, + { + label: '窗口标题', + field: 'title', + align: 'center' + }, + { + label: '对话次数', + field: 'chatTotal', + align: 'center', + width: 180 + }, + { + label: 'Token消耗量', + field: 'tokenUsed', + align: 'center', + width: 180 + }, + { + label: '最后一次对话时间', + field: 'endTime', + align: 'center', + width: 180, + formatter: (row: any) => { + return dayjs(row.endTime).format('YYYY-MM-DD HH:mm:ss') + } + }, + { + label: '创建时间', + field: 'createTime', + width: 180, + align: 'center', + formatter: (row: any) => { + return dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') + } + } + ]) + + const { register, tableObject, methods } = useTable({ + getListApi: ConversationApi.page, + defaultParams: searchParams.value, + delListApi: ConversationApi.del + }) + + const handleSearch = (values: any) => { + methods.setSearchParams(values) + } + + const pagination = computed(() => { + return { + total: tableObject.total, + pageSize: tableObject.pageSize, + currentPage: tableObject.currentPage + } + }) + + const handleShowInfo = (row: any) => { + infoRef.value?.show(row) + } + + onMounted(() => { + methods.getList() + }) + + return { + schema, + columns, + register, + handleSearch, + methods, + tableObject, + pagination, + handleShowInfo, + infoRef + } +} diff --git a/src/views/ai/message/conversation/index.vue b/src/views/ai/message/conversation/index.vue new file mode 100644 index 0000000..51dd132 --- /dev/null +++ b/src/views/ai/message/conversation/index.vue @@ -0,0 +1,45 @@ + + + + + + + diff --git a/src/views/ai/message/index.vue b/src/views/ai/message/index.vue new file mode 100644 index 0000000..ffcffea --- /dev/null +++ b/src/views/ai/message/index.vue @@ -0,0 +1,57 @@ + + + + + + diff --git a/src/views/ai/model/chatModel/composables/columns.ts b/src/views/ai/model/chatModel/composables/columns.ts new file mode 100644 index 0000000..d6d18f4 --- /dev/null +++ b/src/views/ai/model/chatModel/composables/columns.ts @@ -0,0 +1,89 @@ +import {ProviderEnum} from './provider'; + +export const baseColumns = [ + { + label: '模型别名', + field: 'name', + }, + { + label: '模型版本', + field: 'model', + width: '140', + }, + { + label: '回复上限', + field: 'responseLimit', + width: '100', + }, + { + label: '生成随机性', + field: 'temperature', + width: '100', + }, + { + label: 'Top P', + field: 'topP', + width: '100', + }, +]; + +export const openaiColumns = [ + ...baseColumns, + { + label: 'Api Key', + field: 'apiKey', + }, +]; + +export const ollamaColumns = [ + ...baseColumns, + { + label: 'Base Url', + field: 'baseUrl', + }, +]; + +export const qfanColumns = [ + ...baseColumns, + { + label: 'Api Key', + field: 'apiKey', + }, +]; + +export const qwenColumns = [ + ...baseColumns, + { + label: 'Api Key', + field: 'apiKey', + }, +]; +export const zhipuColumns = [ + ...baseColumns, + { + label: 'Api Key', + field: 'apiKey', + }, +]; + +export function getColumns(provider: string) { + switch (provider) { + case ProviderEnum.OLLAMA: { + return ollamaColumns; + } + case ProviderEnum.Q_FAN: { + return qfanColumns; + } + case ProviderEnum.Q_WEN: { + return qwenColumns; + } + case ProviderEnum.ZHIPU: { + return zhipuColumns; + } + } + return [...openaiColumns, { + label: '操作', + field: 'action', + width: '150', + }]; +} diff --git a/src/views/ai/model/chatModel/composables/consts.ts b/src/views/ai/model/chatModel/composables/consts.ts new file mode 100644 index 0000000..3b11bc0 --- /dev/null +++ b/src/views/ai/model/chatModel/composables/consts.ts @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ProviderEnum } from './provider'; + +export const LLMProviders: any[] = [ + { + model: ProviderEnum.OPENAI, + name: 'OpenAI', + models: ['gpt-3.5-turbo', 'gpt-4', 'gpt-4-32k', 'gpt-4-turbo', 'gpt-4o'], + }, + { + model: ProviderEnum.Q_FAN, + name: '百度千帆', + models: [ + 'ERNIE-Bot', + 'ERNIE-Bot 4.0', + 'ERNIE-Bot-8K', + 'ERNIE-Bot-turbo', + 'ERNIE-Speed-128K', + 'EB-turbo-AppBuilder', + 'Yi-34B-Chat', + 'BLOOMZ-7B', + 'Qianfan-BLOOMZ-7B-compressed', + 'Mixtral-8x7B-Instruct', + 'Llama-2-7b-chat', + 'Llama-2-13b-chat', + 'Llama-2-70b-chat', + 'Qianfan-Chinese-Llama-2-7B', + 'ChatGLM2-6B-32K', + 'AquilaChat-7B', + ], + }, + { + model: ProviderEnum.Q_WEN, + name: '阿里百炼', + models: [ + 'qwen-turbo', + 'qwen-plus', + 'qwen-max', + 'qwen-max-longcontext', + 'qwen-7b-chat', + 'qwen-14b-chat', + 'qwen-72b-chat', + ], + }, + { + model: ProviderEnum.ZHIPU, + name: '智谱清言', + models: [ + 'glm-4', + 'glm-4v', + 'glm-4-air', + 'glm-4-airx', + 'glm-4-flash', + 'glm-3-turbo', + 'chatglm_turbo', + ], + }, + { + model: ProviderEnum.GITEEAI, + name: 'Gitee AI', + models: [ + 'Qwen2-72B-Instruct', + 'Qwen2-7B-Instruct', + 'Qwen2.5-72B-Instruct', + 'glm-4-9b-chat', + 'deepseek-coder-33B-instruct', + 'codegeex4-all-9b', + 'Yi-34B-Chat', + 'code-raccoon-v1', + 'Qwen2.5-Coder-32B-Instruct', + ], + }, + { + model: ProviderEnum.DEEPSEEK, + name: 'DeepSeek', + models: ['deepseek-chat', 'deepseek-coder'], + }, + { + model: ProviderEnum.DOUYIN, + name: '抖音豆包', + models: [], + }, + { + model: ProviderEnum.SILICON, + name: '硅基流动', + models: [ + 'deepseek-ai/DeepSeek-V2-Chat', + 'deepseek-ai/DeepSeek-Coder-V2-Instruct', + 'deepseek-ai/DeepSeek-V2.5', + 'Qwen/Qwen2.5-72B-Instruct-128K', + 'Qwen/Qwen2.5-72B-Instruct', + 'Qwen/Qwen2-VL-72B-Instruct', + 'Qwen/Qwen2.5-32B-Instruct', + 'Qwen/Qwen2.5-14B-Instruct', + 'Qwen/Qwen2.5-7B-Instruct', + 'Qwen/Qwen2.5-Math-72B-Instruct', + 'Qwen/Qwen2.5-Coder-7B-Instruct', + 'Qwen/Qwen2-72B-Instruct', + 'Qwen/Qwen2-7B-Instruct', + 'Qwen/Qwen2-1.5B-Instruct', + 'Qwen/Qwen2-57B-A14B-Instruct', + 'TeleAI/TeleChat2', + '01-ai/Yi-1.5-34B-Chat-16K', + '01-ai/Yi-1.5-9B-Chat-16K', + '01-ai/Yi-1.5-6B-Chat', + 'THUDM/chatglm3-6b', + 'THUDM/glm-4-9b-chat', + 'Vendor-A/Qwen/Qwen2-72B-Instruct', + 'Vendor-A/Qwen/Qwen2.5-72B-Instruct', + 'internlm/internlm2_5-7b-chat', + 'internlm/internlm2_5-20b-chat', + 'OpenGVLab/InternVL2-Llama3-76B', + 'OpenGVLab/InternVL2-26B', + 'nvidia/Llama-3.1-Nemotron-70B-Instruct', + 'meta-llama/Meta-Llama-3.1-405B-Instruct', + 'meta-llama/Meta-Llama-3.1-70B-Instruct', + 'meta-llama/Meta-Llama-3.1-8B-Instruct', + 'meta-llama/Meta-Llama-3-8B-Instruct', + 'meta-llama/Meta-Llama-3-70B-Instruct', + 'google/gemma-2-27b-it', + 'google/gemma-2-9b-it', + 'Pro/Qwen/Qwen2.5-7B-Instruct', + 'Pro/Qwen/Qwen2-7B-Instruct', + 'Pro/Qwen/Qwen2-1.5B-Instruct', + 'Pro/Qwen/Qwen2-VL-7B-Instruct', + 'Pro/01-ai/Yi-1.5-9B-Chat-16K', + 'Pro/01-ai/Yi-1.5-6B-Chat', + 'Pro/THUDM/chatglm3-6b', + 'Pro/THUDM/glm-4-9b-chat', + 'Pro/internlm/internlm2_5-7b-chat', + 'Pro/OpenGVLab/InternVL2-8B', + 'Pro/meta-llama/Meta-Llama-3-8B-Instruct', + 'Pro/meta-llama/Meta-Llama-3.1-8B-Instruct', + 'Pro/google/gemma-2-9b-it', + ], + }, + { + model: ProviderEnum.YI, + name: '零一万物', + models: [ + 'yi-lightning', + 'yi-large', + 'yi-medium', + 'yi-medium-200k', + 'yi-spark', + 'yi-large-rag', + 'yi-large-turbo', + ], + }, + { + model: ProviderEnum.SPARK, + name: '讯飞星火', + // models: ['lite', 'generalv3', 'pro-128k', 'generalv3.5', 'max-32k', '4.0Ultra'], + models: [ + { label: 'Spark Lite', value: 'lite' }, + { label: 'Spark Pro', value: 'generalv3' }, + { label: 'Spark Pro-128K', value: 'pro-128k' }, + { label: 'Spark Max', value: 'generalv3.5' }, + { label: 'Spark Max-32K', value: 'max-32k' }, + { label: 'Spark4.0 Ultra', value: '4.0Ultra' }, + ], + }, + { + model: ProviderEnum.OLLAMA, + name: 'Ollama', + models: [], + }, + { + model: ProviderEnum.AZURE_OPENAI, + name: 'Azure OpenAI', + models: ['gpt-3.5-turbo', 'gpt-4', 'gpt-4-32k', 'gpt-4-turbo', 'gpt-4o'], + }, + { + model: ProviderEnum.GEMINI, + name: 'Gemini', + models: ['gemini-1.5-pro'], + }, + { + model: ProviderEnum.CLAUDE, + name: 'Claude', + models: ['claude-3-opus', 'claude-3-opus-20240229', 'claude-3-sonnet', 'claude-3-haiku'], + }, +]; +export enum ModelTypeEnum { + CHAT = 'CHAT', + EMBEDDING = 'EMBEDDING', + TEXT_IMAGE = 'TEXT_IMAGE', + WEB_SEARCH = 'WEB_SEARCH', +} \ No newline at end of file diff --git a/src/views/ai/model/chatModel/composables/provider.ts b/src/views/ai/model/chatModel/composables/provider.ts new file mode 100644 index 0000000..b956cdf --- /dev/null +++ b/src/views/ai/model/chatModel/composables/provider.ts @@ -0,0 +1,37 @@ +export enum ProviderEnum { + OPENAI = 'OPENAI', + AZURE_OPENAI = 'AZURE_OPENAI', + GEMINI = 'GEMINI', + OLLAMA = 'OLLAMA', + CLAUDE = 'CLAUDE', + Q_FAN = 'Q_FAN', + Q_WEN = 'Q_WEN', + ZHIPU = 'ZHIPU', + GITEEAI = 'GITEEAI', + DEEPSEEK = 'DEEPSEEK', + DOUYIN = 'DOUYIN', + SILICON = 'SILICON', + YI = 'YI', + SPARK = 'SPARK', +} + +export function getModels(provider: string, providers: Array) { + const arr = providers.filter((i) => i.model === provider); + if (arr.length === 0) { + return []; + } + if (typeof arr[0].models[0] === 'string') { + return arr[0].models.map((i) => { + return { + label: i, + value: i, + }; + }); + } else { + return arr[0].models; + } +} + +export function getTitle(provider: string, providers: Array) { + return providers.filter((i) => i.model === provider)[0].name; +} diff --git a/src/views/ai/model/chatModel/composables/schemas.ts b/src/views/ai/model/chatModel/composables/schemas.ts new file mode 100644 index 0000000..c0aab8d --- /dev/null +++ b/src/views/ai/model/chatModel/composables/schemas.ts @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// import { FormSchema } from '@/components/Form'; +import { LLMProviders } from './consts'; +import { getModels, ProviderEnum } from './provider'; +// import { ModelTypeEnum } from '@/api/models'; +import {FormSchema} from "@/types/form"; +import { isNullOrWhitespace } from '@/utils/is'; + +const baseSchemas: FormSchema[] = [ + // { + // field: 'id', + // label: 'ID', + // component: 'Input', + // }, + // { + // field: 'type', + // label: 'type', + // component: 'Input', + // // value: ModelTypeEnum.CHAT, + // }, + { + field: 'provider', + label: 'LLM供应商', + component: 'Select', + // isHidden: true, + componentProps: { + placeholder: 'LLM供应商', + options: LLMProviders, + labelField: 'name', + valueField: 'model', + }, + // rules: [{ required: true, message: '请选择LLM供应商', trigger: ['blur'] }], + }, + { + field: 'name', + label: '模型别名', + component: 'Input', + formItemProps: { + rules: [{ required: true, message: '请输入模型别名', trigger: ['blur'] }] + }, + componentProps: { + placeholder: '请输入模型别名', + }, + }, + { + field: 'apiKey', + label: 'Api Key', + labelMessage: '模型的ApiKey', + component: 'Input', + // rules: [{ required: true, message: '请输入API Key', trigger: ['blur'] }], + componentProps: { + placeholder: '请输入Api Key', + }, + }, + { + field: 'responseLimit', + label: '回复上限', + labelMessage: '控制模型输出的Tokens长度上限。通常 100 Tokens 约等于150个中文汉字', + component: 'Slider', + formItemProps:{ + rules: [{ type: 'number', required: true, message: '请输入回复上限', trigger: ['blur'] }] + }, + componentProps: { + showTooltip: true, + value: 2000, + step: 1, + min: 1, + max: 8192, + }, + }, + { + field: 'temperature', + label: '生成随机性', + labelMessage: '调高参数会使得模型的输出更多样性和创新性,反之降低参数将会减少多样性', + component: 'Slider', + formItemProps: { + rules: [{ type: 'number', required: true, message: '请输入生成随机性', trigger: ['blur'] }] + }, + value:0.2, + componentProps: { + showTooltip: true, + step: 0.05, + min: 0, + max: 2, + }, + }, + { + field: 'topP', + label: 'Top P', + labelMessage: + '模型在生成输出时会从概率最高的词汇开始选择,直到这些词汇的总概率累积达到Top p值。这样可以限制模型只选择这些高概率的词汇,从而控制输出内容的多样性。建议不要与“生成随机性“同时调整', + component: 'Slider', + formItemProps: { + rules: [{ type: 'number', required: true, message: '请输入', trigger: ['blur'] }] + }, + componentProps: { + showTooltip: true, + value: 0.8, + step: 0.1, + min: 0, + max: 1, + }, + }, +]; + +export function getSchemas(provider: string) { + const list = JSON.parse(JSON.stringify(baseSchemas)); + console.log(provider); + const modelSchema: any = { + field: 'model', + label: '模型版本', + labelMessage: '该LLM供应商对应的模型版本号', + component: 'Select', + rules: [{ required: true, message: '请选择模型', trigger: ['blur'] }], + componentProps: { + placeholder: '请选择模型版本(可以手动输入)', + filterable: true, + tag: true, + options: getModels(provider, LLMProviders), + }, + }; + list.splice(1, 0, modelSchema); + + let value: any = undefined; + let labelMessage: any = '模型的基础请求URL地址(或中转地址)'; + let disabled = false; + switch (provider) { + case ProviderEnum.GITEEAI: + disabled = true; + value = 'https://ai.gitee.com/v1'; + labelMessage = '对于Gitee AI,此Url固定不可修改'; + break; + case ProviderEnum.DEEPSEEK: + disabled = true; + value = 'https://api.deepseek.com/v1'; + labelMessage = '对于DeepSeek模型,此Url固定不可修改'; + break; + case ProviderEnum.SILICON: + disabled = true; + value = 'https://api.siliconflow.cn/v1'; + labelMessage = '对于硅基流动模型,此Url固定不可修改'; + break; + case ProviderEnum.DOUYIN: + disabled = true; + value = 'https://ark.cn-beijing.volces.com/api/v3'; + labelMessage = '对于抖音豆包模型,此Url固定不可修改'; + break; + case ProviderEnum.YI: + disabled = true; + value = 'https://api.lingyiwanwu.com/v1'; + labelMessage = '对于零一模型,此Url固定不可修改'; + break; + case ProviderEnum.SPARK: + disabled = true; + value = 'https://spark-api-open.xf-yun.com/v1'; + labelMessage = '对于讯飞星火大模型,此Url固定不可修改'; + break; + } + const baseUlrSchema: any = { + field: 'baseUrl', + label: 'Base Url', + labelMessage, + component: 'Input', + value, + componentProps: { + disabled, + placeholder: '请输入BaseUrl', + }, + rules: [ + { + required: false, + trigger: ['blur'], + validator: (_, value: string) => { + if (!value) { + return; + } + const urlRegex = + /^(https?:\/\/)?((([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|localhost|(\d{1,3}\.){3}\d{1,3})(:\d{1,5})?(\/.*)?)$/; + if (isNullOrWhitespace(value) || urlRegex.test(value)) { + return true; + } + return new Error('URL格式错误'); + }, + }, + ], + }; + list.splice(3, 0, baseUlrSchema); + return list; +} diff --git a/src/views/ai/model/chatModel/edit.vue b/src/views/ai/model/chatModel/edit.vue new file mode 100644 index 0000000..6a74c4f --- /dev/null +++ b/src/views/ai/model/chatModel/edit.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/views/ai/model/chatModel/index.vue b/src/views/ai/model/chatModel/index.vue index c550674..ef149ec 100644 --- a/src/views/ai/model/chatModel/index.vue +++ b/src/views/ai/model/chatModel/index.vue @@ -1,185 +1,149 @@ + + + - + diff --git a/src/views/ai/model/embedStore/composables/index.ts b/src/views/ai/model/embedStore/composables/index.ts new file mode 100644 index 0000000..a4947da --- /dev/null +++ b/src/views/ai/model/embedStore/composables/index.ts @@ -0,0 +1,173 @@ +import {ref} from "vue"; +import {FormSchema} from "@/types/form"; +import {ElTag} from "element-plus"; +import {EmbedStoreApi} from "@/api/new-ai/embed-store"; +import { useTable } from "@/hooks/web/useTable"; +import { TableColumn } from "@/types/table"; + +export enum ProviderEnum { + Redis = 'REDIS', + PgVector = 'PGVECTOR', + Milvus = 'MILVUS', +} + +export const ProviderConst = [ + { label: 'Redis', value: ProviderEnum.Redis }, + { label: 'PgVector', value: ProviderEnum.PgVector }, + { label: 'Milvus', value: ProviderEnum.Milvus }, +]; + +export default function () { + const editRef = ref() + const searchParams = ref({}); + const ProviderConst = [ + { label: 'Redis', value: ProviderEnum.Redis }, + { label: 'PgVector', value: ProviderEnum.PgVector }, + { label: 'Milvus', value: ProviderEnum.Milvus }, + ]; + + function getProviderLabel(value: any) { + const arr = ProviderConst.filter((i) => i.value === value); + if (arr === undefined || arr.length === 0) { + return value; + } + return arr[0].label; + } + + const shema = ref([ + { + label: '数据库别名', + field: 'name', + component: 'Input', + colProps: { + span: 6 + }, + } + ]) + + const columns = ref([ + { + label: '数据库别名', + field: 'name', + align: 'center', + }, + { + label: '供应商', + field: 'provider', + align: 'center', + width: '120', + render(row) { + return h( + ElTag, + { + type: 'success', + }, + { + default: () => getProviderLabel(row.provider), + } + ); + }, + }, + { + label: '向量纬度', + field: 'dimension', + align: 'center', + width: '100', + formatter(row) { + return h( + ElTag, + { + size: 'small', + }, + { + default: () => row.dimension, + } + ); + }, + }, + { + label: '数据库地址', + field: 'host', + align: 'center', + width: '110', + }, + { + label: '数据库端口', + field: 'port', + align: 'center', + width: '100', + }, + { + label: '数据库用户名', + field: 'username', + align: 'center', + }, + { + label: '数据库密码', + field: 'password', + align: 'center', + }, + { + label: '数据库名', + field: 'databaseName', + align: 'center', + }, + { + label: '表名称', + field: 'tableName', + align: 'center', + }, + { + label: '操作', + field: "action", + width: 150 + } + ]); + + const {register, tableObject, methods} = useTable({ + getListApi: EmbedStoreApi.getEmbedStorePage, + defaultParams: searchParams.value, + delListApi: EmbedStoreApi.deleteEmbedStore + }); + + // 打开编辑对话框 + const open = (data?: any) => { + editRef.value.show(data); + } + + // 处理搜索 + const handleSearch = (values: any) => { + methods.setSearchParams(values) + } + + const pagination = computed(() => { + return { + total: tableObject.total, + pageSize: tableObject.pageSize, + currentPage: tableObject.currentPage + } + }) + + const handleDel = async (id: string | number) => { + try { + await methods.delList(id, false); + } catch (error) { + console.error('Failed to delete embed store:', error); + } + } + + return { + shema, + columns, + register, + open, + handleSearch, + ProviderConst, + getProviderLabel, + methods, + tableObject, + pagination, + handleDel, + editRef + } +} diff --git a/src/views/ai/model/embedStore/edit.vue b/src/views/ai/model/embedStore/edit.vue new file mode 100644 index 0000000..634f8ca --- /dev/null +++ b/src/views/ai/model/embedStore/edit.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/src/views/ai/model/embedStore/index.vue b/src/views/ai/model/embedStore/index.vue new file mode 100644 index 0000000..0354929 --- /dev/null +++ b/src/views/ai/model/embedStore/index.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/views/ai/model/embedding/composables/consts.ts b/src/views/ai/model/embedding/composables/consts.ts new file mode 100644 index 0000000..a5fc69f --- /dev/null +++ b/src/views/ai/model/embedding/composables/consts.ts @@ -0,0 +1,34 @@ +import {ProviderEnum} from "@/views/ai/model/chatModel/composables/provider"; + +export const LLMProviders: any[] = [ + { + model: ProviderEnum.OPENAI, + name: 'OpenAI', + models: ['text-embedding-3-small', 'text-embedding-3-large', 'text-embedding-ada-002'], + }, + { + model: ProviderEnum.Q_FAN, + name: '百度千帆', + models: ['bge-large-zh', 'bge-large-en', 'tao-8k'], + }, + { + model: ProviderEnum.Q_WEN, + name: '阿里百炼', + models: ['text-embedding-v3'], + }, + { + model: ProviderEnum.ZHIPU, + name: '智谱清言', + models: ['embedding-2', 'embedding-3'], + }, + { + model: ProviderEnum.DOUYIN, + name: '抖音豆包', + models: ['text-240715', 'text-240515'], + }, + { + model: ProviderEnum.OLLAMA, + name: 'Ollama', + models: ['text2vec-bge-large-chinese:latest'], + }, +]; diff --git a/src/views/ai/model/embedding/composables/index.ts b/src/views/ai/model/embedding/composables/index.ts new file mode 100644 index 0000000..97cc98d --- /dev/null +++ b/src/views/ai/model/embedding/composables/index.ts @@ -0,0 +1,107 @@ +import {ref, watch} from "vue"; +import {ProviderEnum} from "@/views/ai/model/chatModel/composables/provider"; +import {ModelApi} from "@/api/new-ai/model"; +import {ElTag, ElMessageBox as dialog, ElMessage as message} from "element-plus"; +import { ModelTypeEnum } from "../../chatModel/composables/consts"; + + +export default function () { + const editRef = ref() + const formData = ref({ + provider: ProviderEnum.OPENAI, + type: ModelTypeEnum.EMBEDDING + }); + const tableData = ref([]) + const loading = ref(false) + const baseColumns = [ + { + label: '模型别名', + field: 'name', + }, + { + label: '模型版本', + field: 'model', + width: '160', + }, + { + label: '向量纬度', + field: 'dimension', + align: 'center', + width: '100', + render(row) { + return h( + ElTag, + { + size: 'small', + }, + { + default: () => row.dimension, + } + ); + }, + }, + { + label: 'Api Key', + field: 'apiKey', + }, + { + label: 'Base Url', + field: 'baseUrl', + }, {label: '操作', field: 'action', width: 150} + ]; + + // 加载数据 + const loadData = async () => { + try { + const res = await ModelApi.getModelList({ provider: formData.value.provider, type: ModelTypeEnum.EMBEDDING }).finally(() => loading.value = false); + tableData.value = res; + } catch (error) { + console.error('Failed to load embedding models:', error); + } + } + + // 监听供应商变化 + watch(() => formData.value.provider, () => { + loadData(); + }, { immediate: true }); + + const open = () => { + editRef.value.show({provider: formData.value.provider, type: ModelTypeEnum.EMBEDDING}); + } + function handleEdit(record: any) { + editRef.value.show(record); + } + + async function reloadTable() { + await loadData(); + } + + async function handleDel(record: any) { + dialog.confirm('确定要删除该模型吗?', '警告', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }).then(async () => { + try { + await ModelApi.deleteModel(record.id); + await reloadTable(); + message.success('模型删除成功'); + } catch (error) { + console.error('Failed to delete model:', error); + message.error('删除模型失败'); + } + }).catch(() => { + }); + } + return { + baseColumns, + tableData, + formData, + editRef, + open, + loadData, + handleDel, + handleEdit, + loading + } +} diff --git a/src/views/ai/model/embedding/composables/schemas.ts b/src/views/ai/model/embedding/composables/schemas.ts new file mode 100644 index 0000000..3e186ca --- /dev/null +++ b/src/views/ai/model/embedding/composables/schemas.ts @@ -0,0 +1,138 @@ + + + import {FormSchema} from "@/types/form"; +// import { ModelTypeEnum } from '@/api/models'; + import {getModels, ProviderEnum} from "@/views/ai/model/chatModel/composables/provider"; + import {LLMProviders} from "@/views/ai/model/embedding/composables/consts"; +// import { LLMProviders } from './consts'; +const baseSchemas: FormSchema[] = [ + // { + // field: 'id', + // label: 'ID', + // component: 'Input', + // isHidden: true, + // }, + // { + // field: 'type', + // label: 'type', + // component: 'Input', + // isHidden: true, + // value: ModelTypeEnum.EMBEDDING, + // }, + { + field: 'provider', + label: 'LLM供应商', + component: 'Select', + componentProps: { + placeholder: '请选择LLM供应商', + options: LLMProviders, + }, + }, + { + field: 'name', + label: '模型别名', + component: 'Input', + formItemProps: { + rules: [{ required: true, message: '请输入模型别名', trigger: ['blur'] }] + }, + componentProps: { + placeholder: '请输入模型别名', + }, + }, + { + field: 'apiKey', + label: 'Api Key', + labelMessage: '模型的ApiKey', + component: 'Input', + // rules: [{ required: true, message: '请输入ApiKey', trigger: ['blur'] }], + componentProps: { + placeholder: '请输入ApiKey', + }, + }, + { + field: 'dimension', + label: '向量纬度', + component: 'Select', + value: 1024, + labelMessage: '慎重修改此参数,纬度高会消耗更多的算力,但纬度高并不代表搜索更精确', + componentProps: { + placeholder: '请输入向量纬度', + options: [ + { + label: '512', + value: 512, + }, + { + label: '768', + value: 768, + }, + { + label: '1024', + value: 1024, + }, + { + label: '1536', + value: 1536, + }, + ], + }, + formItemProps:{ + rules: [{ type: 'number', required: true, message: '请输入向量纬度', trigger: ['blur'] }] + }, + }, +]; + +export function getSchemas(provider: string) { + const list = JSON.parse(JSON.stringify(baseSchemas)); + + const modelSchema: any = { + field: 'model', + label: '模型版本', + labelMessage: '该LLM供应商对应的模型版本号', + component: 'Select', + rules: [{ required: true, message: '请选择模型', trigger: ['blur'] }], + componentProps: { + placeholder: '请选择模型版本', + filterable: true, + tag: true, + options: getModels(provider, LLMProviders), + }, + }; + list.splice(list.length, 0, modelSchema); + + let value: any = undefined; + let labelMessage: any = '模型的基础请求URL地址(或中转地址)'; + let disabled = false; + switch (provider) { + case ProviderEnum.DOUYIN: + disabled = true; + value = 'https://ark.cn-beijing.volces.com/api/v3'; + labelMessage = '对于抖音豆包模型,此Url固定不可修改'; + break; + case ProviderEnum.Q_FAN: + disabled = true; + labelMessage = '对于百度千帆模型,此Url固定不可修改'; + break; + case ProviderEnum.Q_WEN: + disabled = true; + labelMessage = '对于阿里千问模型,此Url固定不可修改'; + break; + case ProviderEnum.ZHIPU: + disabled = true; + labelMessage = '对于智谱清言模型,此Url固定不可修改'; + break; + } + const baseUlrSchema: any = { + field: 'baseUrl', + label: 'Base Url', + labelMessage, + component: 'Input', + value, + componentProps: { + disabled, + placeholder: '请输入BaseUrl', + }, + }; + list.splice(list.length, 0, baseUlrSchema); + return list; +} diff --git a/src/views/ai/model/embedding/edit.vue b/src/views/ai/model/embedding/edit.vue new file mode 100644 index 0000000..853b827 --- /dev/null +++ b/src/views/ai/model/embedding/edit.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/src/views/ai/model/embedding/index.vue b/src/views/ai/model/embedding/index.vue new file mode 100644 index 0000000..12eb8be --- /dev/null +++ b/src/views/ai/model/embedding/index.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/src/views/ai/model/image/composables/consts.ts b/src/views/ai/model/image/composables/consts.ts new file mode 100644 index 0000000..56a95fa --- /dev/null +++ b/src/views/ai/model/image/composables/consts.ts @@ -0,0 +1,22 @@ +export enum ProviderEnum { + OPENAI = 'OPENAI', + AZURE_OPENAI = 'AZURE_OPENAI', + ZHIPU = 'ZHIPU', +} +export const LLMProviders: any[] = [ + { + model: ProviderEnum.OPENAI, + name: 'OpenAI', + models: ['dall-e-2', 'dall-e-3'], + }, + { + model: ProviderEnum.AZURE_OPENAI, + name: 'Azure OpenAI', + models: ['dall-e-2', 'dall-e-3'], + }, + { + model: ProviderEnum.ZHIPU, + name: '智谱清言', + models: ['cogview-3'], + }, +] diff --git a/src/views/ai/model/image/composables/index.ts b/src/views/ai/model/image/composables/index.ts new file mode 100644 index 0000000..44d42c9 --- /dev/null +++ b/src/views/ai/model/image/composables/index.ts @@ -0,0 +1,128 @@ +import {computed, nextTick, onMounted, ref, watch} from "vue"; +import {ProviderEnum} from "@/views/ai/model/image/composables/consts"; +import {ModelApi} from "@/api/new-ai/model"; +import { ModelTypeEnum } from "../../chatModel/composables/consts"; +import {ElTag, ElMessageBox as dialog, ElMessage as message} from "element-plus"; + +export default function () { + const editRef = ref() + const formData = ref({ + provider: ProviderEnum.OPENAI, + type: ModelTypeEnum.TEXT_IMAGE + }); + const tableData = ref([]) + const loading = ref(false) + const baseColumns = [ + { + label: '模型别名', + field: 'name', + }, + { + label: '模型版本', + field: 'model', + }, + ]; + + const openaiColumns = [ + ...baseColumns, + { + label: 'Api Key', + field: 'apiKey', + }, + ]; + + const azureOpenaiColumns = [ + ...baseColumns, + { + label: 'Api Key', + field: 'apiKey', + }, + { + label: 'Endpoint', + field: 'endpoint', + }, + { + label: 'Deployment Name', + field: 'azureDeploymentName', + }, + ]; + + const zhipuColumns = [...baseColumns]; + + function getColumns(provider: string) { + switch (provider) { + case ProviderEnum.OPENAI: { + return openaiColumns; + } + case ProviderEnum.AZURE_OPENAI: { + return azureOpenaiColumns; + } + case ProviderEnum.ZHIPU: { + return zhipuColumns; + } + default: { + return baseColumns; + } + } + } + + const columns = computed(() => { + nextTick(); + return [...getColumns(formData.value.provider), {label: '操作', field: 'action', width: 150}] + }); + + // 加载数据 + const loadData = async () => { + try { + const res = await ModelApi.getModelList({ provider: formData.value.provider, type: ModelTypeEnum.TEXT_IMAGE }).finally(() => loading.value = false); + tableData.value = res; + } catch (error) { + console.error('Failed to load image models:', error); + } + } + + // 监听供应商变化 + watch(() => formData.value.provider, () => { + loadData(); + }, { immediate: true }); + + const open = () => { + editRef.value.show({provider: formData.value.provider, type: ModelTypeEnum.TEXT_IMAGE}); + } + function handleEdit(record: any) { + editRef.value.show(record); + } + + async function reloadTable() { + await loadData(); + } + + async function handleDel(record: any) { + dialog.confirm('确定要删除该模型吗?', '警告', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }).then(async () => { + try { + await ModelApi.deleteModel(record.id); + await reloadTable(); + message.success('模型删除成功'); + } catch (error) { + console.error('Failed to delete model:', error); + message.error('删除模型失败'); + } + }).catch(() => { + }); + } + return { + columns, + tableData, + formData, + editRef, + open, + loadData, + handleDel, + handleEdit, + loading, + } +} diff --git a/src/views/ai/model/image/composables/schemas.ts b/src/views/ai/model/image/composables/schemas.ts new file mode 100644 index 0000000..7079885 --- /dev/null +++ b/src/views/ai/model/image/composables/schemas.ts @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved. + * + * Licensed under the GNU Affero General Public License, Version 3 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {FormSchema} from '@/types/form'; +// import { LLMProviders, ProviderEnum } from './data'; +// import { ModelTypeEnum } from '@/api/models'; +import {isNullOrWhitespace} from '@/utils/is'; +import {LLMProviders, ProviderEnum} from "@/views/ai/model/image/composables/consts"; + +const baseHeadSchemas: FormSchema[] = [ + // { + // field: 'id', + // label: 'ID', + // component: 'Input', + // isHidden: true, + // }, + // { + // field: 'type', + // label: 'type', + // component: 'Input', + // isHidden: true, + // defaultValue: ModelTypeEnum.TEXT_IMAGE, + // }, + { + field: 'provider', + label: 'LLM供应商', + component: 'Select', + componentProps: { + options: LLMProviders, + labelField: 'name', + valueField: 'model', + }, + formItemProps: {rules: [{required: true, message: '请选择LLM供应商', trigger: ['blur']}]}, + }, + { + field: 'name', + label: '模型别名', + component: 'Input', + formItemProps: {rules: [{required: true, message: '请输入模型别名', trigger: ['blur']}]}, + }, +]; +const keySchemas: FormSchema[] = [ + { + field: 'apiKey', + label: 'Api Key', + labelMessage: '模型链接的秘钥,注意有些模型例如Gemini是本地认证方式,则不是通过这种方式', + component: 'Input', + formItemProps: {rules: [{required: true, message: '请输入API Key', trigger: ['blur']}]}, + }, + { + field: 'baseUrl', + label: 'Base Url', + labelMessage: '注意对于大多数模型此参数仅代表中转地址,但是对于Ollama这类本地模型则是必填的', + component: 'Input', + formItemProps: { + rules: [ + { + required: false, + trigger: ['blur'], + validator: (_, value: string) => { + const urlRegex = /^(https?:\/\/)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/.*)?$/; + if (isNullOrWhitespace(value) || urlRegex.test(value)) { + return true; + } + return new Error('URL格式错误'); + }, + }, + ] + }, + }, +]; + +export const openaiSchemas: FormSchema[] = [ + ...baseHeadSchemas, + { + field: 'model', + label: '模型', + labelMessage: '该LLM供应商对应的模型版本号', + component: 'Select', + formItemProps: { + rules: [{required: true, message: '请选择模型', trigger: ['blur']}] + }, + componentProps: { + filterable: true, + options: getModels(ProviderEnum.OPENAI), + }, + }, + { + field: 'imageSize', + label: '图片大小', + labelMessage: '生成图片的大小尺寸', + component: 'Select', + formItemProps: { + rules: [{required: true, message: '请选择图片大小', trigger: ['blur']}] + }, + componentProps: { + options: [ + { + label: '1024x1024', + value: '1024x1024', + }, + { + label: '1024x1792', + value: '1024x1792', + }, + { + label: '1792x1024', + value: '1792x1024', + }, + ], + }, + }, + { + field: 'imageQuality', + label: '图片质量', + labelMessage: '生成图片的质量', + component: 'Select', + formItemProps: { + rules: [{required: true, message: '请选择图片的质量', trigger: ['blur']}] + }, + componentProps: { + options: [ + { + label: 'standard', + value: 'standard', + }, + { + label: 'hd', + value: 'hd', + }, + ], + }, + }, + { + field: 'imageStyle', + label: '图片风格', + labelMessage: '生成图片的风格', + component: 'Select', + formItemProps: { + rules: [{required: true, message: '请选择图片的风格', trigger: ['blur']}] + }, + componentProps: { + options: [ + { + label: 'vivid', + value: 'vivid', + }, + { + label: 'natural', + value: 'natural', + }, + ], + }, + }, + ...keySchemas, +]; + +export const azureOpenaiSchemas: FormSchema[] = [ + ...baseHeadSchemas, + { + field: 'model', + label: '模型', + labelMessage: '该LLM供应商对应的模型版本号', + component: 'Select', + formItemProps: { + rules: [{required: true, message: '请选择模型', trigger: ['blur']}] + }, + componentProps: { + filterable: true, + options: getModels(ProviderEnum.AZURE_OPENAI), + }, + }, + { + field: 'imageSize', + label: '图片大小', + labelMessage: '生成图片的大小尺寸', + component: 'Select', + formItemProps: { + rules: [{required: true, message: '请选择图片大小', trigger: ['blur']}] + }, + componentProps: { + options: [ + { + label: '1024x1024', + value: '1024x1024', + }, + { + label: '1024x1792', + value: '1024x1792', + }, + { + label: '1792x1024', + value: '1792x1024', + }, + ], + }, + }, + { + field: 'imageQuality', + label: '图片质量', + labelMessage: '生成图片的质量', + component: 'Select', + formItemProps: {rules: [{required: true, message: '请选择图片的质量', trigger: ['blur']}]}, + componentProps: { + options: [ + { + label: 'standard', + value: 'standard', + }, + { + label: 'hd', + value: 'hd', + }, + ], + }, + }, + { + field: 'imageStyle', + label: '图片风格', + labelMessage: '生成图片的风格', + component: 'Select', + formItemProps: {rules: [{required: true, message: '请选择图片的风格', trigger: ['blur']}]}, + componentProps: { + options: [ + { + label: 'vivid', + value: 'vivid', + }, + { + label: 'natural', + value: 'natural', + }, + ], + }, + }, + ...keySchemas, +]; + +export const zhipuSchemas: FormSchema[] = [ + ...baseHeadSchemas, + { + field: 'model', + label: '模型', + labelMessage: '该LLM供应商对应的模型版本号', + component: 'Select', + formItemProps: {rules: [{required: true, message: '请选择模型', trigger: ['blur']}]}, + componentProps: { + filterable: true, + options: getModels(ProviderEnum.ZHIPU), + }, + }, + ...keySchemas, +]; + +export function getSchemas(provider: string) { + switch (provider) { + case ProviderEnum.OPENAI: { + return openaiSchemas; + } + case ProviderEnum.AZURE_OPENAI: { + return azureOpenaiSchemas; + } + case ProviderEnum.ZHIPU: { + return zhipuSchemas; + } + } + return []; +} + +export function getModels(provider: string) { + const arr = LLMProviders.filter((i) => i.model === provider); + if (arr.length === 0) { + return []; + } + return arr[0].models.map((i) => { + return { + label: i, + value: i, + }; + }); +} diff --git a/src/views/ai/model/image/edit.vue b/src/views/ai/model/image/edit.vue new file mode 100644 index 0000000..ee9a6ab --- /dev/null +++ b/src/views/ai/model/image/edit.vue @@ -0,0 +1,69 @@ + + + + diff --git a/src/views/ai/model/image/index.vue b/src/views/ai/model/image/index.vue new file mode 100644 index 0000000..c8f4c46 --- /dev/null +++ b/src/views/ai/model/image/index.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/views/ai/order/components/Chart.vue b/src/views/ai/order/components/Chart.vue new file mode 100644 index 0000000..eb230ab --- /dev/null +++ b/src/views/ai/order/components/Chart.vue @@ -0,0 +1,79 @@ + + + diff --git a/src/views/ai/order/components/List.vue b/src/views/ai/order/components/List.vue new file mode 100644 index 0000000..73ddbe4 --- /dev/null +++ b/src/views/ai/order/components/List.vue @@ -0,0 +1,53 @@ + + + + + + + diff --git a/src/views/ai/order/components/columns.ts b/src/views/ai/order/components/columns.ts new file mode 100644 index 0000000..2628593 --- /dev/null +++ b/src/views/ai/order/components/columns.ts @@ -0,0 +1,56 @@ +import type { FormSchema } from '@/types/form'; + +export const columns = [ + { + label: '用户名', + field: 'username', + align: 'center', + }, + { + label: '模型名称', + field: 'model', + align: 'center', + }, + { + label: 'Tokens', + field: 'tokens', + align: 'center', + }, + { + label: 'Prompt Tokens', + field: 'promptTokens', + align: 'center', + }, + { + label: 'Prompt Tokens', + field: 'promptTokens', + align: 'center', + }, + { + label: 'IP地址', + field: 'ip', + align: 'center', + }, + { + label: '调用时间', + field: 'createTime', + align: 'center', + width: 180, + }, +]; + +export const searchSchemas: FormSchema[] = [ + { + field: 'name', + component: 'Input', + label: '用户名', + componentProps: { + placeholder: '请输入用户名查询' + }, + colProps: { + span: 6 + } + }, + + +] diff --git a/src/views/ai/order/composables/index.ts b/src/views/ai/order/composables/index.ts new file mode 100644 index 0000000..aba3ae1 --- /dev/null +++ b/src/views/ai/order/composables/index.ts @@ -0,0 +1,39 @@ +import { ref, computed, onMounted } from 'vue' + +import type { TableColumn } from '@/types/table' +import { useTable } from '@/hooks/web/useTable' +import { dayjs } from 'element-plus' +import {page, del} from '@/api/new-ai/message' + +export default function () { + const searchParams = ref({}) + const { register, tableObject, methods } = useTable({ + getListApi:page, + defaultParams: searchParams.value, + delListApi:del + }) + + const handleSearch = (values: any) => { + methods.setSearchParams(values) + } + + const pagination = computed(() => { + return { + total: tableObject.total, + pageSize: tableObject.pageSize, + currentPage: tableObject.currentPage + } + }) + + onMounted(() => { + methods.getList() + }) + + return { + register, + handleSearch, + methods, + tableObject, + pagination + } +} diff --git a/src/views/ai/order/index.vue b/src/views/ai/order/index.vue new file mode 100644 index 0000000..c663a40 --- /dev/null +++ b/src/views/ai/order/index.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/src/views/common/AppSelect.vue b/src/views/common/AppSelect.vue new file mode 100644 index 0000000..35c2c16 --- /dev/null +++ b/src/views/common/AppSelect.vue @@ -0,0 +1,67 @@ + + + + + + + diff --git a/src/views/common/ModelSelect.vue b/src/views/common/ModelSelect.vue new file mode 100644 index 0000000..d15fd21 --- /dev/null +++ b/src/views/common/ModelSelect.vue @@ -0,0 +1,96 @@ + + + + + + + diff --git a/src/views/knowledge/components/create.vue b/src/views/knowledge/components/create.vue new file mode 100644 index 0000000..d4afe82 --- /dev/null +++ b/src/views/knowledge/components/create.vue @@ -0,0 +1,103 @@ + + + \ No newline at end of file diff --git a/src/views/knowledge/dataset-form/components/data-cut.vue b/src/views/knowledge/dataset-form/components/data-cut.vue new file mode 100644 index 0000000..41eb088 --- /dev/null +++ b/src/views/knowledge/dataset-form/components/data-cut.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/src/views/knowledge/dataset-form/components/data-document.vue b/src/views/knowledge/dataset-form/components/data-document.vue new file mode 100644 index 0000000..b3cd144 --- /dev/null +++ b/src/views/knowledge/dataset-form/components/data-document.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/views/knowledge/dataset-form/components/data-embedding.vue b/src/views/knowledge/dataset-form/components/data-embedding.vue new file mode 100644 index 0000000..30a420d --- /dev/null +++ b/src/views/knowledge/dataset-form/components/data-embedding.vue @@ -0,0 +1,79 @@ + + + + + + + diff --git a/src/views/knowledge/dataset-form/components/data-import.vue b/src/views/knowledge/dataset-form/components/data-import.vue new file mode 100644 index 0000000..aa32fb2 --- /dev/null +++ b/src/views/knowledge/dataset-form/components/data-import.vue @@ -0,0 +1,97 @@ + + + + + + diff --git a/src/views/knowledge/dataset-form/components/edit-doc.vue b/src/views/knowledge/dataset-form/components/edit-doc.vue new file mode 100644 index 0000000..5bf3890 --- /dev/null +++ b/src/views/knowledge/dataset-form/components/edit-doc.vue @@ -0,0 +1,117 @@ + + + + + + + diff --git a/src/views/knowledge/dataset-form/form-step1.vue b/src/views/knowledge/dataset-form/form-step1.vue deleted file mode 100644 index ef3579e..0000000 --- a/src/views/knowledge/dataset-form/form-step1.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - - - diff --git a/src/views/knowledge/dataset-form/form-step2.vue b/src/views/knowledge/dataset-form/form-step2.vue deleted file mode 100644 index f8ca571..0000000 --- a/src/views/knowledge/dataset-form/form-step2.vue +++ /dev/null @@ -1,168 +0,0 @@ - - - - - diff --git a/src/views/knowledge/dataset-form/index.vue b/src/views/knowledge/dataset-form/index.vue new file mode 100644 index 0000000..fe63642 --- /dev/null +++ b/src/views/knowledge/dataset-form/index.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/src/views/knowledge/dataset.vue b/src/views/knowledge/dataset.vue index 4636a91..7d58d65 100644 --- a/src/views/knowledge/dataset.vue +++ b/src/views/knowledge/dataset.vue @@ -1,7 +1,7 @@ -