迁入ERP的组织结构树组件,作为通讯录的组织结构;接入相关依赖组件,调整通讯录入口及相关样式

This commit is contained in:
wangyifeng 2025-05-12 13:55:14 +08:00
parent d021415568
commit 43541a1187
31 changed files with 3887 additions and 43 deletions

View File

@ -13,10 +13,14 @@
"format": "prettier --write src/" "format": "prettier --write src/"
}, },
"dependencies": { "dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@highlightjs/vue-plugin": "^2.1.0", "@highlightjs/vue-plugin": "^2.1.0",
"@iconify-json/ion": "^1.2.3",
"@kangc/v-md-editor": "^2.3.18", "@kangc/v-md-editor": "^2.3.18",
"@vicons/ionicons5": "^0.13.0",
"@vueup/vue-quill": "^1.2.0", "@vueup/vue-quill": "^1.2.0",
"@vueuse/core": "^10.7.0", "@vueuse/core": "^10.7.0",
"ant-design-vue": "^4.2.6",
"axios": "^1.6.2", "axios": "^1.6.2",
"highlight.js": "^11.5.0", "highlight.js": "^11.5.0",
"js-audio-recorder": "^1.0.7", "js-audio-recorder": "^1.0.7",
@ -48,6 +52,7 @@
"naive-ui": "^2.35.0", "naive-ui": "^2.35.0",
"npm-run-all2": "^6.1.1", "npm-run-all2": "^6.1.1",
"prettier": "^3.1.0", "prettier": "^3.1.0",
"sass": "^1.88.0",
"typescript": "~5.2.0", "typescript": "~5.2.0",
"unocss": "0.58.0", "unocss": "0.58.0",
"vite": "^4.5.1", "vite": "^4.5.1",

View File

@ -8,18 +8,30 @@ importers:
.: .:
dependencies: dependencies:
'@ant-design/icons-vue':
specifier: ^7.0.1
version: 7.0.1(vue@3.5.13(typescript@5.2.2))
'@highlightjs/vue-plugin': '@highlightjs/vue-plugin':
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.1.0(highlight.js@11.11.1)(vue@3.5.13(typescript@5.2.2)) version: 2.1.0(highlight.js@11.11.1)(vue@3.5.13(typescript@5.2.2))
'@iconify-json/ion':
specifier: ^1.2.3
version: 1.2.3
'@kangc/v-md-editor': '@kangc/v-md-editor':
specifier: ^2.3.18 specifier: ^2.3.18
version: 2.3.18(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.2.2)) version: 2.3.18(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.2.2))
'@vicons/ionicons5':
specifier: ^0.13.0
version: 0.13.0
'@vueup/vue-quill': '@vueup/vue-quill':
specifier: ^1.2.0 specifier: ^1.2.0
version: 1.2.0(vue@3.5.13(typescript@5.2.2)) version: 1.2.0(vue@3.5.13(typescript@5.2.2))
'@vueuse/core': '@vueuse/core':
specifier: ^10.7.0 specifier: ^10.7.0
version: 10.11.1(vue@3.5.13(typescript@5.2.2)) version: 10.11.1(vue@3.5.13(typescript@5.2.2))
ant-design-vue:
specifier: ^4.2.6
version: 4.2.6(vue@3.5.13(typescript@5.2.2))
axios: axios:
specifier: ^1.6.2 specifier: ^1.6.2
version: 1.9.0 version: 1.9.0
@ -80,10 +92,10 @@ importers:
version: 2.0.0(typescript@5.2.2) version: 2.0.0(typescript@5.2.2)
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: ^4.4.0 specifier: ^4.4.0
version: 4.6.2(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2)) version: 4.6.2(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))
'@vitejs/plugin-vue-jsx': '@vitejs/plugin-vue-jsx':
specifier: ^3.0.2 specifier: ^3.0.2
version: 3.1.0(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2)) version: 3.1.0(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))
'@vue/tsconfig': '@vue/tsconfig':
specifier: ^0.4.0 specifier: ^0.4.0
version: 0.4.0 version: 0.4.0
@ -108,18 +120,21 @@ importers:
prettier: prettier:
specifier: ^3.1.0 specifier: ^3.1.0
version: 3.5.3 version: 3.5.3
sass:
specifier: ^1.88.0
version: 1.88.0
typescript: typescript:
specifier: ~5.2.0 specifier: ~5.2.0
version: 5.2.2 version: 5.2.2
unocss: unocss:
specifier: 0.58.0 specifier: 0.58.0
version: 0.58.0(postcss@8.5.3)(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)) version: 0.58.0(postcss@8.5.3)(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))
vite: vite:
specifier: ^4.5.1 specifier: ^4.5.1
version: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) version: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
vite-plugin-compression: vite-plugin-compression:
specifier: ^0.5.1 specifier: ^0.5.1
version: 0.5.1(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)) version: 0.5.1(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))
vue-tsc: vue-tsc:
specifier: ^1.8.25 specifier: ^1.8.25
version: 1.8.27(typescript@5.2.2) version: 1.8.27(typescript@5.2.2)
@ -133,6 +148,17 @@ packages:
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
'@ant-design/colors@6.0.0':
resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
'@ant-design/icons-svg@4.4.2':
resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==}
'@ant-design/icons-vue@7.0.1':
resolution: {integrity: sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==}
peerDependencies:
vue: '>=3.0.3'
'@antfu/install-pkg@1.1.0': '@antfu/install-pkg@1.1.0':
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
@ -284,9 +310,19 @@ packages:
peerDependencies: peerDependencies:
vue: ^3.0.11 vue: ^3.0.11
'@ctrl/tinycolor@3.6.1':
resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==}
engines: {node: '>=10'}
'@emotion/hash@0.8.0': '@emotion/hash@0.8.0':
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
'@emotion/hash@0.9.2':
resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==}
'@emotion/unitless@0.8.1':
resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
'@esbuild/android-arm64@0.18.20': '@esbuild/android-arm64@0.18.20':
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -437,6 +473,9 @@ packages:
peerDependencies: peerDependencies:
vue: 3.x vue: 3.x
'@iconify-json/ion@1.2.3':
resolution: {integrity: sha512-qV9zsuBFjCgU5WRFO2thhhmaw1wr1wpJMliuuwu7pOtFEEoMOPP45Q7edF+k8uYuouFq+94SlCMIsca+v9kt2g==}
'@iconify/types@2.0.0': '@iconify/types@2.0.0':
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
@ -477,17 +516,110 @@ packages:
resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==}
engines: {node: '>=4'} engines: {node: '>=4'}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
'@nodelib/fs.stat@1.1.3': '@nodelib/fs.stat@1.1.3':
resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
'@polka/url@1.0.0-next.29': '@nodelib/fs.stat@2.0.5':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
'@nodelib/fs.walk@1.2.8': '@nodelib/fs.walk@1.2.8':
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
'@parcel/watcher-android-arm64@2.5.1':
resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [android]
'@parcel/watcher-darwin-arm64@2.5.1':
resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [darwin]
'@parcel/watcher-darwin-x64@2.5.1':
resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [darwin]
'@parcel/watcher-freebsd-x64@2.5.1':
resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [freebsd]
'@parcel/watcher-linux-arm-glibc@2.5.1':
resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm-musl@2.5.1':
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-arm64-glibc@2.5.1':
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm64-musl@2.5.1':
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-x64-glibc@2.5.1':
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-x64-musl@2.5.1':
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
'@parcel/watcher-win32-arm64@2.5.1':
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [win32]
'@parcel/watcher-win32-ia32@2.5.1':
resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==}
engines: {node: '>= 10.0.0'}
cpu: [ia32]
os: [win32]
'@parcel/watcher-win32-x64@2.5.1':
resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [win32]
'@parcel/watcher@2.5.1':
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
'@polka/url@1.0.0-next.29': '@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
@ -509,6 +641,9 @@ packages:
'@sideway/pinpoint@2.0.0': '@sideway/pinpoint@2.0.0':
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
'@simonwep/pickr@1.8.2':
resolution: {integrity: sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==}
'@tsconfig/node18@18.2.4': '@tsconfig/node18@18.2.4':
resolution: {integrity: sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==} resolution: {integrity: sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==}
@ -670,6 +805,9 @@ packages:
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
'@vicons/ionicons5@0.13.0':
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
'@vitejs/plugin-vue-jsx@3.1.0': '@vitejs/plugin-vue-jsx@3.1.0':
resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==} resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
@ -860,6 +998,12 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'} engines: {node: '>=12'}
ant-design-vue@4.2.6:
resolution: {integrity: sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==}
engines: {node: '>=12.22.0'}
peerDependencies:
vue: '>=3.2.0'
anymatch@3.1.3: anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -882,6 +1026,9 @@ packages:
resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
array-tree-filter@2.1.0:
resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==}
array-union@1.0.2: array-union@1.0.2:
resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -989,6 +1136,10 @@ packages:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'} engines: {node: '>= 8.10.0'}
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
chrome-trace-event@1.0.4: chrome-trace-event@1.0.4:
resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
@ -1046,6 +1197,9 @@ packages:
component-emitter@1.3.1: component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
compute-scroll-into-view@1.0.20:
resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
computeds@0.0.1: computeds@0.0.1:
resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==}
@ -1359,6 +1513,11 @@ packages:
destr@2.0.5: destr@2.0.5:
resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
detect-libc@1.0.3:
resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
engines: {node: '>=0.10'}
hasBin: true
diff@5.2.0: diff@5.2.0:
resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
engines: {node: '>=0.3.1'} engines: {node: '>=0.3.1'}
@ -1367,6 +1526,12 @@ packages:
resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==}
engines: {node: '>=4'} engines: {node: '>=4'}
dom-align@1.12.4:
resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==}
dom-scroll-into-view@2.0.1:
resolution: {integrity: sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==}
dompurify@3.1.6: dompurify@3.1.6:
resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==}
@ -1726,6 +1891,9 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
hasBin: true hasBin: true
immutable@5.1.2:
resolution: {integrity: sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==}
inflight@1.0.6: inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
@ -1810,6 +1978,10 @@ packages:
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-plain-object@3.0.1:
resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==}
engines: {node: '>=0.10.0'}
is-regex@1.2.1: is-regex@1.2.1:
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -1957,6 +2129,10 @@ packages:
lodash@4.17.21: lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
lru-cache@5.1.1: lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@ -2107,6 +2283,10 @@ packages:
resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
mime-db@1.52.0: mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -2171,6 +2351,9 @@ packages:
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
nanopop@2.4.2:
resolution: {integrity: sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==}
needle@3.3.1: needle@3.3.1:
resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
engines: {node: '>= 4.4.x'} engines: {node: '>= 4.4.x'}
@ -2182,6 +2365,9 @@ packages:
next-tick@1.1.0: next-tick@1.1.0:
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
node-fetch-native@1.6.6: node-fetch-native@1.6.6:
resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==}
@ -2378,6 +2564,10 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
regex-not@1.0.2: regex-not@1.0.2:
resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2425,6 +2615,9 @@ packages:
engines: {node: '>=14.18.0', npm: '>=8.0.0'} engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true hasBin: true
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
rw@1.3.3: rw@1.3.3:
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
@ -2444,6 +2637,11 @@ packages:
safer-buffer@2.1.2: safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sass@1.88.0:
resolution: {integrity: sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==}
engines: {node: '>=14.0.0'}
hasBin: true
sax@1.4.1: sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
@ -2451,6 +2649,9 @@ packages:
resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==}
engines: {node: '>= 10.13.0'} engines: {node: '>= 10.13.0'}
scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
section-matter@1.0.0: section-matter@1.0.0:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2486,6 +2687,9 @@ packages:
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
shallow-equal@1.2.1:
resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==}
shebang-command@2.0.0: shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2610,6 +2814,10 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
throttle-debounce@5.0.2:
resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==}
engines: {node: '>=12.22'}
tinyexec@1.0.1: tinyexec@1.0.1:
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
@ -2817,6 +3025,12 @@ packages:
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
vue-types@3.0.2:
resolution: {integrity: sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==}
engines: {node: '>=10.15.0'}
peerDependencies:
vue: ^3.0.0
vue-virtual-scroller@2.0.0-beta.8: vue-virtual-scroller@2.0.0-beta.8:
resolution: {integrity: sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==} resolution: {integrity: sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==}
peerDependencies: peerDependencies:
@ -2845,6 +3059,9 @@ packages:
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
hasBin: true hasBin: true
warning@4.0.3:
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
watchpack@2.4.2: watchpack@2.4.2:
resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
@ -2924,6 +3141,18 @@ snapshots:
'@jridgewell/gen-mapping': 0.3.8 '@jridgewell/gen-mapping': 0.3.8
'@jridgewell/trace-mapping': 0.3.25 '@jridgewell/trace-mapping': 0.3.25
'@ant-design/colors@6.0.0':
dependencies:
'@ctrl/tinycolor': 3.6.1
'@ant-design/icons-svg@4.4.2': {}
'@ant-design/icons-vue@7.0.1(vue@3.5.13(typescript@5.2.2))':
dependencies:
'@ant-design/colors': 6.0.0
'@ant-design/icons-svg': 4.4.2
vue: 3.5.13(typescript@5.2.2)
'@antfu/install-pkg@1.1.0': '@antfu/install-pkg@1.1.0':
dependencies: dependencies:
package-manager-detector: 1.3.0 package-manager-detector: 1.3.0
@ -3129,8 +3358,14 @@ snapshots:
dependencies: dependencies:
vue: 3.5.13(typescript@5.2.2) vue: 3.5.13(typescript@5.2.2)
'@ctrl/tinycolor@3.6.1': {}
'@emotion/hash@0.8.0': {} '@emotion/hash@0.8.0': {}
'@emotion/hash@0.9.2': {}
'@emotion/unitless@0.8.1': {}
'@esbuild/android-arm64@0.18.20': '@esbuild/android-arm64@0.18.20':
optional: true optional: true
@ -3212,6 +3447,10 @@ snapshots:
dependencies: dependencies:
vue: 3.5.13(typescript@5.2.2) vue: 3.5.13(typescript@5.2.2)
'@iconify-json/ion@1.2.3':
dependencies:
'@iconify/types': 2.0.0
'@iconify/types@2.0.0': {} '@iconify/types@2.0.0': {}
'@iconify/utils@2.3.0': '@iconify/utils@2.3.0':
@ -3278,15 +3517,81 @@ snapshots:
call-me-maybe: 1.0.2 call-me-maybe: 1.0.2
glob-to-regexp: 0.3.0 glob-to-regexp: 0.3.0
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0
'@nodelib/fs.stat@1.1.3': {} '@nodelib/fs.stat@1.1.3': {}
'@polka/url@1.0.0-next.29': {} '@nodelib/fs.stat@2.0.5': {}
'@quansync/fs@0.1.2': '@nodelib/fs.walk@1.2.8':
dependencies: dependencies:
'@nodelib/fs.scandir': 2.1.5 '@nodelib/fs.scandir': 2.1.5
fastq: 1.19.1 fastq: 1.19.1
'@parcel/watcher-android-arm64@2.5.1':
optional: true
'@parcel/watcher-darwin-arm64@2.5.1':
optional: true
'@parcel/watcher-darwin-x64@2.5.1':
optional: true
'@parcel/watcher-freebsd-x64@2.5.1':
optional: true
'@parcel/watcher-linux-arm-glibc@2.5.1':
optional: true
'@parcel/watcher-linux-arm-musl@2.5.1':
optional: true
'@parcel/watcher-linux-arm64-glibc@2.5.1':
optional: true
'@parcel/watcher-linux-arm64-musl@2.5.1':
optional: true
'@parcel/watcher-linux-x64-glibc@2.5.1':
optional: true
'@parcel/watcher-linux-x64-musl@2.5.1':
optional: true
'@parcel/watcher-win32-arm64@2.5.1':
optional: true
'@parcel/watcher-win32-ia32@2.5.1':
optional: true
'@parcel/watcher-win32-x64@2.5.1':
optional: true
'@parcel/watcher@2.5.1':
dependencies:
detect-libc: 1.0.3
is-glob: 4.0.3
micromatch: 4.0.8
node-addon-api: 7.1.1
optionalDependencies:
'@parcel/watcher-android-arm64': 2.5.1
'@parcel/watcher-darwin-arm64': 2.5.1
'@parcel/watcher-darwin-x64': 2.5.1
'@parcel/watcher-freebsd-x64': 2.5.1
'@parcel/watcher-linux-arm-glibc': 2.5.1
'@parcel/watcher-linux-arm-musl': 2.5.1
'@parcel/watcher-linux-arm64-glibc': 2.5.1
'@parcel/watcher-linux-arm64-musl': 2.5.1
'@parcel/watcher-linux-x64-glibc': 2.5.1
'@parcel/watcher-linux-x64-musl': 2.5.1
'@parcel/watcher-win32-arm64': 2.5.1
'@parcel/watcher-win32-ia32': 2.5.1
'@parcel/watcher-win32-x64': 2.5.1
optional: true
'@polka/url@1.0.0-next.29': {} '@polka/url@1.0.0-next.29': {}
'@rollup/pluginutils@5.1.4(rollup@3.29.5)': '@rollup/pluginutils@5.1.4(rollup@3.29.5)':
@ -3305,6 +3610,11 @@ snapshots:
'@sideway/pinpoint@2.0.0': {} '@sideway/pinpoint@2.0.0': {}
'@simonwep/pickr@1.8.2':
dependencies:
core-js: 3.42.0
nanopop: 2.4.2
'@tsconfig/node18@18.2.4': {} '@tsconfig/node18@18.2.4': {}
'@types/d3-scale-chromatic@3.1.0': {} '@types/d3-scale-chromatic@3.1.0': {}
@ -3372,13 +3682,13 @@ snapshots:
'@types/web-bluetooth@0.0.20': {} '@types/web-bluetooth@0.0.20': {}
'@unocss/astro@0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))': '@unocss/astro@0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))':
dependencies: dependencies:
'@unocss/core': 0.58.0 '@unocss/core': 0.58.0
'@unocss/reset': 0.58.0 '@unocss/reset': 0.58.0
'@unocss/vite': 0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)) '@unocss/vite': 0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))
optionalDependencies: optionalDependencies:
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
@ -3509,7 +3819,7 @@ snapshots:
dependencies: dependencies:
'@unocss/core': 0.58.0 '@unocss/core': 0.58.0
'@unocss/vite@0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))': '@unocss/vite@0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))':
dependencies: dependencies:
'@ampproject/remapping': 2.3.0 '@ampproject/remapping': 2.3.0
'@rollup/pluginutils': 5.1.4(rollup@3.29.5) '@rollup/pluginutils': 5.1.4(rollup@3.29.5)
@ -3521,7 +3831,7 @@ snapshots:
chokidar: 3.6.0 chokidar: 3.6.0
fast-glob: 3.3.3 fast-glob: 3.3.3
magic-string: 0.30.17 magic-string: 0.30.17
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
@ -3533,19 +3843,21 @@ snapshots:
dependencies: dependencies:
vue: 3.5.13(typescript@5.2.2) vue: 3.5.13(typescript@5.2.2)
'@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))': '@vicons/ionicons5@0.13.0': {}
'@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))':
dependencies: dependencies:
'@babel/core': 7.27.1 '@babel/core': 7.27.1
'@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1)
'@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1) '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1)
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
vue: 3.5.13(typescript@5.2.2) vue: 3.5.13(typescript@5.2.2)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@vitejs/plugin-vue@4.6.2(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))': '@vitejs/plugin-vue@4.6.2(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))(vue@3.5.13(typescript@5.2.2))':
dependencies: dependencies:
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
vue: 3.5.13(typescript@5.2.2) vue: 3.5.13(typescript@5.2.2)
'@volar/language-core@1.11.1': '@volar/language-core@1.11.1':
@ -3823,6 +4135,32 @@ snapshots:
ansi-styles@6.2.1: {} ansi-styles@6.2.1: {}
ant-design-vue@4.2.6(vue@3.5.13(typescript@5.2.2)):
dependencies:
'@ant-design/colors': 6.0.0
'@ant-design/icons-vue': 7.0.1(vue@3.5.13(typescript@5.2.2))
'@babel/runtime': 7.27.1
'@ctrl/tinycolor': 3.6.1
'@emotion/hash': 0.9.2
'@emotion/unitless': 0.8.1
'@simonwep/pickr': 1.8.2
array-tree-filter: 2.1.0
async-validator: 4.2.5
csstype: 3.1.3
dayjs: 1.11.13
dom-align: 1.12.4
dom-scroll-into-view: 2.0.1
lodash: 4.17.21
lodash-es: 4.17.21
resize-observer-polyfill: 1.5.1
scroll-into-view-if-needed: 2.2.31
shallow-equal: 1.2.1
stylis: 4.3.6
throttle-debounce: 5.0.2
vue: 3.5.13(typescript@5.2.2)
vue-types: 3.0.2(vue@3.5.13(typescript@5.2.2))
warning: 4.0.3
anymatch@3.1.3: anymatch@3.1.3:
dependencies: dependencies:
normalize-path: 3.0.0 normalize-path: 3.0.0
@ -3840,6 +4178,8 @@ snapshots:
arr-union@3.1.0: {} arr-union@3.1.0: {}
array-tree-filter@2.1.0: {}
array-union@1.0.2: array-union@1.0.2:
dependencies: dependencies:
array-uniq: 1.0.3 array-uniq: 1.0.3
@ -3981,6 +4321,10 @@ snapshots:
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
chrome-trace-event@1.0.4: {} chrome-trace-event@1.0.4: {}
class-utils@0.3.6: class-utils@0.3.6:
@ -4031,6 +4375,8 @@ snapshots:
component-emitter@1.3.1: {} component-emitter@1.3.1: {}
compute-scroll-into-view@1.0.20: {}
computeds@0.0.1: {} computeds@0.0.1: {}
concat-map@0.0.1: {} concat-map@0.0.1: {}
@ -4363,12 +4709,19 @@ snapshots:
destr@2.0.5: {} destr@2.0.5: {}
detect-libc@1.0.3:
optional: true
diff@5.2.0: {} diff@5.2.0: {}
dir-glob@2.2.2: dir-glob@2.2.2:
dependencies: dependencies:
path-type: 3.0.0 path-type: 3.0.0
dom-align@1.12.4: {}
dom-scroll-into-view@2.0.1: {}
dompurify@3.1.6: {} dompurify@3.1.6: {}
downloadjs@1.4.7: {} downloadjs@1.4.7: {}
@ -4758,6 +5111,8 @@ snapshots:
image-size@0.5.5: image-size@0.5.5:
optional: true optional: true
immutable@5.1.2: {}
inflight@1.0.6: inflight@1.0.6:
dependencies: dependencies:
once: 1.4.0 once: 1.4.0
@ -4833,6 +5188,8 @@ snapshots:
dependencies: dependencies:
isobject: 3.0.1 isobject: 3.0.1
is-plain-object@3.0.1: {}
is-regex@1.2.1: is-regex@1.2.1:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
@ -4970,6 +5327,10 @@ snapshots:
lodash@4.17.21: {} lodash@4.17.21: {}
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
lru-cache@5.1.1: lru-cache@5.1.1:
dependencies: dependencies:
yallist: 3.1.1 yallist: 3.1.1
@ -5234,6 +5595,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
micromatch@4.0.8:
dependencies:
braces: 3.0.3
picomatch: 2.3.1
mime-db@1.52.0: {} mime-db@1.52.0: {}
mime-types@2.1.35: mime-types@2.1.35:
@ -5318,6 +5684,8 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
nanopop@2.4.2: {}
needle@3.3.1: needle@3.3.1:
dependencies: dependencies:
iconv-lite: 0.6.3 iconv-lite: 0.6.3
@ -5328,6 +5696,9 @@ snapshots:
next-tick@1.1.0: {} next-tick@1.1.0: {}
node-addon-api@7.1.1:
optional: true
node-fetch-native@1.6.6: {} node-fetch-native@1.6.6: {}
node-releases@2.0.19: {} node-releases@2.0.19: {}
@ -5509,6 +5880,8 @@ snapshots:
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.1
readdirp@4.1.2: {}
regex-not@1.0.2: regex-not@1.0.2:
dependencies: dependencies:
extend-shallow: 3.0.2 extend-shallow: 3.0.2
@ -5545,6 +5918,10 @@ snapshots:
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
rw@1.3.3: {} rw@1.3.3: {}
rxjs@7.8.2: rxjs@7.8.2:
@ -5563,6 +5940,14 @@ snapshots:
safer-buffer@2.1.2: {} safer-buffer@2.1.2: {}
sass@1.88.0:
dependencies:
chokidar: 4.0.3
immutable: 5.1.2
source-map-js: 1.2.1
optionalDependencies:
'@parcel/watcher': 2.5.1
sax@1.4.1: sax@1.4.1:
optional: true optional: true
@ -5573,6 +5958,10 @@ snapshots:
ajv-formats: 2.1.1(ajv@8.17.1) ajv-formats: 2.1.1(ajv@8.17.1)
ajv-keywords: 5.1.0(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1)
scroll-into-view-if-needed@2.2.31:
dependencies:
compute-scroll-into-view: 1.0.20
section-matter@1.0.0: section-matter@1.0.0:
dependencies: dependencies:
extend-shallow: 2.0.1 extend-shallow: 2.0.1
@ -5614,6 +6003,8 @@ snapshots:
is-plain-object: 2.0.4 is-plain-object: 2.0.4
split-string: 3.1.0 split-string: 3.1.0
shallow-equal@1.2.1: {}
shebang-command@2.0.0: shebang-command@2.0.0:
dependencies: dependencies:
shebang-regex: 3.0.0 shebang-regex: 3.0.0
@ -5733,6 +6124,8 @@ snapshots:
commander: 2.20.3 commander: 2.20.3
source-map-support: 0.5.21 source-map-support: 0.5.21
throttle-debounce@5.0.2: {}
tinyexec@1.0.1: {} tinyexec@1.0.1: {}
to-object-path@0.3.0: to-object-path@0.3.0:
@ -5800,9 +6193,9 @@ snapshots:
universalify@2.0.1: {} universalify@2.0.1: {}
unocss@0.58.0(postcss@8.5.3)(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)): unocss@0.58.0(postcss@8.5.3)(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)):
dependencies: dependencies:
'@unocss/astro': 0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)) '@unocss/astro': 0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))
'@unocss/cli': 0.58.0(rollup@3.29.5) '@unocss/cli': 0.58.0(rollup@3.29.5)
'@unocss/core': 0.58.0 '@unocss/core': 0.58.0
'@unocss/extractor-arbitrary-variants': 0.58.0 '@unocss/extractor-arbitrary-variants': 0.58.0
@ -5821,9 +6214,9 @@ snapshots:
'@unocss/transformer-compile-class': 0.58.0 '@unocss/transformer-compile-class': 0.58.0
'@unocss/transformer-directives': 0.58.0 '@unocss/transformer-directives': 0.58.0
'@unocss/transformer-variant-group': 0.58.0 '@unocss/transformer-variant-group': 0.58.0
'@unocss/vite': 0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)) '@unocss/vite': 0.58.0(rollup@3.29.5)(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0))
optionalDependencies: optionalDependencies:
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
transitivePeerDependencies: transitivePeerDependencies:
- postcss - postcss
- rollup - rollup
@ -5867,16 +6260,16 @@ snapshots:
evtd: 0.2.4 evtd: 0.2.4
vue: 3.5.13(typescript@5.2.2) vue: 3.5.13(typescript@5.2.2)
vite-plugin-compression@0.5.1(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0)): vite-plugin-compression@0.5.1(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)):
dependencies: dependencies:
chalk: 4.1.2 chalk: 4.1.2
debug: 4.4.0 debug: 4.4.0
fs-extra: 10.1.0 fs-extra: 10.1.0
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0) vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(terser@5.39.0): vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0):
dependencies: dependencies:
esbuild: 0.18.20 esbuild: 0.18.20
postcss: 8.5.3 postcss: 8.5.3
@ -5885,6 +6278,7 @@ snapshots:
'@types/node': 18.19.99 '@types/node': 18.19.99
fsevents: 2.3.3 fsevents: 2.3.3
less: 4.3.0 less: 4.3.0
sass: 1.88.0
terser: 5.39.0 terser: 5.39.0
vooks@0.2.12(vue@3.5.13(typescript@5.2.2)): vooks@0.2.12(vue@3.5.13(typescript@5.2.2)):
@ -5923,6 +6317,11 @@ snapshots:
semver: 7.7.1 semver: 7.7.1
typescript: 5.2.2 typescript: 5.2.2
vue-types@3.0.2(vue@3.5.13(typescript@5.2.2)):
dependencies:
is-plain-object: 3.0.1
vue: 3.5.13(typescript@5.2.2)
vue-virtual-scroller@2.0.0-beta.8(vue@3.5.13(typescript@5.2.2)): vue-virtual-scroller@2.0.0-beta.8(vue@3.5.13(typescript@5.2.2)):
dependencies: dependencies:
mitt: 2.1.0 mitt: 2.1.0
@ -5966,6 +6365,10 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
warning@4.0.3:
dependencies:
loose-envify: 1.4.0
watchpack@2.4.2: watchpack@2.4.2:
dependencies: dependencies:
glob-to-regexp: 0.4.1 glob-to-regexp: 0.4.1

