双击打开详情修复

This commit is contained in:
2024-12-26 17:53:50 +08:00
parent 05a117152c
commit 2bd0de8c17
36 changed files with 815 additions and 750 deletions

205
cdTMP/package-lock.json generated
View File

@@ -1,21 +1,20 @@
{
"name": "cdtmp",
"version": "0.0.3",
"version": "0.0.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cdtmp",
"version": "0.0.3",
"version": "0.0.4",
"dependencies": {
"@arco-design/color": "^0.4.0",
"@arco-design/web-vue": "^2.56.3",
"@tanstack/vue-query": "^5.62.2",
"@tanstack/vue-query": "^5.62.9",
"@tinymce/tinymce-vue": "^6.1.0",
"@vueuse/core": "^12.0.0",
"@vueuse/core": "^12.2.0",
"axios": "^1.7.9",
"dayjs": "^1.11.13",
"echarts": "^5.5.1",
"file2md5": "^1.3.0",
"lodash-es": "^4.17.21",
"mammoth": "^1.8.0",
@@ -25,34 +24,34 @@
"pinyin-match": "^1.2.6",
"postcss-import": "^16.1.0",
"qs": "^6.13.1",
"tinymce": "^7.5.1",
"tinymce": "^7.6.0",
"vue": "^3.5.13",
"vue-clipboard3": "^2.0.0",
"vue-color-kit": "^1.0.6",
"vue-echarts": "^7.0.3",
"vue-data-ui": "^2.4.50",
"vue-router": "^4.5.0",
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.10.1",
"@types/node": "^22.10.2",
"@types/nprogress": "^0.2.3",
"@types/qs": "^6.9.17",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"@vue/babel-plugin-jsx": "^1.2.5",
"autoprefixer": "^10.4.20",
"browserslist": "^4.24.2",
"eslint": "^9.16.0",
"browserslist": "^4.24.3",
"eslint": "^9.17.0",
"eslint-plugin-vue": "^9.32.0",
"less": "^4.2.1",
"less-loader": "^12.2.0",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"rollup-plugin-visualizer": "^5.12.0",
"tailwindcss": "^3.4.16",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.2",
"vite": "^6.0.3"
"vite": "^6.0.5"
}
},
"node_modules/@alloc/quick-lru": {
@@ -81,6 +80,7 @@
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/@arco-design/color/-/color-0.4.0.tgz",
"integrity": "sha512-s7p9MSwJgHeL8DwcATaXvWT3m2SigKpxx4JA1BGPHL4gfvaQsmQfrLBDpjOJFJuJ2jG2dMt3R3P8Pm9E65q18g==",
"license": "MIT",
"dependencies": {
"color": "^3.1.3"
}
@@ -1013,9 +1013,9 @@
}
},
"node_modules/@eslint/js": {
"version": "9.16.0",
"resolved": "https://registry.npmmirror.com/@eslint/js/-/js-9.16.0.tgz",
"integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==",
"version": "9.17.0",
"resolved": "https://registry.npmmirror.com/@eslint/js/-/js-9.17.0.tgz",
"integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1584,9 +1584,9 @@
}
},
"node_modules/@tanstack/query-core": {
"version": "5.62.2",
"resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.62.2.tgz",
"integrity": "sha512-LcwVcC5qpsDpHcqlXUUL5o9SaOBwhNkGeV+B06s0GBoyBr8FqXPuXT29XzYXR36lchhnerp6XO+CWc84/vh7Zg==",
"version": "5.62.9",
"resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.62.9.tgz",
"integrity": "sha512-lwePd8hNYhyQ4nM/iRQ+Wz2cDtspGeZZHFZmCzHJ7mfKXt+9S301fULiY2IR2byJYY6Z03T427E5PoVfMexHjw==",
"license": "MIT",
"funding": {
"type": "github",
@@ -1594,13 +1594,13 @@
}
},
"node_modules/@tanstack/vue-query": {
"version": "5.62.2",
"resolved": "https://registry.npmmirror.com/@tanstack/vue-query/-/vue-query-5.62.2.tgz",
"integrity": "sha512-osmptKF+Ung+UFNgKDhOrQxmlZsRp0zATCz8ARTbcay20CCnv6rvBR/+LJlb/M9YGQU/chrt/nPIi1Ax+j0SUw==",
"version": "5.62.9",
"resolved": "https://registry.npmmirror.com/@tanstack/vue-query/-/vue-query-5.62.9.tgz",
"integrity": "sha512-L6soXGCGlMT5Xc/ToUNt7AGJjr6C8mc3gkASe1tDhPRyo4VoMcmnha+qf3yP4Uwd38bmZmohZwnBbuT3O3TvQA==",
"license": "MIT",
"dependencies": {
"@tanstack/match-sorter-utils": "^8.19.4",
"@tanstack/query-core": "5.62.2",
"@tanstack/query-core": "5.62.9",
"@vue/devtools-api": "^6.6.3",
"vue-demi": "^0.14.10"
},
@@ -1715,9 +1715,9 @@
}
},
"node_modules/@types/node": {
"version": "22.10.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.1.tgz",
"integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
"version": "22.10.2",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.2.tgz",
"integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1934,14 +1934,14 @@
"license": "MIT"
},
"node_modules/@vueuse/core": {
"version": "12.0.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-12.0.0.tgz",
"integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==",
"version": "12.2.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-12.2.0.tgz",
"integrity": "sha512-jksyNu+5EGwggNkRWd6xX+8qBkYbmrwdFQMgCABsz+wq8bKF6w3soPFLB8vocFp3wFIzn0OYkSPM9JP+AFKwsg==",
"license": "MIT",
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "12.0.0",
"@vueuse/shared": "12.0.0",
"@vueuse/metadata": "12.2.0",
"@vueuse/shared": "12.2.0",
"vue": "^3.5.13"
},
"funding": {
@@ -1949,18 +1949,18 @@
}
},
"node_modules/@vueuse/metadata": {
"version": "12.0.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-12.0.0.tgz",
"integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==",
"version": "12.2.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-12.2.0.tgz",
"integrity": "sha512-x6zynZtTh1l52m0y8d/EgzpshnMjg8cNZ2KWoncJ62Z5qPSGoc4FUunmMVrrRM/I/5542rTEY89CGftngZvrkQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "12.0.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-12.0.0.tgz",
"integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==",
"version": "12.2.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-12.2.0.tgz",
"integrity": "sha512-SRr4AZwv/giS+EmyA1ZIzn3/iALjjnWAGaBNmoDTMEob9JwQaevAocuaMDnPAvU7Z35Y5g3CFRusCWgp1gVJ3Q==",
"license": "MIT",
"dependencies": {
"vue": "^3.5.13"
@@ -2428,9 +2428,9 @@
}
},
"node_modules/browserslist": {
"version": "4.24.2",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.2.tgz",
"integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==",
"version": "4.24.3",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.3.tgz",
"integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
"dev": true,
"funding": [
{
@@ -2448,9 +2448,9 @@
],
"license": "MIT",
"dependencies": {
"caniuse-lite": "^1.0.30001669",
"electron-to-chromium": "^1.5.41",
"node-releases": "^2.0.18",
"caniuse-lite": "^1.0.30001688",
"electron-to-chromium": "^1.5.73",
"node-releases": "^2.0.19",
"update-browserslist-db": "^1.1.1"
},
"bin": {
@@ -2507,9 +2507,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001684",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz",
"integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==",
"version": "1.0.30001688",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz",
"integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==",
"dev": true,
"funding": [
{
@@ -2686,9 +2686,9 @@
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cross-spawn": {
"version": "7.0.5",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.5.tgz",
"integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==",
"version": "7.0.6",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2819,20 +2819,10 @@
"dev": true,
"license": "MIT"
},
"node_modules/echarts": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
"integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "2.3.0",
"zrender": "5.6.0"
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.41",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.41.tgz",
"integrity": "sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==",
"version": "1.5.73",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz",
"integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==",
"dev": true,
"license": "ISC"
},
@@ -2963,9 +2953,9 @@
}
},
"node_modules/eslint": {
"version": "9.16.0",
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.16.0.tgz",
"integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==",
"version": "9.17.0",
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.17.0.tgz",
"integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2974,7 +2964,7 @@
"@eslint/config-array": "^0.19.0",
"@eslint/core": "^0.9.0",
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "9.16.0",
"@eslint/js": "9.17.0",
"@eslint/plugin-kit": "^0.2.3",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
@@ -2983,7 +2973,7 @@
"@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.5",
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.2.0",
@@ -4429,9 +4419,9 @@
"peer": true
},
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.18.tgz",
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
"version": "2.0.19",
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true,
"license": "MIT"
},
@@ -5476,9 +5466,9 @@
"dev": true
},
"node_modules/tailwindcss": {
"version": "3.4.16",
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.16.tgz",
"integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==",
"version": "3.4.17",
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.17.tgz",
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5631,9 +5621,9 @@
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"node_modules/tinymce": {
"version": "7.5.1",
"resolved": "https://registry.npmmirror.com/tinymce/-/tinymce-7.5.1.tgz",
"integrity": "sha512-GRXJUB0BEIOUHUEC+q9IjsgWGIAQ4Tn5t5hfpB/YR7No3oPgKHG03v1d3nbov9aqdyVW7Be+UD4I3ZerQG30VQ==",
"version": "7.6.0",
"resolved": "https://registry.npmmirror.com/tinymce/-/tinymce-7.6.0.tgz",
"integrity": "sha512-kUrklnD7H8JbpSDEGRh51GKK6Mrf+pR9neSDzUHvXKV+2oRtMB7sqfAtEOnM0/WKdstwaX0qoNCZNo2H1Y0EFA==",
"license": "GPL-2.0-or-later"
},
"node_modules/to-regex-range": {
@@ -5659,7 +5649,8 @@
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"dev": true
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -5754,13 +5745,13 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/vite": {
"version": "6.0.3",
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.3.tgz",
"integrity": "sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==",
"version": "6.0.5",
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.5.tgz",
"integrity": "sha512-akD5IAH/ID5imgue2DYhzsEwCi0/4VKY31uhMLEYJwPP4TiUp8pL5PIK+Wo7H8qT8JY9i+pVfPydcFPYD1EL7g==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.24.0",
"esbuild": "0.24.0",
"postcss": "^8.4.49",
"rollup": "^4.23.0"
},
@@ -5863,46 +5854,11 @@
"vue": "^3.0.5"
}
},
"node_modules/vue-echarts": {
"version": "7.0.3",
"resolved": "https://registry.npmmirror.com/vue-echarts/-/vue-echarts-7.0.3.tgz",
"integrity": "sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==",
"license": "MIT",
"dependencies": {
"vue-demi": "^0.13.11"
},
"peerDependencies": {
"@vue/runtime-core": "^3.0.0",
"echarts": "^5.5.1",
"vue": "^2.7.0 || ^3.1.1"
},
"peerDependenciesMeta": {
"@vue/runtime-core": {
"optional": true
}
}
},
"node_modules/vue-echarts/node_modules/vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
"node_modules/vue-data-ui": {
"version": "2.4.50",
"resolved": "https://registry.npmmirror.com/vue-data-ui/-/vue-data-ui-2.4.50.tgz",
"integrity": "sha512-6QMApKXfLIaaYCAsWIcWrfdoHb8yv12iEEzpeNmcN8+puXEL3MzFvBzwdkItdImCJ6b1sdlR6UDGUwmmwza9Pw==",
"license": "MIT"
},
"node_modules/vue-eslint-parser": {
"version": "9.4.3",
@@ -6210,15 +6166,6 @@
"engines": {
"node": ">=10"
}
},
"node_modules/zrender": {
"version": "5.6.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
"integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
"license": "BSD-3-Clause",
"dependencies": {
"tslib": "2.3.0"
}
}
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "cdtmp",
"private": true,
"version": "0.0.3",
"version": "0.0.4",
"type": "module",
"scripts": {
"dev": "vite",
@@ -13,12 +13,11 @@
"dependencies": {
"@arco-design/color": "^0.4.0",
"@arco-design/web-vue": "^2.56.3",
"@tanstack/vue-query": "^5.62.2",
"@tanstack/vue-query": "^5.62.9",
"@tinymce/tinymce-vue": "^6.1.0",
"@vueuse/core": "^12.0.0",
"@vueuse/core": "^12.2.0",
"axios": "^1.7.9",
"dayjs": "^1.11.13",
"echarts": "^5.5.1",
"file2md5": "^1.3.0",
"lodash-es": "^4.17.21",
"mammoth": "^1.8.0",
@@ -28,33 +27,33 @@
"pinyin-match": "^1.2.6",
"postcss-import": "^16.1.0",
"qs": "^6.13.1",
"tinymce": "^7.5.1",
"tinymce": "^7.6.0",
"vue": "^3.5.13",
"vue-clipboard3": "^2.0.0",
"vue-color-kit": "^1.0.6",
"vue-echarts": "^7.0.3",
"vue-data-ui": "^2.4.50",
"vue-router": "^4.5.0",
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.10.1",
"@types/node": "^22.10.2",
"@types/nprogress": "^0.2.3",
"@types/qs": "^6.9.17",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"@vue/babel-plugin-jsx": "^1.2.5",
"autoprefixer": "^10.4.20",
"browserslist": "^4.24.2",
"eslint": "^9.16.0",
"browserslist": "^4.24.3",
"eslint": "^9.17.0",
"eslint-plugin-vue": "^9.32.0",
"less": "^4.2.1",
"less-loader": "^12.2.0",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"rollup-plugin-visualizer": "^5.12.0",
"tailwindcss": "^3.4.16",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.2",
"vite": "^6.0.3"
"vite": "^6.0.5"
}
}

