日常修复内容
This commit is contained in:
98
cdTMP/package-lock.json
generated
98
cdTMP/package-lock.json
generated
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "testplant",
|
"name": "testplant",
|
||||||
"version": "1.0.1",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "testplant",
|
"name": "testplant",
|
||||||
"version": "1.0.1",
|
"version": "0.1.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@arco-design/web-vue": "^2.57.0",
|
"@arco-design/web-vue": "^2.58.0",
|
||||||
"@tanstack/vue-query": "^5.99.0",
|
"@tanstack/vue-query": "^5.99.2",
|
||||||
"@tinymce/tinymce-vue": "^6.3.0",
|
"@tinymce/tinymce-vue": "^6.3.0",
|
||||||
"@vueuse/core": "^14.2.1",
|
"@vueuse/core": "^14.2.1",
|
||||||
"axios": "^1.15.0",
|
"axios": "^1.15.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.20",
|
"dayjs": "^1.11.20",
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
||||||
"@vue/babel-plugin-jsx": "^2.0.1",
|
"@vue/babel-plugin-jsx": "^2.0.1",
|
||||||
"browserslist": "^4.28.2",
|
"browserslist": "^4.28.2",
|
||||||
"eslint": "^10.2.0",
|
"eslint": "^10.2.1",
|
||||||
"eslint-plugin-vue": "^10.8.0",
|
"eslint-plugin-vue": "^10.8.0",
|
||||||
"less": "^4.6.4",
|
"less": "^4.6.4",
|
||||||
"less-loader": "^12.3.2",
|
"less-loader": "^12.3.2",
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
"prettier": "^3.8.3",
|
"prettier": "^3.8.3",
|
||||||
"rollup-plugin-visualizer": "^7.0.1",
|
"rollup-plugin-visualizer": "^7.0.1",
|
||||||
"tailwindcss": "^4.2.2",
|
"tailwindcss": "^4.2.2",
|
||||||
"typescript": "^6.0.2",
|
"typescript": "^6.0.3",
|
||||||
"vite": "^8.0.8",
|
"vite": "^8.0.8",
|
||||||
"vue-eslint-parser": "^10.4.0"
|
"vue-eslint-parser": "^10.4.0"
|
||||||
}
|
}
|
||||||
@@ -83,9 +83,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@arco-design/web-vue": {
|
"node_modules/@arco-design/web-vue": {
|
||||||
"version": "2.57.0",
|
"version": "2.58.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@arco-design/web-vue/-/web-vue-2.57.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@arco-design/web-vue/-/web-vue-2.58.0.tgz",
|
||||||
"integrity": "sha512-R5YReC3C2sG3Jv0+YuR3B7kzkq2KdhhQNCGXD8T11xAoa0zMt6SWTP1xJQOdZcM9du+q3z6tk5mRvh4qkieRJw==",
|
"integrity": "sha512-b1vdPYOmjG5VAkVa7jlVwCb+WynBK+rnKN8zH3yKohpZObZbostRd3HgYNtjjZjGVU3OqR0Yy2FX7ftgF0bcOw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
"vue": "^3.1.0"
|
"vue": "^3.1.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "^3.1.0"
|
"vue": ">=3.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
@@ -570,13 +570,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/config-array": {
|
"node_modules/@eslint/config-array": {
|
||||||
"version": "0.23.4",
|
"version": "0.23.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@eslint/config-array/-/config-array-0.23.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@eslint/config-array/-/config-array-0.23.5.tgz",
|
||||||
"integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==",
|
"integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/object-schema": "^3.0.4",
|
"@eslint/object-schema": "^3.0.5",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"minimatch": "^10.2.4"
|
"minimatch": "^10.2.4"
|
||||||
},
|
},
|
||||||
@@ -585,22 +585,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/config-helpers": {
|
"node_modules/@eslint/config-helpers": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@eslint/config-helpers/-/config-helpers-0.5.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@eslint/config-helpers/-/config-helpers-0.5.5.tgz",
|
||||||
"integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==",
|
"integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/core": "^1.2.0"
|
"@eslint/core": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/core": {
|
"node_modules/@eslint/core": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmmirror.com/@eslint/core/-/core-1.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@eslint/core/-/core-1.2.1.tgz",
|
||||||
"integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==",
|
"integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -611,9 +611,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/object-schema": {
|
"node_modules/@eslint/object-schema": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@eslint/object-schema/-/object-schema-3.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@eslint/object-schema/-/object-schema-3.0.5.tgz",
|
||||||
"integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==",
|
"integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -621,13 +621,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.1",
|
||||||
"resolved": "https://registry.npmmirror.com/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz",
|
||||||
"integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==",
|
"integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/core": "^1.2.0",
|
"@eslint/core": "^1.2.1",
|
||||||
"levn": "^0.4.1"
|
"levn": "^0.4.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1371,9 +1371,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tanstack/query-core": {
|
"node_modules/@tanstack/query-core": {
|
||||||
"version": "5.99.0",
|
"version": "5.99.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.99.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.99.2.tgz",
|
||||||
"integrity": "sha512-3Jv3WQG0BCcH7G+7lf/bP8QyBfJOXeY+T08Rin3GZ1bshvwlbPt7NrDHMEzGdKIOmOzvIQmxjk28YEQX60k7pQ==",
|
"integrity": "sha512-1HunU0bXVsR1ZJMZbcOPE6VtaBJxsW809RE9xPe4Gz7MlB0GWwQvuTPhMoEmQ/hIzFKJ/DWAuttIe7BOaWx0tA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1381,13 +1381,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tanstack/vue-query": {
|
"node_modules/@tanstack/vue-query": {
|
||||||
"version": "5.99.0",
|
"version": "5.99.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@tanstack/vue-query/-/vue-query-5.99.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@tanstack/vue-query/-/vue-query-5.99.2.tgz",
|
||||||
"integrity": "sha512-okrHNkouasL5cjo7O8hUxul22DiIL335KUQus/cfoAdCOUytF/OIv3BpNDevfqE6zHqqJ651Fb9OkUJPUCL0ZQ==",
|
"integrity": "sha512-ll7dzgeM/3/ckNsp+J0ZrUuvJEZan3RlOrb1T4M47CJPM0rS0WNanSYQWPgK0A+Eu/ihwm/kEBmAZOA7toHP8g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/match-sorter-utils": "^8.19.4",
|
"@tanstack/match-sorter-utils": "^8.19.4",
|
||||||
"@tanstack/query-core": "5.99.0",
|
"@tanstack/query-core": "5.99.2",
|
||||||
"@vue/devtools-api": "^6.6.3",
|
"@vue/devtools-api": "^6.6.3",
|
||||||
"vue-demi": "^0.14.10"
|
"vue-demi": "^0.14.10"
|
||||||
},
|
},
|
||||||
@@ -1924,9 +1924,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.15.0",
|
"version": "1.15.1",
|
||||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.15.0.tgz",
|
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.15.1.tgz",
|
||||||
"integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
|
"integrity": "sha512-WOG+Jj8ZOvR0a3rAn+Tuf1UQJRxw5venr6DgdbJzngJE3qG7X0kL83CZGpdHMxEm+ZK3seAbvFsw4FfOfP9vxg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.11",
|
"follow-redirects": "^1.15.11",
|
||||||
@@ -2559,18 +2559,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "10.2.0",
|
"version": "10.2.1",
|
||||||
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-10.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-10.2.1.tgz",
|
||||||
"integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==",
|
"integrity": "sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.2",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@eslint/config-array": "^0.23.4",
|
"@eslint/config-array": "^0.23.5",
|
||||||
"@eslint/config-helpers": "^0.5.4",
|
"@eslint/config-helpers": "^0.5.5",
|
||||||
"@eslint/core": "^1.2.0",
|
"@eslint/core": "^1.2.1",
|
||||||
"@eslint/plugin-kit": "^0.7.0",
|
"@eslint/plugin-kit": "^0.7.1",
|
||||||
"@humanfs/node": "^0.16.6",
|
"@humanfs/node": "^0.16.6",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@humanwhocodes/retry": "^0.4.2",
|
"@humanwhocodes/retry": "^0.4.2",
|
||||||
@@ -5010,9 +5010,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-6.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-6.0.3.tgz",
|
||||||
"integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
|
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "testplant",
|
"name": "testplant",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.1",
|
"version": "0.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@arco-design/web-vue": "^2.57.0",
|
"@arco-design/web-vue": "^2.58.0",
|
||||||
"@tanstack/vue-query": "^5.99.0",
|
"@tanstack/vue-query": "^5.99.2",
|
||||||
"@tinymce/tinymce-vue": "^6.3.0",
|
"@tinymce/tinymce-vue": "^6.3.0",
|
||||||
"@vueuse/core": "^14.2.1",
|
"@vueuse/core": "^14.2.1",
|
||||||
"axios": "^1.15.0",
|
"axios": "^1.15.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.20",
|
"dayjs": "^1.11.20",
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
||||||
"@vue/babel-plugin-jsx": "^2.0.1",
|
"@vue/babel-plugin-jsx": "^2.0.1",
|
||||||
"browserslist": "^4.28.2",
|
"browserslist": "^4.28.2",
|
||||||
"eslint": "^10.2.0",
|
"eslint": "^10.2.1",
|
||||||
"eslint-plugin-vue": "^10.8.0",
|
"eslint-plugin-vue": "^10.8.0",
|
||||||
"less": "^4.6.4",
|
"less": "^4.6.4",
|
||||||
"less-loader": "^12.3.2",
|
"less-loader": "^12.3.2",
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"prettier": "^3.8.3",
|
"prettier": "^3.8.3",
|
||||||
"rollup-plugin-visualizer": "^7.0.1",
|
"rollup-plugin-visualizer": "^7.0.1",
|
||||||
"tailwindcss": "^4.2.2",
|
"tailwindcss": "^4.2.2",
|
||||||
"typescript": "^6.0.2",
|
"typescript": "^6.0.3",
|
||||||
"vite": "^8.0.8",
|
"vite": "^8.0.8",
|
||||||
"vue-eslint-parser": "^10.4.0"
|
"vue-eslint-parser": "^10.4.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<a-spin :loading="dataLoading" tip="加载中..." class="w-full">
|
<a-spin :loading="dataLoading" tip="加载中..." class="w-full">
|
||||||
<!-- 修改源码parentKey -->
|
<!-- 修改源码parentKey -->
|
||||||
<ma-form
|
<ma-form v-model="form" :columns="formColumns" :parent-key="props.parentKey" :options="formOptions" ref="maFormRef">
|
||||||
v-model="form"
|
|
||||||
:columns="formColumns"
|
|
||||||
:parent-key="props.parentKey"
|
|
||||||
:options="formOptions"
|
|
||||||
ref="maFormRef"
|
|
||||||
>
|
|
||||||
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
||||||
<slot :name="slot" v-bind="component" />
|
<slot :name="slot" v-bind="component" />
|
||||||
</template>
|
</template>
|
||||||
@@ -88,12 +82,17 @@ const submit = async () => {
|
|||||||
if (isFunction(options.beforeAdd) && !(await options.beforeAdd(formData))) {
|
if (isFunction(options.beforeAdd) && !(await options.beforeAdd(formData))) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 修改源码添加parameters参数
|
try {
|
||||||
if (!options.parameters) {
|
if (!options.parameters) {
|
||||||
response = await options.add.api(formData)
|
response = await options.add.api(formData)
|
||||||
} else {
|
} else {
|
||||||
response = await options.add.api({ ...formData, ...options.parameters })
|
response = await options.add.api({ ...formData, ...options.parameters })
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("标识重复")
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
// 修改源码添加parameters参数
|
||||||
isFunction(options.afterAdd) && (await options.afterAdd(response, formData))
|
isFunction(options.afterAdd) && (await options.afterAdd(response, formData))
|
||||||
} else {
|
} else {
|
||||||
if (isFunction(options.beforeEdit) && !(await options.beforeEdit(formData))) {
|
if (isFunction(options.beforeEdit) && !(await options.beforeEdit(formData))) {
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
<!--
|
|
||||||
- @Author XXX
|
|
||||||
- @Link XXX
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
:is="getComponentName()"
|
:is="getComponentName()"
|
||||||
v-model="value"
|
v-model="value"
|
||||||
:placeholder="
|
:placeholder="props.component.formType === 'range' ? ['请选择开始时间', '请选择结束时间'] : `请选择${props.component.title}`"
|
||||||
props.component.formType === 'range'
|
|
||||||
? ['请选择开始时间', '请选择结束时间']
|
|
||||||
: `请选择${props.component.title}`
|
|
||||||
"
|
|
||||||
:time-picker-props="props.component.formType == 'range' ? { defaultValue: ['00:00:00', '23:59:59'] } : {}"
|
:time-picker-props="props.component.formType == 'range' ? { defaultValue: ['00:00:00', '23:59:59'] } : {}"
|
||||||
:show-time="props.component.showTime"
|
:show-time="props.component.showTime"
|
||||||
:type="props.component.range ? (props.component.formType === 'time' ? 'time-range' : 'range') : ''"
|
:type="props.component.range ? (props.component.formType === 'time' ? 'time-range' : 'range') : ''"
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ const props = defineProps({
|
|||||||
// 插件
|
// 插件
|
||||||
plugins: {
|
plugins: {
|
||||||
type: [String, Array],
|
type: [String, Array],
|
||||||
default: "visualchars code table nonbreaking lists autosave autoresize"
|
default: "visualchars code table nonbreaking autosave autoresize"
|
||||||
// 备份:"searchreplace visualchars code table nonbreaking lists autosave autoresize"
|
// 备份:"searchreplace visualchars code table nonbreaking lists autosave autoresize"
|
||||||
},
|
},
|
||||||
// 工具栏
|
// 工具栏
|
||||||
toolbar: {
|
toolbar: {
|
||||||
type: [String, Array],
|
type: [String, Array],
|
||||||
// 如果要取消粘贴只粘贴文本,需要用户加格式请加上pastetext
|
// 如果要取消粘贴只粘贴文本,需要用户加格式请加上pastetext
|
||||||
default: "code undo redo aligncenter alignleft indent styleselect formatselect fontselect fontsizeselect removeformat"
|
default: "code undo redo aligncenter alignleft indent styleselect formatselect fontselect fontsizeselect"
|
||||||
|
|
||||||
// 下面是备份配置:
|
// 下面是备份配置:
|
||||||
// default:"code undo redo restoredraft | paste | bold | aligncenter alignleft alignjustify indent searchreplace | \
|
// default:"code undo redo restoredraft | paste | bold | aligncenter alignleft alignjustify indent searchreplace | \
|
||||||
|
|||||||
@@ -1,80 +1,80 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="interface-image-container">
|
<div class="interface-image-container">
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
width="50%"
|
width="50%"
|
||||||
draggable
|
draggable
|
||||||
:on-before-ok="handleSyncOk"
|
:on-before-ok="handleSyncOk"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
ok-text="确认保存"
|
ok-text="确认保存"
|
||||||
cancel-text="关闭不保存"
|
cancel-text="关闭不保存"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
@close="handleOnClose"
|
@close="handleOnClose"
|
||||||
>
|
>
|
||||||
<template #title>软件接口图</template>
|
<template #title>软件接口图</template>
|
||||||
<div class="flex justify-center items-center">
|
<div class="flex justify-center items-center">
|
||||||
<ImageInput v-model="imageUrl" v-model:fontnote="fontnote" />
|
<ImageInput v-model="imageUrl" v-model:fontnote="fontnote" />
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, getCurrentInstance } from "vue"
|
import { ref, getCurrentInstance } from "vue"
|
||||||
import ImageInput from "./projectModal/ImageInput/index.vue"
|
import ImageInput from "./projectModal/ImageInput/index.vue"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import projectApi from "@/api/project/project"
|
import projectApi from "@/api/project/project"
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as any
|
const { proxy } = getCurrentInstance() as any
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
|
|
||||||
// props
|
// props
|
||||||
const { reset } = defineProps<{
|
const { reset } = defineProps<{
|
||||||
reset: () => void
|
reset: () => void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// 题注和图片数据
|
// 题注和图片数据
|
||||||
const fontnote = ref("")
|
const fontnote = ref("")
|
||||||
const imageUrl = ref("")
|
const imageUrl = ref("")
|
||||||
|
|
||||||
const handleSyncOk = async () => {
|
const handleSyncOk = async () => {
|
||||||
// 验证题注是否为空
|
// 验证题注是否为空
|
||||||
if (fontnote.value.trim().length <= 0 || !imageUrl.value.trim()) {
|
if (fontnote.value?.trim().length <= 0 || !imageUrl.value?.trim()) {
|
||||||
Message.error("请输入题注和粘贴图片")
|
Message.error("请输入题注和粘贴图片")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 提交数据
|
// 提交数据
|
||||||
try {
|
try {
|
||||||
await projectApi.postInterfaceImage(route.query.id, { fontnote: fontnote.value, content: imageUrl.value, type: "image" })
|
await projectApi.postInterfaceImage(route.query.id, { fontnote: fontnote.value, content: imageUrl.value, type: "image" })
|
||||||
Message.success("保存成功")
|
Message.success("保存成功")
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnClose = () => {
|
const handleOnClose = () => {
|
||||||
// 用来清空数据
|
// 用来清空数据
|
||||||
fontnote.value = ""
|
fontnote.value = ""
|
||||||
imageUrl.value = ""
|
imageUrl.value = ""
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = async () => {
|
const open = async () => {
|
||||||
proxy?.$loading?.show("数据加载中...")
|
proxy?.$loading?.show("数据加载中...")
|
||||||
try {
|
try {
|
||||||
const { data } = await projectApi.getInterfaceImage(route.query.id)
|
const { data } = await projectApi.getInterfaceImage(route.query.id)
|
||||||
fontnote.value = data.fontnote
|
fontnote.value = data.fontnote || ""
|
||||||
imageUrl.value = data.content
|
imageUrl.value = data.content || ""
|
||||||
visible.value = true
|
visible.value = true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
} finally {
|
} finally {
|
||||||
proxy?.$loading?.hide()
|
proxy?.$loading?.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@@ -1,95 +1,95 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="static-dynamic-table-container">
|
<div class="static-dynamic-table-container">
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
width="50%"
|
width="50%"
|
||||||
draggable
|
draggable
|
||||||
:on-before-ok="handleSyncOk"
|
:on-before-ok="handleSyncOk"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
ok-text="确认保存"
|
ok-text="确认保存"
|
||||||
cancel-text="关闭不保存"
|
cancel-text="关闭不保存"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
@close="handleOnClose"
|
@close="handleOnClose"
|
||||||
>
|
>
|
||||||
<template #title>{{ theTitle }}</template>
|
<template #title>{{ theTitle }}</template>
|
||||||
<WordLikeTable v-model="tableData" v-model:fontnote="fontnote" />
|
<WordLikeTable v-model="tableData" v-model:fontnote="fontnote" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import { getCurrentInstance, ref } from "vue"
|
import { getCurrentInstance, ref } from "vue"
|
||||||
import WordLikeTable from "./projectModal/wordLikeTable/index.vue"
|
import WordLikeTable from "./projectModal/wordLikeTable/index.vue"
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
import { cloneDeep } from "lodash-es"
|
import { cloneDeep } from "lodash-es"
|
||||||
import projectApi from "@/api/project/project"
|
import projectApi from "@/api/project/project"
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as any
|
const { proxy } = getCurrentInstance() as any
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
// props
|
// props
|
||||||
const { reset } = defineProps<{
|
const { reset } = defineProps<{
|
||||||
reset: () => void
|
reset: () => void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const theTitle = ref("")
|
const theTitle = ref("")
|
||||||
|
|
||||||
const tableInitValue = [
|
const tableInitValue = [
|
||||||
["", "", ""],
|
["", "", ""],
|
||||||
["", "", ""],
|
["", "", ""],
|
||||||
["", "", ""]
|
["", "", ""]
|
||||||
]
|
]
|
||||||
const tableData = ref(tableInitValue)
|
const tableData = ref(tableInitValue)
|
||||||
const fontnote = ref("")
|
const fontnote = ref("")
|
||||||
|
|
||||||
const handleSyncOk = async () => {
|
const handleSyncOk = async () => {
|
||||||
// 验证题注是否为空
|
// 验证题注是否为空
|
||||||
if (tableData.value.length <= 0) {
|
if (tableData.value?.length <= 0) {
|
||||||
Message.error("请输入表格内容再提交")
|
Message.error("请输入表格内容再提交")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 请求接口
|
// 请求接口
|
||||||
await projectApi.postStaticDynamicItems({
|
await projectApi.postStaticDynamicItems({
|
||||||
id: route.query.id,
|
id: route.query.id,
|
||||||
category: theTitle.value,
|
category: theTitle.value,
|
||||||
table: tableData.value,
|
table: tableData.value,
|
||||||
fontnote: fontnote.value
|
fontnote: fontnote.value
|
||||||
})
|
})
|
||||||
Message.success("保存成功")
|
Message.success("保存成功")
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnClose = () => {
|
const handleOnClose = () => {
|
||||||
// 用来清空数据
|
// 用来清空数据
|
||||||
tableData.value = cloneDeep(tableInitValue)
|
tableData.value = cloneDeep(tableInitValue)
|
||||||
fontnote.value = ""
|
fontnote.value = ""
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = async (title: string) => {
|
const open = async (title: string) => {
|
||||||
proxy?.$loading?.show("数据加载中...")
|
proxy?.$loading?.show("数据加载中...")
|
||||||
theTitle.value = title
|
theTitle.value = title
|
||||||
try {
|
try {
|
||||||
// 获取数据并赋值给tableData
|
// 获取数据并赋值给tableData
|
||||||
const res = await projectApi.getStaticDynamicItems(route.query.id, title)
|
const res = await projectApi.getStaticDynamicItems(route.query.id, title)
|
||||||
if (res.code === 25001) {
|
if (res.code === 25001) {
|
||||||
const data = res.data
|
const data = res.data
|
||||||
tableData.value = data.table
|
tableData.value = data.table
|
||||||
fontnote.value = data.fontnote
|
fontnote.value = data.fontnote || ""
|
||||||
}
|
}
|
||||||
visible.value = true
|
visible.value = true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
} finally {
|
} finally {
|
||||||
proxy?.$loading?.hide()
|
proxy?.$loading?.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@@ -1,107 +1,107 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="text-table-container">
|
<div class="text-table-container">
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
width="50%"
|
width="50%"
|
||||||
draggable
|
draggable
|
||||||
:on-before-ok="handleSyncOk"
|
:on-before-ok="handleSyncOk"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
ok-text="确认保存"
|
ok-text="确认保存"
|
||||||
cancel-text="关闭不保存"
|
cancel-text="关闭不保存"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
@close="handleOnClose"
|
@close="handleOnClose"
|
||||||
>
|
>
|
||||||
<template #title>{{ theTitle }}</template>
|
<template #title>{{ theTitle }}</template>
|
||||||
<a-space direction="vertical" fill>
|
<a-space direction="vertical" fill>
|
||||||
<a-card title="差异性段落描述" hoverable>
|
<a-card title="差异性段落描述" hoverable>
|
||||||
<a-textarea auto-size placeholder="请填写差异性分析和'见下表所示'" v-model="description"></a-textarea>
|
<a-textarea auto-size placeholder="请填写差异性分析和'见下表所示'" v-model="description"></a-textarea>
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card title="表格" hoverable>
|
<a-card title="表格" hoverable>
|
||||||
<WordLikeTable v-model="tableDatas" v-model:fontnote="fontnote" />
|
<WordLikeTable v-model="tableDatas" v-model:fontnote="fontnote" />
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import { getCurrentInstance, ref } from "vue"
|
import { getCurrentInstance, ref } from "vue"
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
import WordLikeTable from "./projectModal/wordLikeTable/index.vue"
|
import WordLikeTable from "./projectModal/wordLikeTable/index.vue"
|
||||||
import { cloneDeep } from "lodash-es"
|
import { cloneDeep } from "lodash-es"
|
||||||
import projectApi from "@/api/project/project"
|
import projectApi from "@/api/project/project"
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as any
|
const { proxy } = getCurrentInstance() as any
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
// datas
|
// datas
|
||||||
const description = ref("")
|
const description = ref("")
|
||||||
const initialTableData = [
|
const initialTableData = [
|
||||||
["", "", ""],
|
["", "", ""],
|
||||||
["", "", ""],
|
["", "", ""],
|
||||||
["", "", ""]
|
["", "", ""]
|
||||||
]
|
]
|
||||||
const fontnote = ref("")
|
const fontnote = ref("")
|
||||||
const tableDatas = ref(initialTableData)
|
const tableDatas = ref(initialTableData)
|
||||||
|
|
||||||
// props
|
// props
|
||||||
const { reset } = defineProps<{
|
const { reset } = defineProps<{
|
||||||
reset: () => void
|
reset: () => void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const theTitle = ref("")
|
const theTitle = ref("")
|
||||||
|
|
||||||
const handleSyncOk = async () => {
|
const handleSyncOk = async () => {
|
||||||
// 验证输入文字是否为空
|
// 验证输入文字是否为空
|
||||||
if (description.value.trim().length <= 0) {
|
if (description.value.trim().length <= 0) {
|
||||||
Message.error("请输入分析内容再提交")
|
Message.error("请输入分析内容再提交")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 请求接口
|
// 请求接口
|
||||||
await projectApi.postEnvAnalysis({
|
await projectApi.postEnvAnalysis({
|
||||||
id: route.query.id,
|
id: route.query.id,
|
||||||
table: tableDatas.value,
|
table: tableDatas.value,
|
||||||
fontnote: fontnote.value,
|
fontnote: fontnote.value,
|
||||||
description: description.value
|
description: description.value
|
||||||
})
|
})
|
||||||
Message.success("保存成功")
|
Message.success("保存成功")
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnClose = () => {
|
const handleOnClose = () => {
|
||||||
// 用来清空数据
|
// 用来清空数据
|
||||||
fontnote.value = ""
|
fontnote.value = ""
|
||||||
description.value = ""
|
description.value = ""
|
||||||
tableDatas.value = cloneDeep(initialTableData)
|
tableDatas.value = cloneDeep(initialTableData)
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = async (category_str: string) => {
|
const open = async (category_str: string) => {
|
||||||
proxy?.$loading?.show("数据加载中...")
|
proxy?.$loading?.show("数据加载中...")
|
||||||
theTitle.value = category_str
|
theTitle.value = category_str
|
||||||
try {
|
try {
|
||||||
// 获取数据并赋值给tableData
|
// 获取数据并赋值给tableData
|
||||||
const res = await projectApi.getEnvAnalysis(route.query.id)
|
const res = await projectApi.getEnvAnalysis(route.query.id)
|
||||||
if (res.code === 25001) {
|
if (res.code === 25001) {
|
||||||
tableDatas.value = res.data.table
|
tableDatas.value = res.data.table
|
||||||
fontnote.value = res.data.fontnote
|
fontnote.value = res.data.fontnote || ""
|
||||||
description.value = res.data.description
|
description.value = res.data.description || ""
|
||||||
}
|
}
|
||||||
visible.value = true
|
visible.value = true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
} finally {
|
} finally {
|
||||||
proxy?.$loading?.hide()
|
proxy?.$loading?.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open
|
open
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@@ -1,95 +1,114 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 组件:该组件显示一个正方体,可粘贴图片内容进去并展示,并生成base64到数据里面 -->
|
<!-- 组件:该组件显示一个正方体,可粘贴图片内容进去并展示,并生成base64到数据里面 -->
|
||||||
<div class="image-input-container flex flex-col gap-1">
|
<div class="image-input-container flex flex-col gap-1">
|
||||||
<div class="image-input-handle flex items-center justify-center" @paste="handlePaste">
|
<div class="image-input-handle flex items-center justify-center" @paste="handlePaste">
|
||||||
<!-- 加载状态 -->
|
<!-- 加载状态 -->
|
||||||
<div v-if="isLoading">
|
<div v-if="isLoading">
|
||||||
<a-spin :size="32" />
|
<a-spin :size="32" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 正常显示状态 -->
|
<!-- 正常显示状态 -->
|
||||||
<template v-else-if="imgData">
|
<template v-else-if="imgData">
|
||||||
<img :src="imgData" alt="粘贴的图片" class="preview-image img-container" />
|
<img :src="imgData" alt="粘贴的图片" class="preview-image img-container" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="placeholder">此处Ctrl+V粘贴图片</div>
|
<div class="placeholder">此处Ctrl+V粘贴图片</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<!-- 题注:fontnote -->
|
<!-- 题注:fontnote -->
|
||||||
<a-input v-model="fontnote" class="max-w-100" placeholder="请输入题注"></a-input>
|
<a-input v-model="fontnote" class="max-w-100" placeholder="请输入题注"></a-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import { nextTick, ref } from "vue"
|
import { nextTick, ref, onMounted, onBeforeUnmount } from "vue"
|
||||||
|
|
||||||
// 储存图片base64
|
const imgData = defineModel<string>()
|
||||||
const imgData = defineModel<string>()
|
const fontnote = defineModel<string>("fontnote")
|
||||||
// 储存题注
|
const isLoading = ref(false)
|
||||||
const fontnote = defineModel<string>("fontnote")
|
|
||||||
// 加载状态
|
// 全局粘贴处理函数
|
||||||
const isLoading = ref(false)
|
const onGlobalPaste = (e: ClipboardEvent) => {
|
||||||
|
// 可以增加判断:只有当前组件所在的 modal 打开时才处理(通过 props 传入 visible 状态或使用 provide/inject)
|
||||||
// 处理粘贴事件
|
// 简单起见,这里假设始终需要处理(父组件控制显示隐藏)
|
||||||
const handlePaste = async (e: ClipboardEvent) => {
|
handlePaste(e)
|
||||||
e.preventDefault()
|
}
|
||||||
// 处理没有粘贴内容
|
|
||||||
if (!e.clipboardData) return
|
// 处理粘贴逻辑(复用之前的修复版)
|
||||||
const items = e.clipboardData!.items
|
const handlePaste = (e: ClipboardEvent) => {
|
||||||
// 遍历粘贴板内容
|
e.preventDefault()
|
||||||
for (let i = 0; i < items.length; i++) {
|
const clipboardData = e.clipboardData
|
||||||
const item = items[i]
|
if (!clipboardData) return
|
||||||
// 判断是否是粘贴的图片
|
|
||||||
if (item.kind === "file" && item.type.startsWith("image/")) {
|
const items = clipboardData.items
|
||||||
const file = item.getAsFile()
|
let imageItem: DataTransferItem | null = null
|
||||||
if (!file) {
|
|
||||||
Message.error("读取图片失败,请重新粘贴")
|
for (let i = 0; i < items.length; i++) {
|
||||||
break
|
const item = items[i]
|
||||||
}
|
if (item.kind === "file" && item.type.startsWith("image/")) {
|
||||||
// 判断大小不超过50M
|
imageItem = item
|
||||||
if (file.size > 50 * 1024 * 1024) {
|
break
|
||||||
Message.error("要求图片不超过50M")
|
}
|
||||||
break
|
}
|
||||||
}
|
|
||||||
isLoading.value = true
|
if (!imageItem) {
|
||||||
const reader = new FileReader()
|
Message.error("请粘贴图片,无法粘贴文字或其他内容")
|
||||||
reader.onload = async (e: ProgressEvent<FileReader>) => {
|
return
|
||||||
imgData.value = e.target!.result as string
|
}
|
||||||
await nextTick() // 保证图片展示
|
|
||||||
isLoading.value = false
|
const file = imageItem.getAsFile()
|
||||||
}
|
if (!file) {
|
||||||
// 加载失败处理
|
Message.error("读取图片失败,请重新粘贴")
|
||||||
reader.onerror = () => {
|
return
|
||||||
Message.error("图片加载失败,请重试")
|
}
|
||||||
isLoading.value = false
|
|
||||||
}
|
if (file.size > 50 * 1024 * 1024) {
|
||||||
reader.readAsDataURL(file) // 可直接转为base64的url给img元素使用
|
Message.error("要求图片不超过50M")
|
||||||
break
|
return
|
||||||
} else {
|
}
|
||||||
Message.error("请粘贴图片,无法粘贴文字或其他内容")
|
|
||||||
break
|
isLoading.value = true
|
||||||
}
|
const reader = new FileReader()
|
||||||
}
|
reader.onload = (e) => {
|
||||||
}
|
imgData.value = e.target!.result as string
|
||||||
</script>
|
nextTick(() => {
|
||||||
|
isLoading.value = false
|
||||||
<style scoped lang="less">
|
})
|
||||||
.image-input-handle {
|
}
|
||||||
width: 200px;
|
reader.onerror = () => {
|
||||||
height: 180px;
|
Message.error("图片加载失败,请重试")
|
||||||
border: 1px solid #eee;
|
isLoading.value = false
|
||||||
cursor: alias;
|
}
|
||||||
|
reader.readAsDataURL(file)
|
||||||
.img-container{
|
}
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
// 挂载全局监听
|
||||||
}
|
onMounted(() => {
|
||||||
}
|
document.addEventListener("paste", onGlobalPaste)
|
||||||
|
})
|
||||||
.preview-image {
|
|
||||||
max-width: 100%;
|
onBeforeUnmount(() => {
|
||||||
max-height: 100%;
|
document.removeEventListener("paste", onGlobalPaste)
|
||||||
object-fit: contain;
|
})
|
||||||
}
|
</script>
|
||||||
</style>
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.image-input-handle {
|
||||||
|
width: 200px;
|
||||||
|
height: 180px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
cursor: alias;
|
||||||
|
|
||||||
|
.img-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,122 +1,123 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 完成自定义表格 -->
|
<!-- 完成自定义表格 -->
|
||||||
<div class="fontnote">
|
<div class="fontnote">
|
||||||
<a-space class="w-full">
|
<a-space class="w-full">
|
||||||
<span>题注:</span>
|
<span>题注:</span>
|
||||||
<a-input v-model="fontnote" :style="{ width: '500px' }"></a-input>
|
<a-input v-model="fontnote" :style="{ width: '500px' }"></a-input>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
<a-alert type="warning" class="mt-2">表格第一行为[表头],测评数据、软/硬件项表格会自动添加序号列,而其他纯自定义表格(动态环境描述、软件概述)不会添加序号列</a-alert>
|
||||||
<div class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
|
</div>
|
||||||
<div class="arco-table-container">
|
<div class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
|
||||||
<table class="arco-table-element" cellpadding="0" cellspacing="0">
|
<div class="arco-table-container">
|
||||||
<thead>
|
<table class="arco-table-element" cellpadding="0" cellspacing="0">
|
||||||
<tr class="arco-table-tr">
|
<thead>
|
||||||
<th class="arco-table-th" v-for="(_, colIndex) in datas![0]" :key="colIndex">
|
<tr class="arco-table-tr">
|
||||||
<span class="arco-table-cell items-center justify-center">
|
<th class="arco-table-th" v-for="(_, colIndex) in datas![0]" :key="colIndex">
|
||||||
<a-tooltip content="此列后新增列">
|
<span class="arco-table-cell items-center justify-center">
|
||||||
<a-button type="text" size="mini" @click="addColumn(colIndex)" class="delete-col-btn">
|
<a-tooltip content="此列后新增列">
|
||||||
<template #icon>
|
<a-button type="text" size="mini" @click="addColumn(colIndex)" class="delete-col-btn">
|
||||||
<icon-plus />
|
<template #icon>
|
||||||
</template>
|
<icon-plus />
|
||||||
</a-button>
|
</template>
|
||||||
</a-tooltip>
|
</a-button>
|
||||||
<a-tooltip content="删除该列">
|
</a-tooltip>
|
||||||
<a-button
|
<a-tooltip content="删除该列">
|
||||||
type="text"
|
<a-button
|
||||||
size="mini"
|
type="text"
|
||||||
status="danger"
|
size="mini"
|
||||||
@click="deleteColumn(colIndex)"
|
status="danger"
|
||||||
:disabled="datas![0].length <= 1"
|
@click="deleteColumn(colIndex)"
|
||||||
class="delete-col-btn"
|
:disabled="datas![0].length <= 1"
|
||||||
>
|
class="delete-col-btn"
|
||||||
<template #icon>
|
>
|
||||||
<icon-close />
|
<template #icon>
|
||||||
</template>
|
<icon-close />
|
||||||
</a-button>
|
</template>
|
||||||
</a-tooltip>
|
</a-button>
|
||||||
</span>
|
</a-tooltip>
|
||||||
</th>
|
</span>
|
||||||
<th class="arco-table-th" :style="{ textAlign: 'center' }">
|
</th>
|
||||||
<span>操作</span>
|
<th class="arco-table-th" :style="{ textAlign: 'center' }">
|
||||||
</th>
|
<span>操作</span>
|
||||||
</tr>
|
</th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
<tr class="arco-table-tr" v-for="(row, rowIndex) in datas" :key="rowIndex">
|
<tbody>
|
||||||
<td class="arco-table-td" v-for="(col, colIndex) in row" :key="colIndex">
|
<tr class="arco-table-tr" v-for="(row, rowIndex) in datas" :key="rowIndex">
|
||||||
<span class="arco-table-cell">
|
<td class="arco-table-td" v-for="(col, colIndex) in row" :key="colIndex">
|
||||||
<a-textarea auto-size v-model="datas![rowIndex][colIndex]" />
|
<span class="arco-table-cell">
|
||||||
</span>
|
<a-textarea auto-size v-model="datas![rowIndex][colIndex]" />
|
||||||
</td>
|
</span>
|
||||||
<td class="arco-table-td">
|
</td>
|
||||||
<span class="arco-table-cell items-center justify-center">
|
<td class="arco-table-td">
|
||||||
<a-tooltip content="此行后新增行">
|
<span class="arco-table-cell items-center justify-center">
|
||||||
<a-button type="text" size="mini" @click="addRow(rowIndex)" class="delete-col-btn">
|
<a-tooltip content="此行后新增行">
|
||||||
<template #icon>
|
<a-button type="text" size="mini" @click="addRow(rowIndex)" class="delete-col-btn">
|
||||||
<icon-plus />
|
<template #icon>
|
||||||
</template>
|
<icon-plus />
|
||||||
</a-button>
|
</template>
|
||||||
</a-tooltip>
|
</a-button>
|
||||||
<a-tooltip content="删除该行">
|
</a-tooltip>
|
||||||
<a-button size="mini" type="text" status="danger" @click="deleteRow(rowIndex)" :disabled="datas!.length <= 1">
|
<a-tooltip content="删除该行">
|
||||||
<template #icon>
|
<a-button size="mini" type="text" status="danger" @click="deleteRow(rowIndex)" :disabled="datas!.length <= 1">
|
||||||
<icon-delete />
|
<template #icon>
|
||||||
</template>
|
<icon-delete />
|
||||||
</a-button>
|
</template>
|
||||||
</a-tooltip>
|
</a-button>
|
||||||
</span>
|
</a-tooltip>
|
||||||
</td>
|
</span>
|
||||||
</tr>
|
</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
</tbody>
|
||||||
</div>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
|
</template>
|
||||||
<script setup lang="ts">
|
|
||||||
// 该组件储存数据
|
<script setup lang="ts">
|
||||||
const fontnote = defineModel<string>("fontnote")
|
// 该组件储存数据
|
||||||
|
const fontnote = defineModel<string>("fontnote")
|
||||||
const datas = defineModel<string[][]>()
|
|
||||||
|
const datas = defineModel<string[][]>()
|
||||||
// 行列操作
|
|
||||||
const deleteRow = (rowIndex: number) => {
|
// 行列操作
|
||||||
datas.value!.splice(rowIndex, 1)
|
const deleteRow = (rowIndex: number) => {
|
||||||
}
|
datas.value!.splice(rowIndex, 1)
|
||||||
const deleteColumn = (colIndex: number) => {
|
}
|
||||||
datas.value!.forEach((row) => {
|
const deleteColumn = (colIndex: number) => {
|
||||||
row.splice(colIndex, 1)
|
datas.value!.forEach((row) => {
|
||||||
})
|
row.splice(colIndex, 1)
|
||||||
}
|
})
|
||||||
const addRow = (rowIndex: number) => {
|
}
|
||||||
const newRow = new Array(datas.value![0].length).fill("")
|
const addRow = (rowIndex: number) => {
|
||||||
datas.value!.splice(rowIndex + 1, 0, newRow)
|
const newRow = new Array(datas.value![0].length).fill("")
|
||||||
}
|
datas.value!.splice(rowIndex + 1, 0, newRow)
|
||||||
const addColumn = (colIndex: number) => {
|
}
|
||||||
// 处理空表格的特殊情况
|
const addColumn = (colIndex: number) => {
|
||||||
if (datas.value!.length === 0) {
|
// 处理空表格的特殊情况
|
||||||
datas.value!.push([""])
|
if (datas.value!.length === 0) {
|
||||||
return
|
datas.value!.push([""])
|
||||||
}
|
return
|
||||||
// 新增后续列
|
}
|
||||||
datas.value!.forEach((row) => {
|
// 新增后续列
|
||||||
const insertPosition = colIndex === -1 ? row.length : colIndex + 1
|
datas.value!.forEach((row) => {
|
||||||
row.splice(insertPosition, 0, "")
|
const insertPosition = colIndex === -1 ? row.length : colIndex + 1
|
||||||
})
|
row.splice(insertPosition, 0, "")
|
||||||
}
|
})
|
||||||
</script>
|
}
|
||||||
|
</script>
|
||||||
<style scoped lang="less">
|
|
||||||
.fontnote {
|
<style scoped lang="less">
|
||||||
margin: 10px 0;
|
.fontnote {
|
||||||
width: 100%;
|
margin: 10px 0;
|
||||||
}
|
width: 100%;
|
||||||
|
}
|
||||||
.arco-textarea {
|
|
||||||
min-width: 120px;
|
.arco-textarea {
|
||||||
}
|
min-width: 120px;
|
||||||
|
}
|
||||||
.arco-table-cell {
|
|
||||||
padding: 5px;
|
.arco-table-cell {
|
||||||
}
|
padding: 5px;
|
||||||
</style>
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -70,7 +70,8 @@ const handleRelatedChange = async (record) => {
|
|||||||
// 因为switch绑定了record.related所以可以动态改变
|
// 因为switch绑定了record.related所以可以动态改变
|
||||||
loading.value = true
|
loading.value = true
|
||||||
// 判断该用例是否是未通过,如果未执行或已通过则不允许关联问题单
|
// 判断该用例是否是未通过,如果未执行或已通过则不允许关联问题单
|
||||||
if (!caseIsPassed(caseInfo.value)) {
|
// 修改:当用户取消关联时应该不判断是否caseIsPassed
|
||||||
|
if (record.related && !caseIsPassed(caseInfo.value)) {
|
||||||
Message.error("该用例没有缓存或无未通过步骤,请切换页面或设置未通过步骤后添加问题单!")
|
Message.error("该用例没有缓存或无未通过步骤,请切换页面或设置未通过步骤后添加问题单!")
|
||||||
loading.value = false
|
loading.value = false
|
||||||
record.related = !record.related
|
record.related = !record.related
|
||||||
@@ -90,7 +91,7 @@ const handleRelatedChange = async (record) => {
|
|||||||
})
|
})
|
||||||
if (res) {
|
if (res) {
|
||||||
if (!res.data.isOK) {
|
if (!res.data.isOK) {
|
||||||
// 后台说没关联成功则保持不变
|
// 后端返回失败则回退switch状态
|
||||||
record.related = !record.related
|
record.related = !record.related
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,349 +1,348 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ai-modal-container">
|
<div class="ai-modal-container">
|
||||||
<a-modal v-model:visible="visible" width="90%" unmount-on-close draggable :footer="false">
|
<a-modal v-model:visible="visible" width="90%" unmount-on-close draggable :footer="false">
|
||||||
<template #title> AI生成测试项 </template>
|
<template #title> AI生成测试项 </template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<a-button type="primary" :disabled="generateLoading" @click="generateClick">{{
|
<a-button type="primary" :disabled="generateLoading" @click="generateClick">{{
|
||||||
generateLoading ? "AI正在生成测试项中..." : "点击生成测试项"
|
generateLoading ? "AI正在生成测试项中..." : "点击生成测试项"
|
||||||
}}</a-button>
|
}}</a-button>
|
||||||
<a-progress
|
<a-progress
|
||||||
:percent="percent"
|
:percent="percent"
|
||||||
:style="{ width: '100%' }"
|
:style="{ width: '100%' }"
|
||||||
size="large"
|
size="large"
|
||||||
:show-text="false"
|
:show-text="false"
|
||||||
:color="{
|
:color="{
|
||||||
'0%': 'rgb(var(--primary-6))',
|
'0%': 'rgb(var(--primary-6))',
|
||||||
'100%': 'rgb(var(--success-6))'
|
'100%': 'rgb(var(--success-6))'
|
||||||
}"
|
}"
|
||||||
class="mb-2"
|
class="mb-2"
|
||||||
/>
|
/>
|
||||||
<a-list :loading="listLoading" :data="dataList">
|
<a-list :loading="listLoading" :data="dataList">
|
||||||
<template #header> 设计需求:{{ designObj?.name ?? "暂无内容" }} </template>
|
<template #header> 设计需求:{{ designObj?.name ?? "暂无内容" }} </template>
|
||||||
<template #item="{ item, index }">
|
<template #item="{ item, index }">
|
||||||
<a-list-item>
|
<a-list-item>
|
||||||
<div class="item-container">
|
<div class="item-container">
|
||||||
<a-input-group>
|
<a-input-group>
|
||||||
<div class="index-hao">{{ indexTu[index] }}</div>
|
<div class="index-hao">{{ indexTu[index] }}</div>
|
||||||
<span class="label">测试项:</span>
|
<span class="label">测试项:</span>
|
||||||
<a-input placeholder="测试项标识" v-model="item.ident" :style="{ width: '100px' }" @click.stop.prevent></a-input>
|
<a-input placeholder="测试项标识" v-model="item.ident" :style="{ width: '100px' }" @click.stop.prevent></a-input>
|
||||||
<a-input placeholder="测试项名称" v-model="item.title" :style="{ width: '250px' }" @click.stop.prevent></a-input>
|
<a-input placeholder="测试项名称" v-model="item.title" :style="{ width: '250px' }" @click.stop.prevent></a-input>
|
||||||
<a-select placeholder="选择优先级" v-model="item.priority" :style="{ width: '150px' }">
|
<a-select placeholder="选择优先级" v-model="item.priority" :style="{ width: '150px' }">
|
||||||
<a-option value="1">高</a-option>
|
<a-option value="1">高</a-option>
|
||||||
<a-option value="2">中</a-option>
|
<a-option value="2">中</a-option>
|
||||||
<a-option value="3">低</a-option>
|
<a-option value="3">低</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
<a-select placeholder="选择测试类型" v-model="item.testType" :style="{ width: '200px' }">
|
<a-select placeholder="选择测试类型" v-model="item.testType" :style="{ width: '200px' }">
|
||||||
<a-option v-for="type in testType" :key="type.key" :value="type.key">
|
<a-option v-for="type in testType" :key="type.key" :value="type.key">
|
||||||
{{ type.title }}
|
{{ type.title }}
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
<a-select placeholder="选择测试手段" multiple v-model="item.testMethod" :style="{ width: '400px' }">
|
<a-select placeholder="选择测试手段" multiple v-model="item.testMethod" :style="{ width: '400px' }">
|
||||||
<a-option v-for="method in testMethod" :key="method.key" :value="method.key">
|
<a-option v-for="method in testMethod" :key="method.key" :value="method.key">
|
||||||
{{ method.title }}
|
{{ method.title }}
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-input-group>
|
</a-input-group>
|
||||||
<div class="m-2 flex justify-start items-center">
|
<div class="m-2 flex justify-start items-center">
|
||||||
<template v-if="isFPGA">
|
<template v-if="isFPGA">
|
||||||
<div class="label">测试项描述:</div>
|
<div class="label">测试项描述:</div>
|
||||||
<div class="input flex-1">
|
<div class="input flex-1">
|
||||||
<a-input v-model="item.demandDescription"></a-input>
|
<a-input v-model="item.demandDescription"></a-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
|
<div class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
|
||||||
<div class="arco-table-container">
|
<div class="arco-table-container">
|
||||||
<table class="arco-table-element" cellpadding="0" cellspacing="0">
|
<table class="arco-table-element" cellpadding="0" cellspacing="0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="arco-table-tr">
|
<tr class="arco-table-tr">
|
||||||
<th class="arco-table-th" :width="100">
|
<th class="arco-table-th" :width="100">
|
||||||
<span class="arco-table-cell arco-table-cell-align-center">
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
<span class="arco-table-th-title label">子项序号</span>
|
<span class="arco-table-th-title label">子项序号</span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="arco-table-th" :width="200">
|
<th class="arco-table-th" :width="200">
|
||||||
<span class="arco-table-cell arco-table-cell-align-center">
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
<span class="arco-table-th-title label">子项名称</span>
|
<span class="arco-table-th-title label">子项名称</span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
<template v-if="!isFPGA">
|
<template v-if="!isFPGA">
|
||||||
<th class="arco-table-th" :width="250">
|
<th class="arco-table-th" :width="250">
|
||||||
<span class="arco-table-cell arco-table-cell-align-center">
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
<span class="arco-table-th-title label">测试子项描述</span>
|
<span class="arco-table-th-title label">测试子项描述</span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<th class="arco-table-th" :width="800">
|
<th class="arco-table-th" :width="800">
|
||||||
<span class="arco-table-cell arco-table-cell-align-center">
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
<span class="arco-table-th-title label">测试子项步骤</span>
|
<span class="arco-table-th-title label">测试子项步骤</span>
|
||||||
</span>
|
</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<!-- 这里tr要v-for渲染 -->
|
<!-- 这里tr要v-for渲染 -->
|
||||||
<tr class="arco-table-tr" v-for="(row, idx) in item.children" :key="idx">
|
<tr class="arco-table-tr" v-for="(row, idx) in item.children" :key="idx">
|
||||||
<td class="arco-table-td">
|
<td class="arco-table-td">
|
||||||
<span class="arco-table-cell arco-table-cell-align-center">
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
{{ idx + 1 }}
|
{{ Number(idx) + 1 }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="arco-table-td">
|
<td class="arco-table-td">
|
||||||
<span class="arco-table-cell">
|
<span class="arco-table-cell">
|
||||||
<a-textarea auto-size placeholder="请填写测试子项名称" v-model="row.name"></a-textarea>
|
<a-textarea auto-size placeholder="请填写测试子项名称" v-model="row.name"></a-textarea>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<template v-if="!isFPGA">
|
<template v-if="!isFPGA">
|
||||||
<td class="arco-table-td">
|
<td class="arco-table-td">
|
||||||
<span class="arco-table-cell">
|
<span class="arco-table-cell">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
auto-size
|
auto-size
|
||||||
placeholder="请填写测试子项描述"
|
placeholder="请填写测试子项描述"
|
||||||
v-model="row.subDescription"
|
v-model="row.subDescription"
|
||||||
></a-textarea>
|
></a-textarea>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</template>
|
</template>
|
||||||
<td class="arco-table-td">
|
<td class="arco-table-td">
|
||||||
<span class="arco-table-cell">
|
<span class="arco-table-cell">
|
||||||
<OpeAndExpect v-model="row.subStep" />
|
<OpeAndExpect v-model="row.subStep" />
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
</template>
|
</template>
|
||||||
</a-list>
|
</a-list>
|
||||||
<div class="luButton">
|
<div class="luButton">
|
||||||
<a-button :loading="luButtonLoading" type="primary" @click="luButtonClick">确认录入测试项</a-button>
|
<a-button :loading="luButtonLoading" type="primary" @click="luButtonClick">确认录入测试项</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ParentPreview :parent-key="currentKey" />
|
<ParentPreview :parent-key="currentKey" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onUnmounted, ref } from "vue"
|
import { onUnmounted, ref } from "vue"
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
import designApi from "@/api/project/designDemand"
|
import designApi from "@/api/project/designDemand"
|
||||||
import dictApi from "@/api/common"
|
import dictApi from "@/api/common"
|
||||||
import OpeAndExpect from "./OpeAndExpect.vue" // 操作和预期子表格
|
import OpeAndExpect from "./OpeAndExpect.vue" // 操作和预期子表格
|
||||||
import aiApi from "@/api/outs/aiApi"
|
import aiApi from "@/api/outs/aiApi"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import { isEmpty } from "lodash-es"
|
import { isEmpty } from "lodash-es"
|
||||||
import demandApi from "@/api/project/testDemand"
|
import demandApi from "@/api/project/testDemand"
|
||||||
import ParentPreview from "@/views/project/ParentPreview/index.vue"
|
import ParentPreview from "@/views/project/ParentPreview/index.vue"
|
||||||
|
|
||||||
// 常量
|
// 常量
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const indexTu = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚"
|
const indexTu = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚"
|
||||||
const isFPGA = tool.checkForCpuOrFPGA(route.query.plant_type)
|
const isFPGA = tool.checkForCpuOrFPGA(route.query.plant_type)
|
||||||
|
|
||||||
// 初始化测试类型-一起请求处理错误
|
// 初始化测试类型-一起请求处理错误
|
||||||
const testType = ref<any>([])
|
const testType = ref<any>([])
|
||||||
const testMethod = ref<any>([])
|
const testMethod = ref<any>([])
|
||||||
const fetchTestType = async () => {
|
const fetchTestType = async () => {
|
||||||
try {
|
try {
|
||||||
const [typeResponse, methodResponse] = await Promise.all([dictApi.getDict("testType"), dictApi.getDict("testMethod")])
|
const [typeResponse, methodResponse] = await Promise.all([dictApi.getDict("testType"), dictApi.getDict("testMethod")])
|
||||||
testType.value = typeResponse.data
|
testType.value = typeResponse.data
|
||||||
testMethod.value = methodResponse.data
|
testMethod.value = methodResponse.data
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Message.error("初始化测试类型或测试手段错误,请检查网络后重试!")
|
Message.error("初始化测试类型或测试手段错误,请检查网络后重试!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchTestType()
|
fetchTestType()
|
||||||
|
|
||||||
// 初始化设计需求
|
// 初始化设计需求
|
||||||
|
const currentKey: string = route.query.key as string
|
||||||
const currentKey: string = route.query.key as string
|
const getDesign = async () => {
|
||||||
const getDesign = async () => {
|
try {
|
||||||
try {
|
const res = await designApi.getDesignDemandOne({ project_id: route.query.id, key: route.query.key })
|
||||||
const res = await designApi.getDesignDemandOne({ project_id: route.query.id, key: route.query.key })
|
designObj.value = res.data
|
||||||
designObj.value = res.data
|
} catch (e) {
|
||||||
} catch (e) {
|
Message.error("初始化设计需求信息错误,请检查网络后重试!")
|
||||||
Message.error("初始化设计需求信息错误,请检查网络后重试!")
|
}
|
||||||
}
|
}
|
||||||
}
|
getDesign()
|
||||||
getDesign()
|
const designObj: any = ref()
|
||||||
const designObj: any = ref()
|
|
||||||
|
// 进度条和列表加载loading
|
||||||
// 进度条和列表加载loading
|
const percent = ref(0.0)
|
||||||
const percent = ref(0.0)
|
const listLoading = ref(false)
|
||||||
const listLoading = ref(false)
|
|
||||||
|
// 根据测试项生成按钮
|
||||||
// 根据测试项生成按钮
|
const generateLoading = ref(false)
|
||||||
const generateLoading = ref(false)
|
const generateClick = async () => {
|
||||||
const generateClick = async () => {
|
try {
|
||||||
try {
|
generateLoading.value = true
|
||||||
generateLoading.value = true
|
listLoading.value = true
|
||||||
listLoading.value = true
|
percent.value = 0.1 // 开始进度
|
||||||
percent.value = 0.1 // 开始进度
|
startProgressSimulation()
|
||||||
startProgressSimulation()
|
// 变量:给AI的问题
|
||||||
// 变量:给AI的问题
|
const question = tool.htmlToTextWithDOM(designObj.value?.description || "")
|
||||||
const question = tool.htmlToTextWithDOM(designObj.value?.description || "")
|
// 请求后处理结果
|
||||||
// 请求后处理结果
|
const res = await aiApi.getAiTestItem({ question: question, stream: false })
|
||||||
const res = await aiApi.getAiTestItem({ question: question, stream: false })
|
// 判断真实接口和开发环境接口
|
||||||
// 判断真实接口和开发环境接口
|
let tempSolve: any = null
|
||||||
let tempSolve: any = null
|
if (res.data) {
|
||||||
if (res.data) {
|
// 说明是开发环境
|
||||||
// 说明是开发环境
|
tempSolve = res.data
|
||||||
tempSolve = res.data
|
} else {
|
||||||
} else {
|
tempSolve = res
|
||||||
tempSolve = res
|
}
|
||||||
}
|
const solveRes = JSON.parse(tempSolve.history[0].at(-1))
|
||||||
const solveRes = JSON.parse(tempSolve.history[0].at(-1))
|
console.log("AI生成测试项结果:", solveRes)
|
||||||
console.log("AI生成测试项结果:", solveRes)
|
// 给Vue渲染测试项
|
||||||
// 给Vue渲染测试项
|
dataList.value = solveRes
|
||||||
dataList.value = solveRes
|
dataList.value.forEach((it: any) => {
|
||||||
dataList.value.forEach((it: any) => {
|
it.ident = designObj.value.ident
|
||||||
it.ident = designObj.value.ident
|
it.priority = "1"
|
||||||
it.priority = "1"
|
it.testType = "4"
|
||||||
it.testType = "4"
|
it.testMethod = ["4"]
|
||||||
it.testMethod = ["4"]
|
})
|
||||||
})
|
percent.value = 1.0 // 完成进度
|
||||||
percent.value = 1.0 // 完成进度
|
Message.success("生成测试项成功,请完善信息后录入数据")
|
||||||
Message.success("生成测试项成功,请完善信息后录入数据")
|
} catch (e) {
|
||||||
} catch (e) {
|
console.log(e)
|
||||||
console.log(e)
|
percent.value = 0.0
|
||||||
percent.value = 0.0
|
} finally {
|
||||||
} finally {
|
stopProgressSimulation()
|
||||||
stopProgressSimulation()
|
generateLoading.value = false
|
||||||
generateLoading.value = false
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
listLoading.value = false
|
||||||
listLoading.value = false
|
}, 500)
|
||||||
}, 500)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// 生成的AI测试项数据
|
||||||
// 生成的AI测试项数据
|
const dataList = ref([])
|
||||||
const dataList = ref([])
|
|
||||||
|
// 进度条模拟变量和函数
|
||||||
// 进度条模拟变量和函数
|
const progressInterval = ref<NodeJS.Timeout>()
|
||||||
const progressInterval = ref<NodeJS.Timeout>()
|
const startProgressSimulation = () => {
|
||||||
const startProgressSimulation = () => {
|
progressInterval.value = setInterval(() => {
|
||||||
progressInterval.value = setInterval(() => {
|
if (percent.value < 0.8) {
|
||||||
if (percent.value < 0.8) {
|
percent.value += (0.8 - percent.value) * 0.1
|
||||||
percent.value += (0.8 - percent.value) * 0.1
|
}
|
||||||
}
|
}, 200)
|
||||||
}, 200)
|
}
|
||||||
}
|
|
||||||
|
const stopProgressSimulation = () => {
|
||||||
const stopProgressSimulation = () => {
|
if (progressInterval.value) {
|
||||||
if (progressInterval.value) {
|
clearInterval(progressInterval.value)
|
||||||
clearInterval(progressInterval.value)
|
progressInterval.value = undefined
|
||||||
progressInterval.value = undefined
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
onUnmounted(() => {
|
||||||
onUnmounted(() => {
|
stopProgressSimulation()
|
||||||
stopProgressSimulation()
|
})
|
||||||
})
|
|
||||||
|
// defineModel
|
||||||
// defineModel
|
const visible = defineModel<boolean>("visible", { default: false })
|
||||||
const visible = defineModel<boolean>("visible", { default: false })
|
|
||||||
|
// 录入按钮相关
|
||||||
// 录入按钮相关
|
const luButtonLoading = ref(false)
|
||||||
const luButtonLoading = ref(false)
|
const emit = defineEmits(["updateTable"])
|
||||||
const emit = defineEmits(["updateTable"])
|
const luButtonClick = async () => {
|
||||||
const luButtonClick = async () => {
|
// 1.检查是否还未生成测试项
|
||||||
// 1.检查是否还未生成测试项
|
if (isEmpty(dataList.value)) {
|
||||||
if (isEmpty(dataList.value)) {
|
Message.warning("您还未生成测试项,请生成后再试")
|
||||||
Message.warning("您还未生成测试项,请生成后再试")
|
return
|
||||||
return
|
}
|
||||||
}
|
// 2.检查测试项标识、测试项名称、优先级、测试类型、测试手段是否填写
|
||||||
// 2.检查测试项标识、测试项名称、优先级、测试类型、测试手段是否填写
|
const testItem: any = dataList.value.at(0)
|
||||||
const testItem: any = dataList.value.at(0)
|
if (!testItem.title.trim()) {
|
||||||
if (!testItem.title.trim()) {
|
Message.warning("请先填写测试项名称!")
|
||||||
Message.warning("请先填写测试项名称!")
|
return
|
||||||
return
|
}
|
||||||
}
|
if (!testItem.demandDescription.trim()) {
|
||||||
if (!testItem.demandDescription.trim()) {
|
Message.warning("请填写测试项描述后再试!")
|
||||||
Message.warning("请填写测试项描述后再试!")
|
return
|
||||||
return
|
}
|
||||||
}
|
if (testItem.testMethod.length === 0) {
|
||||||
if (testItem.testMethod.length === 0) {
|
Message.warning("请先选择测试手段后再试!")
|
||||||
Message.warning("请先选择测试手段后再试!")
|
return
|
||||||
return
|
}
|
||||||
}
|
// 3.组装接口需要的数据
|
||||||
// 3.组装接口需要的数据
|
const projectId = route.query.id
|
||||||
const projectId = route.query.id
|
const splitKey: string[] = (route.query.key as any).split("-")
|
||||||
const splitKey: string[] = (route.query.key as any).split("-")
|
const round = splitKey[0]
|
||||||
const round = splitKey[0]
|
const dut = splitKey[1]
|
||||||
const dut = splitKey[1]
|
const designDemand = splitKey.at(-1)
|
||||||
const designDemand = splitKey.at(-1)
|
const adequacy: string = "测试用例覆盖测试子项要求的全部内容。\n所有用例执行完毕,对于未执行用例说明未执行原因。"
|
||||||
const adequacy: string = "测试用例覆盖测试子项要求的全部内容。\n所有用例执行完毕,对于未执行用例说明未执行原因。"
|
const ident = testItem.ident
|
||||||
const ident = testItem.ident
|
const name = testItem.title
|
||||||
const name = testItem.title
|
const testType = testItem.testType
|
||||||
const testType = testItem.testType
|
const testMethod = testItem.testMethod
|
||||||
const testMethod = testItem.testMethod
|
const testDesciption = testItem.demandDescription
|
||||||
const testDesciption = testItem.demandDescription
|
const priority = testItem.priority
|
||||||
const priority = testItem.priority
|
const testContent = testItem.children.map(({ name: subName, ...rest }) => ({
|
||||||
const testContent = testItem.children.map(({ name: subName, ...rest }) => ({
|
subName,
|
||||||
subName,
|
...rest
|
||||||
...rest
|
}))
|
||||||
}))
|
// 4.异步录入啦
|
||||||
// 4.异步录入啦
|
try {
|
||||||
try {
|
// 首先设置状态
|
||||||
// 首先设置状态
|
luButtonLoading.value = true
|
||||||
luButtonLoading.value = true
|
generateLoading.value = true
|
||||||
generateLoading.value = true
|
await demandApi.save({
|
||||||
await demandApi.save({
|
projectId,
|
||||||
projectId,
|
round,
|
||||||
round,
|
dut,
|
||||||
dut,
|
designDemand,
|
||||||
designDemand,
|
adequacy,
|
||||||
adequacy,
|
ident,
|
||||||
ident,
|
name,
|
||||||
name,
|
testType,
|
||||||
testType,
|
testMethod,
|
||||||
testMethod,
|
testDesciption,
|
||||||
testDesciption,
|
priority,
|
||||||
priority,
|
testContent
|
||||||
testContent
|
})
|
||||||
})
|
// 请求成功后需要:清除dataList内容,关闭弹窗,提示新增成功,刷新树状结构以及表格(给父组件刷新)
|
||||||
// 请求成功后需要:清除dataList内容,关闭弹窗,提示新增成功,刷新树状结构以及表格(给父组件刷新)
|
dataList.value = []
|
||||||
dataList.value = []
|
visible.value = false
|
||||||
visible.value = false
|
Message.success("录入测试项成功")
|
||||||
Message.success("录入测试项成功")
|
emit("updateTable")
|
||||||
emit("updateTable")
|
} catch (e) {
|
||||||
} catch (e) {
|
} finally {
|
||||||
} finally {
|
luButtonLoading.value = false
|
||||||
luButtonLoading.value = false
|
generateLoading.value = false
|
||||||
generateLoading.value = false
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// 悬浮按钮显示上级设计需求内容
|
||||||
// 悬浮按钮显示上级设计需求内容
|
</script>
|
||||||
</script>
|
|
||||||
|
<style scoped lang="less">
|
||||||
<style scoped lang="less">
|
.index-hao {
|
||||||
.index-hao {
|
font-size: 18px;
|
||||||
font-size: 18px;
|
padding: 0 9px;
|
||||||
padding: 0 9px;
|
color: rgb(var(--primary-5));
|
||||||
color: rgb(var(--primary-5));
|
}
|
||||||
}
|
:deep(.arco-list-item) {
|
||||||
:deep(.arco-list-item) {
|
border: 1px solid #999 !important;
|
||||||
border: 1px solid #999 !important;
|
}
|
||||||
}
|
:deep(.arco-progress-line-bar) {
|
||||||
:deep(.arco-progress-line-bar) {
|
border-radius: 0 !important;
|
||||||
border-radius: 0 !important;
|
}
|
||||||
}
|
:deep(.arco-progress-line) {
|
||||||
:deep(.arco-progress-line) {
|
border-radius: 0 !important;
|
||||||
border-radius: 0 !important;
|
}
|
||||||
}
|
.label {
|
||||||
.label {
|
font-weight: 700;
|
||||||
font-weight: 700;
|
}
|
||||||
}
|
.luButton {
|
||||||
.luButton {
|
margin-left: auto;
|
||||||
margin-left: auto;
|
padding: 10px;
|
||||||
padding: 10px;
|
padding-right: 0;
|
||||||
padding-right: 0;
|
}
|
||||||
}
|
</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import caseApi from "@/api/project/case"
|
|||||||
import { useTreeDataStore } from "@/store"
|
import { useTreeDataStore } from "@/store"
|
||||||
import { isEqual, cloneDeep } from "lodash-es"
|
import { isEqual, cloneDeep } from "lodash-es"
|
||||||
/**
|
/**
|
||||||
* Dut被测件的crud选项
|
* 用例的Crud Init
|
||||||
*/
|
*/
|
||||||
export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
||||||
// globals
|
// globals
|
||||||
@@ -24,7 +24,6 @@ export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
|||||||
if (!beforeFormStep) {
|
if (!beforeFormStep) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
crudRef.value.getFormData().testStep
|
|
||||||
const iuEqualValue = isEqual(crudRef.value.getFormData().testStep, beforeFormStep)
|
const iuEqualValue = isEqual(crudRef.value.getFormData().testStep, beforeFormStep)
|
||||||
!iuEqualValue &&
|
!iuEqualValue &&
|
||||||
app.$modal.confirm({
|
app.$modal.confirm({
|
||||||
|
|||||||
@@ -39,17 +39,9 @@
|
|||||||
@replaceSuccess="replaceSuccessHandle"
|
@replaceSuccess="replaceSuccessHandle"
|
||||||
/>
|
/>
|
||||||
<!-- 批量替换人员组件 -->
|
<!-- 批量替换人员组件 -->
|
||||||
<replace-person
|
<replace-person :selectRows="undefined" @modify-success="crudRef.refresh()" ref="replacePersonModalRef" />
|
||||||
:selectRows="undefined"
|
|
||||||
@modify-success="crudRef.refresh()"
|
|
||||||
ref="replacePersonModalRef"
|
|
||||||
/>
|
|
||||||
<!-- 批量替换时间 -->
|
<!-- 批量替换时间 -->
|
||||||
<replace-exetime
|
<replace-exetime :selectRows="undefined" @modify-success="crudRef.refresh()" ref="replaceExetimeModalRef" />
|
||||||
:selectRows="undefined"
|
|
||||||
@modify-success="crudRef.refresh()"
|
|
||||||
ref="replaceExetimeModalRef"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,8 @@ const useCrudInit = function () {
|
|||||||
hide: true,
|
hide: true,
|
||||||
search: false,
|
search: false,
|
||||||
formType: "select",
|
formType: "select",
|
||||||
|
maxTagCount: 4,
|
||||||
|
multiple: true,
|
||||||
allowCreate: true,
|
allowCreate: true,
|
||||||
createInfo: {
|
createInfo: {
|
||||||
title: "运行环境"
|
title: "运行环境"
|
||||||
@@ -259,6 +261,8 @@ const useCrudInit = function () {
|
|||||||
hide: true,
|
hide: true,
|
||||||
search: false,
|
search: false,
|
||||||
formType: "select",
|
formType: "select",
|
||||||
|
multiple:true,
|
||||||
|
maxTagCount: 4,
|
||||||
allowCreate: true,
|
allowCreate: true,
|
||||||
createInfo: {
|
createInfo: {
|
||||||
title: "开发环境"
|
title: "开发环境"
|
||||||
|
|||||||
@@ -26,9 +26,7 @@
|
|||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
<a-button @click="enterWorkPlant(record)" size="mini" status="warning" type="outline">
|
<a-button @click="enterWorkPlant(record)" size="mini" status="warning" type="outline"> 工作区 </a-button>
|
||||||
工作区
|
|
||||||
</a-button>
|
|
||||||
<a-link @click="previewRef.open(record)"><icon-eye />预览</a-link>
|
<a-link @click="previewRef.open(record)"><icon-eye />预览</a-link>
|
||||||
<a-link @click="handleFragmentClick(record)"><icon-file />片段</a-link>
|
<a-link @click="handleFragmentClick(record)"><icon-file />片段</a-link>
|
||||||
<a-link @click="handleBoardClick(record)"><icon-dashboard />看板</a-link>
|
<a-link @click="handleBoardClick(record)"><icon-dashboard />看板</a-link>
|
||||||
|
|||||||
Reference in New Issue
Block a user