22
src/api/components.js Normal file
View File

@ -0,0 +1,22 @@
import _axios from '@/utils/erpRequest'
export default {
deleteDataByParams: (url, data) => _axios.fetch(url, data, 'DELETE'),
putDataByParams: (url, data) => _axios.fetch(url, data, 'PUT'),
postDataByParams: (url, data) => _axios.fetch(url, data, 'POST'),
findDates: ( data) => _axios.fetch('/report/find/dates', data, 'GET'),
postBlobByParams: (url, data) => _axios.fetch(url, data, 'POST', 'blob'),
getDataByParams: (url, data) => _axios.fetch(url, data, 'GET'),
getBlobByParams: (url, data) => _axios.fetch(url, data, 'GET', 'blob'),
uploadFormData: (url, data) => _axios.fetch(url, data, 'POST', 'json', '', true, true),
viewDetails: (data) => _axios.fetch('/health/info', data, 'POST'),
healthDelex: (data) => _axios.fetch('/health/delex', data, 'POST'),
healthDrde: (data) => _axios.fetch('/health/drde', data, 'POST'),
healthEdit: (data) => _axios.fetch('/health/edit', data, 'POST'),
healthAdddr: (data) => _axios.fetch('/health/adddr', data, 'POST'),
healthEditStreet: (data) => _axios.fetch('/health/editstreet', data, 'POST'),
healthIllmessage: (data) => _axios.fetch('/health/illmessage', data, 'POST'),
healthCall: (url, data) => _axios.fetch(url, data, 'POST'),
promotionDownload: (data) => _axios.fetch('/collections/extend', data, 'POST', 'blob'),
//只能看到我所在的组织机构树
viewMyTree: (data) => _axios.fetch('/department/v2/tree/my', data, 'POST'),
}