View File

@@ -200,11 +200,22 @@ export default {
},
/**
*
* @returns 生成测评大纲-测试总体要求
* @returns 生成测评大纲-测试级别和测试类型
*/
createRequirement(params = {}) {
createLevelAndType(params = {}) {
return request({
url: `/generate/create/requirement`,
url: `/generate/create/levelAndType`,
method: "get",
params
})
},
/**
*
* @returns 生成测评大纲-测试策略
*/
createStrategy(params = {}) {
return request({
url: `/generate/create/strategy`,
method: "get",
params
})

View File

@@ -12,6 +12,17 @@ export default {
params
})
},
/**
* 根据项目id、round信息请求dut
* @returns dut数据
*/
getDutOne(params = {}) {
return request({
url: `/project/getDutOne`,
method: "get",
params
})
},
/**
* 添加被测件
* @returns

View File

@@ -1,21 +1,7 @@
/**
* 所属产品文档名称的enum
*/
export enum FragBelongDoc {
dg = "大纲",
sm = "说明",
jl = "记录",
hsm = "回归说明",
hjl = "回归记录",
bg = "报告",
wtd = "问题单"
}
/**
* 接口:文档片段查询条件
*/
export interface IFragSearchCondition {
belongDocName?: FragBelongDoc
name?: string
is_main?: boolean
projectId?: string

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -1,17 +1,5 @@
import { use } from "echarts/core"
import { CanvasRenderer } from "echarts/renderers"
import { BarChart, LineChart, PieChart, RadarChart, GaugeChart } from "echarts/charts"
import {
GridComponent,
TooltipComponent,
LegendComponent,
DataZoomComponent,
GraphicComponent
} from "echarts/components"
import MaCrud from "./ma-crud/index.vue"
import MaForm from "./ma-form/index.vue"
import MaChart from "./ma-charts/index.vue"
import MaUpload from "./ma-upload/index.vue"
import MaTreeSlider from "./ma-treeSlider/index.vue"
import MaResource from "./ma-resource/index.vue"
@@ -20,27 +8,11 @@ import MaUser from "./ma-user/index.vue"
import MaEditor from "./ma-editor/index.vue"
import MaIcon from "./ma-icon/index.vue"
import MaUserInfo from "./ma-userInfo/index.vue"
import "echarts/dist/echarts.esm.min.mjs"
// 后续增加的全局组件
import Empty from "./Empty/index.vue"
use([
CanvasRenderer,
BarChart,
LineChart,
PieChart,
RadarChart,
GaugeChart,
GridComponent,
TooltipComponent,
LegendComponent,
DataZoomComponent,
GraphicComponent
])
export default {
install(Vue) {
Vue.component("MaChart", MaChart)
Vue.component("MaCrud", MaCrud)
Vue.component("MaForm", MaForm)
Vue.component("MaUpload", MaUpload)

View File

@@ -1,48 +0,0 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<v-charts v-if="renderChart" :option="options" :autoresize="autoresize" :style="{ width, height }" />
</template>
<script setup>
import { ref, computed, nextTick } from "vue"
import VCharts from "vue-echarts"
import { useAppStore } from "@/store"
const props = defineProps({
options: {
type: Object,
default() {
return {}
}
},
autoresize: {
type: Boolean,
default: true
},
width: {
type: String,
default: "100%"
},
height: {
type: String,
default: "100%"
}
})
const appStore = useAppStore()
let mode = computed(() => {
return appStore.mode === "dark" ? "dark" : "auto"
})
const renderChart = ref(false)
nextTick(() => {
renderChart.value = true
})
</script>
<style scoped lang="less"></style>

View File

@@ -13,7 +13,7 @@
>
测试管理平台
</a-typography-title>
<a-typography-title :heading="6" class="version">V0.0.3</a-typography-title>
<a-typography-title :heading="6" class="version">V0.0.4</a-typography-title>
<icon-menu-fold
v-if="!topMenu && appStore.device === 'mobile'"
style="font-size: 22px; cursor: pointer"

View File

@@ -20,14 +20,13 @@ import Empty from "@/components/Empty/index.vue"
// 获取缓存列表
const tabBarStore = useTabBarStore()
const cacheList = computed(() => tabBarStore.getCacheList)
// 调用router-view组件的刷新方法
const viewChildRef = ref()
// 调用router-view组件的刷新方法 - 并暴露给子节点
const viewChildRef = ref(null)
const refresh = () => {
try {
viewChildRef.value.refreshCrudTable()
} catch (err) {
console.log("无法找到router-view动态组件的刷新函数")
} finally {
}
}
defineExpose({ refresh })

View File

@@ -231,6 +231,8 @@
></roundRight>
<!-- w2:轮次的问题单ma-crud这里要传参2个首先是请求另外一个接口然后取消是否关联字段 -->
<problem-choose ref="problemRoundRef" hasRelated="roundProblem" :title="problemTitle"></problem-choose>
<!-- 下面都是对应被测件设计需求测试项测试用例问题单的SubForm -->
<DutSubForm ref="dutSubFormRef"></DutSubForm>
</template>
<script setup>
@@ -246,6 +248,8 @@ import { useRoute } from "vue-router"
import { useTreeDataStore } from "@/store"
import { storeToRefs } from "pinia"
import Progress from "@/views/testmanage/projmanage/cpns/progress.vue"
// 导入单独节点类型单独对应的Modal组件
import DutSubForm from "@/views/project/round/DutSubForm"
// hooks模块化
import useTreeDrag from "@/layout/treeHooks/treeDrag.js"
import { useRightClick } from "./treeHooks/rightClick"
@@ -258,6 +262,7 @@ import useLoadTreeNode from "./treeHooks/useLoadTreeNodes"
import useRoundMaForm from "./treeHooks/useRoundMaForm"
// router-view里面组件的ref -> 多个hook使用
const routeViewRef = ref()
provide("rightViewRef", routeViewRef)
const treeDataStore = useTreeDataStore()
const { treeData, currentNode } = storeToRefs(treeDataStore)
const route = useRoute()
@@ -291,7 +296,7 @@ const {
const { expandedKeys, toggleExpanded } = useNodeExpand()
//~~~~~~大功能:单击/双击节点逻辑~~~~~~
const { selectedKeys, pointNode } = useNodeClick(expandedKeys)
const { selectedKeys, pointNode, dutSubFormRef } = useNodeClick(expandedKeys)
//~~~~~~大功能动态加载a-tree节点函数~~~~~~
const { loadMore } = useLoadTreeNode()

View File

@@ -59,7 +59,7 @@ export default function useTreeDrag(projectId, routeViewRef) {
}
}
}
// a-tree是否运行拖拽
// a-tree是否允许拖拽节点
const allowdrop = (options) => {
if (options.dropNode.level === "4" || options.dropNode.level === "3") {
return true

View File

@@ -5,7 +5,6 @@ export default function useLoadTreeNode() {
// global
const route = useRoute()
const projectInfo = ref({ ...route.query })
// Events
const loadMore = (nodeData) => {
if (nodeData.level == "0") {

View File

@@ -4,6 +4,8 @@ import { useRoute } from "vue-router"
import { useTreeDataStore } from "@/store"
import { storeToRefs } from "pinia"
import { useRouter } from "vue-router"
// 导入组件用于类型
import type { DutSubFormInstance } from "@/views/project/round/DutSubForm"
export default function useNodeClick(expandedKeys: Ref<string[]>) {
// global
const route = useRoute()
@@ -17,8 +19,10 @@ export default function useNodeClick(expandedKeys: Ref<string[]>) {
// refs
const selectedKeys = ref<any>([]) // 中间变量用于判断
const previousKey = ref<any>() // 上一次点击
// 点击事件
const pointNode = (value, data) => {
// SubFormRefs
const dutSubFormRef = ref<DutSubFormInstance | null>(null)
// 点击节点事件
const pointNode = (value: any, data: any) => {
// 获取处理单击不选中,双击选中的变量
let catch_selected_key = selectedKeys.value
selectedKeys.value = previousKey.value
@@ -39,28 +43,12 @@ export default function useNodeClick(expandedKeys: Ref<string[]>) {
})
}
if (data.node.level == "1") {
projectApi.getDemandInfo(projectInfo.value.id, data.node.key, data.node.level).then((res) => {
data.node.children = res.data
if (!expandedKeys.value.includes(value[0])) {
expandedKeys.value.push(value[0])
}
})
// 打开弹窗
dutSubFormRef.value!.open(data.node)
}
if (data.node.level == "2") {
projectApi.getTestInfo(projectInfo.value.id, data.node.key, data.node.level).then((res) => {
data.node.children = res.data
if (!expandedKeys.value.includes(value[0])) {
expandedKeys.value.push(value[0])
}
})
}
if (data.node.level == "3") {
projectApi.getCaseInfo(projectInfo.value.id, data.node.key, data.node.level).then((res) => {
data.node.children = res.data
if (!expandedKeys.value.includes(value[0])) {
expandedKeys.value.push(value[0])
}
})
}
count = 0
if (timerId) clearTimeout(timerId)
@@ -98,6 +86,7 @@ export default function useNodeClick(expandedKeys: Ref<string[]>) {
}
return {
selectedKeys,
pointNode
pointNode,
dutSubFormRef
}
}

View File

@@ -5,18 +5,19 @@ import globalComponents from "@/components"
import App from "./App.vue"
import router from "./router"
import pinia from "@/store"
// arcodesign的样式全局引入
import "@arco-design/web-vue/dist/arco.css"
// 导入全局样式
import "@/style/skin.less"
import "@/style/index.css"
import "@/style/global.less"
// 导入vue-data-ui样式
import "vue-data-ui/style.css"
// 读取package.json打印个软件名称和版本
import tool from "@/utils/tool"
import packageJson from "../package.json"
// 启动app之前
// Before App Started
const app = createApp(App)
app.use(ArcoVue, {})
app.use(ArcoVueIcon)
@@ -29,7 +30,7 @@ app.use(VueQueryPlugin)
import directives from "@/directives"
app.use(directives)
// 注册ma-icon图标
// 注册ma图标
const modules = import.meta.glob("./assets/ma-icons/*.vue", { eager: true })
for (const path in modules) {
const name = path.match(/([A-Za-z0-9_-]+)/g)![2]
@@ -43,5 +44,5 @@ app.config.globalProperties.$title = import.meta.env.VITE_APP_TITLE
app.config.globalProperties.$url = import.meta.env.VITE_APP_BASE
app.mount("#app")
// 无用的东西:下面就打印一个东西
// show version tag in console
tool.capsule("TestManagePlant", `v${packageJson.version} debug`)

View File

@@ -60,7 +60,7 @@ const useTreeDataStore = defineStore("treeDataStore", {
temp.pop(-1)
let roundKey = temp[0]
const nodeKey = temp.join("-")
const res = await projectApi.getDutInfo(projrctId, nodeKey, "0")
const res = await projectApi.getDutInfo(projrctId, nodeKey, "0") // nodeKey:'0'
this.treeData[roundKey].children = res.data
},
// 新增删除designDemand后tree显示-注意传的是测试项的key

View File

@@ -1,6 +1,8 @@
// 先导入arco的样式-里面有变量
@import "@arco-design/web-vue/dist/arco.css";
@import "dark.less";
@import "animation.less";
// 导入自己的样式覆盖
// 导入自己的样式覆盖原有的变量
@import "warp.less";
@@ -8,6 +10,7 @@ html,
body {
height: 100%;
}
.arco-layout-sider-children {
overflow-x: hidden;
}
@@ -15,6 +18,7 @@ body {
.arco-switch {
background-color: var(--color-fill-4);
}
.arco-switch-checked {
background-color: rgb(var(--primary-6));
}
@@ -51,6 +55,7 @@ body {
.layout-columns-right-panel {
width: 100%;
background-color: var(--color-neutral-2);
.layout-header {
background-color: var(--color-bg-2);
width: 100%;
@@ -62,6 +67,7 @@ body {
height: 52px;
border-bottom: 1px solid var(--color-border-1);
background-color: var(--color-bg-2);
.logo {
width: 220px;
padding-bottom: 1px;
@@ -87,12 +93,14 @@ body {
.banner-menus li:hover {
background-color: var(--color-neutral-2);
}
.banner-menus li.active {
background-color: rgb(var(--primary-4));
color: var(--color-white);
fill: var(--color-white);
}
}
.layout-banner-content {
.tags {
border-top: 0;
@@ -102,6 +110,7 @@ body {
.layout-classic-sider {
box-shadow: none;
}
.layout-classic-header {
.layout-classic-header-container {
background-color: var(--color-bg-2);
@@ -113,7 +122,8 @@ body {
.backend-setting .arco-drawer-body::-webkit-scrollbar,
.arco-list::-webkit-scrollbar,
.customer-scrollbar::-webkit-scrollbar {
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
width: 6px;
/*高宽分别对应横竖滚动条的尺寸*/
height: 7px;
}
@@ -124,6 +134,7 @@ body {
border-radius: 2px;
background: var(--color-text-4);
}
.ma-menu .arco-menu-inner::-webkit-scrollbar-thumb:hover,
.backend-setting .arco-drawer-body::-webkit-scrollbar-thumb:hover,
.arco-list::-webkit-scrollbar-thumb:hover,
@@ -131,6 +142,7 @@ body {
border-radius: 2px;
background: var(--color-text-3);
}
.ma-menu .arco-menu-inner::-webkit-scrollbar-track,
.backend-setting .arco-drawer-body::-webkit-scrollbar-track,
.arco-list::-webkit-scrollbar-track,
@@ -142,6 +154,7 @@ body {
.tags-container {
background-color: var(--color-bg-2);
border-top: 1px solid var(--color-border-1);
.tags {
border-bottom: 1px solid var(--color-border-1);
background-color: var(--color-bg-2);
@@ -151,6 +164,7 @@ body {
display: flex;
overflow: hidden;
width: 100%;
a {
background: var(--color-fill-3);
color: var(--color-text-2);
@@ -185,9 +199,11 @@ body {
a.active {
background: rgb(var(--primary-6));
color: var(--color-white);
.tag-icon {
color: var(--color-white);
}
.tag-icon:hover {
color: rgb(var(--primary-4));
background-color: var(--color-bg-2);
@@ -217,10 +233,12 @@ body {
color: var(--color-text-2);
font-size: 13px;
}
li:hover {
background-color: rgb(var(--primary-1));
cursor: pointer;
}
li.disabled {
color: var(--color-text-4);
cursor: no-drop;
@@ -233,6 +251,7 @@ body {
color: var(--color-text-2);
height: 100%;
overflow-y: auto;
.content-block-title {
color: var(--color-text-1);
font-size: 1.3em;
@@ -249,6 +268,7 @@ body {
bottom: 30px;
left: 20px;
z-index: 100;
.button-trigger {
display: flex;
align-items: center;
@@ -260,13 +280,16 @@ body {
border-radius: 50%;
cursor: pointer;
transition: all 0.1s;
:deep(.icon) {
margin-left: 1px !important;
}
}
.button-trigger:nth-child(1) {
background-color: var(--color-primary-light-4);
}
.button-trigger:nth-child(1).button-trigger-active {
background-color: rgb(var(--primary-6));
}
@@ -276,6 +299,7 @@ body {
.max-size-exit {
display: block;
}
.ma-ui-slider,
.ma-ui-header,
.ma-ui-menu,
@@ -303,6 +327,7 @@ body {
background: rgba(0, 0, 0, 0.2);
transition: all 0.3s;
}
.max-size-exit:hover {
top: 0px;
}

View File

@@ -5,3 +5,11 @@
height: 100%;
}
}
// 覆盖arco的圆角设置原来设置是0、2px、4px、6px
body {
--border-radius-none: 0;
--border-radius-small: 0px;
--border-radius-medium: 0px;
--border-radius-large: 0px;
}

View File

@@ -1,21 +0,0 @@
/**
* 文档片段所属的enum
*/
export enum ProductFileEnum {
dg = "测评大纲",
sm = "测试说明",
jl = "测试记录",
hsm = "回归说明",
hjl = "回归记录",
bg = "测评报告",
wtd = "问题单"
}
/**
* 常规tag颜色
*/
export enum TagColorEnum {
normal = "green",
warn = "orange",
sub = "magenta"
}

View File

@@ -60,4 +60,16 @@ tool.local = {
}
}
/**
* 辅助函数,删除旧属性,生成新属性 crudColumn -> formColumn
*/
const renameKeyInArray = (arr, oldKey, newKey) => {
return arr.map((obj) => {
let { [oldKey]: value, ...rest } = obj
return { ...rest, [newKey]: value }
})
}
tool.renameKeyInArray = renameKeyInArray
export default tool

View File

@@ -0,0 +1,177 @@
import { Ref, ref, watch, computed } from "vue"
import { VueUiXyConfig, VueUiXyDatasetItem } from "vue-data-ui"
// 单个每月项目数量对象格式
interface IData {
mouth: string
count: number
}
// 响应.data的数据格式
interface ResData {
data: IData[]
}
function useVueDataUI(data: Ref<ResData>) {
const initialData = [
{
name: "项目数量",
series: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
type: "line",
color: "rgb(95,139,238)",
scaleSteps: 10,
suffix: "个",
smooth: true
}
]
const chartData = computed<any[]>(() => {
if (data.value) {
const countData = data.value.data.map((it) => it.count)
initialData[0].series = countData
}
return initialData
})
const initialConfig = {
theme: "",
responsive: false,
customPalette: [],
downsample: { threshold: 500 },
chart: {
fontFamily: "inherit",
backgroundColor: "#FFFFFFff",
color: "#1A1A1Aff",
height: 300,
width: 1200,
padding: { top: 36, right: 24, bottom: 48, left: 48 },
highlighter: { color: "#1A1A1Aff", opacity: 5, useLine: false, lineDasharray: 2, lineWidth: 1 },
grid: {
stroke: "#e1e5e8ff",
showVerticalLines: false,
showHorizontalLines: false,
position: "middle",
frame: {
show: false,
stroke: "#E1E5E8ff",
strokeWidth: 2,
strokeLinecap: "round",
strokeLinejoin: "round",
strokeDasharray: 0
},
labels: {
show: true,
color: "#1A1A1Aff",
fontSize: 12,
axis: { yLabel: "", yLabelOffsetX: 0, xLabel: "", xLabelOffsetY: 14, fontSize: 12 },
zeroLine: { show: true },
xAxis: { showBaseline: true },
yAxis: {
showBaseline: true,
commonScaleSteps: 1,
useIndividualScale: false,
stacked: false,
gap: 12,
labelWidth: 40,
formatter: null,
scaleMin: 0,
scaleMax: 20
},
xAxisLabels: {
color: "#1A1A1Aff",
show: true,
values: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月"
],
fontSize: 12,
showOnlyFirstAndLast: false,
showOnlyAtModulo: false,
modulo: 12,
yOffset: 8,
rotation: 0
}
}
},
comments: { show: true, showInTooltip: true, width: 200, offsetX: 0, offsetY: 0 },
labels: { fontSize: 10, prefix: "", suffix: "" },
legend: { color: "#1A1A1Aff", show: false, fontSize: 16 },
title: {
text: "项目每月统计",
color: "#1A1A1Aff",
fontSize: 18,
bold: true,
textAlign: "left",
paddingLeft: 0,
paddingRight: 0,
subtitle: { color: "#CCCCCCff", text: "", fontSize: 16, bold: false },
show: true
},
tooltip: {
show: true,
color: "#1A1A1Aff",
backgroundColor: "#FFFFFFff",
fontSize: 14,
customFormat: null,
borderRadius: 4,
borderColor: "#e1e5e8",
borderWidth: 1,
backgroundOpacity: 30,
position: "center",
offsetY: 24,
showValue: true,
showPercentage: false,
roundingValue: 0,
roundingPercentage: 0
},
userOptions: {
show: true,
position: "right",
buttons: {
tooltip: true,
pdf: true,
csv: true,
img: true,
table: false,
labels: false,
fullscreen: true,
sort: false,
stack: true,
animation: false,
annotator: false
},
buttonTitles: {
open: "打开选项",
close: "关闭选项",
tooltip: "切换提示开关",
pdf: "下载为PDF",
csv: "下载为CSV",
img: "下载为PNG",
table: "表格显示/隐藏",
labels: "标签显示/隐藏",
fullscreen: "切换全屏",
stack: "切换stack模式"
}
},
zoom: { show: false }
},
showTable: false
}
const chartConfig = computed(() => {
if (data.value) {
const countData = data.value.data.map((it) => it.count)
initialConfig.chart.grid.labels.yAxis.scaleMax = Math.max(...countData)
}
return initialConfig
})
return { chartData, chartConfig }
}
export default useVueDataUI

View File

@@ -23,7 +23,7 @@
</a>
</a-card>
<div class="mt-2">管理平台版本</div>
<a-tag class="mt-2 w-fit" color="#0fc6c2">TestPlant V0.0.3</a-tag>
<a-tag class="mt-2 w-fit" color="#0fc6c2">TestPlant V0.0.4</a-tag>
</div>
</div>
</template>

View File

@@ -1,179 +1,31 @@
<template>
<div class="ma-content-block p-3 mt-3 bg-white">
<a-spin class="chartContainer" :loading="isDataLoading" tip="图标数据加载中...">
<ma-chart height="300px" :option="loginChartOptions" v-if="!isDataLoading" />
<a-spin class="chartContainer" :loading="isPending" tip="图标数据加载中...">
<div class="flex justify-center items-center" v-if="!isPending">
<template v-if="isError">
<img class="w-[200px] h-[300px]" src="@/assets/img/ErrorLoad.svg" alt="" />
</template>
<template v-else>
<VueUiXy :dataset="chartData" :config="chartConfig" />
</template>
</div>
</a-spin>
</div>
</template>
<script setup>
import { computed, ref } from "vue"
import { graphic } from "echarts"
import fetchData from "@/hooks/fetchData"
import commonApi from "@/api/common"
// 传给hook的远程请求数据函数
async function fetchDataFunc() {
return await commonApi.getChartData()
}
const { loadingData, isDataLoading } = fetchData(
[
{ month: "1", count: 2 },
{ month: "2", count: 10 }
],
fetchDataFunc
)
// 计算属性将loadingData转为xAxis
const xAxisData = computed(() => {
return loadingData.value.map((item) => {
return item.month + "月"
})
import { VueUiXy } from "vue-data-ui"
import useVueDataUI from "@/views/dashboard/workplace/components/cpns/hooks/vueDataUI"
import { useQuery } from "@tanstack/vue-query"
// vue-query请求图表接口
const { isPending, data, isError } = useQuery({
queryKey: ["chart"],
queryFn: commonApi.getChartData,
refetchOnWindowFocus: false
})
const yAxisData = computed(() => {
return loadingData.value.map((item) => {
return item.count
})
})
function graphicFactory(side) {
return {
type: "text",
bottom: "8",
...side,
style: {
text: "",
textAlign: "center",
fill: "#4E5969",
fontSize: 12
}
}
}
const graphicElements = ref([graphicFactory({ left: "3%" }), graphicFactory({ right: 0 })])
const loginChartOptions = computed(() => ({
title: {
text: `项目每月统计-${new Date().getFullYear()}年份`
},
grid: {
left: "3%",
right: "3%",
top: "50",
bottom: "30"
},
xAxis: {
type: "category",
offset: 2,
data: xAxisData.value,
boundaryGap: true,
axisLabel: {
color: "#4E5969",
formatter(value, idx) {
return `${value}`
}
},
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
show: true,
interval: (idx) => {
if (idx === xAxisData.value.length - 1) return false
return true
},
lineStyle: {
color: "#E5E8EF"
}
},
axisPointer: {
show: true,
lineStyle: {
color: "#23ADFF",
width: 2
}
}
},
yAxis: {
type: "value",
axisLine: {
show: false
},
axisLabel: {
formatter(value, idx) {
if (idx === 0) return value
return `${value}`
}
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
color: "#E5E8EF"
}
}
},
tooltip: {
trigger: "axis",
formatter(params) {
return `<div class="login-chart">
<p class="tooltip-title">${params[0].axisValueLabel}</p>
<div class="content-panel"><span>项目数量</span><span class="tooltip-value">${Number(
params[0].value
).toLocaleString()}</span></div>
</div>`
}
},
graphic: {
elements: graphicElements.value
},
series: [
{
data: yAxisData.value,
type: "line",
smooth: true,
symbolSize: 14,
emphasis: {
focus: "series",
itemStyle: {
borderWidth: 2
}
},
lineStyle: {
width: 3,
color: new graphic.LinearGradient(0, 0, 1, 0, [
{
offset: 0,
color: "rgba(30, 231, 255, 1)"
},
{
offset: 0.5,
color: "rgba(36, 154, 255, 1)"
},
{
offset: 1,
color: "rgba(111, 66, 251, 1)"
}
])
},
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: new graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(17, 126, 255, 0.16)"
},
{
offset: 1,
color: "rgba(17, 128, 255, 0)"
}
])
}
}
]
}))
// vue-data-ui图表
const { chartData, chartConfig } = useVueDataUI(data)
</script>
<style lang="less" scoped>

View File

@@ -180,7 +180,7 @@ const handleSubmit = async ({ values, errors }) => {
position: relative;
top: 50%;
margin-top: -255px;
border-radius: 2px;
border-radius: var(--border-radius-small);
}
.left-panel {

View File

@@ -431,6 +431,13 @@ const crudColumns = ref([
}
])
// 暴露给route-view的刷新表格函数
const refreshCrudTable = () => {
crudRef.value.refresh()
}
defineExpose({ refreshCrudTable })
defineOptions({
name: "case"
})

View File

@@ -238,6 +238,11 @@ const handleAddFileInputDemand = () => {
fileInputRef.value.open()
}
const refreshCrudTable = () => {
crudRef.value.refresh()
}
defineExpose({ refreshCrudTable })
defineOptions({
name: "dut"
})

View File

@@ -0,0 +1,95 @@
import { defineComponent, inject, ref } from "vue"
import { TreeNodeData } from "@arco-design/web-vue"
import { useRoute } from "vue-router"
import { Message } from "@arco-design/web-vue"
import { useTreeDataStore } from "@/store"
import dutAPI from "@/api/project/dut"
import useOptions from "./useOptions"
import MaForm from "@/components/ma-form/index.vue"
const DutSubForm = defineComponent({
name: "DutSubForm",
setup(props, { expose }) {
// globals
const route = useRoute()
const project_id = route.query.id
const treeDataStore = useTreeDataStore()
const rightViewRef = inject("rightViewRef")
// refs
const visible = ref(false)
const formRef = ref<InstanceType<typeof MaForm> | null>(null)
const formData = ref<any>({})
// hooks
const { options, columnOptions } = useOptions(formRef)
// 标题
const title = ref("被测件详情")
// 双击打开回调
const open = async (nodeData: TreeNodeData) => {
// 请求数据
try {
const key = nodeData.key
// 设置表单名称
title.value = nodeData.title!
const res = await dutAPI.getDutOne({ project_id, key })
// 更新表单
formData.value = res.data
formData.value.round = key
visible.value = true
} catch (e) {
visible.value = false
}
}
// 异步确认按钮点击
const handleBeforeOk = async () => {
const isValidated = await formRef.value!.validateForm()
if (isValidated) {
// 失败
return false
} else {
// 成功
const res = await dutAPI.update(formData.value.id, { project_id, ...formData.value })
treeDataStore.updateDutTreeData(res.data, project_id) // 刷新树节点信息
!(rightViewRef as any).value.refresh()
Message.success("修改成功")
}
}
// out use
expose({ open })
// Dom
return () => (
<a-modal
v-model:visible={visible.value}
width={"40%"}
draggable
unmount-on-close
ok-text="保存"
cancel-text="关闭"
on-before-ok={handleBeforeOk}
>
{{
title: () => <span>[]-{title.value}</span>,
default: () => (
<ma-form
ref={formRef}
v-model={formData.value}
options={options.value}
columns={columnOptions.value}
>
{{
"inputPrepend-version": () => <span>V</span>
}}
</ma-form>
)
}}
</a-modal>
)
}
})
export default DutSubForm
// 组件类型导出
type DutSubFormOrigin = InstanceType<typeof DutSubForm>
export interface DutSubFormInstance extends DutSubFormOrigin {
open(nodeData: TreeNodeData): void
}

View File

@@ -0,0 +1,15 @@
import { ref, computed } from "vue"
import useCrudRef from "@/views/project/round/hooks/useCrudRef"
import tool from "@/utils/tool"
export default function useOptions(formRef: any) {
const options = ref({
showButtons: false,
labelAlign: "center"
})
const { crudColumns } = useCrudRef(undefined, formRef)
const columnOptions = computed(() => {
return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules")
})
return { options, columnOptions }
}

View File

@@ -0,0 +1,15 @@
import { IDictData } from "@/utils/types/CommonType"
type BeiceTypeT = {
[K in keyof IDictData<string>]: string
}
const beiceType: BeiceTypeT[] = [
{ label: "源代码", value: "SO" },
{ label: "设计说明", value: "SJ" },
{ label: "需求文档", value: "XQ" },
{ label: "通信协议", value: "XY" },
{ label: "研制总要求", value: "YZ" }
]
export default beiceType

View File

@@ -0,0 +1,261 @@
import { ref } from "vue"
import dutApi from "@/api/project/dut"
import { useRoute } from "vue-router"
import { useTreeDataStore } from "@/store"
import beiceType from "@/views/project/round/beiceType"
/**
* 传入组件Ref返回其options和columnOptions
* @param crudRef crud组件的Ref注意不存在传递undefined
* @param formRef ma-form组件Ref
* @returns
*/
export default function useCrudRef(crudRef?, formRef?) {
// globals
const route = useRoute()
const projectId = ref(route.query.id)
const treeDataStore = useTreeDataStore()
const roundNumber = (route.query.key as any).split("-")[0]
// 计算注释率计算crud/form的数据判断
const calcPercent = () => {
if (crudRef) {
const formData = crudRef.value.getFormData()
const total_line = +formData.black_line + +formData.code_line + +formData.comment_line + +formData.mix_line
const comment_total = +formData.comment_line + +formData.mix_line
formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%`
} else if (formRef) {
const formData = formRef.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()}%`
}
}
// refs
const crudOptions = ref({
api: dutApi.getDutList,
add: { show: true, api: dutApi.save, text: "新增被测件" },
edit: { show: true, api: dutApi.update, text: "编辑被测件" },
delete: { show: true, api: dutApi.delete },
// 处理添加后函数
beforeOpenAdd: function () {
let round_str = parseInt(route.query.key as any) + 1
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件-`
return true
},
beforeOpenEdit: function (record) {
let round_str = parseInt(route.query.key as any) + 1
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件[${record.name}]-`
return true
},
afterAdd: (res) => {
let id = projectId.value
treeDataStore.updateDutTreeData(res.data, id)
},
afterEdit: (res) => {
let id = projectId.value
treeDataStore.updateDutTreeData(res.data, id)
},
afterDelete: (res, record) => {
let id = projectId.value
if (!record) {
record = { key: route.query.key + "-X" }
}
treeDataStore.updateDutTreeData(record, id)
// 清空行选择器
crudRef.value.tableRef.selectAll(false)
},
// 新增、编辑、删除均携带下面
parameters: {
projectId: route.query.id,
round: roundNumber
},
operationWidth: 500,
showIndex: false,
showTools: false,
rowSelection: { showCheckedAll: true },
searchColNumber: 3,
tablePagination: false,
operationColumnWidth: 200, // 操作列宽度
operationColumn: true,
operationColumnAlign: "center",
formOption: {
viewType: "drawer",
width: 600,
mask: false
}
})
const crudColumns = ref([
{
title: "ID",
width: 50,
align: "center",
hide: true,
dataIndex: "id",
commonRules: [{ required: true, message: "ID是必填" }],
validateTrigger: "blur",
display: false
},
{
title: "测件标识",
width: 150,
sortable: { sortDirections: ["ascend"] },
align: "center",
dataIndex: "ident",
search: true,
// 这里做的标识预填
addDefaultValue: route.query.ident + "-R" + (parseInt(route.query.key as any) + 1) + "-UT",
addDisabled: true,
editDisabled: true,
validateTrigger: "blur",
disabled: true,
placeholder: "被测件标识未空,请检查"
},
{
title: "被测类型",
align: "center",
dataIndex: "type",
search: true,
formType: "radio",
addDefaultValue: "SO",
dict: {
data: beiceType,
translation: true,
tagColors: { XQ: "blue", SO: "green", SJ: "orangered", XY: "pinkpurple", YZ: "red" }
},
onControl: (value) => {
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 },
comment_percent: { 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 },
comment_percent: { display: false },
release_date: { display: true }
}
}
}
},
{
title: "被测件名",
width: 120,
align: "center",
dataIndex: "name",
search: true,
commonRules: [{ required: true, message: "被测件名称必填" }],
validateTrigger: "blur"
},
{
title: "版本",
align: "center",
dataIndex: "version",
search: true,
commonRules: [{ required: true, message: "版本必填" }],
validateTrigger: "blur",
help: "填写不带V字符",
openPrepend: true
},
{
title: "用户标识",
align: "center",
dataIndex: "ref",
search: true,
commonRules: [{ required: true, message: "用户标识必填" }],
validateTrigger: "blur",
help: "客户使用的标识"
},
{
title: "单位",
align: "center",
dataIndex: "release_union",
search: true,
commonRules: [{ required: true, message: "单位必选" }],
formType: "select",
dict: { url: "system/contact/index", props: { label: "name", value: "name" }, translation: true }
},
{
title: "发布时间",
dataIndex: "release_date",
hide: true,
commonRules: [{ required: true, message: "时间必填" }],
formType: "date"
},
{
title: "空行",
hide: true,
align: "center",
dataIndex: "black_line",
formType: "input-number",
commonRules: [{ required: true, message: "空行数必填" }],
min: 0,
onControl: () => {
calcPercent()
}
},
{
title: "纯代码行",
hide: true,
align: "center",
dataIndex: "code_line",
formType: "input-number",
commonRules: [{ required: true, message: "纯代码行数必填" }],
min: 0,
onControl: () => {
calcPercent()
}
},
{
title: "纯注释行",
hide: true,
align: "center",
dataIndex: "comment_line",
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: "混合行数必填" }],
min: 0,
onControl: () => {
calcPercent()
}
},
{
title: "注释率 %",
align: "center",
dataIndex: "comment_percent",
placeholder: "计算注释率",
hide: true,
addDisabled: true,
editDisabled: true
}
])
return {
crudOptions,
crudColumns
}
}

View File

@@ -12,251 +12,15 @@
<script setup lang="jsx">
import { ref } from "vue"
import { useRoute, useRouter } from "vue-router"
import dutApi from "@/api/project/dut"
import { useTreeDataStore } from "@/store"
const treeDataStore = useTreeDataStore()
const route = useRoute()
const roundNumber = route.query.key.split("-")[0]
const projectId = ref(route.query.id)
import useCrudRef from "@/views/project/round/hooks/useCrudRef"
const crudRef = ref()
let beiceType = [
{ label: "源代码", value: "SO" },
{ label: "设计说明", value: "SJ" },
{ label: "需求文档", value: "XQ" },
{ label: "通信协议", value: "XY" },
{ label: "研制总要求", value: "YZ" }
]
// crud组件
const crudOptions = ref({
api: dutApi.getDutList,
add: { show: true, api: dutApi.save, text: "新增被测件" },
edit: { show: true, api: dutApi.update, text: "编辑被测件" },
delete: { show: true, api: dutApi.delete },
// 处理添加后函数
beforeOpenAdd: function () {
let round_str = parseInt(route.query.key) + 1
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件-`
return true
},
beforeOpenEdit: function (record) {
let round_str = parseInt(route.query.key) + 1
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件[${record.name}]-`
return true
},
afterAdd: (res) => {
let id = projectId.value
treeDataStore.updateDutTreeData(res.data, id)
},
afterEdit: (res) => {
let id = projectId.value
treeDataStore.updateDutTreeData(res.data, id)
},
afterDelete: (res, record) => {
let id = projectId.value
if (!record) {
record = { key: route.query.key + "-X" }
}
treeDataStore.updateDutTreeData(record, id)
// 清空行选择器
crudRef.value.tableRef.selectAll(false)
},
const { crudOptions, crudColumns } = useCrudRef(crudRef)
// 新增、编辑、删除均携带下面
parameters: {
projectId: route.query.id,
round: roundNumber
},
operationWidth: 500,
showIndex: false,
showTools: false,
rowSelection: { showCheckedAll: true },
searchColNumber: 3,
tablePagination: false,
operationColumnWidth: 200, // 操作列宽度
operationColumn: true,
operationColumnAlign: "center",
formOption: {
viewType: "drawer",
width: 600,
mask: false
}
})
// 1.计算注释率函数 -> 用于字段交互
const calcPercent = () => {
const formData = crudRef.value.getFormData()
const total_line = +formData.black_line + +formData.code_line + +formData.comment_line + +formData.mix_line
const comment_total = +formData.comment_line + +formData.mix_line
formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%`
const refreshCrudTable = () => {
crudRef.value.refresh()
}
const crudColumns = ref([
{
title: "ID",
width: 50,
align: "center",
hide: true,
dataIndex: "id",
commonRules: [{ required: true, message: "ID是必填" }],
validateTrigger: "blur"
},
{
title: "测件标识",
width: 150,
sortable: { sortDirections: ["ascend"] },
align: "center",
dataIndex: "ident",
search: true,
// 这里做的标识预填
addDefaultValue: route.query.ident + "-R" + (parseInt(route.query.key) + 1) + "-UT",
addDisabled: true,
editDisabled: true,
validateTrigger: "blur"
},
{
title: "被测类型",
align: "center",
dataIndex: "type",
search: true,
formType: "radio",
addDefaultValue: "SO",
dict: {
data: beiceType,
translation: true,
tagColors: { XQ: "blue", SO: "green", SJ: "orangered", XY: "pinkpurple", YZ: "red" }
},
onControl: (value) => {
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 },
comment_percent: { 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 },
comment_percent: { display: false },
release_date: { display: true }
}
}
}
},
{
title: "被测件名",
width: 120,
align: "center",
dataIndex: "name",
search: true,
commonRules: [{ required: true, message: "被测件名称必填" }],
validateTrigger: "blur"
},
{
title: "版本",
align: "center",
dataIndex: "version",
search: true,
commonRules: [{ required: true, message: "版本必填" }],
validateTrigger: "blur",
help: "填写不带V字符",
openPrepend: true
},
{
title: "用户标识",
align: "center",
dataIndex: "ref",
search: true,
commonRules: [{ required: true, message: "用户标识必填" }],
validateTrigger: "blur",
help: "客户使用的标识"
},
{
title: "单位",
align: "center",
dataIndex: "release_union",
search: true,
commonRules: [{ required: true, message: "单位必选" }],
formType: "select",
dict: { url: "system/contact/index", props: { label: "name", value: "name" }, translation: true }
},
{
title: "发布时间",
dataIndex: "release_date",
hide: true,
commonRules: [{ required: true, message: "时间必填" }],
formType: "date"
},
{
title: "空行",
hide: true,
align: "center",
dataIndex: "black_line",
formType: "input-number",
commonRules: [{ required: true, message: "空行数必填" }],
min: 0,
onControl: () => {
calcPercent()
}
},
{
title: "纯代码行",
hide: true,
align: "center",
dataIndex: "code_line",
formType: "input-number",
commonRules: [{ required: true, message: "纯代码行数必填" }],
min: 0,
onControl: () => {
calcPercent()
}
},
{
title: "纯注释行",
hide: true,
align: "center",
dataIndex: "comment_line",
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: "混合行数必填" }],
min: 0,
onControl: () => {
calcPercent()
}
},
{
title: "注释率 %",
align: "center",
dataIndex: "comment_percent",
placeholder: "计算注释率",
hide: true,
addDisabled: true,
editDisabled: true
}
])
defineExpose({ refreshCrudTable })
defineOptions({
name: "round"

View File

@@ -1,20 +1,13 @@
import { useRoute } from "vue-router"
import { ref } from "vue"
import { FragApi } from "@/api/system/fragment"
import { ProductFileEnum } from "@/utils/enums/productTypes"
import type { IDictData } from "@/utils/types/CommonType"
import { IFragSearchCondition } from "@/api/system/types/fragmentTypes"
const useCrudOption = () => {
// global
const route = useRoute()
const crudRef = ref()
// 产品文档类型写死7种
const productFileType: IDictData<ProductFileEnum>[] = Object.keys(ProductFileEnum).map((it, index) => ({
label: ProductFileEnum[it],
value: index + 1
}))
// crud-option
// crud-options
const crudOptions = ref<object>({
api: FragApi.getFragList,
add: { show: true, api: FragApi.add },
@@ -45,10 +38,7 @@ const useCrudOption = () => {
layout: [
{
formType: "grid",
cols: [
{ span: 12, formList: [{ dataIndex: "name" }] },
{ span: 12, formList: [{ dataIndex: "belong_doc" }] }
]
cols: [{ span: 12, formList: [{ dataIndex: "name" }] }]
}
]
}
@@ -72,16 +62,6 @@ const useCrudOption = () => {
commonRules: [{ required: true, message: "片段名称必填" }],
validateTrigger: "blur"
},
{
title: "所属文档",
align: "center",
width: 100,
dataIndex: "belong_doc",
formType: "select",
search: true,
commonRules: [{ required: true, message: "所属文档必选" }],
dict: { data: productFileType, translation: true }
},
{
title: "替换片段",
width: 100,

View File

@@ -82,7 +82,8 @@ const useGenerateSecond = function () {
dgGenerateApi.createInterface({ id }), // 生成-被测软件接口
dgGenerateApi.createPerformance({ id }), // 生成-被测软件性能
dgGenerateApi.createBaseInformation({ id }), // 生成-被测软件基本信息
dgGenerateApi.createRequirement({ id }), // 生成-测试总体要求
dgGenerateApi.createLevelAndType({ id }), // 生成-测试级别和测试类型 -【修改】
dgGenerateApi.createStrategy({ id }), // 生成-测试级别和测试类型 -【新增】
dgGenerateApi.createYzComparison({ id }), // 生成-研总-测试项对照表
dgGenerateApi.createXqComparison({ id }), // 生成-需求规格说明-测试项对照表
dgGenerateApi.createFanXqComparison({ id }), // 生成-反向测试项-需求规格说明对照表

View File

@@ -1,27 +1,25 @@
const colors = require("tailwindcss/colors")
module.exports = {
content: ["./src/**/*.{js,jxs,vue}"],
darkMode: "media", // or 'media' or 'class'
theme: {
fontFamily: {
sans: ["Graphik", "sans-serif"],
serif: ["Merriweather", "serif"]
import colors from "tailwindcss/colors"
export const content = ["./src/**/*.{js,jxs,vue}"]
export const darkMode = "media"
export const theme = {
fontFamily: {
sans: ["Graphik", "sans-serif"],
serif: ["Merriweather", "serif"]
},
extend: {
spacing: {
128: "32rem",
144: "36rem"
},
extend: {
spacing: {
128: "32rem",
144: "36rem"
},
borderRadius: {
"4xl": "2rem"
}
borderRadius: {
"4xl": "2rem"
}
},
variants: {
extend: {
borderColor: ["focus-visible"],
opacity: ["disabled"]
}
},
plugins: []
}
}
export const variants = {
extend: {
borderColor: ["focus-visible"],
opacity: ["disabled"]
}
}
export const plugins = []

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,7 @@ export default ({ mode }) => {
vueJsx(),
visualizer({
open: true,
filename: "visualizer.html" //分析图生成的文件名
filename: "visualizer.html" // 分析图生成的文件名
})
],
resolve: {
@@ -35,7 +35,6 @@ export default ({ mode }) => {
rollupOptions: {
output: {
manualChunks: (id) => {
if (id.includes("echarts")) return "echarts"
if (id.includes("tinymce")) return "tinymce"
return null
}