diff --git a/cdTMP/components.json b/cdTMP/components.json new file mode 100644 index 0000000..d8c95c4 --- /dev/null +++ b/cdTMP/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "new-york", + "typescript": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/style/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "composables": "@/composables", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/cdTMP/package-lock.json b/cdTMP/package-lock.json index 776535e..cdc22ca 100644 --- a/cdTMP/package-lock.json +++ b/cdTMP/package-lock.json @@ -10,41 +10,46 @@ "dependencies": { "@arco-design/color": "^0.4.0", "@arco-design/web-vue": "^2.57.0", - "@tanstack/vue-query": "^5.74.5", + "@tanstack/vue-query": "^5.74.9", "@tinymce/tinymce-vue": "^6.1.0", "@vueuse/core": "^13.1.0", - "axios": "^1.8.4", + "axios": "^1.9.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "dayjs": "^1.11.13", "file2md5": "^1.3.0", "lodash-es": "^4.17.21", + "lucide-vue-next": "^0.503.0", "mammoth": "^1.9.0", "mitt": "^3.0.1", "nprogress": "^0.2.0", "pinia": "^3.0.2", - "pinyin-match": "^1.2.6", + "pinyin-match": "^1.2.7", "postcss-import": "^16.1.0", "qs": "^6.14.0", + "tailwind-merge": "^3.2.0", "tinymce": "^7.8.0", + "tw-animate-css": "^1.2.8", "vue": "^3.5.13", "vue-clipboard3": "^2.0.0", "vue-color-kit": "^1.0.6", - "vue-data-ui": "^2.6.40", - "vue-router": "^4.5.0", + "vue-data-ui": "^2.6.41", + "vue-router": "^4.5.1", "vuedraggable": "^2.24.3" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.4", "@tailwindcss/vite": "^4.1.4", "@types/lodash-es": "^4.17.12", - "@types/node": "^22.14.1", + "@types/node": "^22.15.3", "@types/nprogress": "^0.2.3", "@types/qs": "^6.9.18", "@vitejs/plugin-vue": "^5.2.3", "@vitejs/plugin-vue-jsx": "^4.1.2", "@vue/babel-plugin-jsx": "^1.4.0", "browserslist": "^4.24.4", - "eslint": "^9.25.0", - "eslint-plugin-vue": "^10.0.0", + "eslint": "^9.25.1", + "eslint-plugin-vue": "^10.0.1", "less": "^4.3.0", "less-loader": "^12.2.0", "postcss": "^8.5.3", @@ -52,7 +57,7 @@ "rollup-plugin-visualizer": "^5.14.0", "tailwindcss": "^4.1.4", "typescript": "^5.8.3", - "vite": "^6.3.2", + "vite": "^6.3.3", "vue-eslint-parser": "^10.1.3" } }, @@ -1019,9 +1024,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", + "version": "9.25.1", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-9.25.1.tgz", + "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==", "dev": true, "license": "MIT", "engines": { @@ -1753,9 +1758,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.74.4", - "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.74.4.tgz", - "integrity": "sha512-YuG0A0+3i9b2Gfo9fkmNnkUWh5+5cFhWBN0pJAHkHilTx6A0nv8kepkk4T4GRt4e5ahbtFj2eTtkiPcVU1xO4A==", + "version": "5.74.9", + "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.74.9.tgz", + "integrity": "sha512-qmjXpWyigDw4SfqdSBy24FzRvpBPXlaSbl92N77lcrL+yvVQLQkf0T6bQNbTxl9IEB/SvVFhhVZoIlQvFnNuuw==", "license": "MIT", "funding": { "type": "github", @@ -1763,13 +1768,13 @@ } }, "node_modules/@tanstack/vue-query": { - "version": "5.74.5", - "resolved": "https://registry.npmmirror.com/@tanstack/vue-query/-/vue-query-5.74.5.tgz", - "integrity": "sha512-1IvuUASQ3h5jbM+90AR4vIDDLxYyGA9Iefvzx9uQMDA4c5Gpd9ETKHZgSUvFM3sXw6k0tY3uHtllBf875OqOcQ==", + "version": "5.74.9", + "resolved": "https://registry.npmmirror.com/@tanstack/vue-query/-/vue-query-5.74.9.tgz", + "integrity": "sha512-iMZxrKfIiDdX9uNH8WusBZXq87lBL8v2UXhifYiBNH+BUPCaezP7gNv4TN7WAlHVSfAx0fsnMKLB5+D3GAspbA==", "license": "MIT", "dependencies": { "@tanstack/match-sorter-utils": "^8.19.4", - "@tanstack/query-core": "5.74.4", + "@tanstack/query-core": "5.74.9", "@vue/devtools-api": "^6.6.3", "vue-demi": "^0.14.10" }, @@ -1884,9 +1889,9 @@ } }, "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "version": "22.15.3", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.15.3.tgz", + "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", "dev": true, "license": "MIT", "dependencies": { @@ -2481,9 +2486,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -2657,6 +2662,18 @@ "node": ">=6.0" } }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmmirror.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, "node_modules/clipboard": { "version": "2.0.11", "resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz", @@ -2682,6 +2699,15 @@ "node": ">=12" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color": { "version": "3.2.1", "resolved": "https://registry.npmmirror.com/color/-/color-3.2.1.tgz", @@ -3023,9 +3049,9 @@ } }, "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", + "version": "9.25.1", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.25.1.tgz", + "integrity": "sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3035,7 +3061,7 @@ "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.13.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", + "@eslint/js": "9.25.1", "@eslint/plugin-kit": "^0.2.8", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -3084,9 +3110,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "10.0.0", - "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-10.0.0.tgz", - "integrity": "sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w==", + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-10.0.1.tgz", + "integrity": "sha512-A5dRYc3eQ5i2rJFBW8J6F69ur/H7YfYg+5SCg6v829FU0BhM4fUTrRVR2d4MdZgzw0ioJEk6otYHEAnoGFqO4A==", "dev": true, "license": "MIT", "dependencies": { @@ -3314,9 +3340,9 @@ "dev": true }, "node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "version": "6.4.4", + "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -4275,6 +4301,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-vue-next": { + "version": "0.503.0", + "resolved": "https://registry.npmmirror.com/lucide-vue-next/-/lucide-vue-next-0.503.0.tgz", + "integrity": "sha512-3MrtHIBdh4dPCUZDLxQnvmQ17UzUnBYgezUSIo87Laais8hOz6qIPllp0iG/uS/UIzk7bJxyZRzoZTW/gLSr4A==", + "license": "ISC", + "peerDependencies": { + "vue": ">=3.0.1" + } + }, "node_modules/magic-string": { "version": "0.30.11", "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz", @@ -4702,9 +4737,9 @@ } }, "node_modules/pinyin-match": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/pinyin-match/-/pinyin-match-1.2.6.tgz", - "integrity": "sha512-d9fMSwZujH7UlMu+FO8MGXrgUYv0CwJtzpf3fQ8xgLJy1qfXlzOZsnQuL7Ej7msAiEtt37U7bE4dkVmyWaFfwA==", + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/pinyin-match/-/pinyin-match-1.2.7.tgz", + "integrity": "sha512-RnypoF7OKgSKL8L4IayHmmHj9cHeked45TFAOffddcvpIIDrLcTSEJNruprE5otXCegBBqWm4YEi8JwMqToeig==", "license": "SATA" }, "node_modules/postcss": { @@ -5346,6 +5381,16 @@ "node": ">= 0.4" } }, + "node_modules/tailwind-merge": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/tailwind-merge/-/tailwind-merge-3.2.0.tgz", + "integrity": "sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "4.1.4", "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-4.1.4.tgz", @@ -5428,13 +5473,13 @@ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" }, "node_modules/tinyglobby": { - "version": "0.2.12", - "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.12.tgz", - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "version": "0.2.13", + "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2" }, "engines": { @@ -5456,6 +5501,15 @@ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", "dev": true }, + "node_modules/tw-animate-css": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/tw-animate-css/-/tw-animate-css-1.2.8.tgz", + "integrity": "sha512-AxSnYRvyFnAiZCUndS3zQZhNfV/B77ZhJ+O7d3K6wfg/jKJY+yv6ahuyXwnyaYA9UdLqnpCwhTRv9pPTBnPR2g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", @@ -5541,18 +5595,18 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/vite": { - "version": "6.3.2", - "resolved": "https://registry.npmmirror.com/vite/-/vite-6.3.2.tgz", - "integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==", + "version": "6.3.3", + "resolved": "https://registry.npmmirror.com/vite/-/vite-6.3.3.tgz", + "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", - "tinyglobby": "^0.2.12" + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -5654,9 +5708,9 @@ } }, "node_modules/vue-data-ui": { - "version": "2.6.40", - "resolved": "https://registry.npmmirror.com/vue-data-ui/-/vue-data-ui-2.6.40.tgz", - "integrity": "sha512-vd9Zy1WawOQAeqtpP7LE+nuqgaZ8RVc9ij+DxdsP6m7McKgG+cbse9Irk7nOQrQ0om6gZvZciCOyKKw4TKUzaw==", + "version": "2.6.41", + "resolved": "https://registry.npmmirror.com/vue-data-ui/-/vue-data-ui-2.6.41.tgz", + "integrity": "sha512-Sfy3TypoDvB14WpXk3UmlWCtXjUQjqNfxzy6gl+RJ2oGYqNY6LA2Xxun8428oxQ2CS3NaGTCinvddR+TDDd9pw==", "license": "MIT", "peerDependencies": { "vue": ">=3.3.0" @@ -5714,9 +5768,9 @@ } }, "node_modules/vue-router": { - "version": "4.5.0", - "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz", - "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "version": "4.5.1", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", "license": "MIT", "dependencies": { "@vue/devtools-api": "^6.6.4" diff --git a/cdTMP/package.json b/cdTMP/package.json index 93a4dc4..bd86ff0 100644 --- a/cdTMP/package.json +++ b/cdTMP/package.json @@ -13,41 +13,46 @@ "dependencies": { "@arco-design/color": "^0.4.0", "@arco-design/web-vue": "^2.57.0", - "@tanstack/vue-query": "^5.74.5", + "@tanstack/vue-query": "^5.74.9", "@tinymce/tinymce-vue": "^6.1.0", "@vueuse/core": "^13.1.0", - "axios": "^1.8.4", + "axios": "^1.9.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "dayjs": "^1.11.13", "file2md5": "^1.3.0", "lodash-es": "^4.17.21", + "lucide-vue-next": "^0.503.0", "mammoth": "^1.9.0", "mitt": "^3.0.1", "nprogress": "^0.2.0", "pinia": "^3.0.2", - "pinyin-match": "^1.2.6", + "pinyin-match": "^1.2.7", "postcss-import": "^16.1.0", "qs": "^6.14.0", + "tailwind-merge": "^3.2.0", "tinymce": "^7.8.0", + "tw-animate-css": "^1.2.8", "vue": "^3.5.13", "vue-clipboard3": "^2.0.0", "vue-color-kit": "^1.0.6", - "vue-data-ui": "^2.6.40", - "vue-router": "^4.5.0", + "vue-data-ui": "^2.6.41", + "vue-router": "^4.5.1", "vuedraggable": "^2.24.3" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.4", "@tailwindcss/vite": "^4.1.4", "@types/lodash-es": "^4.17.12", - "@types/node": "^22.14.1", + "@types/node": "^22.15.3", "@types/nprogress": "^0.2.3", "@types/qs": "^6.9.18", "@vitejs/plugin-vue": "^5.2.3", "@vitejs/plugin-vue-jsx": "^4.1.2", "@vue/babel-plugin-jsx": "^1.4.0", "browserslist": "^4.24.4", - "eslint": "^9.25.0", - "eslint-plugin-vue": "^10.0.0", + "eslint": "^9.25.1", + "eslint-plugin-vue": "^10.0.1", "less": "^4.3.0", "less-loader": "^12.2.0", "postcss": "^8.5.3", @@ -55,7 +60,7 @@ "rollup-plugin-visualizer": "^5.14.0", "tailwindcss": "^4.1.4", "typescript": "^5.8.3", - "vite": "^6.3.2", + "vite": "^6.3.3", "vue-eslint-parser": "^10.1.3" } } diff --git a/cdTMP/src/api/generate/bgGenerate.js b/cdTMP/src/api/generate/bgGenerate.js index f21cd31..8578925 100644 --- a/cdTMP/src/api/generate/bgGenerate.js +++ b/cdTMP/src/api/generate/bgGenerate.js @@ -143,6 +143,28 @@ export default { params }) }, + /** + * 生成-软件问题统计-2025年4月27日新增 + * @returns + */ + createProblemStatistics(params = {}) { + return request({ + url: `/generateBG/create/problem_statistics`, + method: "get", + params + }) + }, + /** + * 生成摸底清单-依据测试项 + * @returns + */ + createBgModiList(params = {}) { + return request({ + url: `/generateBG/create/modi_list`, + method: "get", + params + }) + }, /** * 删除output/bg中所有文件,防止之前数据干扰 * @returns diff --git a/cdTMP/src/api/generate/dgGenerate.js b/cdTMP/src/api/generate/dgGenerate.js index 89a0fb4..913a30a 100644 --- a/cdTMP/src/api/generate/dgGenerate.js +++ b/cdTMP/src/api/generate/dgGenerate.js @@ -22,6 +22,17 @@ export default { params }) }, + /** + * + * @returns 顶层技术依据文件 + */ + createTopFile(params = {}) { + return request({ + url: `/generate/create/top_file`, + method: "get", + params + }) + }, /** * * @returns 生成联系方式 @@ -55,17 +66,6 @@ export default { params }) }, - /** - * - * @returns 生成测评大纲-被测软件功能 - */ - createFuncList(params = {}) { - return request({ - url: `/generate/create/funcList`, - method: "get", - params - }) - }, /** * * @returns 生成测评大纲-测评对象的软件组成描述 @@ -88,17 +88,6 @@ export default { params }) }, - /** - * - * @returns 生成测评大纲-被测软件性能 - */ - createPerformance(params = {}) { - return request({ - url: `/generate/create/performance`, - method: "get", - params - }) - }, /** * * @returns 生成测评大纲-被测软件基本信息 @@ -318,5 +307,5 @@ export default { method: "get", params }) - }, + } } diff --git a/cdTMP/src/api/project/dut.js b/cdTMP/src/api/project/dut.js index e66b2fe..56195b6 100644 --- a/cdTMP/src/api/project/dut.js +++ b/cdTMP/src/api/project/dut.js @@ -1,4 +1,5 @@ import { request } from "@/api/request" +import { head } from "lodash-es" export default { /** diff --git a/cdTMP/src/assets/BingWallpaper.jpg b/cdTMP/src/assets/BingWallpaper.jpg deleted file mode 100644 index 499b5c8..0000000 Binary files a/cdTMP/src/assets/BingWallpaper.jpg and /dev/null differ diff --git a/cdTMP/src/components/UploadInput/index.vue b/cdTMP/src/components/UploadInput/index.vue new file mode 100644 index 0000000..c8710f3 --- /dev/null +++ b/cdTMP/src/components/UploadInput/index.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/cdTMP/src/components/ma-editor/index.vue b/cdTMP/src/components/ma-editor/index.vue index b786d60..7e2b4ff 100644 --- a/cdTMP/src/components/ma-editor/index.vue +++ b/cdTMP/src/components/ma-editor/index.vue @@ -57,7 +57,7 @@ const props = defineProps({ type: [String, Array], // 如果要取消粘贴只粘贴文本,需要用户加格式请加上pastetext default: - "undo redo aligncenter alignleft indent styleselect formatselect fontselect fontsizeselect removeformat" + "code undo redo aligncenter alignleft indent styleselect formatselect fontselect fontsizeselect removeformat" // 下面是备份配置: // default:"code undo redo restoredraft | paste | bold | aligncenter alignleft alignjustify indent | \ diff --git a/cdTMP/src/components/ma-upload/index.vue b/cdTMP/src/components/ma-upload/index.vue index b48defb..8e18de7 100644 --- a/cdTMP/src/components/ma-upload/index.vue +++ b/cdTMP/src/components/ma-upload/index.vue @@ -3,60 +3,65 @@ - @Link XXX --> diff --git a/cdTMP/src/components/ui/particles-bg/ParticlesBg.vue b/cdTMP/src/components/ui/particles-bg/ParticlesBg.vue new file mode 100644 index 0000000..380fb29 --- /dev/null +++ b/cdTMP/src/components/ui/particles-bg/ParticlesBg.vue @@ -0,0 +1,250 @@ + + + diff --git a/cdTMP/src/components/ui/particles-bg/index.ts b/cdTMP/src/components/ui/particles-bg/index.ts new file mode 100644 index 0000000..ced719b --- /dev/null +++ b/cdTMP/src/components/ui/particles-bg/index.ts @@ -0,0 +1 @@ +export { default as ParticlesBg } from './ParticlesBg.vue'; diff --git a/cdTMP/src/layout/treeHooks/mustSoDut.ts b/cdTMP/src/layout/treeHooks/mustSoDut.ts index a56e83f..c115fa1 100644 --- a/cdTMP/src/layout/treeHooks/mustSoDut.ts +++ b/cdTMP/src/layout/treeHooks/mustSoDut.ts @@ -39,31 +39,24 @@ const soDutColumn = ref([ rules: [{ required: true, message: "单位必选" }] }, { - title: "空行", - dataIndex: "black_line", + title: "总行数", + dataIndex: "total_lines", formType: "input-number", - rules: [{ required: true, message: "空行数必填" }], + rules: [{ required: true, message: "总行数必填" }], min: 0 }, { - title: "纯注释", - dataIndex: "comment_line", + title: "有效行数", + dataIndex: "effective_lines", formType: "input-number", - rules: [{ required: true, message: "纯注释数必填" }], + rules: [{ required: true, message: "有效行数必填" }], min: 0 }, { - title: "混合行", - dataIndex: "mix_line", + title: "注释行数", + dataIndex: "comment_lines", formType: "input-number", - rules: [{ required: true, message: "混合行必填" }], - min: 0 - }, - { - title: "纯代码", - dataIndex: "code_line", - formType: "input-number", - rules: [{ required: true, message: "纯代码行必填" }], + rules: [{ required: true, message: "注释行数必填" }], min: 0 } ]) diff --git a/cdTMP/src/layout/treeHooks/rightClick.js b/cdTMP/src/layout/treeHooks/rightClick.js index 7e9b022..b48123c 100644 --- a/cdTMP/src/layout/treeHooks/rightClick.js +++ b/cdTMP/src/layout/treeHooks/rightClick.js @@ -31,7 +31,11 @@ export function useRightClick(projectId, routeViewRef) { */ const displayRightMenu = (e) => { if (e.target) { - const { nodekey, level, title, isLeaf } = getContextNodeInfo(e.target) + const context = getContextNodeInfo(e.target) + if (!context) { + return + } + const { nodekey = undefined, level, title, isLeaf } = context // 如果是测试项则弹出【1.根据测试项步骤生成当前测试项用例 2.复制测试项到设计需求】 if (+level === 3) { e.preventDefault() diff --git a/cdTMP/src/lib/utils.ts b/cdTMP/src/lib/utils.ts new file mode 100644 index 0000000..d32b0fe --- /dev/null +++ b/cdTMP/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from 'clsx' +import { twMerge } from 'tailwind-merge' + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/cdTMP/src/style/index.css b/cdTMP/src/style/index.css index ef72b5f..66c9d9a 100644 --- a/cdTMP/src/style/index.css +++ b/cdTMP/src/style/index.css @@ -1,4 +1,9 @@ @import 'tailwindcss'; +@import "tw-animate-css"; +/* + ---break--- +*/ +@custom-variant dark (&:is(.dark *)); @config '../../tailwind.config.js'; @@ -20,3 +25,130 @@ border-color: var(--color-gray-200, currentColor); } } +/* + ---break--- +*/ +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} +/* + ---break--- +*/ +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} +/* + ---break--- +*/ +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.145 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.145 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: oklch(0.269 0 0); + --input: oklch(0.269 0 0); + --ring: oklch(0.439 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(0.269 0 0); + --sidebar-ring: oklch(0.439 0 0); +} +/* + ---break--- +*/ +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/cdTMP/src/views/login.vue b/cdTMP/src/views/login.vue index 498b929..eaccf60 100644 --- a/cdTMP/src/views/login.vue +++ b/cdTMP/src/views/login.vue @@ -1,6 +1,8 @@ diff --git a/cdTMP/src/views/project/dut/components/FileInputModal/useListOperation.ts b/cdTMP/src/views/project/dut/components/FileInputModal/useListOperation.ts new file mode 100644 index 0000000..7bae3f4 --- /dev/null +++ b/cdTMP/src/views/project/dut/components/FileInputModal/useListOperation.ts @@ -0,0 +1,39 @@ +import { ref } from "vue" + +const templateDemandObj = { + chapter: "", + title: "", + ident: "", + demandType: "", + content: "" +} + +export default function useListOperaton(htmlData: any) { + // 数据变化spin显示 + const loading = ref(false) + // 上方按钮:直接在最下新增一条 + const handleCreateAtLatest = () => { + const newDemand = JSON.parse(JSON.stringify(templateDemandObj)) + htmlData.value.push(newDemand) + } + // 上方按钮:重置数据,点击页面不卡段 + const handleResetData = () => { + htmlData.value = [] + } + // 点击单条右侧按钮:下方新增 - 深拷贝,并插入到下方 + const handledownCreate = (index: number) => { + const newDemand = JSON.parse(JSON.stringify(templateDemandObj)) + htmlData.value.splice(index + 1, 0, newDemand) + } + // 因为a-list限制必须知道当前页码和页容量 + const currentPage = ref(1) + const handlePageChange = (page) => { + currentPage.value = page + } + // 点击单条右侧按钮:删除 - 需要根据currentPage动态觉得因为a-list每页都是这样计算的 + const handleDelete = (index: number) => { + const currentIndex = index + (currentPage.value - 1) * 15 + htmlData.value.splice(currentIndex, 1) + } + return { loading, handleCreateAtLatest, handleResetData, handledownCreate, handlePageChange, handleDelete } +} diff --git a/cdTMP/src/views/project/dut/components/FileInputModal/useUpload.ts b/cdTMP/src/views/project/dut/components/FileInputModal/useUpload.ts new file mode 100644 index 0000000..9116172 --- /dev/null +++ b/cdTMP/src/views/project/dut/components/FileInputModal/useUpload.ts @@ -0,0 +1,130 @@ +import { ref } from "vue" +import { Message, Notification } from "@arco-design/web-vue" + +const templateDemandObj = { + chapter: "", + title: "", + ident: "", + demandType: "", + content: "" +} +// 判断是否为{"__type__": "image","format": "base64","data": "base64数据"} +function isImageObject(obj: any) { + return ( + obj !== null && + typeof obj === "object" && + !Array.isArray(obj) && + Object.hasOwn(obj, "__type__") && + Object.hasOwn(obj, "format") && + Object.hasOwn(obj, "data") + ) +} + +export default function useUpload(htmlData: any) { + const parseChapter = ref("") // 定义用户想解析的章节名称 + const selectValue = ref("1") // 定义选择框 + const handleUploadSuccess = (fileItem: any) => { + const data = fileItem.response.data + if (!data.children) { + Notification.error({ + content: "解析失败:请确认上传文件目录级别包含6以上;章节名称正确", + duration: 3000, + closable: true + }) + parseChapter.value = "" + return + } + // 这里就是解析出东西了 + const parsedData = getObjFromChapter(data) + if (parsedData) { + enterDemand(parsedData) + } + // 上传成功后清空解析章节名称 + parseChapter.value = "" + } + const handleUploadError = (fileItem: any) => { + console.log(fileItem.response) + } + const getObjFromChapter = (parseObj: any) => { + if (parseObj.title === parseChapter.value) return parseObj + if (Array.isArray(parseObj.children) && parseObj.children.length > 0) { + for (const child of parseObj.children) { + const found = getObjFromChapter(child) + if (found) return found // 递归返回obj或null + } + } + return null // 如果都没找到返回null + } + // 辅助函数:(递归)将parseObj转为templateDemandObj录入,递归录入 + const enterDemand = (parseObj: any) => { + // 下面是录入 + const demandObj = JSON.parse(JSON.stringify(templateDemandObj)) + demandObj.chapter = parseObj.number + demandObj.title = parseObj.title + demandObj.ident = parseObj.ordinal ? parseObj.ordinal : "" // 设计需求标识如果没有则为空 + demandObj.demandType = selectValue.value + // 解析数组,然后添加到内容中 + const content = formatContentForTinyMCE(JSON.parse(parseObj.content)) + demandObj.content = content + htmlData.value.push(demandObj) + // 如果有子对象,则再运行一次即可 + if (Array.isArray(parseObj.children) && parseObj.children.length > 0) { + for (const childObj of parseObj.children) { + enterDemand(childObj) + } + } + } + // 上面函数的辅助函数:将数组变为HTML给tinymce使用 + function formatContentForTinyMCE(data: any) { + let htmlContent = "" + // 处理普通文本行 + for (const item of data) { + // 如果是普通文本 + if (typeof item === "string") { + // 处理表头标记 + if (item.includes("见表") || item.includes("如表") || item.includes("如下表")) { + htmlContent += `

${item.replace(/见表\d+/, "见下表").replace(/见图\d+/, "见下图")}

` + } else if (item.includes("见图") || item.includes("如图") || item.includes("如下图")) { + htmlContent += `

${item.replace(/见图\d+/, "见下图").replace(/见表\d+/, "见下表")}

` + } else if (/表\d+/.test(item)) { + htmlContent += `` + } else if (/图\d+/.test(item)) { + htmlContent += `${item.replace(/图\d+/, "下图")}` + } else { + htmlContent += `

${item}

` + } + } + // 如果是对象(根据后端逻辑是图片) + else if (isImageObject(item)) { + // item现在是对象,其data是base64字符串 + htmlContent += `

` + } + // 处理表格数据 + else if (Array.isArray(item)) { + htmlContent += '' + // 处理表头 + const headers = item[0].split("\t") + htmlContent += "" + for (const header of headers) { + htmlContent += `` + } + htmlContent += "" + // 处理表格内容 + htmlContent += "" + for (let i = 1; i < item.length; i++) { + const cells = item[i].split("\t") + htmlContent += "" + for (const cell of cells) { + // 处理单元格内的换行符 + const formattedCell = cell.replace(/\n/g, "
") + htmlContent += `` + } + htmlContent += "" + } + htmlContent += "
${header}
${formattedCell}
" + } + } + return htmlContent + } + return { handleUploadSuccess, handleUploadError, parseChapter, selectValue } +} diff --git a/cdTMP/src/views/project/dut/index.vue b/cdTMP/src/views/project/dut/index.vue index 93cb19e..e4e3735 100644 --- a/cdTMP/src/views/project/dut/index.vue +++ b/cdTMP/src/views/project/dut/index.vue @@ -19,7 +19,7 @@ - + diff --git a/cdTMP/src/views/project/dut/tools/parseHtmlString.js b/cdTMP/src/views/project/dut/tools/parseHtmlString.js deleted file mode 100644 index 7ad7e11..0000000 --- a/cdTMP/src/views/project/dut/tools/parseHtmlString.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * 辅助函数,给每个h2增加个自定义属性,用来储存章节号,返回功能/接口h2节点对象【非DOM,有dom属性表示DOM】 - */ -function getNeedH2NodeList(h1h2Node) { - const h2ObjList = [] - // 首先将h1和h2节点都组成一个数组 - let h1Index = 0, - h2Index = 0 - h1h2Node.forEach((hDom) => { - if (hDom.tagName === "H1") { - // 找到h1,那么其index+1 - h1Index += 1 - h2Index = 0 - } else if (hDom.tagName === "H2") { - // 按顺序找到h2了, - h2Index += 1 - let h2Obj = { - chapter: h1Index + "." + h2Index, - dom: hDom, - text: hDom.innerText - } - h2ObjList.push(h2Obj) - } - }) - // 1.~~~~TODO:可以从这里修改识别范围~~~~ - return h2ObjList.filter( - (item) => - item.text.includes("CSCI功能需求") || - item.text.includes("CSCI外部接口需求") || - item.text.includes("CSCI能力需求") - ) -} - -/** - * 思路:因为mammoth解析后变为html字符串,使用new DOMParser()转换为DOM进行解析 - * 作用:创建DOMParser()对象,然后解析需求规格说明的html字符串,目前仅支持功能和接口需求 - * 返回:Array[Object[String,String]] - */ -export function parseHtmlStringByDemandDut(htmlString) { - const parser = new DOMParser() - const doc = parser.parseFromString(htmlString, "text/html") - const h1h2NodeList = doc.querySelectorAll("h1,h2") - // 这一步得到功能需求、接口需求的h2对象,里面有dom、text、chapter - const h2ObjArray = getNeedH2NodeList(h1h2NodeList) - // 这里开始就要获取全部有用信息: - // 2.遍历全部DOM - const allArray = Array.from(doc.body.children) - const demandArray = [] - let h2Index = 0 - let locker = false - // 3.将H3和H4的索引增加 - let currentH3ele = { - initChapter: "", - index: 0, - title: "", - ident: "", - isIn: false - } - let currentH4ele = { - initChapter: "", - index: 0, - title: "", - ident: "" - } - let adpterIndex = 0 - - allArray.forEach((element) => { - // 2.1.找到h2ObjArray的位置 - if (h2ObjArray[h2Index] && element === h2ObjArray[h2Index].dom) { - h2Index += 1 - currentH3ele.index = 0 - locker = true - } else if (element.tagName === "H1" || element.tagName === "H2") { - locker = false - } else if (locker && element.tagName !== "H2") { - // 就是从H3开始需求的 - if (element.tagName === "H3") { - // 按顺序解析到H3 - currentH3ele.index += 1 - currentH4ele.index = 0 - const splitString = element.innerText.split(/[(())]/) - currentH3ele.title = splitString[0] - currentH3ele.ident = splitString[1] ? splitString[1] : "" - currentH3ele.initChapter = h2ObjArray[h2Index - 1].chapter + "." + currentH3ele.index - // 将isIn变为true,说明当前解析在这里面 - currentH3ele.isIn = true - // 段落索引设置0 - adpterIndex = 0 - } else if (element.tagName === "H4") { - // 按顺序解析到H4 - currentH4ele.index += 1 - const splitString = element.innerText.split(/[(())]/) - currentH4ele.title = splitString[0] - currentH4ele.ident = splitString[1] ? splitString[1] : "" - // 将H3的isIn变为false,说明在H4里面不在H3了 - currentH3ele.isIn = false - // chapter - currentH4ele.initChapter = currentH3ele.initChapter + "." + currentH4ele.index - // 段落索引 - adpterIndex = 0 - } else { - // 当currentH3ele的title有值的时候开始解析 - if (currentH3ele.title) { - const demandObj = { - chapter: "", - title: "", - ident: "", - demandType: "", - content: "" - } - if (currentH3ele.isIn) { - demandObj.chapter = currentH3ele.initChapter - demandObj.title = currentH3ele.title - demandObj.ident = currentH3ele.ident - demandObj.demandType = demandObj.title.includes("接口") ? "3" : "1" - } else { - demandObj.chapter = currentH4ele.initChapter - demandObj.title = currentH4ele.title - demandObj.ident = currentH4ele.ident - demandObj.demandType = demandObj.title.includes("接口") ? "3" : "1" - } - // 1.解析table元素 - if (element.tagName === "TABLE") { - demandObj.content = element.outerHTML - adpterIndex += 1 - demandObj.ident = demandObj.ident + `-t${adpterIndex}` - demandArray.push(demandObj) - } - // 2.解析p元素-注意排除图片元素 - if (element.tagName === "P" && !element.querySelector("img")) { - demandObj.content = element.innerText - adpterIndex += 1 - demandObj.ident = demandObj.ident + `-p${adpterIndex}` - demandArray.push(demandObj) - } - // 3.解析ol和ul元素 - if (element.tagName === "OL" || element.tagName === "UL") { - demandObj.content = element.innerHTML - adpterIndex += 1 - demandObj.ident = demandObj.ident + `-u${adpterIndex}` - demandArray.push(demandObj) - } - } - } - } - }) - return demandArray -} diff --git a/cdTMP/src/views/project/dut/tools/parser.ts b/cdTMP/src/views/project/dut/tools/parser.ts deleted file mode 100644 index eb893b3..0000000 --- a/cdTMP/src/views/project/dut/tools/parser.ts +++ /dev/null @@ -1,174 +0,0 @@ -// 根据后端定义,不能更改的枚举 -enum DemandType { - gn = "1", - xn = "2", - jk = "3", - kkx = "4", - aqx = "5", - other = "6" -} - -// 数据每一项的结构 -interface DemandObj { - chapter: string - title: string - ident?: string // 如果其标题有()则放入 - demandType: DemandType - content: string -} - -// 定义h元素对象接口 -interface IHobj { - level: number // h1 -> 1 - title: string // 标题文字 - ident?: string // 如果有()则放入 - index: number // 该标题的索引,先map的时候不设置后续再排列 - demandType: DemandType -} - -// h元素对象带计算出的章节号的对象 -interface IHobjWithChapter extends IHobj { - chapter: string -} - -export class HtmlParser { - domArray: Element[] // 初始化得到一个元素的集合 - hWithChapter: IHobjWithChapter[] - constructor(htmlText: string) { - const parser = new DOMParser() - const doc = parser.parseFromString(htmlText, "text/html") - this.domArray = Array.from(doc.body.children) - // 解析domArray将h元素加入 - const HDomArray = this.domArray.filter((domItem) => domItem.tagName.startsWith("H")) - const storeArray: IHobj[] = [] - HDomArray.forEach((it, i) => { - !it.textContent && (it.textContent = "") - // 这里判断是什么类型的设计需求 -> 后续可以添加 - let type: DemandType = DemandType.gn - if (it.textContent.includes("接口")) { - type = DemandType.jk - } else if (it.textContent.includes("性能")) { - type = DemandType.xn - } else if (it.textContent.includes("可靠")) { - type = DemandType.kkx - } else if (it.textContent.includes("安全")) { - type = DemandType.aqx - } - // 获取章节号 - const level = +it.tagName.slice(1) - // 1.判断当前的章节级别的前一个级别的level是否一样/小于/大于 - let index = 0 - if (i > 0) { - // 找上一个标题对象的level - if (level === storeArray[i - 1].level) { - index = storeArray[i - 1].index + 1 - } else if (level < storeArray[i - 1].level) { - // 如果等级小于上一个标题对象,找storeArray里面level一样的长度 - for (let j = storeArray.length - 1; j >= 0; j--) { - if (storeArray[j].level === level) { - index = storeArray[j].index + 1 - break - } - } - } - } - storeArray.push({ - level: level, - title: it.textContent, - ident: it.textContent.match(/[\((](.*?)[\))]/)?.[1], - index: index, - demandType: type - }) - }) - // 直接将storeArray计算出章节号 - const chapterArray: any[] = storeArray.map((it, indx) => { - let str = it.index + 1 + "" - for (let i = it.level - 1; i > 0; i--) { - for (let j = indx - 1; j >= 0; j--) { - if (storeArray[j].level === i) { - str = storeArray[j].index + 1 + "." + str - break - } - } - } - return { - ...it, - chapter: str - } - }) - this.hWithChapter = chapterArray - } - /** - * 将所有Element元素遍历,输出列表格式 - */ - parseToArray(): DemandObj[] { - const resArr: DemandObj[] = [] - let index = 0 - let currentHElement: IHobjWithChapter = this.hWithChapter[index] - let adapterIndex: number = 1 - this.domArray.forEach((item) => { - // 1.如果循环到H元素,将其存入 - if (item.tagName.startsWith("H")) { - const text = item.textContent - if (text !== currentHElement.title) { - currentHElement = this.hWithChapter[index + 1] - index++ - adapterIndex = 1 - } - } else { - // 2.构造每一项放入 - chapter和content计算 - let content = "" - let ident = currentHElement.ident - if (!ident) { - ident = "" - } - // 这里对图片进行处理 - if (item.querySelector("img")) { - const img = item.querySelector("img") - if (img) { - const strblob = img.src + "" - const blob = strblob.split(",")[1] - content = `` - } - ident += `-g${adapterIndex}` - adapterIndex++ - resArr.push({ - chapter: currentHElement.chapter, - title: currentHElement.title, - ident: ident, - demandType: currentHElement.demandType, - content - }) - } else { - // 如果不是图片进行判断 - if (item.textContent) { - if (item.tagName === "TABLE") { - content = item.outerHTML - ident += `-t${adapterIndex}` - adapterIndex++ - } - if (item.tagName === "P" && !item.querySelector("img")) { - content = item.innerHTML.trim() - ident += `-p${adapterIndex}` - adapterIndex++ - } - if (item.tagName === "OL" || item.tagName === "UL") { - content = item.innerHTML.trim() - ident += `-u${adapterIndex}` - adapterIndex++ - } - // title要将括号去除 - resArr.push({ - chapter: currentHElement.chapter, - title: currentHElement.title, - ident: ident, - demandType: currentHElement.demandType, - content - }) - } - } - } - }) - return resArr - } -} diff --git a/cdTMP/src/views/project/round/beiceType.ts b/cdTMP/src/views/project/round/beiceType.ts index 287df86..b5b84a0 100644 --- a/cdTMP/src/views/project/round/beiceType.ts +++ b/cdTMP/src/views/project/round/beiceType.ts @@ -9,7 +9,7 @@ const beiceType: BeiceTypeT[] = [ { label: "设计说明", value: "SJ" }, { label: "需求文档", value: "XQ" }, { label: "通信协议", value: "XY" }, - { label: "研制总要求", value: "YZ" } + { label: "研制总要求/技术协议等", value: "YZ" } ] export default beiceType diff --git a/cdTMP/src/views/project/round/hooks/useColumn.ts b/cdTMP/src/views/project/round/hooks/useColumn.ts index 8070015..6b76894 100644 --- a/cdTMP/src/views/project/round/hooks/useColumn.ts +++ b/cdTMP/src/views/project/round/hooks/useColumn.ts @@ -1,6 +1,8 @@ -import { ref } from "vue" +import { ref, shallowRef } from "vue" import { useRoute } from "vue-router" import beiceType from "@/views/project/round/beiceType" +// 导入自定义组件 +import UploadInput from "@/components/UploadInput/index.vue" export default function (crudOrFormRef: any) { // global @@ -8,10 +10,8 @@ export default function (crudOrFormRef: any) { // 计算注释率计算crud/form的数据,判断 const calcPercent = () => { const formData = crudOrFormRef.value.getFormData() - const { code_line, comment_line, mix_line, black_line } = formData - const total_line = +black_line + +code_line + +comment_line + +mix_line - const comment_total = +comment_line + +mix_line - formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%` + const { total_lines, comment_lines } = formData + formData.comment_percent = `${(comment_lines / total_lines).toFixed(2).toString()}%` } const crudColumns = ref([ { @@ -51,28 +51,24 @@ export default function (crudOrFormRef: any) { translation: true, tagColors: { XQ: "blue", SO: "green", SJ: "orangered", XY: "pinkpurple", YZ: "red" } }, - onControl: (value) => { + onControl: (value: string) => { if (value === "SO") { return { - black_line: { display: true }, - code_line: { display: true }, - mix_line: { display: true }, - comment_line: { display: true }, - total_code_line: { display: true }, - total_line: { display: true }, + total_lines: { display: true }, + effective_lines: { display: true }, + comment_lines: { display: true }, comment_percent: { display: true }, + upload: { display: true }, release_date: { display: false } } } else { // 其他数据清除 return { - black_line: { display: false }, - code_line: { display: false }, - mix_line: { display: false }, - comment_line: { display: false }, - total_code_line: { display: false }, - total_line: { display: false }, + total_lines: { display: false }, + effective_lines: { display: false }, + comment_lines: { display: false }, comment_percent: { display: false }, + upload: { display: false }, release_date: { display: true } } } @@ -123,49 +119,36 @@ export default function (crudOrFormRef: any) { formType: "date" }, { - title: "空行", + title: "总行数", hide: true, align: "center", - dataIndex: "black_line", + dataIndex: "total_lines", formType: "input-number", - commonRules: [{ required: true, message: "空行数必填" }], + commonRules: [{ required: true, message: "总行数必填" }], min: 0, onControl: () => { calcPercent() } }, { - title: "纯代码行", + title: "有效行数", hide: true, align: "center", - dataIndex: "code_line", + dataIndex: "effective_lines", formType: "input-number", - commonRules: [{ required: true, message: "纯代码行数必填" }], + commonRules: [{ required: true, message: "有效行数必填" }], min: 0, onControl: () => { calcPercent() } }, { - title: "纯注释行", + title: "注释行数", hide: true, align: "center", - dataIndex: "comment_line", + dataIndex: "comment_lines", formType: "input-number", - commonRules: [{ required: true, message: "纯注释行数必填" }], - min: 0, - onControl: () => { - calcPercent() - } - }, - { - title: "混合行", - hide: true, - align: "center", - dataIndex: "mix_line", - formType: "input-number", - help: "混合行是指:代码中一行即包含代码也包含注释", - commonRules: [{ required: true, message: "混合行数必填" }], + commonRules: [{ required: true, message: "注释行数必填" }], min: 0, onControl: () => { calcPercent() @@ -180,6 +163,15 @@ export default function (crudOrFormRef: any) { addDisabled: true, editDisabled: true, disabled: true + }, + { + title: "上传源代码", + align: "center", + dataIndex: "upload", + placeholder: "上传源代码", + hide: true, + formType: "component", + component: shallowRef(UploadInput) } ]) return crudColumns diff --git a/cdTMP/src/views/project/testDemand/CaseSubForm/useOptions.ts b/cdTMP/src/views/project/testDemand/CaseSubForm/useOptions.ts index 638064e..9765f15 100644 --- a/cdTMP/src/views/project/testDemand/CaseSubForm/useOptions.ts +++ b/cdTMP/src/views/project/testDemand/CaseSubForm/useOptions.ts @@ -10,7 +10,78 @@ export default function useOptions(formRef: any) { }) const crudColumns = useColumn(formRef) const columnOptions = computed(() => { - return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules") + // 处理表单布局 + const transformColumns = tool.renameKeyInArray(crudColumns.value, "commonRules", "rules") + // 取出字段column对象 + const identColumn = transformColumns.find((item: any) => item.dataIndex === "ident") + const nameColumn = transformColumns.find((item: any) => item.dataIndex === "name") + const designPersonColumn = transformColumns.find((item: any) => item.dataIndex === "designPerson") + const testPersonColumn = transformColumns.find((item: any) => item.dataIndex === "testPerson") + const monitorPersonColumn = transformColumns.find((item: any) => item.dataIndex === "monitorPerson") + const summarizeColumn = transformColumns.find((item: any) => item.dataIndex === "summarize") + const initializationColumn = transformColumns.find((item: any) => item.dataIndex === "initialization") + const premiseColumn = transformColumns.find((item: any) => item.dataIndex === "premise") + const exe_timeColumn = transformColumns.find((item: any) => item.dataIndex === "exe_time") + // 组装表单布局 + const identAndNameColumn = { + formType: "grid", + cols: [ + { span: 12, formList: [identColumn] }, + { span: 12, formList: [nameColumn] } + ] + } + const cardColumn = { + formType: "card", + customClass: ["ml-5", "mb-3", "py-0", "px-0"], + title: "人员信息", + formList: [ + { + formType: "grid", + cols: [ + { span: 8, formList: [designPersonColumn] }, + { span: 8, formList: [testPersonColumn] }, + { span: 8, formList: [monitorPersonColumn] } + ] + } + ] + } + const summarizeColumnNew = { + formType: "grid", + cols: [{ span: 24, formList: [summarizeColumn] }] + } + const initializationColumnNew = { + formType: "grid", + cols: [{ span: 24, formList: [initializationColumn] }] + } + const premiseAndExeColumn = { + formType: "grid", + cols: [ + { span: 12, formList: [premiseColumn] }, + { span: 12, formList: [exe_timeColumn] } + ] + } + // 取除原数组里面的内容 + const newColumnsArray = transformColumns.filter( + (it: any) => + it.dataIndex !== "ident" && + it.dataIndex !== "name" && + it.dataIndex !== "designPerson" && + it.dataIndex !== "testPerson" && + it.dataIndex !== "monitorPerson" && + it.dataIndex !== "summarize" && + it.dataIndex !== "initialization" && + it.dataIndex !== "premise" && + it.dataIndex !== "exe_time" + ) + newColumnsArray.unshift( + identAndNameColumn, + cardColumn, + summarizeColumnNew, + initializationColumnNew, + premiseAndExeColumn + ) + return newColumnsArray }) + return { options, columnOptions } } diff --git a/cdTMP/src/views/project/testDemand/hooks/useColumn.tsx b/cdTMP/src/views/project/testDemand/hooks/useColumn.tsx index de6cd07..ee90c10 100644 --- a/cdTMP/src/views/project/testDemand/hooks/useColumn.tsx +++ b/cdTMP/src/views/project/testDemand/hooks/useColumn.tsx @@ -140,9 +140,20 @@ export default function (crudOrFormRef: any, problemFormRef?: any) { }, { title: "执行时间", + align: "center", dataIndex: "exe_time", + formType: "date", + customRender: ({ record }) => { + // 如果不存在exe_time则显示为“没有设置” + return record.exe_time ? record.exe_time : 未填写 + } + }, + { + title: "时序图(cpu不填写此字段)", hide: true, - formType: "date" + dataIndex: "timing_diagram", + addDefaultValue: "", + formType: "editor" }, { title: "测试步骤", diff --git a/cdTMP/src/views/project/testDemand/hooks/useCrudOpMore.ts b/cdTMP/src/views/project/testDemand/hooks/useCrudOpMore.ts index f64196d..421f97e 100644 --- a/cdTMP/src/views/project/testDemand/hooks/useCrudOpMore.ts +++ b/cdTMP/src/views/project/testDemand/hooks/useCrudOpMore.ts @@ -123,7 +123,7 @@ export default function (crudRef: Ref>) { }, { formType: "card", - customClass: ["ml-10", "mb-3", "py-0", "px-0"], + customClass: ["ml-5", "mb-3", "py-0", "px-0"], title: "人员信息", formList: [ { diff --git a/cdTMP/src/views/testmanage/projmanage/hooks/useGenerateSecond.ts b/cdTMP/src/views/testmanage/projmanage/hooks/useGenerateSecond.ts index b96d175..0bdea1c 100644 --- a/cdTMP/src/views/testmanage/projmanage/hooks/useGenerateSecond.ts +++ b/cdTMP/src/views/testmanage/projmanage/hooks/useGenerateSecond.ts @@ -32,14 +32,12 @@ const useGenerateSecond = function () { dgGenerateApi.createTechYiju({ id }), // 技术依据文件 dgGenerateApi.createContact({ id }), // 生成联系人和方式 dgGenerateApi.createTimeaddress({ id }), // 生成测评时间和地点 - dgGenerateApi.createFuncList({ id }), // 生成被测软件功能列表 dgGenerateApi.createSoftComposition({ id }), // 生成测评对象-软件组成 dgGenerateApi.createAdequacyEffectiveness({ id }), // 生成测试充分性(adequancy)和有效性(effectiveness)说明 dgGenerateApi.createGroup({ id }), // 生成测评组织及分工 dgGenerateApi.createGuarantee({ id }), // 生成测评保障 dgGenerateApi.createAbbreviation({ id }), // 生成缩略语 dgGenerateApi.createInterface({ id }), // 生成-被测软件接口 - dgGenerateApi.createPerformance({ id }), // 生成-被测软件性能 dgGenerateApi.createBaseInformation({ id }), // 生成-被测软件基本信息 dgGenerateApi.createLevelAndType({ id }), // 生成-测试级别和测试类型 -【修改】 dgGenerateApi.createStrategy({ id }), // 生成-测试策略 -【新增】 @@ -47,6 +45,8 @@ const useGenerateSecond = function () { dgGenerateApi.createXqComparison({ id }), // 生成-需求规格说明-测试项对照表 dgGenerateApi.createFanXqComparison({ id }), // 生成-反向测试项-需求规格说明对照表 dgGenerateApi.createCodeQuality({ id }), // 生成-代码质量度量分析表 + // 2025年4月29日新增 - 顶层技术文件 + dgGenerateApi.createTopFile({ id }), // 生成顶层技术文件 // 新增拆分接口 dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明 dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项 @@ -69,9 +69,7 @@ const useGenerateSecond = function () { isSmLoading.value = true await Promise.all([ dgGenerateApi.createSoftComposition({ id }), // 生成测评对象 - 和大纲一样 - dgGenerateApi.createFuncList({ id }), // 生成被测软件功能 - 和大纲重复 dgGenerateApi.createInterface({ id }), // 生成被测软件接口 - 和大纲重复 - 可能会删除 - dgGenerateApi.createPerformance({ id }), // 生成被测软件性能 - 和大纲重复 - 可能会删除 dgGenerateApi.createBaseInformation({ id }), // 生成被测软件基本信息 - 和大纲重复 - 可能会删除 dgGenerateApi.createYiju({ id }), // 生成标准类引用文档 - 和大纲重复 - 可能会删除 smGenerateApi.createSMTechyiju({ id }), // 生成技术类引用文档列表 -> 在大纲基础上添加《测评大纲》 @@ -97,7 +95,12 @@ const useGenerateSecond = function () { const createJLItem = async (id: number) => { isGenerating.value = true isJlloading.value = true - await jlGenerateApi.createJLcaserecord({ id }).finally(() => { + await Promise.all([ + // 生成-被测软件基本信息 - 和大纲一样 + dgGenerateApi.createBaseInformation({ id }), + // 记录相关片段 + jlGenerateApi.createJLcaserecord({ id }) + ]).finally(() => { isGenerating.value = false isJlloading.value = false }) @@ -116,7 +119,10 @@ const useGenerateSecond = function () { hsmGenerateApi.createCaseListDesc({ id }), hsmGenerateApi.createCaseList({ id }), hsmGenerateApi.createTrack({ id }), - // 拆分大纲软硬件环境 + // 拆分大纲软硬件环境-大纲内容 + dgGenerateApi.createSoftComposition({ id }), // 生成测评对象-软件组成 + dgGenerateApi.createYiju({ id }), // 生成依据文件 + dgGenerateApi.createInterface({ id }), // 生成-被测软件接口 - 和大纲一样 dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明 dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项 dgGenerateApi.createStaticHard({ id }), // 生成-静态硬件和固件项 @@ -171,7 +177,15 @@ const useGenerateSecond = function () { bgGenerateApi.createBgEntire({ id }), bgGenerateApi.createBgYzxqTrack({ id }), bgGenerateApi.createBgProblemsSummary({ id }), - // 拆分软硬件环境 + // 2025年4月27日新增:软件问题统计 + bgGenerateApi.createProblemStatistics({ id }), // 生成软件问题统计 + // 2025年4月28日新增:摸底清单 + bgGenerateApi.createBgModiList({ id }), // 生成摸底清单 + // 拆分软硬件环境-大纲内容 + dgGenerateApi.createSoftComposition({ id }), // 生成测评对象 - 大纲内容 + dgGenerateApi.createYiju({ id }), // 生成依据文件 + dgGenerateApi.createInterface({ id }), // 生成-被测软件接口 - 大纲内容 + dgGenerateApi.createAbbreviation({ id }), // 生成缩略语 - 大纲内容 dgGenerateApi.createStaticEnvironment({ id }), // 生成-静态测试环境说明 dgGenerateApi.createStaticSoft({ id }), // 生成-静态软件项 dgGenerateApi.createStaticHard({ id }), // 生成-静态硬件和固件项 @@ -179,7 +193,9 @@ const useGenerateSecond = function () { dgGenerateApi.createDynamicSoft({ id }), // 生成-动态软件项 dgGenerateApi.createDynamicHard({ id }), // 生成-动态硬件和固件项 dgGenerateApi.createTestData({ id }), // 生成-测评数据 - dgGenerateApi.createEnvDiff({ id }) // 生成-环境差异性分析 + dgGenerateApi.createEnvDiff({ id }), // 生成-环境差异性分析 + // 2025年4月29日新增 - 顶层技术文件 + dgGenerateApi.createTopFile({ id }) // 生成顶层技术文件 ]).finally(() => { isGenerating.value = false isBgLoading.value = false diff --git a/cdTMP/visualizer.html b/cdTMP/visualizer.html index 6fef6a5..e05f30e 100644 --- a/cdTMP/visualizer.html +++ b/cdTMP/visualizer.html @@ -4929,7 +4929,7 @@ var drawChart = (function (exports) {