18
src/api/index.js Normal file
View File

@ -0,0 +1,18 @@
// 使用 `import.meta.glob` 来同步导入所有匹配的模块
// 使用 `{ eager: true }` 选项来立即加载这些模块
const modules = import.meta.glob('./*.js', { eager: true });
const HTTP = {};
for (const path in modules) {
if (Object.hasOwnProperty.call(modules, path)) {
// 正确移除 './' 和 '.js',只保留文件名
const componentName = path.replace(/^\.\/(.*)\.\w+$/, '$1');
if (componentName !== 'index') {
// 确保我们只获取模块的默认导出
HTTP[componentName] = modules[path]?.default;
}
}
}
// 导出 HTTP 对象
export default { HTTP };

View File

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 530 B

View File

@ -9,13 +9,20 @@
<template v-else> <template v-else>
{{ title }} {{ title }}
</template> </template>
<div class="custom-close-btn" v-if="customCloseBtn">
<img src="@/assets/image/icon/close-btn-grey.png" alt="" @click="handleCloseModal"/>
</div>
</div> </div>
</div> </div>
</template> </template>
<slot name="content"></slot> <slot name="content"></slot>
<template #footer> <template #footer>
<div class="custom-modal-btns"> <div class="custom-modal-btns">
<customBtn color="#C7C7C9" style="width: 161px; height: 34px;" @click="handleCancel" <customBtn
color="#C7C7C9"
style="width: 161px; height: 34px;"
@click="handleCancel"
v-if="actionBtns.cancelBtn"
>取消</customBtn >取消</customBtn
> >
<customBtn <customBtn
@ -23,6 +30,7 @@
style="width: 161px; height: 34px;" style="width: 161px; height: 34px;"
@click="handleConfirm" @click="handleConfirm"
:loading="state.confirmBtnLoading" :loading="state.confirmBtnLoading"
v-if="actionBtns.confirmBtn"
>确定</customBtn >确定</customBtn
> >
</div> </div>
@ -32,17 +40,29 @@
<script setup> <script setup>
import { reactive, computed } from 'vue' import { reactive, computed } from 'vue'
import xNModal from '@/components/x-n-modal/index.vue' import xNModal from '@/components/x-naive-ui/x-n-modal/index.vue'
import customBtn from '@/components/common/customBtn.vue' import customBtn from '@/components/common/customBtn.vue'
const props = defineProps({ const props = defineProps({
show: { show: {
//
type: Boolean, type: Boolean,
default: false default: false
}, },
title: { title: {
//
type: String, type: String,
default: '' default: ''
},
actionBtns: {
//
type: Object,
default: () => ({})
},
customCloseBtn: {
//
type: Boolean,
default: false
} }
}) })
@ -70,12 +90,16 @@ const closeLoading = () => {
const state = reactive({ const state = reactive({
confirmBtnLoading: false // loading confirmBtnLoading: false // loading
}) })
const handleCloseModal = () => {
show.value = false
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.custom-modal-header { .custom-modal-header {
border-bottom: 1px solid #e5e5e5; border-bottom: 1px solid #e5e5e5;
margin: 0 30px; margin: 0 12px;
.header-content { .header-content {
padding: 0 0 15px; padding: 0 0 15px;
@ -84,6 +108,18 @@ const state = reactive({
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
line-height: 28px; line-height: 28px;
position: relative;
.custom-close-btn {
position: absolute;
right: 0;
top: 0;
cursor: pointer;
img {
width: 30px;
height: 30px;
}
}
} }
} }

View File

@ -0,0 +1,121 @@
<template>
<div class="fl-tree width-100 fl-mt-md">
<n-tree v-if="state.treeLoading"
block-line
:default-expanded-keys="state.expandedKeys"
:default-selected-keys="state.clickKey"
label-field="name"
key-field="key"
:expand-on-click="true"
:render-label="renderLabel"
:data="state.treeData"
@update:selected-keys="handleSelectTree" />
</div>
</template>
<script setup>
import {
ref,
reactive,
onBeforeMount,
onMounted,
getCurrentInstance,
computed,
defineEmits,
watch,
nextTick,
h
} from "vue";
import { PlusCircleOutlined, MinusCircleOutlined, EditOutlined, PlusOutlined, MinusOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue';
import treeLabel from "./treelabel.vue";
import { NTree } from 'naive-ui';
const currentInstance = getCurrentInstance();
const { $request } = currentInstance.appContext.config.globalProperties;
let props = defineProps({
data: Object,
refreshCount: Number,
config: Object,
expandedKeys: Array,
clickKey: [String, Number]
})
const state = reactive({
expandedKeys: [],
editTitle: '',
treeData: [],
clickKey: [],
treeLoading: true
});
watch(() => props.refreshCount, () => {
state.clickKey = [props.clickKey]
state.treeLoading = false
nextTick(() => {
state.treeData = props.data
calcDefaultConfig(state.treeData, 1)
state.treeLoading = true
})
});
watch(() => props.expandedKeys, () => {
state.clickKey = [props.clickKey]
state.expandedKeys = props.expandedKeys
}, { deep: true });
onBeforeMount(() => {
state.clickKey = [props.clickKey]
state.treeData = props.data
calcDefaultConfig(state.treeData, 1);
state.expandedKeys = state.treeData.map(item => item.key)
});
onMounted(() => {
});
const emit = defineEmits(["triggerTreeAction", "triggerTreeClick", "triggerTreeDefaultClick"]);
const handleSelectTree = (keys, option, meta) => {
if (keys.length === 1) {
emit('triggerTreeClick', { selectedKey: keys[0], tree: option[0] })
} else {
emit('triggerTreeDefaultClick')
}
}
const renderLabel = (option, checked) => {
return h(
treeLabel,
{
dataRef: option,
checked: checked,
config: props.config,
clickKey: props.clickKey,
onTriggerTreeAction: handleTreeAction
},
{}
)
}
const calcDefaultConfig = (data, level) => {
for (let item of data) {
if (!item.key) {
item.key = item.title + '_' + level;
}
item.edit = false
if (item.children) {
calcDefaultConfig(item.children, level + 1);
}
}
}
const override = ({ option }) => {
if (option.children) {
return "toggleExpand";
}
return "default";
};
const handleTreeAction = ({ type, val }) => {
emit('triggerTreeAction', { type, val })
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,121 @@
<template>
<div class="row items-center">
<div v-if="state.treeData.edit">
<n-input v-model:value="state.editTitle"
style="width:120px" />
</div>
<n-popover trigger="hover"
v-else>
<template #trigger>
<div style="width:120px"
class="fl-px-sm sf-text-ellipsis">{{ state.treeData.title }}</div>
</template>
<div>{{ state.treeData.title }}</div>
</n-popover>
<n-icon :component="CreateOutline"
class="fl-ml-sm"
size="20"
v-if="config?.actions.includes('edit')&&!state.treeData.edit"
@click.stop="handleTreeEdit(state.treeData)" />
<n-icon :component="Remove"
size="20"
v-if="config?.actions.includes('subtraction')&&!state.treeData.edit&&visibleFormItem(config.subtractionShow, state.treeData)"
class="fl-ml-sm"
@click.stop="handleTreeSubtraction(state.treeData)" />
<n-icon :component="Add"
size="20"
v-if="config?.actions.includes('add')&&!state.treeData.edit&&visibleFormItem(config.addShow, state.treeData)"
class="fl-ml-sm"
@click.stop="handleTreeAdd(state.treeData)" />
<drag-outlined v-if="config?.actions.includes('move')&&!state.treeData.edit&&visibleFormItem(config.moveShow, state.treeData)"
class="fl-ml-sm"
@click.stop="handleTreeMove(state.treeData)" />
<!-- <n-icon :component="MoveOutline"
size="20"
v-if="config?.actions.includes('move')&&!state.treeData.edit&&visibleFormItem(config.moveShow, state.treeData)"
class="fl-ml-sm"
@click.stop="handleTreeMove(state.treeData)" /> -->
<n-icon :component="Checkmark"
size="20"
v-if="state.treeData.edit"
class="fl-ml-sm"
@click.stop="handleTreeSave(state.treeData)" />
<n-icon :component="Close"
size="20"
v-if="state.treeData.edit"
class="fl-ml-md"
@click.stop="handleTreeNotSave(state.treeData)" />
</div>
</template>
<script setup>
import {
onBeforeMount,
onMounted,
watch,
reactive
} from "vue";
import {
visibleFormItem,
} from "@/utils/helper/form";
import {
UpOutlined,
DownOutlined,
CloseCircleOutlined,
PlusOutlined,
DragOutlined,
} from "@ant-design/icons-vue";
import { Add, Checkmark, Close, CreateOutline, Remove, MoveOutline } from "@vicons/ionicons5";
import { NPopover, NInput, NIcon } from "naive-ui";
let props = defineProps({
dataRef: Object,
checked: Boolean,
config: Object,
clickKey: [String, Number]
})
const state = reactive({
expandedKeys: [],
editTitle: '',
treeData: [],
});
onBeforeMount(() => {
state.treeData = props.dataRef.option
})
watch(() => props.dataRef.option, (val) => {
state.treeData = props.dataRef.option
}, { deep: true })
onMounted(() => {
})
const emit = defineEmits(["triggerTreeAction", "triggerTreeClick"]);
// const myComponentRef = ref(null);
const handleTreeEdit = () => {
state.editTitle = state.treeData.title
state.treeData.edit = true
// myComponentRef.value.$forceUpdate();
}
const handleTreeAdd = () => {
emit('triggerTreeAction', { type: 'add', val: state.treeData })
}
const handleTreeMove = () => {
emit('triggerTreeAction', { type: 'move', val: state.treeData })
}
const handleTreeSubtraction = () => {
emit('triggerTreeAction', { type: 'subtraction', val: state.treeData })
}
const handleTreeSave = () => {
state.treeData.title = state.editTitle
emit('triggerTreeAction', { type: 'save', val: state.treeData })
}
const handleTreeNotSave = () => {
state.editTitle = ''
emit('triggerTreeAction', { type: 'cancel', val: state.treeData })
}
</script>

View File

@ -49,7 +49,11 @@ const state = reactive({
height: '314px' height: '314px'
}, // }, //
chatSettingOperateHint: '', // chatSettingOperateHint: '', //
chatSettingOperateSubHint: '' // chatSettingOperateSubHint: '', //
actionBtns: {
confirmBtn: true,
cancelBtn: true
}, //
}) })
const members = ref<any[]>([]) const members = ref<any[]>([])
@ -382,6 +386,7 @@ const showChatSettingOperateModal = (type: string) => {
:style="state.customModalStyle" :style="state.customModalStyle"
:closable="false" :closable="false"
@confirm="handleModalConfirm" @confirm="handleModalConfirm"
:actionBtns="state.actionBtns"
> >
<template #content> <template #content>
<div class="custom-modal-content"> <div class="custom-modal-content">
@ -566,6 +571,8 @@ const showChatSettingOperateModal = (type: string) => {
gap: 30px; gap: 30px;
.btn { .btn {
width: calc(100% - 50px); width: calc(100% - 50px);
background-color: #fff;
color: #CF3050;
} }
} }

View File

@ -0,0 +1,142 @@
# @x-naive-ui 组件库
基于 Naive UI 的二次封装组件库,旨在提供更高层级的抽象和更便捷的使用方式,同时保持足够的灵活性。
@x-naive-ui 的设计理念是在易用性和灵活性之间找到平衡点,通过合理的默认值和可配置项,能够快速开发出高质量的页面,同时保留足够的扩展空间应对特殊需求。
**如发现文档与实际使用有出入或者不完善 可提交修改**
## 设计理念
### 1. 易用性与灵活性的平衡
- **约定优于配置**:提供合理的默认值,减少基础使用时的配置量
- **保持原有能力**:通过属性透传,保留 Naive UI 原组件的所有功能
- **渐进式配置**:简单场景可以快速使用,复杂场景仍可深度定制
### 2. 通用性与特殊性的权衡
- **场景覆盖**:优先覆盖 80% 的常见业务场景
- **扩展机制**:为剩余 20% 的特殊场景预留扩展接口
### 3.<span style="background-color: red;color:#fff">避免过度封装:不追求完美覆盖所有场景,保持组件的可维护性</span>
## 组件列表
### x-n-data-table
数据表格组件,增强了以下能力:
- ✨ 拖拽排序(支持整行/手柄模式)
- ✨ 列级别的插槽系统
- 🎯 统一的样式和交互
**权衡点**
- 牺牲了一定的性能来换取更好的开发体验
- 固化了部分样式以确保视觉一致性
### x-n-modal
模态框组件,预设了常用配置:
- ✨ 统一的挂载点管理
- ✨ 预设的关闭行为
- 🎯 居中布局和统一样式
**权衡点**
- 限制了一些灵活性以确保使用的一致性
- 强制了某些最佳实践(如挂载点)
### x-n-upload
文件上传组件,增强了以下功能:
- ✨ 统一的文件处理逻辑
- ✨ 内置预览能力
- 🎯 更友好的类型支持
**权衡点**
- 上传接口格式固定,需要后端配合
- 为了通用性,部分特殊格式需要额外处理
### x-search-form
搜索表单组件,提供了:
- ✨ 声明式配置
- ✨ 自动布局
- 🎯 统一的搜索重置行为
**权衡点**
- 牺牲了一些布局灵活性换取使用便利性
- 配置项相对复杂,但换来了更好的复用性
## 最佳实践
### 1. 组件使用建议
```vue
<!-- 推荐:使用声明式配置 -->
<x-search-form
:search-config="searchConfig"
:cols="4"
@change="handleSearch"
/>
<!-- 不推荐:内联复杂配置 -->
<x-search-form
:search-config="[
{ type: 'input', key: 'name', label: '姓名' },
{ type: 'select', key: 'status', label: '状态' }
]"
/>
```
### 2. 配置管理建议
```ts
// 推荐:将配置抽离到单独的配置文件
import { searchConfig } from './config'
import { tableConfig } from './config'
// 不推荐在组件内部直接定义<E5AE9A><E4B989><EFBFBD>杂配置
const searchConfig = [
// ... 大量配置
]
```
## 注意事项
1. **性能考虑**
- 大数据量场景下,优先使用原生组件
- 合理使用 `shallowRef``markRaw`
- 避免不必要的响应式转换
2. **扩展性保证**
- 使用 `v-bind` 透传原组件属性
- 预留合理的插槽接口
- 导出必要的类型定义
3. **代码质量**
- 统一的错误处理机制
- 完善的类型声明
- 详细的文档注释
## 未来规划
1. **组件增强**
- 添加更多常用预设
- 优化性能表现
- 增加更多定制选项
2. **文档完善**
- 补充更多使用示例
- 添加在线演示
- 完善类型声明
3. **工具支持**
- 提供配置生成器
- 添加主题定制能力
- 集成表单验证工具
## 贡献指南
1. **组件开发原则**
- 保持简单性
- 关注通用性
- 预留扩展性
2. **代码规范**
- 遵循项目 ESLint 配置
- 编写单元测试
- 提供完整文档

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,54 @@
<script setup>
import { computed } from "vue";
import levelTwo from "./data/pc-code.json";
import levelThree from "./data/pca-code.json";
import levelFour from "./data/pcas-code.json";
const props = defineProps({
value: {
type: String,
default: undefined
},
label: {
type: String,
default: undefined
},
level: {
type: Number,
default: 3
}
});
const cascaderRef = ref(null);
const emit = defineEmits(['update:value']);
const levelMap = {
2: levelTwo,
3: levelThree,
4: levelFour
};
const options = computed(() => levelMap[props.level] || []);
const updateValue = (value, option) => {
emit("update:value", value);
};
defineExpose({
cascaderRef
});
</script>
<template>
<n-cascader
ref="cascaderRef"
:value="value"
placeholder="请选择"
:options="options"
showPath
check-strategy="child"
value-field="code"
label-field="name"
filterable
@update:value="updateValue"
v-bind="{...$attrs}"
/>
</template>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,144 @@
import { createApp, h, ref } from 'vue'
import { NImage, NImageGroup } from 'naive-ui'
interface PreviewOptions {
onStart?: () => void
onError?: (e: Event) => void
showToolbar?: boolean
}
class ImagePreview {
private static instance: {
app: any
container: HTMLElement
} | null = null
static async preview(
sources: string | File | (string | File)[],
index = 0,
options: PreviewOptions = {},
) {
try {
const urls = await this.normalizeImageSources(
Array.isArray(sources) ? sources : [sources]
)
if (!urls.length) {
console.warn('[ImagePreview] No valid image sources')
return
}
this.destroy()
options.onStart?.()
const container = document.createElement('div')
container.style.display = 'none'
document.body.appendChild(container)
const app = createApp({
setup() {
const imageRef = ref<InstanceType<typeof NImage> | null>(null)
return () => {
if (urls.length === 1) {
return h(NImage, {
ref: imageRef,
src: urls[0],
previewDisabled: false,
preview: true,
showToolbar: options.showToolbar ?? true,
style: {
display: 'none'
},
onLoad: () => {
imageRef.value?.click()
}
})
} else {
return h(NImageGroup, {
showToolbar: options.showToolbar ?? true,
currentIndex: index
}, {
default: () => urls.map((url, i) => {
const imgRef = ref<InstanceType<typeof NImage> | null>(null)
return h(NImage, {
ref: i === index ? imgRef : undefined,
src: url,
previewDisabled: false,
preview: true,
style: {
display: 'none'
},
onLoad: i === index ? () => {
imgRef.value?.click()
} : undefined
})
})
})
}
}
}
})
app.mount(container)
this.instance = { app, container }
} catch (error) {
console.error('[ImagePreview] Error:', error)
options.onError?.(error as Event)
}
}
private static async normalizeImageSources(sources: (string | File)[]): Promise<string[]> {
const urls: string[] = []
for (const source of sources) {
try {
if (typeof source === 'string') {
if (source.startsWith('data:') || source.startsWith('http')) {
urls.push(source)
} else {
console.warn('[ImagePreview] Invalid image source:', source)
}
} else if (source instanceof File) {
const url = await this.fileToUrl(source)
urls.push(url)
}
} catch (error) {
console.warn('[ImagePreview] Failed to process source:', source, error)
}
}
return urls
}
private static fileToUrl(file: File): Promise<string> {
return new Promise((resolve, reject) => {
if (!file.type.startsWith('image/')) {
reject(new Error('Not an image file'))
return
}
const reader = new FileReader()
reader.onload = () => resolve(reader.result as string)
reader.onerror = reject
reader.readAsDataURL(file)
})
}
private static destroy() {
if (this.instance) {
const { app, container } = this.instance
app.unmount()
container.remove()
this.instance = null
}
}
static close() {
this.destroy()
}
}
export const previewImage = ImagePreview.preview.bind(ImagePreview)
export const closePreview = ImagePreview.close.bind(ImagePreview)

View File

@ -0,0 +1,54 @@
import Viewer from 'viewerjs';
import 'viewerjs/dist/viewer.css';
interface PreviewOptions {
toolbar?: boolean;
navbar?: boolean;
transition?: boolean;
transitionDuration?: number;
// 其他选项
}
export function previewImage(
sources: string | File | (string | File)[],
index = 0,
options: PreviewOptions = {}
) {
const container = document.createElement('div');
container.style.display = 'none';
document.body.appendChild(container);
const processSource = async (source: string | File) => {
const img = document.createElement('img');
img.src = typeof source === 'string'
? source
: await readFileAsDataURL(source);
container.appendChild(img);
};
const readFileAsDataURL = (file: File): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => resolve(e.target?.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
Promise.all(
(Array.isArray(sources) ? sources : [sources])
.map(source => processSource(source))
).then(() => {
const viewer = new Viewer(container, {
zoomRatio: 0.8,
transition: false,
transitionDuration: 100, // 默认是300设置更小的值可以加快动画速度
...options,
hidden() {
viewer.destroy();
document.body.removeChild(container);
},
});
viewer.view(index);
});
}

View File

@ -0,0 +1,272 @@
<script setup>
import { cloneDeep, debounce } from "lodash-es";
import { computed, onBeforeUnmount, ref } from "vue";
import { NButton, NForm, NFormItemGi, NGrid, NInput, NSelect, NDatePicker } from 'naive-ui'
const props = defineProps({
title: {
type: String,
default: '',
},
cols: {
type: [Number, String],
default: 4,
},
searchConfig: {
type: Array,
default: () => ([]),
},
xGap: {
type: [Number, String],
default: 81,
},
yGap: {
type: [Number, String],
default: 20,
},
autoSearch: {
type: Boolean,
default: true,
},
debounceWait: {
type: Number,
default: 300,
},
loading: {
type: Boolean,
default: false,
}
})
const emit = defineEmits(['change', 'init'])
const resetForm = ref({})
const formData = ref({})
const indexRef = ref(0)
const datePickerRef = ref(null)
const formRef = ref(null)
//
const debouncedSearch = debounce(() => {
emit('change', formData.value)
}, props.debounceWait)
//
onBeforeUnmount(() => {
debouncedSearch.cancel()
})
//
const calculateEmptySpans = computed(() => {
const num = props.searchConfig?.reduce((acc, cur) =>
acc + (cur.col || 1), 0
)
const remainder = num % props.cols
return remainder === 0 ? props.cols - 1 : props.cols - remainder - 1
})
//
const manualChange = () => {
if (props.autoSearch) {
debouncedSearch()
}
}
const handleInputChange = (value, item) => {
// pair
if (item.props?.pair && Array.isArray(item.key)) {
// value
const valueArray = Array.isArray(value) ? value : [value, value];
//
const defaultValues = Array.isArray(item.default) ? item.default : [];
// keydefault
item.key.forEach((key, index) => {
const defaultValue = defaultValues[index];
const currentValue = valueArray[index] || '';
//
if (typeof defaultValue === 'number') {
formData.value[key] = currentValue === '' ? defaultValue : Number(currentValue);
} else {
formData.value[key] = currentValue;
}
});
} else {
//
formData.value[item.key] = value;
}
manualChange();
};
const handleSelectChange = (value, item) => {
formData.value[item.key] = value
console.log('formData.value[item.key]',formData.value[item.key]);
manualChange()
}
const handleDateChange = (value, key) => {
if (Array.isArray(key)) {
key.forEach((k, i) => {
formData.value[k] = value?.[i]
})
} else {
formData.value[key] = value
}
manualChange()
}
const search = async () => {
if (!formRef.value) {
emit('change', formData.value)
return
}
try {
await formRef.value?.validate()
emit('change', formData.value)
} catch (errors) {
console.error('表单验证失败:', errors)
}
}
//
const reset = () => {
formData.value = cloneDeep(resetForm.value)
emit('change', formData.value)
indexRef.value++
if (formRef.value) {
formRef.value?.restoreValidation()
}
}
//
const generateFormObject = (config) => {
return config.reduce((formObject, field) => {
const defaultValue = field.default ?? undefined;
if (Array.isArray(field.key)) {
if (Array.isArray(defaultValue)) {
field.key.forEach((subKey, index) => {
// 使
formObject[subKey] = defaultValue[index];
});
} else {
field.key.forEach(subKey => {
formObject[subKey] = defaultValue;
});
}
} else {
formObject[field.key] = defaultValue;
}
return formObject;
}, {});
};
//
const initData = () => {
const initialData = generateFormObject(props.searchConfig)
formData.value = initialData
resetForm.value = cloneDeep(initialData)
emit('init', initialData)
}
//
initData()
</script>
<template>
<div class="search-form w-[100%] pb-[20px] bg-[#fff] rounded-[3px] overflow-hidden">
<div
v-if="title"
class="search-form__header h-[59px] border-b-[2px] border-[#EAEAEA]"
>
<div class="text-[#1F2225] text-[18px] font-[600] h-[100%] flex justify-center align-center w-fit border-b-[4px] border-[#46299D]">
{{ title }}
</div>
</div>
<n-form
ref="formRef"
class="mt-[20px]"
:show-feedback="false"
label-placement="left"
label-align="left"
label-width="110"
:key="indexRef"
>
<n-grid :cols="cols" :x-gap="xGap" :y-gap="yGap">
<n-form-item-gi
v-for="item in searchConfig"
:key="item.key"
:span="item.col || 1"
:label="item.label"
:rule="item.rule"
>
<!-- Input 类型 -->
<template v-if="item.type === 'input'">
<n-input
:value="formData[item.key]"
placeholder="请输入"
@input="value => handleInputChange(value, item)"
clearable
v-bind="item.props"
/>
</template>
<!-- Select 类型 -->
<template v-else-if="item.type === 'select'">
<n-select
:value="formData[item.key]"
placeholder="请选择"
@update:value="value => handleSelectChange(value, item)"
clearable
v-bind="item.props"
/>
</template>
<!-- DatePicker 类型 -->
<template v-else-if="item.type === 'date-picker'">
<n-date-picker
ref="datePickerRef"
class="w-[100%]"
clearable
:value="formData[item.key]"
@update-formatted-value="value => handleDateChange(value, item.key)"
v-bind="item.props"
/>
</template>
</n-form-item-gi>
<!-- 空白占位 -->
<n-form-item-gi :span="calculateEmptySpans" />
<!-- 操作按钮 -->
<n-form-item-gi :span="1">
<div class="flex justify-end w-full">
<n-button
class="w-[145px] h-[34px] mr-[20px]"
@click="search"
type="primary"
:loading="loading"
>
查询
</n-button>
<n-button
class="w-[145px] h-[34px]"
color="#EEE9F8"
text-color="#46299D"
@click="reset"
>
重置
</n-button>
</div>
</n-form-item-gi>
</n-grid>
</n-form>
</div>
</template>
<style scoped lang="scss">
.search-form {
&__header {
margin-bottom: 16px;
}
}
</style>

View File

@ -1,10 +1,10 @@
// 主题配置 // 主题配置
export const overrides = { export const overrides = {
common: { common: {
primaryColor: '#1890ff', primaryColor: '#46299D',
primaryColorHover: '#1890ff', primaryColorHover: '#46299D',
primaryColorPressed: '#1890ff', primaryColorPressed: '#46299D',
primaryColorSuppl: '#1890ff', primaryColorSuppl: '#46299D',
bodyColor: '#ffffff' bodyColor: '#ffffff'
}, },

View File

@ -1,15 +1,19 @@
import '@/assets/css/define/theme.less' import '@/assets/css/define/theme.less'
import '@/assets/css/define/global.less' import '@/assets/css/define/global.less'
import '@/assets/css/dropsize.less' import '@/assets/css/dropsize.less'
import 'uno.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import router from './router' import router from './router'
import App from './App.vue' import App from './App.vue'
import * as plugins from './plugins' import * as plugins from './plugins'
import request from "@/api/index.js";
async function bootstrap() { async function bootstrap() {
const app = createApp(App) const app = createApp(App)
app.use(router) app.use(router)
app.config.globalProperties.$request = request;
plugins.setPinia(app) plugins.setPinia(app)
plugins.setHljsVuePlugin(app) plugins.setHljsVuePlugin(app)

View File

@ -18,7 +18,7 @@ export function isLoggedIn() {
*/ */
export function getAccessToken() { export function getAccessToken() {
// return storage.get(AccessToken) || '' // return storage.get(AccessToken) || ''
return JSON.parse(localStorage.getItem('token'))||'79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b892000b1d18303354ea8a7c57f91ffb617f5d82513d2af46e6ce5848a80c59c75b9ddf4a552092d70ecda72c97d99cb5d0f114a50ddfd9674f22576675e3390d2367951eb502aa1dd94e8823d528a503fb' return JSON.parse(localStorage.getItem('token'))||'79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b891bd3a81a1ac4e73e2aed60deeaec60792c525cc0c96e8f4a666eca6ee7a10716507b402cde5759bbcda1fa681fbe4dcdfe05abbc2b1644c68dc74ebaf8d9c9cc4eb61afaf3de52fa357dbfdfe17acf14'
} }
/** /**

143
src/utils/erpRequest.js Normal file
View File

@ -0,0 +1,143 @@
import axios from "axios";
import $router from "../router";
import { message } from "ant-design-vue";
import { Local } from "@/utils/erpStorage.js";
const service = axios.create({
baseURL: import.meta.env.VITE_EPR_BASEURL,
timeout: 60 * 60 * 1000,
authToken: true,
responseType: "json", // 请求数据格式
});
service.interceptors.request.use(
(config) => {
// set header Content-Type
if (config.method === "get") {
// || config.method === "delete"
config.headers["Content-Type"] = "application/x-www-form-urlencoded";
} else {
config.headers["Content-Type"] = "application/json";
}
if (config.isFormData) {
config.headers["Content-Type"] = "multipart/form-data";
config.headers.Authorization = Local.get("token") || "";
} else config.headers.Authorization = Local.get("token") || "";
return config;
},
(error) => {
return Promise.reject(error);
}
);
let isRefreshing = false;
let refreshSubscribers = [];
service.interceptors.response.use(
(response) => {
let isResourse = response.config.responseType;
if (response && response.data.status === 409) {
// 账户另一处登录 此处踢下线
message.error('您的账号已在其他设备登录')
$router.push("/login");
return;
}
if (response && response.data.code === 401) {
// 若token过期则态获取RefreshToken重新获取token
return getRefreshToken(response);
}
if (
response.status === 200 ||
response.status === 201 ||
response.status === 204
) {
return isResourse == "blob" ? response : response.data;
} else {
message.success(res.msg);
Promise.reject(response);
}
},
(error) => {
return Promise.reject(error);
}
);
const getRefreshToken = async (response) => {
if (!isRefreshing) {
isRefreshing = true;
const refreshToken = Local.get("RefreshToken");
if (refreshToken) {
try {
const data = { refreshToken };
const res = await fetch(
"/user/refresh/token",
data,
"POST",
"json",
"application/json",
false
);
if (res.code === 200) {
Local.set("token", res.data.Token);
Local.set("userInfo", res.data.AccountInfo);
Local.set("RefreshToken", res.data.RefreshToken);
return Promise.resolve(service(response.config));
} else {
// 跳转登录页
$router.push("/login");
res.message = res.message || res.msg;
return Promise.reject(res);
}
} catch (error) {
return Promise.reject(error);
} finally {
isRefreshing = false;
refreshSubscribers.forEach((callback) => callback());
refreshSubscribers = [];
}
} else {
$router.push("/login");
return Promise.reject(response);
}
} else {
return new Promise((resolve) => {
refreshSubscribers.push(() => {
resolve(service(response.config));
});
});
}
};
const fetch = async (
url = "",
data = {},
method = "",
responseType = "json",
contentType = "",
authToken = true,
isFormData = false
) => {
if (!method) {
method = "GET";
}
let args = { url, method };
if (method === "GET") {
// || method === "DELETE"
args.params = data;
} else {
args.data = data;
}
if (contentType) {
args = Object.assign({}, args, {
headers: {
"Content-Type": contentType,
},
});
}
// 请求数据格式
args.responseType = responseType;
args.authToken = authToken;
args.isFormData = isFormData;
return service(args);
};
export default { fetch, getRefreshToken };

91
src/utils/erpStorage.js Normal file
View File

@ -0,0 +1,91 @@
function createStorage(storage) {
const cache = new Map();
const stringifyCache = new Map();
const batchWrites = [];
let flushTimer = null;
// 优化的 JSON 序列化
function fastStringify(obj) {
const type = typeof obj;
if (obj === null) return 'null';
if (type === 'string') return `"${obj}"`;
if (type === 'number' || type === 'boolean') return String(obj);
if (type !== 'object') return '{}';
const cached = stringifyCache.get(obj);
if (cached) return cached;
try {
const result = JSON.stringify(obj);
if (result.length < 1000) {
stringifyCache.set(obj, result);
}
return result;
} catch {
return '{}';
}
}
return {
set(key, val) {
if (!key) return;
try {
// 更新缓存
cache.set(key, val);
// 序列化并立即写入
const serialized = fastStringify(val);
storage.setItem(key, serialized);
// 批量写入作为备份
batchWrites.push([key, serialized]);
if (!flushTimer) {
flushTimer = setTimeout(() => {
batchWrites.forEach(([k, v]) => {
try { storage.setItem(k, v); } catch {}
});
batchWrites.length = 0;
flushTimer = null;
}, 100);
}
} catch (e) {
console.error('Storage error:', e);
}
},
get(key) {
if (!key) return null;
// 优先读缓存
const cached = cache.get(key);
if (cached !== undefined) return cached;
try {
const val = JSON.parse(storage.getItem(key));
cache.set(key, val);
return val;
} catch {
return null;
}
},
remove(key) {
cache.delete(key);
storage.removeItem(key);
},
clear() {
cache.clear();
stringifyCache.clear();
storage.clear();
batchWrites.length = 0;
if (flushTimer) {
clearTimeout(flushTimer);
flushTimer = null;
}
}
};
}
// 导出单例实例
export const Local = createStorage(window.localStorage);
export const Session = createStorage(window.sessionStorage);

347
src/utils/helper/form.js Normal file
View File

@ -0,0 +1,347 @@
export const getParamsByObj = (params, paramsConfig, obj) => {
if (paramsConfig !== undefined && paramsConfig.length > 0 && obj !== null) {
for (let i in paramsConfig) {
let paramsItem = paramsConfig[i];
if (paramsItem.value !== undefined) {
params[paramsItem.label] = paramsItem.value;
}
if (obj && paramsItem.field !== undefined) {
if (
obj[paramsItem.field] !== undefined &&
obj[paramsItem.field] !== null
) {
params[paramsItem.label] = obj[paramsItem.field];
// 对值数组化
params[paramsItem.label] =
paramsItem.type === "Array"
? [params[paramsItem.label]]
: params[paramsItem.label];
}
}
}
}
return params;
};
export const getLabelByOptions = (val, options, customEmpty) => {
let label = "";
let valOpt = {};
for (let i in options) {
if (options[i].value === val) {
valOpt = options[i];
break;
}
}
if (valOpt.class || valOpt.style) {
return `<div class="sf-status-label ${valOpt.class}" style="${
valOpt.style
}">${valOpt.label || customEmpty}</div>`;
}
return valOpt.label || customEmpty;
};
export const getFormObj = (formConfig) => {
let data = {};
formConfig.forEach((item) => {
if (item.field) {
data[item.field] = item.value;
if (item.type === "date") {
data[item.field] = item.value ? item.value?.format("YYYY-MM-DD") : "";
}
}
});
return data;
};
export const setFormObj = (formConfig, data) => {
formConfig.forEach((item) => {
if (item.field && data[item.field] !== undefined) {
item.value = data[item.field];
}
});
};
export const clearObj = (formData) => {
for (let field in formData) {
if (Array.isArray(formData[field])) {
formData[field] = [];
} else if (
Object.prototype.toString.call(formData[field]) === "[object Number]"
) {
formData[field] = 0;
} else if (
Object.prototype.toString.call(formData[field]) === "[object Object]"
) {
formData[field] = {};
} else {
formData[field] = null;
}
}
};
export const visibleFormItem = (itemshow, formObj = {}) => {
let flag = true;
if (Object.prototype.toString.call(itemshow) === "[object Function]") {
return itemshow(formObj);
}
if (Object.prototype.toString.call(itemshow) === "[object Boolean]") {
return itemshow;
}
let mathArr = [
"+",
"-",
"/",
"*",
">",
">=",
"<",
"<=",
"==",
"===",
"!==",
"||",
"&&",
];
if (itemshow && Object.keys(formObj).length > 0) {
let expression = itemshow
.replace(/\[%=/g, "")
.replace(/%\]/g, "")
.replace(/'/g, "");
let cs = expression.split(/(\/|%|\*|\+|-|&&|\|\||>|<|>=|<=|\(|\)|===|!==)/);
for (let idx in cs) {
let csItem = cs[idx];
// 右边为''
if (formObj[csItem] === "") {
cs[idx] = "'" + formObj[csItem] + "'";
// 左边可转为数值计算
} else if (
formObj[csItem] !== undefined &&
Object.prototype.toString.call(formObj[csItem]) === "object String"
) {
cs[idx] = formObj[csItem];
} else if (
formObj[csItem] !== undefined &&
Object.prototype.toString.call(formObj[csItem]) === "object Number"
) {
cs[idx] = "'" + formObj[csItem] + "'";
// 左边字段不存在 右边字段值字符串化
} else if (!mathArr.includes(csItem) && formObj[csItem] === undefined) {
cs[idx] = "'" + csItem + "'";
// 计算公式
} else if (mathArr.includes(csItem)) {
cs[idx] = csItem;
} else {
// 左边 在obj中存在 字符串化
cs[idx] = "'" + formObj[csItem] + "'";
}
}
cs = cs.join("");
flag = flag && window.eval(cs);
}
return flag;
};
export const validateItem = (item, itemValue) => {
let validate = item.validate;
let noErr = true;
let message = "";
switch (validate) {
case "required": {
// ADD input type is number is empty is null And dropdowntable,userDropdowntable,dropdownbox is empty is []
if (itemValue === null || itemValue.length === 0) {
noErr = false;
message = "请输入内容";
}
break;
}
case "": {
// ADD input type is number is empty is null And dropdowntable,userDropdowntable,dropdownbox is empty is []
if (itemValue === null || itemValue.length === 0) {
noErr = false;
message = "请输入内容";
}
break;
}
case "email": {
const regEmail =
/^[a-zA-Z0-9_-]+([._\\-]*[a-zA-Z0-9_-])*@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
if (regEmail.test(itemValue) === false) {
noErr = false;
message = "请输入正确邮箱";
}
break;
}
case "chinese": {
const regChinese = /^[^\u4e00-\u9fa5]{0,}$/;
if (regChinese.test(itemValue) === false) {
noErr = false;
message = "请输入中文字符";
}
break;
}
case "maxDecimals4": {
// let regDecimals2 = /^\d+(\.\d{2})?$/
const regDecimals4 = /^\d+(?:\.\d{1,4})?$/;
if (
itemValue !== null &&
itemValue !== "" &&
regDecimals4.test(itemValue) === false
) {
noErr = false;
message = "最多四位小数";
}
break;
}
case "english": {
// 添加英文支持-
const regEnglish = /^[a-zA-Z0-9_@-]{1,}$/;
if (regEnglish.test(itemValue) === false) {
noErr = false;
message = "请输入英文字符";
}
break;
}
case "datetime": {
const regDatetime =
/^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
if (regDatetime.test(itemValue) === false) {
noErr = false;
message = "请输入正确时间";
}
break;
}
case "date": {
const regDate = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/;
if (regDate.test(itemValue) === false) {
noErr = false;
message = "请输入正确日期";
}
break;
}
case "time": {
const regTime = /^(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
if (regTime.test(itemValue) === false) {
noErr = false;
message = "请输入正确时间";
}
break;
}
case "interger": {
const regInterger = /^[1-9]\d*$/;
if (regInterger.test(itemValue) === false) {
noErr = false;
message = "请输入整数";
}
break;
}
case "positiveNumber": {
// 包括0的正数
if (itemValue < 0) {
noErr = false;
message = "请输入非负数";
}
break;
}
case "gt0Number": {
// 不包括0的正数
if (itemValue <= 0) {
noErr = false;
message = "请输入非零正数";
}
break;
}
case "telephone": {
const telephoneNumber = /^1(3|4|5|6|7|8|9)\d{9}$/;
if (telephoneNumber.test(itemValue) === false) {
noErr = false;
message = "请输入正确手机号码";
}
break;
}
case "pwdstrong": {
const forceRegex = new RegExp("(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z]).{6,20}");
if (forceRegex.test(itemValue) === false) {
noErr = false;
message = "请输入符合格式的密码";
}
break;
}
default:
noErr = true;
}
if (!noErr) {
item.errorMessage = message;
} else {
item.errorMessage = "";
}
};
export const validataForm = (formConfig) => {
if (formConfig) {
let formHasErr = false;
formConfig.forEach((item) => {
if (item.validate !== undefined) {
validateItem(item, item.value);
}
if (item.errorMessage) {
formHasErr = true;
}
});
return formHasErr;
}
};
export const calcFormat = (config, val) => {
if (val === 0 || val === "0") {
return 0;
}
if (config.format === "w" && val) {
return ((Number(val) * 1) / 10000).toFixed(config.toFixed || 2) + "w";
}
};
export const verifyFormat = (config, val) => {
// 满足 true
if (config.verifyFormat === ".00" && val) {
return val.endsWith(".00");
}
return true;
};
export const deepCopy = (obj) => {
let copy;
// 处理非对象类型和函数类型
if (obj === null || typeof obj !== "object" || obj instanceof Function) {
return obj;
}
// 处理日期类型
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// 处理数组类型
if (obj instanceof Array) {
copy = [];
for (let i = 0, len = obj.length; i < len; i++) {
copy[i] = deepCopy(obj[i]);
}
return copy;
}
// 处理对象类型
if (obj instanceof Object) {
copy = {};
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
copy[prop] = deepCopy(obj[prop]);
}
}
return copy;
}
throw new Error("无法复制此对象,因为类型未知: " + obj);
};
// 数值千分位显示
export const formatNumberWithCommas = (num) => {
if (!num) return 0;
if (typeof num === "string") {
num = Number(num);
}
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};

View File

@ -0,0 +1,9 @@
export const processSuccess = (res, time = 3) => {
message.success(res, time)
}
export const processError = (res, time = 3) => {
message.error(res, time)
}
export const processWarning = (res, time = 3) => {
message.warning(res, time)
}

View File

@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, onMounted,watch } from 'vue' import { computed, ref, onMounted, watch, reactive, onBeforeMount, getCurrentInstance } from 'vue'
import { onBeforeRouteUpdate } from 'vue-router' import { onBeforeRouteUpdate } from 'vue-router'
import { useDialogueStore, useTalkStore } from '@/store' import { useDialogueStore, useTalkStore } from '@/store'
import { NDropdown, NIcon, NInput, NPopover } from 'naive-ui' import { NDropdown, NIcon, NInput, NPopover, NTabs, NTab, NCard } from 'naive-ui'
import { Search, Plus } from '@icon-park/vue-next' import { Search, Plus } from '@icon-park/vue-next'
import TalkItem from './TalkItem.vue' import TalkItem from './TalkItem.vue'
import Skeleton from './Skeleton.vue' import Skeleton from './Skeleton.vue'
@ -11,6 +11,13 @@ import GroupLaunch from '@/components/group/GroupLaunch.vue'
import { getCacheIndexName } from '@/utils/talk' import { getCacheIndexName } from '@/utils/talk'
import { ISession } from '@/types/chat' import { ISession } from '@/types/chat'
import { useSessionMenu } from '@/hooks' import { useSessionMenu } from '@/hooks'
import customModal from '@/components/common/customModal.vue'
import xSearchForm from '@/components/x-naive-ui/x-search-form/index.vue'
import flTree from '@/components/flnlayout/tree/flnindex.vue'
import { processError, processSuccess } from '@/utils/helper/message.js'
const currentInstance = getCurrentInstance()
const { $request } = currentInstance?.appContext.config.globalProperties
const { const {
dropdown, dropdown,
@ -27,6 +34,29 @@ const searchKeyword = ref('')
const topItems = computed((): ISession[] => talkStore.topItems) const topItems = computed((): ISession[] => talkStore.topItems)
const unreadNum = computed(() => talkStore.talkUnreadNum) const unreadNum = computed(() => talkStore.talkUnreadNum)
const state = reactive({
isShowAddressBookModal: false, //
customModalStyle: {
width: '1288px',
height: '846px',
backgroundColor: '#F9F9FD'
}, //
searchConfig: [
{
label: '姓名',
key: 'name',
type: 'input',
valueType: 'string'
}
], //
treeData: [],
expandedKeys: [],
clickKey: '',
treeRefreshCount: 0,
treeSelectData: {}
})
const items = computed((): ISession[] => { const items = computed((): ISession[] => {
if (searchKeyword.value.length === 0) { if (searchKeyword.value.length === 0) {
return talkStore.talkItems return talkStore.talkItems
@ -39,10 +69,13 @@ const items = computed((): ISession[] => {
}) })
}) })
watch(() => talkStore, (newValue, oldValue) => { watch(
console.log(newValue); () => talkStore,
(newValue, oldValue) => {
},{deep:true,immediate:true}) console.log(newValue)
},
{ deep: true, immediate: true }
)
// //
const loadStatus = computed(() => talkStore.loadStatus) const loadStatus = computed(() => talkStore.loadStatus)
@ -100,9 +133,81 @@ const onInitialize = () => {
// //
onBeforeRouteUpdate(onInitialize) onBeforeRouteUpdate(onInitialize)
onBeforeMount(() => {
getTreeData()
})
onMounted(() => { onMounted(() => {
onInitialize() onInitialize()
}) })
//
const showAddressBookModal = () => {
state.isShowAddressBookModal = true
}
const handleTreeClick = ({ selectedKey, tree }) => {
state.clickKey = tree.key
state.treeSelectData = tree
}
const calcTreeData = (data) => {
for (let item of data) {
item.key = item.ID
item.label = item.name
item.title = item.name
if (item.sons) {
item.children = item.sons
calcTreeData(item.children)
}
delete item.ID
delete item.name
delete item.sons
}
}
//
const getTreeData = () => {
let url = '/department/v2/tree/filter'
let params = {}
$request.HTTP.components.postDataByParams(url, params).then(
(res) => {
if (res.status === 0 && Array.isArray(res.data.nodes)) {
let data = res.data.nodes
calcTreeData(data)
state.treeData = data
// //
// let localSelect = Local.get("posimanage_treeSelectData");
// if (localSelect && JSON.stringify(localSelect) !== "{}") {
// state.treeSelectData = localSelect;
// state.expandedKeys = localSelect.pathIds;
// state.clickKey = localSelect.key;
// } else {
// if (JSON.stringify(state.treeSelectData) === "{}") {
// state.treeSelectData = data[0];
// state.clickKey = data[0].key;
// }
// if (
// state.clickKey === data[0].key &&
// !state.expandedKeys.includes(data[0].key)
// ) {
// state.expandedKeys.push(data[0].key);
// }
// if (!state.expandedKeys.includes(state.clickKey)) {
// state.expandedKeys.push(state.clickKey);
// }
// }
state.treeRefreshCount++
// state.tableConfig.refreshCount++;
} else {
processError(res.msg || '获取失败!')
}
},
() => {
processError('获取失败!')
},
() => {
processError('获取失败!')
}
)
}
</script> </script>
<template> <template>
@ -125,7 +230,7 @@ onMounted(() => {
v-model:value.trim="searchKeyword" v-model:value.trim="searchKeyword"
round round
clearable clearable
style="width: 78%" style="width: 78%;"
> >
<template #prefix> <template #prefix>
<n-icon :component="Search" /> <n-icon :component="Search" />
@ -137,6 +242,12 @@ onMounted(() => {
<n-icon :component="Plus" /> <n-icon :component="Plus" />
</template> </template>
</n-button> </n-button>
<img
style="width: 19px; height: 20px;"
src="@/assets/image/chatList/addressBook.png"
alt=""
@click="showAddressBookModal"
/>
</header> </header>
<!-- 置顶栏目 --> <!-- 置顶栏目 -->
@ -196,6 +307,37 @@ onMounted(() => {
</section> </section>
<GroupLaunch v-if="isShowGroup" @close="isShowGroup = false" @on-submit="onReload" /> <GroupLaunch v-if="isShowGroup" @close="isShowGroup = false" @on-submit="onReload" />
<customModal
v-model:show="state.isShowAddressBookModal"
title="通讯录"
:style="state.customModalStyle"
:customCloseBtn="true"
:closable="false"
>
<template #content>
<div class="custom-modal-content">
<n-card>
<n-tabs type="line">
<n-tab name="employeeAddressBook">员工通讯录</n-tab>
<n-tab name="groupChatList">群聊列表</n-tab>
</n-tabs>
<xSearchForm :search-config="state.searchConfig"></xSearchForm>
<div class="addressBook-content">
<div class="addressBook-tree">
<fl-tree
:data="state.treeData"
:expandedKeys="state.expandedKeys"
:refreshCount="state.treeRefreshCount"
:clickKey="state.clickKey"
@triggerTreeClick="handleTreeClick"
></fl-tree>
</div>
</div>
</n-card>
</div>
</template>
</customModal>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
@ -299,4 +441,21 @@ html[theme-mode='dark'] {
} }
} }
} }
.custom-modal-content {
box-sizing: border-box;
width: 100%;
padding: 0 12px;
.addressBook-content {
.addressBook-tree {
width: 328px;
height: 524px;
overflow: auto;
border: 1px solid #efeff5;
border-radius: 4px;
padding: 12px 20px;
box-sizing: border-box;
}
}
}
</style> </style>

View File

@ -1,8 +1,9 @@
import { defineConfig } from 'unocss' import { defineConfig, presetUno, presetAttributify, presetIcons } from 'unocss'
import { presetAttributify, presetIcons } from 'unocss'
export default defineConfig({ export default defineConfig({
// 预设 // 预设
presets: [ presets: [
presetUno(), // 添加核心预设
presetAttributify(), // 启用属性模式 presetAttributify(), // 启用属性模式
presetIcons(), // 启用图标 presetIcons(), // 启用图标
], ],