双击详情完成
This commit is contained in:
263
cdTMP/package-lock.json
generated
263
cdTMP/package-lock.json
generated
@@ -28,7 +28,7 @@
|
||||
"vue": "^3.5.13",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-color-kit": "^1.0.6",
|
||||
"vue-data-ui": "^2.4.50",
|
||||
"vue-data-ui": "^2.4.58",
|
||||
"vue-router": "^4.5.0",
|
||||
"vuedraggable": "^2.24.3"
|
||||
},
|
||||
@@ -48,10 +48,10 @@
|
||||
"less-loader": "^12.2.0",
|
||||
"postcss": "^8.4.49",
|
||||
"prettier": "^3.4.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"rollup-plugin-visualizer": "^5.13.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.2",
|
||||
"vite": "^6.0.5"
|
||||
"vite": "^6.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
@@ -487,9 +487,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz",
|
||||
"integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
|
||||
"integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -504,9 +504,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz",
|
||||
"integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
|
||||
"integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -521,9 +521,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz",
|
||||
"integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -538,9 +538,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -555,9 +555,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz",
|
||||
"integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -572,9 +572,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -589,9 +589,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz",
|
||||
"integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -606,9 +606,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -623,9 +623,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz",
|
||||
"integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
|
||||
"integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -640,9 +640,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz",
|
||||
"integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -657,9 +657,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz",
|
||||
"integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
|
||||
"integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -674,9 +674,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz",
|
||||
"integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
|
||||
"integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -691,9 +691,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz",
|
||||
"integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
|
||||
"integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
@@ -708,9 +708,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz",
|
||||
"integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
|
||||
"integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -725,9 +725,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz",
|
||||
"integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
|
||||
"integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -742,9 +742,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz",
|
||||
"integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
|
||||
"integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -759,9 +759,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -775,10 +775,27 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -793,9 +810,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz",
|
||||
"integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -810,9 +827,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -827,9 +844,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -844,9 +861,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz",
|
||||
"integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -861,9 +878,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz",
|
||||
"integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
|
||||
"integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -878,9 +895,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz",
|
||||
"integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2903,9 +2920,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.0.tgz",
|
||||
"integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==",
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz",
|
||||
"integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
@@ -2916,30 +2933,31 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.24.0",
|
||||
"@esbuild/android-arm": "0.24.0",
|
||||
"@esbuild/android-arm64": "0.24.0",
|
||||
"@esbuild/android-x64": "0.24.0",
|
||||
"@esbuild/darwin-arm64": "0.24.0",
|
||||
"@esbuild/darwin-x64": "0.24.0",
|
||||
"@esbuild/freebsd-arm64": "0.24.0",
|
||||
"@esbuild/freebsd-x64": "0.24.0",
|
||||
"@esbuild/linux-arm": "0.24.0",
|
||||
"@esbuild/linux-arm64": "0.24.0",
|
||||
"@esbuild/linux-ia32": "0.24.0",
|
||||
"@esbuild/linux-loong64": "0.24.0",
|
||||
"@esbuild/linux-mips64el": "0.24.0",
|
||||
"@esbuild/linux-ppc64": "0.24.0",
|
||||
"@esbuild/linux-riscv64": "0.24.0",
|
||||
"@esbuild/linux-s390x": "0.24.0",
|
||||
"@esbuild/linux-x64": "0.24.0",
|
||||
"@esbuild/netbsd-x64": "0.24.0",
|
||||
"@esbuild/openbsd-arm64": "0.24.0",
|
||||
"@esbuild/openbsd-x64": "0.24.0",
|
||||
"@esbuild/sunos-x64": "0.24.0",
|
||||
"@esbuild/win32-arm64": "0.24.0",
|
||||
"@esbuild/win32-ia32": "0.24.0",
|
||||
"@esbuild/win32-x64": "0.24.0"
|
||||
"@esbuild/aix-ppc64": "0.24.2",
|
||||
"@esbuild/android-arm": "0.24.2",
|
||||
"@esbuild/android-arm64": "0.24.2",
|
||||
"@esbuild/android-x64": "0.24.2",
|
||||
"@esbuild/darwin-arm64": "0.24.2",
|
||||
"@esbuild/darwin-x64": "0.24.2",
|
||||
"@esbuild/freebsd-arm64": "0.24.2",
|
||||
"@esbuild/freebsd-x64": "0.24.2",
|
||||
"@esbuild/linux-arm": "0.24.2",
|
||||
"@esbuild/linux-arm64": "0.24.2",
|
||||
"@esbuild/linux-ia32": "0.24.2",
|
||||
"@esbuild/linux-loong64": "0.24.2",
|
||||
"@esbuild/linux-mips64el": "0.24.2",
|
||||
"@esbuild/linux-ppc64": "0.24.2",
|
||||
"@esbuild/linux-riscv64": "0.24.2",
|
||||
"@esbuild/linux-s390x": "0.24.2",
|
||||
"@esbuild/linux-x64": "0.24.2",
|
||||
"@esbuild/netbsd-arm64": "0.24.2",
|
||||
"@esbuild/netbsd-x64": "0.24.2",
|
||||
"@esbuild/openbsd-arm64": "0.24.2",
|
||||
"@esbuild/openbsd-x64": "0.24.2",
|
||||
"@esbuild/sunos-x64": "0.24.2",
|
||||
"@esbuild/win32-arm64": "0.24.2",
|
||||
"@esbuild/win32-ia32": "0.24.2",
|
||||
"@esbuild/win32-x64": "0.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
@@ -5105,14 +5123,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer": {
|
||||
"version": "5.12.0",
|
||||
"resolved": "https://registry.npmmirror.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz",
|
||||
"integrity": "sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==",
|
||||
"version": "5.13.1",
|
||||
"resolved": "https://registry.npmmirror.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.13.1.tgz",
|
||||
"integrity": "sha512-vMg8i6BprL8aFm9DKvL2c8AwS8324EgymYQo9o6E26wgVvwMhsJxS37aNL6ZsU7X9iAcMYwdME7gItLfG5fwJg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"open": "^8.4.0",
|
||||
"picomatch": "^2.3.1",
|
||||
"picomatch": "^4.0.2",
|
||||
"source-map": "^0.7.4",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
@@ -5120,17 +5138,34 @@
|
||||
"rollup-plugin-visualizer": "dist/bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rolldown": "1.x",
|
||||
"rollup": "2.x || 3.x || 4.x"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rolldown": {
|
||||
"optional": true
|
||||
},
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/picomatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz",
|
||||
@@ -5745,13 +5780,13 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.5.tgz",
|
||||
"integrity": "sha512-akD5IAH/ID5imgue2DYhzsEwCi0/4VKY31uhMLEYJwPP4TiUp8pL5PIK+Wo7H8qT8JY9i+pVfPydcFPYD1EL7g==",
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.6.tgz",
|
||||
"integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "0.24.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"postcss": "^8.4.49",
|
||||
"rollup": "^4.23.0"
|
||||
},
|
||||
@@ -5855,9 +5890,9 @@
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "2.4.58",
|
||||
"resolved": "https://registry.npmmirror.com/vue-data-ui/-/vue-data-ui-2.4.58.tgz",
|
||||
"integrity": "sha512-D3GXumRbllzqCqfJtN7DlZs04utnfL585jkHFmv0nLd8fcRzYRQ7k9D+H/lsdOsNGUWemqmuPmZuJrgXFVAUGQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue-eslint-parser": {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"vue": "^3.5.13",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-color-kit": "^1.0.6",
|
||||
"vue-data-ui": "^2.4.50",
|
||||
"vue-data-ui": "^2.4.58",
|
||||
"vue-router": "^4.5.0",
|
||||
"vuedraggable": "^2.24.3"
|
||||
},
|
||||
@@ -51,9 +51,9 @@
|
||||
"less-loader": "^12.2.0",
|
||||
"postcss": "^8.4.49",
|
||||
"prettier": "^3.4.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"rollup-plugin-visualizer": "^5.13.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.2",
|
||||
"vite": "^6.0.5"
|
||||
"vite": "^6.0.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,18 @@ export default {
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 请求单个case信息
|
||||
* @params 传入case完整的key
|
||||
* @params 项目id
|
||||
*/
|
||||
getCaseOne(params = {}) {
|
||||
return request({
|
||||
url: "/project/getCaseOne",
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 添加测试用例
|
||||
* @returns
|
||||
@@ -76,17 +88,5 @@ export default {
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 请求单个case信息
|
||||
* @params 传入case完整的key
|
||||
* @params 项目id
|
||||
*/
|
||||
getCaseOne(params = {}) {
|
||||
return request({
|
||||
url: "/project/getCaseOne",
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,17 @@ export default {
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 查询单个设计需求
|
||||
* @returns 单个设计需求数据
|
||||
*/
|
||||
getDesignDemandOne(params = {}) {
|
||||
return request({
|
||||
url: `project/getDesignOne`,
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 编辑设计需求
|
||||
* @returns 成功编辑或失败
|
||||
@@ -51,7 +62,7 @@ export default {
|
||||
*/
|
||||
update(id, data = {}) {
|
||||
return request({
|
||||
url: "/project/designDemand/update/" + id,
|
||||
url: `project/editDesignDemand/` + id,
|
||||
method: "put",
|
||||
data
|
||||
})
|
||||
|
||||
@@ -11,6 +11,17 @@ export default {
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取单个测试项信息
|
||||
* @returns 单个测试项信息
|
||||
*/
|
||||
getTestDemandOne(params = {}) {
|
||||
return request({
|
||||
url: `project/getTestDemandOne`,
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 添加被测件
|
||||
* @returns
|
||||
|
||||
@@ -232,7 +232,10 @@
|
||||
<!-- w2:轮次的问题单ma-crud,这里要传参2个,首先是请求另外一个接口,然后取消是否关联字段 -->
|
||||
<problem-choose ref="problemRoundRef" hasRelated="roundProblem" :title="problemTitle"></problem-choose>
|
||||
<!-- 下面都是对应被测件、设计需求、测试项、测试用例、问题单的SubForm -->
|
||||
<DutSubForm ref="dutSubFormRef"></DutSubForm>
|
||||
<DutSubForm ref="dutSubFormRef" />
|
||||
<DesignSubForm ref="designSubFormRef" />
|
||||
<TestDemandSubForm ref="testDemandSubFormRef" />
|
||||
<CaseSubForm ref="caseSubFormRef" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -250,6 +253,9 @@ import { storeToRefs } from "pinia"
|
||||
import Progress from "@/views/testmanage/projmanage/cpns/progress.vue"
|
||||
// 导入单独节点类型单独对应的Modal组件
|
||||
import DutSubForm from "@/views/project/round/DutSubForm"
|
||||
import DesignSubForm from "@/views/project/dut/DesignSubForm"
|
||||
import TestDemandSubForm from "@/views/project/design-demand/DemandSubForm"
|
||||
import CaseSubForm from "@/views/project/testDemand/CaseSubForm"
|
||||
// hooks模块化
|
||||
import useTreeDrag from "@/layout/treeHooks/treeDrag.js"
|
||||
import { useRightClick } from "./treeHooks/rightClick"
|
||||
@@ -296,7 +302,8 @@ const {
|
||||
const { expandedKeys, toggleExpanded } = useNodeExpand()
|
||||
|
||||
//~~~~~~大功能:单击/双击节点逻辑~~~~~~
|
||||
const { selectedKeys, pointNode, dutSubFormRef } = useNodeClick(expandedKeys)
|
||||
const { selectedKeys, pointNode, dutSubFormRef, designSubFormRef, testDemandSubFormRef, caseSubFormRef } =
|
||||
useNodeClick(expandedKeys)
|
||||
|
||||
//~~~~~~大功能:动态加载a-tree节点函数~~~~~~
|
||||
const { loadMore } = useLoadTreeNode()
|
||||
|
||||
@@ -6,6 +6,9 @@ import { storeToRefs } from "pinia"
|
||||
import { useRouter } from "vue-router"
|
||||
// 导入组件用于类型
|
||||
import type { DutSubFormInstance } from "@/views/project/round/DutSubForm"
|
||||
import type { DesignSubFormInstance } from "@/views/project/dut/DesignSubForm"
|
||||
import type { DemandSubFormInstance } from "@/views/project/design-demand/DemandSubForm"
|
||||
import type { CaseSubFormInstance } from "@/views/project/testDemand/CaseSubForm"
|
||||
export default function useNodeClick(expandedKeys: Ref<string[]>) {
|
||||
// global
|
||||
const route = useRoute()
|
||||
@@ -21,6 +24,9 @@ export default function useNodeClick(expandedKeys: Ref<string[]>) {
|
||||
const previousKey = ref<any>() // 上一次点击
|
||||
// SubFormRefs
|
||||
const dutSubFormRef = ref<DutSubFormInstance | null>(null)
|
||||
const designSubFormRef = ref<DesignSubFormInstance | null>(null)
|
||||
const testDemandSubFormRef = ref<DemandSubFormInstance | null>(null)
|
||||
const caseSubFormRef = ref<CaseSubFormInstance | null>(null)
|
||||
// 点击节点事件
|
||||
const pointNode = (value: any, data: any) => {
|
||||
// 获取处理单击不选中,双击选中的变量
|
||||
@@ -47,8 +53,13 @@ export default function useNodeClick(expandedKeys: Ref<string[]>) {
|
||||
dutSubFormRef.value!.open(data.node)
|
||||
}
|
||||
if (data.node.level == "2") {
|
||||
designSubFormRef.value!.open(data.node)
|
||||
}
|
||||
if (data.node.level == "3") {
|
||||
testDemandSubFormRef.value!.open(data.node)
|
||||
}
|
||||
if (data.node.level == "4") {
|
||||
caseSubFormRef.value!.open(data.node)
|
||||
}
|
||||
count = 0
|
||||
if (timerId) clearTimeout(timerId)
|
||||
@@ -87,6 +98,9 @@ export default function useNodeClick(expandedKeys: Ref<string[]>) {
|
||||
return {
|
||||
selectedKeys,
|
||||
pointNode,
|
||||
dutSubFormRef
|
||||
dutSubFormRef,
|
||||
designSubFormRef,
|
||||
testDemandSubFormRef,
|
||||
caseSubFormRef
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { defineComponent } from "vue"
|
||||
import { TreeNodeData } from "@arco-design/web-vue"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import testDemandAPI from "@/api/project/testDemand"
|
||||
import useOptions from "./useOptions"
|
||||
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
||||
|
||||
const DemandSubForm = defineComponent({
|
||||
name: "DemandSubFormForm",
|
||||
setup(_, { expose }) {
|
||||
// hook variable
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const { title, formData, formRef, modalOptions, project_id, visible } = subFormHooks(
|
||||
testDemandAPI.update,
|
||||
treeDataStore.updateTestDemandTreeData,
|
||||
"80%"
|
||||
)
|
||||
// hooks
|
||||
const { options, columnOptions } = useOptions(formRef) // **option里面变化**
|
||||
// 双击打开回调
|
||||
const open = async (nodeData: TreeNodeData) => {
|
||||
// 请求数据
|
||||
try {
|
||||
const key = nodeData.key as string
|
||||
// 设置表单名称
|
||||
title.value = nodeData.title!
|
||||
const res = await testDemandAPI.getTestDemandOne({ project_id, key }) // **API变化**
|
||||
// 更新表单
|
||||
formData.value = res.data // **属性变化**
|
||||
formData.value.round = key.split("-")[0]
|
||||
formData.value.dut = key.split("-")[1]
|
||||
formData.value.designDemand = key.split("-")[2]
|
||||
visible.value = true
|
||||
} catch (e) {
|
||||
visible.value = false
|
||||
}
|
||||
}
|
||||
// out use
|
||||
expose({ open })
|
||||
|
||||
// Dom
|
||||
return () => (
|
||||
// 注意v-model:visible是不能放在对象解构的
|
||||
<a-modal {...modalOptions} v-model:visible={visible.value}>
|
||||
{{
|
||||
title: () => <span>[设计需求]-{title.value}</span>,
|
||||
default: () => (
|
||||
<ma-form
|
||||
ref={formRef}
|
||||
v-model={formData.value}
|
||||
options={options.value}
|
||||
columns={columnOptions.value}
|
||||
>
|
||||
{{
|
||||
"inputPrepend-ident": () => <span>XQ_XX_</span>
|
||||
}}
|
||||
</ma-form>
|
||||
)
|
||||
}}
|
||||
</a-modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default DemandSubForm
|
||||
// 组件类型导出
|
||||
type DemandSubFormOrigin = InstanceType<typeof DemandSubForm>
|
||||
export interface DemandSubFormInstance extends DemandSubFormOrigin {
|
||||
open(nodeData: TreeNodeData): void
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ref, computed } from "vue"
|
||||
import tool from "@/utils/tool"
|
||||
import useColumn from "../hooks/useColumns"
|
||||
|
||||
// demand在这里设置不同ma-form选项
|
||||
export default function useOptions(formRef: any) {
|
||||
const options = ref({
|
||||
showButtons: false,
|
||||
labelAlign: "center"
|
||||
})
|
||||
const crudColumns = useColumn(formRef)
|
||||
const columnOptions = computed(() => {
|
||||
return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules")
|
||||
})
|
||||
return { options, columnOptions }
|
||||
}
|
||||
145
cdTMP/src/views/project/design-demand/hooks/useColumns.ts
Normal file
145
cdTMP/src/views/project/design-demand/hooks/useColumns.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { ref } from "vue"
|
||||
import PinYinMatch from "pinyin-match"
|
||||
|
||||
export default function (crudOrFormRef: any) {
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
align: "center",
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
display: false
|
||||
},
|
||||
{
|
||||
title: "测项标识",
|
||||
width: 150,
|
||||
dataIndex: "ident",
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
align: "center",
|
||||
search: true,
|
||||
validateTrigger: "blur",
|
||||
placeholder: "请填写测试项的标识,注意标识不能重复",
|
||||
commonRules: [{ required: true, message: "测试项标识必填" }],
|
||||
openPrepend: true
|
||||
},
|
||||
{
|
||||
title: "名称",
|
||||
dataIndex: "name",
|
||||
width: 120,
|
||||
align: "center",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "名称是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "优先级",
|
||||
dataIndex: "priority",
|
||||
search: true,
|
||||
formType: "radio",
|
||||
align: "center",
|
||||
addDefaultValue: "1",
|
||||
dict: {
|
||||
name: "priority",
|
||||
props: { label: "title", value: "key" },
|
||||
translation: true,
|
||||
tagColors: { 1: "red", 2: "blue", 3: "green" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "测试类型",
|
||||
dataIndex: "testType",
|
||||
search: true,
|
||||
align: "center",
|
||||
formType: "select",
|
||||
sortable: { sortDirections: ["ascend", "descend"] },
|
||||
addDefaultValue: "4",
|
||||
maxLength: 200,
|
||||
commonRules: [{ required: true, message: "测试类型必选" }],
|
||||
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
|
||||
extra: "支持拼音搜索,例如:gn可以搜索出功能测试",
|
||||
// 这是arco的属性,所以在ma-crud和ma-form可以直接使用arco属性和事件(事件+onXXX)
|
||||
filterOption: function (inputValue, selectedOption) {
|
||||
if (inputValue) {
|
||||
let matchRes = PinYinMatch.match(selectedOption.label, inputValue)
|
||||
if (matchRes) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "测试手段",
|
||||
align: "center",
|
||||
dataIndex: "testMethod",
|
||||
formType: "select",
|
||||
multiple: true,
|
||||
dict: { name: "testMethod", props: { label: "title", value: "key" }, translation: true }
|
||||
},
|
||||
{
|
||||
title: "充分性要求",
|
||||
hide: true,
|
||||
dataIndex: "adequacy",
|
||||
formType: "textarea",
|
||||
maxLength: 256,
|
||||
commonRules: [{ required: true, message: "充分性描述必填" }],
|
||||
addDefaultValue:
|
||||
"测试用例覆盖XX子项名称1、XX子项名称2、XX子项名称3子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。"
|
||||
},
|
||||
{
|
||||
title: "测试子项",
|
||||
hide: true,
|
||||
dataIndex: "testContent",
|
||||
commonRules: [{ required: true, message: "测试方法是必填的" }],
|
||||
formType: "children-form",
|
||||
formList: [
|
||||
{
|
||||
title: "子项名称",
|
||||
dataIndex: "subName",
|
||||
placeholder: "对应测试项描述标题,和测试方法的标题",
|
||||
rules: [{ required: true, message: "测试子项名称必填" }],
|
||||
onChange: (ev) => {
|
||||
// 取出子项的对象数组
|
||||
const subItemFormData = crudOrFormRef.value.getFormData().testContent
|
||||
// 取出充分性条件字段字符串
|
||||
const mapRes = subItemFormData.map((subItem) => subItem.subName)
|
||||
crudOrFormRef.value.getFormData().adequacy = `测试用例覆盖${mapRes.join(
|
||||
"、"
|
||||
)}子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "子项描述",
|
||||
dataIndex: "subDesc",
|
||||
formType: "textarea",
|
||||
placeholder: "对应大纲测试项表格的测试项描述",
|
||||
rules: [{ required: true, message: "测试子项描述必填" }]
|
||||
},
|
||||
{
|
||||
title: "条件",
|
||||
dataIndex: "condition",
|
||||
formType: "textarea",
|
||||
placeholder: "在什么环境和前置条件下"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
formType: "textarea",
|
||||
placeholder: "通过xxx操作"
|
||||
},
|
||||
{
|
||||
title: "观察",
|
||||
dataIndex: "observe",
|
||||
formType: "textarea",
|
||||
placeholder: "查看xxx内容"
|
||||
},
|
||||
{
|
||||
title: "期望",
|
||||
dataIndex: "expect",
|
||||
formType: "textarea",
|
||||
placeholder: "xxx结果正确"
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
return crudColumns
|
||||
}
|
||||
131
cdTMP/src/views/project/design-demand/hooks/useCrudOpMore.ts
Normal file
131
cdTMP/src/views/project/design-demand/hooks/useCrudOpMore.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import MaCrud from "@/components/ma-crud/index.vue"
|
||||
import { type Ref, ref, getCurrentInstance } from "vue"
|
||||
import testDemandApi from "@/api/project/testDemand"
|
||||
import { useRoute } from "vue-router"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import { cloneDeep, isEqual } from "lodash-es"
|
||||
// types
|
||||
interface ITestContent {
|
||||
subName: string
|
||||
subDesc: string
|
||||
}
|
||||
/**
|
||||
* 测试项表格的Crud-options
|
||||
*/
|
||||
export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
||||
// global
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const route = useRoute() as any
|
||||
// variable
|
||||
const roundNumber = (route.query.key as string)!.split("-")[0]
|
||||
const dutNumber = (route.query.key as string)!.split("-")[1]
|
||||
const designDemandNumber = (route.query.key as string)!.split("-")[2]
|
||||
// refs
|
||||
const projectId = ref(route.query.id)
|
||||
// 处理弹窗关闭事件:处理用户数据是否保留
|
||||
const app = getCurrentInstance()!.appContext.config.globalProperties
|
||||
let beforeFormContent: ITestContent[] | undefined = undefined
|
||||
const handleBeforeCancel = () => {
|
||||
if (!beforeFormContent) {
|
||||
return
|
||||
}
|
||||
const iuEqualValue = isEqual(crudRef.value.getFormData().testContent, beforeFormContent)
|
||||
!iuEqualValue &&
|
||||
app.$modal.confirm({
|
||||
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||
content: "",
|
||||
okText: "保留",
|
||||
cancelText: "恢复原数据",
|
||||
simple: true,
|
||||
onOk: () => null,
|
||||
onCancel: () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
const crudOptions = ref({
|
||||
api: testDemandApi.getTestDemandList,
|
||||
add: { show: true, api: testDemandApi.save, text: "新增测试项" },
|
||||
edit: { show: true, api: testDemandApi.update, text: "修改测试项" },
|
||||
delete: { show: true, api: testDemandApi.delete },
|
||||
showTools: false,
|
||||
beforeOpenAdd: function () {
|
||||
// 1.新增则将form的content数据变为undifined以便判断
|
||||
beforeFormContent = undefined
|
||||
// 2.设置标识
|
||||
let key_split = (route.query.key as string)!.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} > ${td[round_key].children[dut_key].children[design_key].title} > 测试项-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
// 1.储存打开前form的content数据到ref中,以便后续比较
|
||||
beforeFormContent = cloneDeep(record.testContent)
|
||||
// 2.处理标识
|
||||
let key_split = (route.query.key as string)!.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} > ${td[round_key].children[dut_key].children[design_key].title} >测试项[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res: any) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateTestDemandTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res: any) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateTestDemandTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (_: any, record: any) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateTestDemandTreeData(record, id)
|
||||
// 清空选择
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber,
|
||||
dut: dutNumber,
|
||||
designDemand: designDemandNumber
|
||||
},
|
||||
showIndex: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 3,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 200,
|
||||
operationColumn: true,
|
||||
operationColumnAlign: "center",
|
||||
formOption: {
|
||||
width: 1200,
|
||||
layout: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "ident" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "name" }] }
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ dataIndex: "priority" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "testType" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "testMethod" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
return { projectId, crudOptions, handleBeforeCancel }
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
import { ref, getCurrentInstance } from "vue"
|
||||
import PinYinMatch from "pinyin-match"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import { useRoute } from "vue-router"
|
||||
import testDemandApi from "@/api/project/testDemand"
|
||||
import { isEqual, cloneDeep } from "lodash-es"
|
||||
interface ITestContent {
|
||||
subName: string
|
||||
subDesc: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 1.配置crud以及全组件使用变量
|
||||
* 2.另外包含一个测试项是否保留数据的功能,含一个ref以及一个事件处理函数
|
||||
*/
|
||||
export default function useCrudRef() {
|
||||
// global
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const route = useRoute()
|
||||
// variable
|
||||
const roundNumber = (route.query.key as string)!.split("-")[0]
|
||||
const dutNumber = (route.query.key as string)!.split("-")[1]
|
||||
const designDemandNumber = (route.query.key as string)!.split("-")[2]
|
||||
// refs
|
||||
const projectId = ref(route.query.id)
|
||||
const crudRef = ref()
|
||||
// 处理弹窗关闭事件:处理用户数据是否保留
|
||||
|
||||
const app = getCurrentInstance()!.appContext.config.globalProperties
|
||||
let beforeFormContent: ITestContent[] | undefined = undefined
|
||||
const handleBeforeCancel = () => {
|
||||
if (!beforeFormContent) {
|
||||
return
|
||||
}
|
||||
const iuEqualValue = isEqual(crudRef.value.getFormData().testContent, beforeFormContent)
|
||||
!iuEqualValue &&
|
||||
app.$modal.confirm({
|
||||
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||
content: "",
|
||||
okText: "保留",
|
||||
cancelText: "恢复原数据",
|
||||
simple: true,
|
||||
onOk: () => null,
|
||||
onCancel: () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
// 配置
|
||||
// crud组件
|
||||
const crudOptions = ref({
|
||||
api: testDemandApi.getTestDemandList,
|
||||
add: { show: true, api: testDemandApi.save, text: "新增测试项" },
|
||||
edit: { show: true, api: testDemandApi.update, text: "修改测试项" },
|
||||
delete: { show: true, api: testDemandApi.delete },
|
||||
showTools: false,
|
||||
beforeOpenAdd: function () {
|
||||
// 1.新增则将form的content数据变为undifined以便判断
|
||||
beforeFormContent = undefined
|
||||
// 2.设置标识
|
||||
let key_split = (route.query.key as string)!.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} > ${td[round_key].children[dut_key].children[design_key].title} > 测试项-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
// 1.储存打开前form的content数据到ref中,以便后续比较
|
||||
beforeFormContent = cloneDeep(record.testContent)
|
||||
// 2.处理标识
|
||||
let key_split = (route.query.key as string)!.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} > ${td[round_key].children[dut_key].children[design_key].title} >测试项[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateTestDemandTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateTestDemandTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateTestDemandTreeData(record, id)
|
||||
// 清空选择
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber,
|
||||
dut: dutNumber,
|
||||
designDemand: designDemandNumber
|
||||
},
|
||||
showIndex: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 3,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 200,
|
||||
operationColumn: true,
|
||||
operationColumnAlign: "center",
|
||||
formOption: {
|
||||
width: 1200,
|
||||
layout: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "ident" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "name" }] }
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ dataIndex: "priority" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "testType" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "testMethod" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
align: "center",
|
||||
hide: true,
|
||||
dataIndex: "id"
|
||||
},
|
||||
{
|
||||
title: "测项标识",
|
||||
width: 150,
|
||||
dataIndex: "ident",
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
align: "center",
|
||||
search: true,
|
||||
validateTrigger: "blur",
|
||||
placeholder: "请填写测试项的标识,注意标识不能重复",
|
||||
commonRules: [{ required: true, message: "测试项标识必填" }],
|
||||
openPrepend: true
|
||||
},
|
||||
{
|
||||
title: "名称",
|
||||
dataIndex: "name",
|
||||
width: 120,
|
||||
align: "center",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "名称是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "优先级",
|
||||
dataIndex: "priority",
|
||||
search: true,
|
||||
formType: "radio",
|
||||
align: "center",
|
||||
addDefaultValue: "1",
|
||||
dict: {
|
||||
name: "priority",
|
||||
props: { label: "title", value: "key" },
|
||||
translation: true,
|
||||
tagColors: { 1: "red", 2: "blue", 3: "green" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "测试类型",
|
||||
dataIndex: "testType",
|
||||
search: true,
|
||||
align: "center",
|
||||
formType: "select",
|
||||
sortable: { sortDirections: ["ascend", "descend"] },
|
||||
addDefaultValue: "4",
|
||||
maxLength: 200,
|
||||
commonRules: [{ required: true, message: "测试类型必选" }],
|
||||
dict: { name: "testType", translation: true, props: { label: "title", value: "key" } },
|
||||
extra: "支持拼音搜索,例如:gn可以搜索出功能测试",
|
||||
// 这是arco的属性,所以在ma-crud和ma-form可以直接使用arco属性和事件(事件+onXXX)
|
||||
filterOption: function (inputValue, selectedOption) {
|
||||
if (inputValue) {
|
||||
let matchRes = PinYinMatch.match(selectedOption.label, inputValue)
|
||||
if (matchRes) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "测试手段",
|
||||
align: "center",
|
||||
dataIndex: "testMethod",
|
||||
formType: "select",
|
||||
multiple: true,
|
||||
dict: { name: "testMethod", props: { label: "title", value: "key" }, translation: true }
|
||||
},
|
||||
{
|
||||
title: "充分性要求",
|
||||
hide: true,
|
||||
dataIndex: "adequacy",
|
||||
formType: "textarea",
|
||||
maxLength: 256,
|
||||
commonRules: [{ required: true, message: "充分性描述必填" }],
|
||||
addDefaultValue:
|
||||
"测试用例覆盖XX子项名称1、XX子项名称2、XX子项名称3子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。"
|
||||
},
|
||||
{
|
||||
title: "测试子项",
|
||||
hide: true,
|
||||
dataIndex: "testContent",
|
||||
commonRules: [{ required: true, message: "测试方法是必填的" }],
|
||||
formType: "children-form",
|
||||
formList: [
|
||||
{
|
||||
title: "子项名称",
|
||||
dataIndex: "subName",
|
||||
placeholder: "对应测试项描述标题,和测试方法的标题",
|
||||
rules: [{ required: true, message: "测试子项名称必填" }],
|
||||
onChange: (ev) => {
|
||||
// 取出子项的对象数组
|
||||
const subItemFormData = crudRef.value.getFormData().testContent
|
||||
// 取出充分性条件字段字符串
|
||||
const mapRes = subItemFormData.map((subItem) => subItem.subName)
|
||||
crudRef.value.getFormData().adequacy = `测试用例覆盖${mapRes.join(
|
||||
"、"
|
||||
)}子项要求的全部内容。\n所有用例执行完毕,对于未执行的用例说明未执行原因。`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "子项描述",
|
||||
dataIndex: "subDesc",
|
||||
formType: "textarea",
|
||||
placeholder: "对应大纲测试项表格的测试项描述",
|
||||
rules: [{ required: true, message: "测试子项描述必填" }]
|
||||
},
|
||||
{
|
||||
title: "条件",
|
||||
dataIndex: "condition",
|
||||
formType: "textarea",
|
||||
placeholder: "在什么环境和前置条件下"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
formType: "textarea",
|
||||
placeholder: "通过xxx操作"
|
||||
},
|
||||
{
|
||||
title: "观察",
|
||||
dataIndex: "observe",
|
||||
formType: "textarea",
|
||||
placeholder: "查看xxx内容"
|
||||
},
|
||||
{
|
||||
title: "期望",
|
||||
dataIndex: "expect",
|
||||
formType: "textarea",
|
||||
placeholder: "xxx结果正确"
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
return {
|
||||
projectId,
|
||||
crudRef,
|
||||
crudOptions,
|
||||
crudColumns,
|
||||
handleBeforeCancel
|
||||
}
|
||||
}
|
||||
@@ -45,11 +45,14 @@
|
||||
import { ref } from "vue"
|
||||
import commonApi from "@/api/common"
|
||||
// hooks
|
||||
import useCrudRef from "./hooks/useCrudRef"
|
||||
import useCrudOpMore from "./hooks/useCrudOpMore"
|
||||
import useColumn from "./hooks/useColumns"
|
||||
import useRalateDemand from "./hooks/useRalateDemand"
|
||||
|
||||
// refs
|
||||
const crudRef = ref(null)
|
||||
// 根据传参获取key,分别为轮次、设计需求的key
|
||||
const { projectId, crudRef, crudOptions, crudColumns, handleBeforeCancel } = useCrudRef()
|
||||
const { projectId, crudOptions, handleBeforeCancel } = useCrudOpMore(crudRef)
|
||||
const crudColumns = useColumn(crudRef)
|
||||
// 关联弹窗、关联的事件处理
|
||||
const { visible, relatedData, options, cascaderLoading, computedRelatedData, handleOpenRelationCSX, handleRelatedOk } =
|
||||
useRalateDemand(projectId)
|
||||
|
||||
69
cdTMP/src/views/project/dut/DesignSubForm/index.tsx
Normal file
69
cdTMP/src/views/project/dut/DesignSubForm/index.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { defineComponent } from "vue"
|
||||
import { TreeNodeData } from "@arco-design/web-vue"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import designDemandAPI from "@/api/project/designDemand"
|
||||
import useOptions from "./useOptions"
|
||||
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
||||
|
||||
const DesignSubForm = defineComponent({
|
||||
name: "DesignSubForm",
|
||||
setup(_, { expose }) {
|
||||
// hook variable
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const { title, formData, formRef, modalOptions, project_id, visible } = subFormHooks(
|
||||
designDemandAPI.update,
|
||||
treeDataStore.updateDesignDemandTreeData,
|
||||
"80%"
|
||||
)
|
||||
// hooks
|
||||
const { options, columnOptions } = useOptions(formRef) // **option里面变化**
|
||||
// 双击打开回调
|
||||
const open = async (nodeData: TreeNodeData) => {
|
||||
// 请求数据
|
||||
try {
|
||||
const key = nodeData.key as string
|
||||
// 设置表单名称
|
||||
title.value = nodeData.title!
|
||||
const res = await designDemandAPI.getDesignDemandOne({ project_id, key }) // **API变化**
|
||||
// 更新表单
|
||||
formData.value = res.data // **属性变化**
|
||||
formData.value.round = key.split("-")[0]
|
||||
formData.value.dut = key.split("-")[1]
|
||||
visible.value = true
|
||||
} catch (e) {
|
||||
visible.value = false
|
||||
}
|
||||
}
|
||||
// out use
|
||||
expose({ open })
|
||||
|
||||
// Dom
|
||||
return () => (
|
||||
// 注意v-model:visible是不能放在对象解构的
|
||||
<a-modal {...modalOptions} v-model:visible={visible.value}>
|
||||
{{
|
||||
title: () => <span>[设计需求]-{title.value}</span>,
|
||||
default: () => (
|
||||
<ma-form
|
||||
ref={formRef}
|
||||
v-model={formData.value}
|
||||
options={options.value}
|
||||
columns={columnOptions.value}
|
||||
>
|
||||
{{
|
||||
"inputPrepend-ident": () => <span>SJ-XX-</span>
|
||||
}}
|
||||
</ma-form>
|
||||
)
|
||||
}}
|
||||
</a-modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default DesignSubForm
|
||||
// 组件类型导出
|
||||
type DesignSubFormOrigin = InstanceType<typeof DesignSubForm>
|
||||
export interface DesignSubFormInstance extends DesignSubFormOrigin {
|
||||
open(nodeData: TreeNodeData): void
|
||||
}
|
||||
16
cdTMP/src/views/project/dut/DesignSubForm/useOptions.ts
Normal file
16
cdTMP/src/views/project/dut/DesignSubForm/useOptions.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ref, computed } from "vue"
|
||||
import tool from "@/utils/tool"
|
||||
import useColumn from "../hooks/useColumns"
|
||||
|
||||
// 设置不同ma-form选项
|
||||
export default function useOptions(formRef: any) {
|
||||
const options = ref({
|
||||
showButtons: false,
|
||||
labelAlign: "center"
|
||||
})
|
||||
const crudColumns = useColumn(formRef)
|
||||
const columnOptions = computed(() => {
|
||||
return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules")
|
||||
})
|
||||
return { options, columnOptions }
|
||||
}
|
||||
119
cdTMP/src/views/project/dut/hooks/useColumns.ts
Normal file
119
cdTMP/src/views/project/dut/hooks/useColumns.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { ref } from "vue"
|
||||
|
||||
export default function (crudOrFormRef: any) {
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
align: "center",
|
||||
width: 50,
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
commonRules: [{ required: true, message: "ID必填" }],
|
||||
validateTrigger: "blur",
|
||||
display: false
|
||||
},
|
||||
{
|
||||
title: "设需标识",
|
||||
align: "center",
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
width: 180,
|
||||
dataIndex: "ident",
|
||||
search: true,
|
||||
validateTrigger: "blur",
|
||||
placeholder: "请输入文档中设计需求的标识",
|
||||
help: '若不知道则填"无"或不填',
|
||||
openPrepend: true
|
||||
},
|
||||
{
|
||||
title: "设需名称",
|
||||
align: "center",
|
||||
width: 200,
|
||||
dataIndex: "name",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "设计需求名称是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "章节号",
|
||||
align: "center",
|
||||
width: 150,
|
||||
dataIndex: "chapter",
|
||||
search: true,
|
||||
help: '若为隐含需求则填"/"'
|
||||
},
|
||||
{
|
||||
title: "需求类型",
|
||||
width: 150,
|
||||
align: "center",
|
||||
dataIndex: "demandType",
|
||||
addDefaultValue: "1",
|
||||
formType: "radio",
|
||||
search: true,
|
||||
dict: { name: "demandType", props: { label: "title", value: "key" }, translation: true },
|
||||
commonRules: [{ required: true, message: "需求类型是必填" }],
|
||||
validateTrigger: "blur",
|
||||
// 主要为了添加“接口”的4个字段
|
||||
onControl: (value) => {
|
||||
if (value === "3") {
|
||||
return {
|
||||
source: { display: true },
|
||||
to: { display: true },
|
||||
type: { display: true },
|
||||
protocal: { display: true }
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
source: { display: false },
|
||||
to: { display: false },
|
||||
type: { display: false },
|
||||
protocal: { display: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
formType: "grid-tailwind",
|
||||
customClass: [],
|
||||
colNumber: 2,
|
||||
cols: [
|
||||
{
|
||||
formList: [
|
||||
{
|
||||
title: "接口来源",
|
||||
dataIndex: "source",
|
||||
hide: true
|
||||
},
|
||||
{
|
||||
title: "目的地",
|
||||
dataIndex: "to",
|
||||
hide: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
formList: [
|
||||
{
|
||||
title: "接口类型",
|
||||
dataIndex: "type",
|
||||
hide: true
|
||||
},
|
||||
{
|
||||
title: "接口内容",
|
||||
dataIndex: "protocal",
|
||||
hide: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "需求描述",
|
||||
dataIndex: "description",
|
||||
hide: true,
|
||||
width: 300,
|
||||
formType: "editor",
|
||||
height: 300
|
||||
}
|
||||
])
|
||||
return crudColumns
|
||||
}
|
||||
74
cdTMP/src/views/project/dut/hooks/useCrudOptions.ts
Normal file
74
cdTMP/src/views/project/dut/hooks/useCrudOptions.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import MaCrud from "@/components/ma-crud/index.vue"
|
||||
import { type Ref, ref } from "vue"
|
||||
import designDemandApi from "@/api/project/designDemand"
|
||||
import { useRoute } from "vue-router"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
/**
|
||||
* Dut被测件的crud选项
|
||||
*/
|
||||
export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
||||
// globals
|
||||
const route = useRoute() as any
|
||||
const projectId = ref(route.query.id)
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const roundNumber = (route.query.key as any).split("-")[0]
|
||||
const dutNumber = (route.query.key as any).split("-")[1]
|
||||
// refs
|
||||
const crudOptions = ref({
|
||||
api: designDemandApi.getDesignDemandList,
|
||||
add: { show: true, api: designDemandApi.save, text: "新增设计需求" },
|
||||
edit: { show: true, api: designDemandApi.editDesignDemand, text: "编辑设计需求" },
|
||||
delete: { show: true, api: designDemandApi.delete },
|
||||
// 处理添加后函数
|
||||
beforeOpenAdd: function () {
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${(td[round_key] as any).title} > ${(td[round_key] as any).children[dut_key].title} > 设计需求-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${(td[round_key] as any).title} > ${(td[round_key] as any).children[dut_key].title} >设计需求[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDesignDemandTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDesignDemandTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateDesignDemandTreeData(record, id)
|
||||
// 删除后情况行选择器
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber,
|
||||
dut: dutNumber
|
||||
},
|
||||
showIndex: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 4,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 250,
|
||||
operationColumn: true,
|
||||
operationColumnAlign: "center",
|
||||
formOption: {
|
||||
width: 1200
|
||||
},
|
||||
showTools: false
|
||||
})
|
||||
return crudOptions
|
||||
}
|
||||
@@ -25,21 +25,18 @@
|
||||
|
||||
<script setup lang="jsx">
|
||||
import { ref } from "vue"
|
||||
import useCrudOptions from "@/views/project/dut/hooks/useCrudOptions"
|
||||
import useColumns from "./hooks/useColumns"
|
||||
import { useRoute } from "vue-router"
|
||||
import designDemandApi from "@/api/project/designDemand"
|
||||
import dutApi from "@/api/project/dut"
|
||||
import commonApi from "@/api/common"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import FileInputModal from "./components/FileInputModal/index.vue"
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const route = useRoute()
|
||||
const crudRef = ref()
|
||||
const roundNumber = route.query.key.split("-")[0]
|
||||
const dutNumber = route.query.key.split("-")[1]
|
||||
const projectId = ref(route.query.id)
|
||||
// 5月8日修改设计需求标识就按SJ-FT-设计需求标识来
|
||||
const demandTypeDict = ref([])
|
||||
!(function () {
|
||||
;(function () {
|
||||
commonApi.getDict("demandType").then((res) => {
|
||||
demandTypeDict.value = res
|
||||
})
|
||||
@@ -63,175 +60,8 @@ const showType = (record) => {
|
||||
}
|
||||
}
|
||||
// crud组件
|
||||
const crudOptions = ref({
|
||||
api: designDemandApi.getDesignDemandList,
|
||||
add: { show: true, api: designDemandApi.save, text: "新增设计需求" },
|
||||
edit: { show: true, api: designDemandApi.editDesignDemand, text: "编辑设计需求" },
|
||||
delete: { show: true, api: designDemandApi.delete },
|
||||
// 处理添加后函数
|
||||
beforeOpenAdd: function () {
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} > 设计需求-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} > ${td[round_key].title} > ${td[round_key].children[dut_key].title} >设计需求[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDesignDemandTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDesignDemandTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateDesignDemandTreeData(record, id)
|
||||
// 删除后情况行选择器
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber,
|
||||
dut: dutNumber
|
||||
},
|
||||
showIndex: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 4,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 250,
|
||||
operationColumn: true,
|
||||
operationColumnAlign: "center",
|
||||
formOption: {
|
||||
width: 1200
|
||||
},
|
||||
showTools: false
|
||||
})
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
align: "center",
|
||||
width: 50,
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
commonRules: [{ required: true, message: "ID必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "设需标识",
|
||||
align: "center",
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
width: 180,
|
||||
dataIndex: "ident",
|
||||
search: true,
|
||||
validateTrigger: "blur",
|
||||
placeholder: "请输入文档中设计需求的标识",
|
||||
help: '若不知道则填"无"或不填',
|
||||
openPrepend: true
|
||||
},
|
||||
{
|
||||
title: "设需名称",
|
||||
align: "center",
|
||||
width: 200,
|
||||
dataIndex: "name",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "设计需求名称是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "章节号",
|
||||
align: "center",
|
||||
width: 150,
|
||||
dataIndex: "chapter",
|
||||
search: true,
|
||||
help: '若为隐含需求则填"/"'
|
||||
},
|
||||
{
|
||||
title: "需求类型",
|
||||
width: 150,
|
||||
align: "center",
|
||||
dataIndex: "demandType",
|
||||
addDefaultValue: "1",
|
||||
formType: "radio",
|
||||
search: true,
|
||||
dict: { name: "demandType", props: { label: "title", value: "key" }, translation: true },
|
||||
commonRules: [{ required: true, message: "需求类型是必填" }],
|
||||
validateTrigger: "blur",
|
||||
// 主要为了添加“接口”的4个字段
|
||||
onControl: (value) => {
|
||||
if (value === "3") {
|
||||
return {
|
||||
source: { display: true },
|
||||
to: { display: true },
|
||||
type: { display: true },
|
||||
protocal: { display: true }
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
source: { display: false },
|
||||
to: { display: false },
|
||||
type: { display: false },
|
||||
protocal: { display: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
formType: "grid-tailwind",
|
||||
customClass: [],
|
||||
colNumber: 2,
|
||||
cols: [
|
||||
{
|
||||
formList: [
|
||||
{
|
||||
title: "接口来源",
|
||||
dataIndex: "source",
|
||||
hide: true
|
||||
},
|
||||
{
|
||||
title: "目的地",
|
||||
dataIndex: "to",
|
||||
hide: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
formList: [
|
||||
{
|
||||
title: "接口类型",
|
||||
dataIndex: "type",
|
||||
hide: true
|
||||
},
|
||||
{
|
||||
title: "接口内容",
|
||||
dataIndex: "protocal",
|
||||
hide: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "需求描述",
|
||||
dataIndex: "description",
|
||||
hide: true,
|
||||
width: 300,
|
||||
formType: "editor",
|
||||
height: 300
|
||||
}
|
||||
])
|
||||
const crudOptions = useCrudOptions(crudRef)
|
||||
const crudColumns = useColumns(crudRef)
|
||||
// ~~~大功能打开ma-form-modal~~~
|
||||
const fileInputRef = ref(null)
|
||||
const handleAddFileInputDemand = () => {
|
||||
|
||||
42
cdTMP/src/views/project/projPublicHooks/subFormHooks.ts
Normal file
42
cdTMP/src/views/project/projPublicHooks/subFormHooks.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 该hook为了各个页面双击弹窗SubForm进行公共代码提取
|
||||
*/
|
||||
import { ref, inject } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import MaForm from "@/components/ma-form/index.vue"
|
||||
import { Message } from "@arco-design/web-vue"
|
||||
|
||||
export default function (updateApiFunc: Function, updateTreeFunc: Function, width = "40%") {
|
||||
const route = useRoute()
|
||||
const project_id = route.query.id // 只能拿ID其他是null
|
||||
const rightViewRef = inject("rightViewRef")
|
||||
// has returns
|
||||
const visible = ref(false)
|
||||
const formRef = ref<InstanceType<typeof MaForm> | null>(null)
|
||||
const formData = ref<any>({})
|
||||
// 标题
|
||||
const title = ref("")
|
||||
// 异步确认按钮点击
|
||||
const handleBeforeOk = async () => {
|
||||
const isValidated = await formRef.value!.validateForm()
|
||||
if (isValidated) {
|
||||
// 失败
|
||||
return false
|
||||
} else {
|
||||
// 成功 **变化**
|
||||
const res = await updateApiFunc(formData.value.id, { project_id, ...formData.value })
|
||||
updateTreeFunc(res.data, project_id) // 刷新树节点信息
|
||||
!(rightViewRef as any).value.refresh()
|
||||
Message.success("修改成功")
|
||||
}
|
||||
}
|
||||
const modalOptions = {
|
||||
width,
|
||||
draggable: true,
|
||||
"unmount-on-close": true,
|
||||
"ok-text": "保存",
|
||||
"cancel-text": "关闭",
|
||||
"on-before-ok": handleBeforeOk
|
||||
}
|
||||
return { title, formData, formRef, modalOptions, project_id, visible }
|
||||
}
|
||||
@@ -1,28 +1,21 @@
|
||||
import { defineComponent, inject, ref } from "vue"
|
||||
import { defineComponent } 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"
|
||||
import subFormHooks from "../../projPublicHooks/subFormHooks"
|
||||
|
||||
const DutSubForm = defineComponent({
|
||||
name: "DutSubForm",
|
||||
setup(props, { expose }) {
|
||||
// globals
|
||||
const route = useRoute()
|
||||
const project_id = route.query.id
|
||||
setup(_, { expose }) {
|
||||
// hook variable
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const rightViewRef = inject("rightViewRef")
|
||||
// refs
|
||||
const visible = ref(false)
|
||||
const formRef = ref<InstanceType<typeof MaForm> | null>(null)
|
||||
const formData = ref<any>({})
|
||||
const { title, formData, formRef, modalOptions, project_id, visible } = subFormHooks(
|
||||
dutAPI.update,
|
||||
treeDataStore.updateDutTreeData
|
||||
)
|
||||
// hooks
|
||||
const { options, columnOptions } = useOptions(formRef)
|
||||
// 标题
|
||||
const title = ref("被测件详情")
|
||||
const { options, columnOptions } = useOptions(formRef) // **变化**
|
||||
// 双击打开回调
|
||||
const open = async (nodeData: TreeNodeData) => {
|
||||
// 请求数据
|
||||
@@ -30,43 +23,22 @@ const DutSubForm = defineComponent({
|
||||
const key = nodeData.key
|
||||
// 设置表单名称
|
||||
title.value = nodeData.title!
|
||||
const res = await dutAPI.getDutOne({ project_id, key })
|
||||
const res = await dutAPI.getDutOne({ project_id, key }) // **API变化**
|
||||
// 更新表单
|
||||
formData.value = res.data
|
||||
formData.value.round = key
|
||||
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}
|
||||
>
|
||||
// 注意v-model:visible是不能放在对象解构的
|
||||
<a-modal {...modalOptions} v-model:visible={visible.value}>
|
||||
{{
|
||||
title: () => <span>[被测件]-{title.value}</span>,
|
||||
default: () => (
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ref, computed } from "vue"
|
||||
import useCrudRef from "@/views/project/round/hooks/useCrudRef"
|
||||
import tool from "@/utils/tool"
|
||||
import useColumn from "../hooks/useColumn"
|
||||
|
||||
export default function useOptions(formRef: any) {
|
||||
const options = ref({
|
||||
showButtons: false,
|
||||
labelAlign: "center"
|
||||
})
|
||||
const { crudColumns } = useCrudRef(undefined, formRef)
|
||||
const crudColumns = useColumn(formRef)
|
||||
const columnOptions = computed(() => {
|
||||
return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules")
|
||||
})
|
||||
|
||||
@@ -1,91 +1,18 @@
|
||||
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
|
||||
|
||||
export default function (crudOrFormRef: any) {
|
||||
// global
|
||||
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()}%`
|
||||
}
|
||||
const formData = crudOrFormRef.value.getFormData()
|
||||
const { code_line, comment_line, mix_line, black_line } = formData
|
||||
const total_line = +black_line + +code_line + +comment_line + +mix_line
|
||||
const comment_total = +comment_line + +mix_line
|
||||
formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%`
|
||||
}
|
||||
// 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",
|
||||
@@ -251,11 +178,9 @@ export default function useCrudRef(crudRef?, formRef?) {
|
||||
placeholder: "计算注释率",
|
||||
hide: true,
|
||||
addDisabled: true,
|
||||
editDisabled: true
|
||||
editDisabled: true,
|
||||
disabled: true
|
||||
}
|
||||
])
|
||||
return {
|
||||
crudOptions,
|
||||
crudColumns
|
||||
}
|
||||
return crudColumns
|
||||
}
|
||||
71
cdTMP/src/views/project/round/hooks/useCrudOptions.ts
Normal file
71
cdTMP/src/views/project/round/hooks/useCrudOptions.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import MaCrud from "@/components/ma-crud/index.vue"
|
||||
import { type Ref, ref } from "vue"
|
||||
import dutApi from "@/api/project/dut"
|
||||
import { useRoute } from "vue-router"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
/**
|
||||
* Dut被测件的crud选项
|
||||
*/
|
||||
export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
||||
// globals
|
||||
const route = useRoute()
|
||||
const projectId = ref(route.query.id)
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const roundNumber = (route.query.key as any).split("-")[0]
|
||||
// refs
|
||||
const crudOptions = {
|
||||
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
|
||||
}
|
||||
}
|
||||
return crudOptions
|
||||
}
|
||||
@@ -12,10 +12,12 @@
|
||||
|
||||
<script setup lang="jsx">
|
||||
import { ref } from "vue"
|
||||
import useCrudRef from "@/views/project/round/hooks/useCrudRef"
|
||||
import useCrudOptions from "@/views/project/round/hooks/useCrudOptions"
|
||||
import useColumn from "@/views/project/round/hooks/useColumn"
|
||||
const crudRef = ref()
|
||||
// crud组件
|
||||
const { crudOptions, crudColumns } = useCrudRef(crudRef)
|
||||
const crudOptions = useCrudOptions(crudRef)
|
||||
const crudColumns = useColumn(crudRef)
|
||||
|
||||
const refreshCrudTable = () => {
|
||||
crudRef.value.refresh()
|
||||
|
||||
69
cdTMP/src/views/project/testDemand/CaseSubForm/index.tsx
Normal file
69
cdTMP/src/views/project/testDemand/CaseSubForm/index.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { defineComponent } from "vue"
|
||||
import { Message, TreeNodeData } from "@arco-design/web-vue"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import caseApi from "@/api/project/case"
|
||||
import useOptions from "./useOptions"
|
||||
import subFormHooks from "@/views/project/projPublicHooks/subFormHooks"
|
||||
|
||||
const CaseSubForm = defineComponent({
|
||||
name: "DemandSubFormForm",
|
||||
setup(_, { expose }) {
|
||||
// hook variable
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const { title, formData, formRef, modalOptions, project_id, visible } = subFormHooks(
|
||||
caseApi.update,
|
||||
treeDataStore.updateCaseTreeData,
|
||||
"80%"
|
||||
)
|
||||
// hooks
|
||||
const { options, columnOptions } = useOptions(formRef) // **option里面变化**
|
||||
// 双击打开回调
|
||||
const open = async (nodeData: TreeNodeData) => {
|
||||
// 请求数据
|
||||
try {
|
||||
const key = nodeData.key as string
|
||||
// 设置表单名称
|
||||
title.value = nodeData.title!
|
||||
// 注意这里因为case接口原因,这里需要projectId!!!!!!!!!!!!!!!
|
||||
const res = await caseApi.getCaseOne({ projectId: project_id, key }) // **API变化**
|
||||
// 更新表单
|
||||
formData.value = res.data // **属性变化**
|
||||
formData.value.round = key.split("-")[0]
|
||||
formData.value.dut = key.split("-")[1]
|
||||
formData.value.designDemand = key.split("-")[2]
|
||||
formData.value.testDemand = key.split("-")[3]
|
||||
visible.value = true
|
||||
} catch (e) {
|
||||
Message.error("数据未获取到,请联系开发者")
|
||||
visible.value = false
|
||||
}
|
||||
}
|
||||
// out use
|
||||
expose({ open })
|
||||
|
||||
// Dom
|
||||
return () => (
|
||||
// 注意v-model:visible是不能放在对象解构的
|
||||
<a-modal {...modalOptions} v-model:visible={visible.value}>
|
||||
{{
|
||||
title: () => <span>[设计需求]-{title.value}</span>,
|
||||
default: () => (
|
||||
<ma-form
|
||||
ref={formRef}
|
||||
v-model={formData.value}
|
||||
options={options.value}
|
||||
columns={columnOptions.value}
|
||||
></ma-form>
|
||||
)
|
||||
}}
|
||||
</a-modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default CaseSubForm
|
||||
// 组件类型导出
|
||||
type CaseSubFormOrigin = InstanceType<typeof CaseSubForm>
|
||||
export interface CaseSubFormInstance extends CaseSubFormOrigin {
|
||||
open(nodeData: TreeNodeData): void
|
||||
}
|
||||
16
cdTMP/src/views/project/testDemand/CaseSubForm/useOptions.ts
Normal file
16
cdTMP/src/views/project/testDemand/CaseSubForm/useOptions.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ref, computed } from "vue"
|
||||
import tool from "@/utils/tool"
|
||||
import useColumn from "../hooks/useColumn"
|
||||
|
||||
// Case用例在这里设置不同ma-form选项
|
||||
export default function useOptions(formRef: any) {
|
||||
const options = ref({
|
||||
showButtons: false,
|
||||
labelAlign: "center"
|
||||
})
|
||||
const crudColumns = useColumn(formRef)
|
||||
const columnOptions = computed(() => {
|
||||
return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules")
|
||||
})
|
||||
return { options, columnOptions }
|
||||
}
|
||||
213
cdTMP/src/views/project/testDemand/hooks/useColumn.tsx
Normal file
213
cdTMP/src/views/project/testDemand/hooks/useColumn.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import { ref } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
|
||||
export default function (crudOrFormRef: any, problemFormRef?: any) {
|
||||
const title = ref("问题单表单")
|
||||
const route = useRoute()
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
width: 60,
|
||||
align: "center",
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
fixed: "left",
|
||||
display: false
|
||||
},
|
||||
{
|
||||
title: "用例标识",
|
||||
dataIndex: "ident",
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
width: 180,
|
||||
align: "center",
|
||||
addDisabled: true,
|
||||
addDefaultValue: "用例标识自动生成,结构为YL_IO_XXXX_001",
|
||||
editDefaultValue: "用例标识自动生成,结构为YL_IO_XXXX_001",
|
||||
editDisabled: true,
|
||||
search: true,
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "名称",
|
||||
dataIndex: "name",
|
||||
align: "center",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "名称是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "是否通过",
|
||||
align: "center",
|
||||
display: false,
|
||||
addDisplay: false,
|
||||
editDisplay: false,
|
||||
customRender: ({ record }) => {
|
||||
let passCount = 0
|
||||
let failCount = 0
|
||||
let stepCount = record.testStep.length
|
||||
record.testStep.forEach((item) => {
|
||||
if (item.passed === "1") {
|
||||
passCount++
|
||||
} else if (item.passed === "2") {
|
||||
failCount++
|
||||
}
|
||||
})
|
||||
if (failCount > 0) {
|
||||
return (
|
||||
<a-tag bordered color="red">
|
||||
未通过
|
||||
</a-tag>
|
||||
)
|
||||
} else {
|
||||
if (passCount === stepCount) {
|
||||
return (
|
||||
<a-tag bordered color="green">
|
||||
已通过
|
||||
</a-tag>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<a-tag bordered color="orange">
|
||||
包含未执行
|
||||
</a-tag>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "设计人员",
|
||||
width: 80,
|
||||
dataIndex: "designPerson",
|
||||
align: "center",
|
||||
hide: true,
|
||||
search: true,
|
||||
formType: "select",
|
||||
dict: {
|
||||
url: "system/user/list",
|
||||
params: { project_id: route.query.id },
|
||||
translation: true,
|
||||
props: { label: "name", value: "name" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "执行人员",
|
||||
dataIndex: "testPerson",
|
||||
width: 120,
|
||||
align: "center",
|
||||
search: true,
|
||||
formType: "select",
|
||||
dict: {
|
||||
url: "system/user/list",
|
||||
params: { project_id: route.query.id },
|
||||
translation: true,
|
||||
props: { label: "name", value: "name" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "审核人员",
|
||||
dataIndex: "monitorPerson",
|
||||
width: 80,
|
||||
align: "center",
|
||||
hide: true,
|
||||
formType: "select",
|
||||
dict: {
|
||||
url: "system/user/list",
|
||||
params: { project_id: route.query.id },
|
||||
translation: true,
|
||||
props: { label: "name", value: "name" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "用例综述",
|
||||
align: "center",
|
||||
dataIndex: "summarize",
|
||||
hide: true,
|
||||
search: true,
|
||||
addDefaultValue: ""
|
||||
},
|
||||
{
|
||||
title: "用例初始化",
|
||||
dataIndex: "initialization",
|
||||
hide: true,
|
||||
addDefaultValue: "软件正常启动,正常登录进软件"
|
||||
},
|
||||
{
|
||||
title: "前提和约束",
|
||||
dataIndex: "premise",
|
||||
hide: true,
|
||||
addDefaultValue: "软件正常启动,各界面显示工作正常"
|
||||
},
|
||||
{
|
||||
title: "执行时间",
|
||||
dataIndex: "exe_time",
|
||||
hide: true,
|
||||
formType: "date"
|
||||
},
|
||||
{
|
||||
title: "测试步骤",
|
||||
dataIndex: "testStep",
|
||||
hide: true,
|
||||
addDefaultValue: [
|
||||
{
|
||||
operation: "",
|
||||
expect: "",
|
||||
result: "",
|
||||
passed: "3"
|
||||
}
|
||||
],
|
||||
formType: "children-form",
|
||||
type: "group",
|
||||
formList: [
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
formType: "editor",
|
||||
height: 180
|
||||
},
|
||||
{
|
||||
title: "预期",
|
||||
placeholder: "请输入预期结果",
|
||||
dataIndex: "expect"
|
||||
},
|
||||
{
|
||||
title: "结果",
|
||||
dataIndex: "result",
|
||||
formType: "editor",
|
||||
height: 180
|
||||
},
|
||||
{
|
||||
title: "是否通过",
|
||||
dataIndex: "passed",
|
||||
formType: "radio",
|
||||
dict: { name: "passType", props: { label: "title", value: "key" } },
|
||||
commonRules: [{ required: true, message: "是否通过必填" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "关联问题",
|
||||
dataIndex: "problem",
|
||||
width: 150,
|
||||
addDisplay: false,
|
||||
editDisplay: false,
|
||||
align: "center",
|
||||
display: false,
|
||||
customRender: ({ record }) => {
|
||||
if (record.problem) {
|
||||
return (
|
||||
<a-link
|
||||
onClick={() => {
|
||||
title.value = `PT_${route.query.ident}_${record.problem.ident.padStart(3, 0)}`
|
||||
problemFormRef.value.open(record.problem)
|
||||
}}
|
||||
>{`PT_${route.query.ident}_${record.problem.ident.padStart(3, 0)}`}</a-link>
|
||||
)
|
||||
} else {
|
||||
return "无问题单"
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
return crudColumns
|
||||
}
|
||||
159
cdTMP/src/views/project/testDemand/hooks/useCrudOpMore.ts
Normal file
159
cdTMP/src/views/project/testDemand/hooks/useCrudOpMore.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import { ref, getCurrentInstance, type Ref } from "vue"
|
||||
import MaCrud from "@/components/ma-crud/index.vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import caseApi from "@/api/project/case"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import { isEqual, cloneDeep } from "lodash-es"
|
||||
/**
|
||||
* Dut被测件的crud选项
|
||||
*/
|
||||
export default function (crudRef: Ref<InstanceType<typeof MaCrud>>) {
|
||||
// globals
|
||||
const route = useRoute() as any
|
||||
const projectId = ref(route.query.id)
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const roundNumber = route.query.key.split("-")[0]
|
||||
const dutNumber = route.query.key.split("-")[1]
|
||||
const designDemandNumber = route.query.key.split("-")[2]
|
||||
const testDemandNumber = route.query.key.split("-")[3]
|
||||
// 辅助
|
||||
const app = getCurrentInstance()!.appContext.config.globalProperties
|
||||
let beforeFormStep = undefined
|
||||
// 注意只保留测试步骤!!!
|
||||
const handleBeforeCancel = () => {
|
||||
if (!beforeFormStep) {
|
||||
return
|
||||
}
|
||||
crudRef.value.getFormData().testStep
|
||||
const iuEqualValue = isEqual(crudRef.value.getFormData().testStep, beforeFormStep)
|
||||
!iuEqualValue &&
|
||||
app.$modal.confirm({
|
||||
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||
content: "",
|
||||
okText: "保留",
|
||||
cancelText: "恢复原数据",
|
||||
simple: true,
|
||||
onOk: () => null,
|
||||
onCancel: () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
// refs
|
||||
const crudOptions = ref({
|
||||
api: caseApi.getCaseList,
|
||||
add: { show: true, api: caseApi.save, text: "新增用例" },
|
||||
edit: { show: true, api: caseApi.update, text: "修改用例" },
|
||||
delete: { show: true, api: caseApi.delete },
|
||||
operationColumnAlign: "center",
|
||||
isDbClickEdit: true, // 关闭双击编辑
|
||||
// 处理新增删除后树状图显示
|
||||
beforeOpenAdd: function () {
|
||||
// 1.新增则将form的content数据变为undifined以便判断
|
||||
beforeFormStep = undefined
|
||||
// 2.标识处理
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let test_key = key_split[3]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} >
|
||||
${(td[round_key] as any).title} > ${(td[round_key] as any).children[dut_key].title} >
|
||||
${(td[round_key] as any).children[dut_key].children[design_key].title} >
|
||||
${(td[round_key] as any).children[dut_key].children[design_key].children[test_key].title} > 用例-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
// 1.储存打开前form的content数据到ref中,以便后续比较
|
||||
beforeFormStep = cloneDeep(record.testStep)
|
||||
// 2.标识处理
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let test_key = key_split[3]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} >
|
||||
${(td[round_key] as any).title} > ${(td[round_key] as any).children[dut_key].title} >
|
||||
${(td[round_key] as any).children[dut_key].children[design_key].title} >
|
||||
${(td[round_key] as any).children[dut_key].children[design_key].children[test_key].title}
|
||||
>用例[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateCaseTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateCaseTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateCaseTreeData(record, id)
|
||||
// 被删除还是在选择里面
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber,
|
||||
dut: dutNumber,
|
||||
designDemand: designDemandNumber,
|
||||
testDemand: testDemandNumber
|
||||
},
|
||||
showIndex: false,
|
||||
showTools: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 3,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 180,
|
||||
operationColumn: true,
|
||||
formOption: {
|
||||
width: 1200,
|
||||
layout: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "ident" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "name" }] }
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "card",
|
||||
customClass: ["ml-10", "mb-3", "py-0", "px-0"],
|
||||
title: "人员信息",
|
||||
formList: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 8, formList: [{ dataIndex: "designPerson" }] },
|
||||
{ span: 8, formList: [{ dataIndex: "testPerson" }] },
|
||||
{ span: 8, formList: [{ dataIndex: "monitorPerson" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ dataIndex: "summarize" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ dataIndex: "initialization" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "premise" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "exe_time" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
return { handleBeforeCancel, crudOptions }
|
||||
}
|
||||
@@ -13,369 +13,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="jsx">
|
||||
import { ref, getCurrentInstance } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import caseApi from "@/api/project/case"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import { ref } from "vue"
|
||||
import ProblemForm from "@/views/project/case/components/ProblemForm.vue"
|
||||
import { isEqual, cloneDeep } from "lodash-es"
|
||||
import useCrudOpMore from "./hooks/useCrudOpMore"
|
||||
import useColumn from "./hooks/useColumn"
|
||||
const problemFormRef = ref(null)
|
||||
const title = ref("问题单表单")
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const route = useRoute()
|
||||
const roundNumber = route.query.key.split("-")[0]
|
||||
const dutNumber = route.query.key.split("-")[1]
|
||||
const designDemandNumber = route.query.key.split("-")[2]
|
||||
const testDemandNumber = route.query.key.split("-")[3]
|
||||
const crudRef = ref()
|
||||
const projectId = ref(route.query.id)
|
||||
// 标识显示字段-用例比较特殊让后端返回了“FT”字样,因为FT是在测试项里面标识的
|
||||
// 标识重新定义
|
||||
const showType = (record) => {
|
||||
let key_string = parseInt(record.key.substring(record.key.lastIndexOf("-") + 1)) + 1
|
||||
return "YL-" + record.testType + "-" + record.ident + "-" + key_string.toString().padStart(3, "0")
|
||||
}
|
||||
|
||||
// crud设置以及是否保留step数据事件函数
|
||||
const app = getCurrentInstance().appContext.config.globalProperties
|
||||
let beforeFormStep = undefined
|
||||
// 注意只保留测试步骤!!!
|
||||
const handleBeforeCancel = () => {
|
||||
if (!beforeFormStep) {
|
||||
return
|
||||
}
|
||||
crudRef.value.getFormData().testStep
|
||||
const iuEqualValue = isEqual(crudRef.value.getFormData().testStep, beforeFormStep)
|
||||
!iuEqualValue &&
|
||||
app.$modal.confirm({
|
||||
title: "测试项步骤内容你已改动,是否保留您编写的测试项/测试用例步骤数据?",
|
||||
content: "",
|
||||
okText: "保留",
|
||||
cancelText: "恢复原数据",
|
||||
simple: true,
|
||||
onOk: () => null,
|
||||
onCancel: () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
const crudOptions = ref({
|
||||
api: caseApi.getCaseList,
|
||||
add: { show: true, api: caseApi.save, text: "新增用例" },
|
||||
edit: { show: true, api: caseApi.update, text: "修改用例" },
|
||||
delete: { show: true, api: caseApi.delete },
|
||||
operationColumnAlign: "center",
|
||||
isDbClickEdit: true, // 关闭双击编辑
|
||||
// 处理新增删除后树状图显示
|
||||
beforeOpenAdd: function () {
|
||||
// 1.新增则将form的content数据变为undifined以便判断
|
||||
beforeFormStep = undefined
|
||||
// 2.标识处理
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let test_key = key_split[3]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} >
|
||||
${td[round_key].title} > ${td[round_key].children[dut_key].title} >
|
||||
${td[round_key].children[dut_key].children[design_key].title} >
|
||||
${td[round_key].children[dut_key].children[design_key].children[test_key].title} > 用例-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
// 1.储存打开前form的content数据到ref中,以便后续比较
|
||||
beforeFormStep = cloneDeep(record.testStep)
|
||||
// 2.标识处理
|
||||
let key_split = route.query.key.split("-")
|
||||
let round_key = key_split[0]
|
||||
let dut_key = key_split[1]
|
||||
let design_key = key_split[2]
|
||||
let test_key = key_split[3]
|
||||
let td = treeDataStore.treeData
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident} >
|
||||
${td[round_key].title} > ${td[round_key].children[dut_key].title} >
|
||||
${td[round_key].children[dut_key].children[design_key].title} >
|
||||
${td[round_key].children[dut_key].children[design_key].children[test_key].title}
|
||||
>用例[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateCaseTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateCaseTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateCaseTreeData(record, id)
|
||||
// 被删除还是在选择里面
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber,
|
||||
dut: dutNumber,
|
||||
designDemand: designDemandNumber,
|
||||
testDemand: testDemandNumber
|
||||
},
|
||||
showIndex: false,
|
||||
showTools: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 3,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 180,
|
||||
operationColumn: true,
|
||||
formOption: {
|
||||
width: 1200,
|
||||
layout: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "ident" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "name" }] }
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "card",
|
||||
customClass: ["ml-10", "mb-3", "py-0", "px-0"],
|
||||
title: "人员信息",
|
||||
formList: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 8, formList: [{ dataIndex: "designPerson" }] },
|
||||
{ span: 8, formList: [{ dataIndex: "testPerson" }] },
|
||||
{ span: 8, formList: [{ dataIndex: "monitorPerson" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ dataIndex: "summarize" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [{ span: 24, formList: [{ dataIndex: "initialization" }] }]
|
||||
},
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "premise" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "exe_time" }] }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
width: 60,
|
||||
align: "center",
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
fixed: "left"
|
||||
},
|
||||
{
|
||||
title: "用例标识",
|
||||
dataIndex: "ident",
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
width: 180,
|
||||
align: "center",
|
||||
addDisabled: true,
|
||||
addDefaultValue: "用例标识自动生成,结构为YL_IO_XXXX_001",
|
||||
editDefaultValue: "用例标识自动生成,结构为YL_IO_XXXX_001",
|
||||
editDisabled: true,
|
||||
search: true,
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "名称",
|
||||
dataIndex: "name",
|
||||
align: "center",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "名称是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "是否通过",
|
||||
align: "center",
|
||||
display: false,
|
||||
addDisplay: false,
|
||||
editDisplay: false,
|
||||
customRender: ({ record }) => {
|
||||
let passCount = 0
|
||||
let failCount = 0
|
||||
let stepCount = record.testStep.length
|
||||
record.testStep.forEach((item) => {
|
||||
if (item.passed === "1") {
|
||||
passCount++
|
||||
} else if (item.passed === "2") {
|
||||
failCount++
|
||||
}
|
||||
})
|
||||
if (failCount > 0) {
|
||||
return (
|
||||
<a-tag bordered color="red">
|
||||
未通过
|
||||
</a-tag>
|
||||
)
|
||||
} else {
|
||||
if (passCount === stepCount) {
|
||||
return (
|
||||
<a-tag bordered color="green">
|
||||
已通过
|
||||
</a-tag>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<a-tag bordered color="orange">
|
||||
包含未执行
|
||||
</a-tag>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "设计人员",
|
||||
width: 80,
|
||||
dataIndex: "designPerson",
|
||||
align: "center",
|
||||
hide: true,
|
||||
search: true,
|
||||
formType: "select",
|
||||
dict: {
|
||||
url: "system/user/list",
|
||||
params: { project_id: route.query.id },
|
||||
translation: true,
|
||||
props: { label: "name", value: "name" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "执行人员",
|
||||
dataIndex: "testPerson",
|
||||
width: 120,
|
||||
align: "center",
|
||||
search: true,
|
||||
formType: "select",
|
||||
dict: {
|
||||
url: "system/user/list",
|
||||
params: { project_id: route.query.id },
|
||||
translation: true,
|
||||
props: { label: "name", value: "name" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "审核人员",
|
||||
dataIndex: "monitorPerson",
|
||||
width: 80,
|
||||
align: "center",
|
||||
hide: true,
|
||||
formType: "select",
|
||||
dict: {
|
||||
url: "system/user/list",
|
||||
params: { project_id: route.query.id },
|
||||
translation: true,
|
||||
props: { label: "name", value: "name" }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "用例综述",
|
||||
align: "center",
|
||||
dataIndex: "summarize",
|
||||
hide: true,
|
||||
search: true,
|
||||
addDefaultValue: ""
|
||||
},
|
||||
{
|
||||
title: "用例初始化",
|
||||
dataIndex: "initialization",
|
||||
hide: true,
|
||||
addDefaultValue: "软件正常启动,正常登录进软件"
|
||||
},
|
||||
{
|
||||
title: "前提和约束",
|
||||
dataIndex: "premise",
|
||||
hide: true,
|
||||
addDefaultValue: "软件正常启动,各界面显示工作正常"
|
||||
},
|
||||
{
|
||||
title: "执行时间",
|
||||
dataIndex: "exe_time",
|
||||
hide: true,
|
||||
formType: "date"
|
||||
},
|
||||
{
|
||||
title: "测试步骤",
|
||||
dataIndex: "testStep",
|
||||
hide: true,
|
||||
addDefaultValue: [
|
||||
{
|
||||
operation: "",
|
||||
expect: "",
|
||||
result: "",
|
||||
passed: "3"
|
||||
}
|
||||
],
|
||||
formType: "children-form",
|
||||
type: "group",
|
||||
formList: [
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
formType: "editor",
|
||||
height: 180
|
||||
},
|
||||
{
|
||||
title: "预期",
|
||||
placeholder: "请输入预期结果",
|
||||
dataIndex: "expect"
|
||||
},
|
||||
{
|
||||
title: "结果",
|
||||
dataIndex: "result",
|
||||
formType: "editor",
|
||||
height: 180
|
||||
},
|
||||
{
|
||||
title: "是否通过",
|
||||
dataIndex: "passed",
|
||||
formType: "radio",
|
||||
dict: { name: "passType", props: { label: "title", value: "key" } },
|
||||
commonRules: [{ required: true, message: "是否通过必填" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "关联问题",
|
||||
dataIndex: "problem",
|
||||
width: 150,
|
||||
addDisplay: false,
|
||||
editDisplay: false,
|
||||
align: "center",
|
||||
customRender: ({ record }) => {
|
||||
if (record.problem) {
|
||||
return (
|
||||
<a-link
|
||||
onClick={() => {
|
||||
title.value = `PT_${route.query.ident}_${record.problem.ident.padStart(3, 0)}`
|
||||
problemFormRef.value.open(record.problem)
|
||||
}}
|
||||
>{`PT_${route.query.ident}_${record.problem.ident.padStart(3, 0)}`}</a-link>
|
||||
)
|
||||
} else {
|
||||
return "无问题单"
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
const { handleBeforeCancel, crudOptions } = useCrudOpMore(crudRef)
|
||||
const crudColumns = useColumn(crudRef, problemFormRef)
|
||||
|
||||
// 暴露刷新表格方法给外部
|
||||
const refreshCrudTable = () => {
|
||||
crudRef.value.refresh()
|
||||
|
||||
Reference in New Issue
Block a user