Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
6934a59e56
|
@ -10,6 +10,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||||
"@vuemap/vue-amap": "^1.1.20",
|
"@vuemap/vue-amap": "^1.1.20",
|
||||||
|
"@vueuse/core": "^9.10.0",
|
||||||
"ant-design-vue": "^3.2.15",
|
"ant-design-vue": "^3.2.15",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"echarts": "^5.4.1",
|
"echarts": "^5.4.1",
|
||||||
|
@ -24,7 +25,8 @@
|
||||||
"unplugin-auto-import": "^0.12.1",
|
"unplugin-auto-import": "^0.12.1",
|
||||||
"unplugin-vue-components": "^0.22.12",
|
"unplugin-vue-components": "^0.22.12",
|
||||||
"vue": "^3.2.45",
|
"vue": "^3.2.45",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6",
|
||||||
|
"vue3-markdown-it": "^1.0.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.4.1",
|
"@commitlint/cli": "^17.4.1",
|
||||||
|
@ -1481,6 +1483,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
|
||||||
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
|
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/linkify-it": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/@types/lodash": {
|
"node_modules/@types/lodash": {
|
||||||
"version": "4.14.191",
|
"version": "4.14.191",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
|
||||||
|
@ -1496,6 +1504,22 @@
|
||||||
"@types/lodash": "*"
|
"@types/lodash": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/markdown-it": {
|
||||||
|
"version": "12.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
|
||||||
|
"integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/linkify-it": "*",
|
||||||
|
"@types/mdurl": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/mdurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/@types/minimist": {
|
"node_modules/@types/minimist": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz",
|
||||||
|
@ -1532,6 +1556,11 @@
|
||||||
"@types/webxr": "*"
|
"@types/webxr": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/web-bluetooth": {
|
||||||
|
"version": "0.0.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
||||||
|
},
|
||||||
"node_modules/@types/webxr": {
|
"node_modules/@types/webxr": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.0.tgz",
|
||||||
|
@ -1823,6 +1852,39 @@
|
||||||
"vue": "^3.2.0"
|
"vue": "^3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vueuse/core": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-CxMewME07qeuzuT/AOIQGv0EhhDoojniqU6pC3F8m5VC76L47UT18DcX88kWlP3I7d3qMJ4u/PD8iSRsy3bmNA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/web-bluetooth": "^0.0.16",
|
||||||
|
"@vueuse/metadata": "9.10.0",
|
||||||
|
"@vueuse/shared": "9.10.0",
|
||||||
|
"vue-demi": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/metadata": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-G5VZhgTCapzU9rv0Iq2HBrVOSGzOKb+OE668NxhXNcTjUjwYxULkEhAw70FtRLMZc+hxcFAzDZlKYA0xcwNMuw==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/shared": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-vakHJ2ZRklAzqmcVBL38RS7BxdBA4+5poG9NsSyqJxrt9kz0zX3P5CXMy0Hm6LFbZXUgvKdqAS3pUH1zX/5qTQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"vue-demi": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/3d-tiles-renderer": {
|
"node_modules/3d-tiles-renderer": {
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"resolved": "https://registry.npmjs.org/3d-tiles-renderer/-/3d-tiles-renderer-0.3.16.tgz",
|
"resolved": "https://registry.npmjs.org/3d-tiles-renderer/-/3d-tiles-renderer-0.3.16.tgz",
|
||||||
|
@ -1998,8 +2060,7 @@
|
||||||
"node_modules/argparse": {
|
"node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/array-ify": {
|
"node_modules/array-ify": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
@ -3883,6 +3944,14 @@
|
||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/highlight.js": {
|
||||||
|
"version": "11.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
|
||||||
|
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/homedir-polyfill": {
|
"node_modules/homedir-polyfill": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||||
|
@ -5465,6 +5534,14 @@
|
||||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/linkify-it": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"uc.micro": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lint-staged": {
|
"node_modules/lint-staged": {
|
||||||
"version": "13.1.0",
|
"version": "13.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.1.0.tgz",
|
||||||
|
@ -5741,6 +5818,11 @@
|
||||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.flow": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
|
||||||
|
"integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw=="
|
||||||
|
},
|
||||||
"node_modules/lodash.isfunction": {
|
"node_modules/lodash.isfunction": {
|
||||||
"version": "3.0.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
"resolved": "https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
||||||
|
@ -5952,6 +6034,102 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/markdown-it": {
|
||||||
|
"version": "12.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
|
||||||
|
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1",
|
||||||
|
"entities": "~2.1.0",
|
||||||
|
"linkify-it": "^3.0.1",
|
||||||
|
"mdurl": "^1.0.1",
|
||||||
|
"uc.micro": "^1.0.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"markdown-it": "bin/markdown-it.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-abbr": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-anchor": {
|
||||||
|
"version": "8.6.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.6.tgz",
|
||||||
|
"integrity": "sha512-jRW30YGywD2ESXDc+l17AiritL0uVaSnWsb26f+68qaW9zgbIIr1f4v2Nsvc0+s0Z2N3uX6t/yAw7BwCQ1wMsA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/markdown-it": "*",
|
||||||
|
"markdown-it": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-deflist": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-emoji": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-footnote": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-highlightjs": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-highlightjs/-/markdown-it-highlightjs-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-ex+Lq3cVkprh0GpGwFyc53A/rqY6GGzopPCG1xMsf8Ya3XtGC8Uw9tChN1rWbpyDae7tBBhVHVcMM29h4Btamw==",
|
||||||
|
"dependencies": {
|
||||||
|
"highlight.js": "^11.3.1",
|
||||||
|
"lodash.flow": "^3.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-ins": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-32SSfZqSzqyAmmQ4SHvhxbFqSzPDqsZgMHDwxqPzp+v+t8RsmqsBZRG+RfRQskJko9PfKC2/oxyOs4Yg/CfiRw=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-mark": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-sub": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-sup": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-task-lists": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it-toc-done-right": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UB/IbzjWazwTlNAX0pvWNlJS8NKsOQ4syrXZQ/C72j+jirrsjVRT627lCaylrKJFBQWfRsPmIVQie8x38DEhAQ=="
|
||||||
|
},
|
||||||
|
"node_modules/markdown-it/node_modules/entities": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mdurl": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="
|
||||||
|
},
|
||||||
"node_modules/meow": {
|
"node_modules/meow": {
|
||||||
"version": "8.1.2",
|
"version": "8.1.2",
|
||||||
"resolved": "https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz",
|
"resolved": "https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz",
|
||||||
|
@ -7943,6 +8121,11 @@
|
||||||
"node": ">=4.2.0"
|
"node": ">=4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uc.micro": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||||
|
},
|
||||||
"node_modules/ufo": {
|
"node_modules/ufo": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz",
|
||||||
|
@ -8499,6 +8682,26 @@
|
||||||
"vue": "^3.0.0"
|
"vue": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue3-markdown-it": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-mTvHu0zl7jrh7ojgaZ+tTpCLiS4CVg4bTgTu4KGhw/cRRY5YgIG8QgFAPu6kCzSW6Znc9a52Beb6hFvF4hSMkQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"markdown-it": "^12.3.2",
|
||||||
|
"markdown-it-abbr": "^1.0.4",
|
||||||
|
"markdown-it-anchor": "^8.4.1",
|
||||||
|
"markdown-it-deflist": "^2.1.0",
|
||||||
|
"markdown-it-emoji": "^2.0.0",
|
||||||
|
"markdown-it-footnote": "^3.0.3",
|
||||||
|
"markdown-it-highlightjs": "^3.6.0",
|
||||||
|
"markdown-it-ins": "^3.0.1",
|
||||||
|
"markdown-it-mark": "^3.0.1",
|
||||||
|
"markdown-it-sub": "^1.0.0",
|
||||||
|
"markdown-it-sup": "^1.0.0",
|
||||||
|
"markdown-it-task-lists": "^2.1.1",
|
||||||
|
"markdown-it-toc-done-right": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/warning": {
|
"node_modules/warning": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
@ -9766,6 +9969,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
|
||||||
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
|
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
|
||||||
},
|
},
|
||||||
|
"@types/linkify-it": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"@types/lodash": {
|
"@types/lodash": {
|
||||||
"version": "4.14.191",
|
"version": "4.14.191",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
|
||||||
|
@ -9781,6 +9990,22 @@
|
||||||
"@types/lodash": "*"
|
"@types/lodash": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/markdown-it": {
|
||||||
|
"version": "12.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
|
||||||
|
"integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
|
||||||
|
"peer": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/linkify-it": "*",
|
||||||
|
"@types/mdurl": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/mdurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"@types/minimist": {
|
"@types/minimist": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz",
|
||||||
|
@ -9816,6 +10041,11 @@
|
||||||
"@types/webxr": "*"
|
"@types/webxr": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/web-bluetooth": {
|
||||||
|
"version": "0.0.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
||||||
|
},
|
||||||
"@types/webxr": {
|
"@types/webxr": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.0.tgz",
|
||||||
|
@ -10077,6 +10307,30 @@
|
||||||
"uppercamelcase": "^1.1.0"
|
"uppercamelcase": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@vueuse/core": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-CxMewME07qeuzuT/AOIQGv0EhhDoojniqU6pC3F8m5VC76L47UT18DcX88kWlP3I7d3qMJ4u/PD8iSRsy3bmNA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/web-bluetooth": "^0.0.16",
|
||||||
|
"@vueuse/metadata": "9.10.0",
|
||||||
|
"@vueuse/shared": "9.10.0",
|
||||||
|
"vue-demi": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vueuse/metadata": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-G5VZhgTCapzU9rv0Iq2HBrVOSGzOKb+OE668NxhXNcTjUjwYxULkEhAw70FtRLMZc+hxcFAzDZlKYA0xcwNMuw=="
|
||||||
|
},
|
||||||
|
"@vueuse/shared": {
|
||||||
|
"version": "9.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.10.0.tgz",
|
||||||
|
"integrity": "sha512-vakHJ2ZRklAzqmcVBL38RS7BxdBA4+5poG9NsSyqJxrt9kz0zX3P5CXMy0Hm6LFbZXUgvKdqAS3pUH1zX/5qTQ==",
|
||||||
|
"requires": {
|
||||||
|
"vue-demi": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"3d-tiles-renderer": {
|
"3d-tiles-renderer": {
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"resolved": "https://registry.npmjs.org/3d-tiles-renderer/-/3d-tiles-renderer-0.3.16.tgz",
|
"resolved": "https://registry.npmjs.org/3d-tiles-renderer/-/3d-tiles-renderer-0.3.16.tgz",
|
||||||
|
@ -10216,8 +10470,7 @@
|
||||||
"argparse": {
|
"argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"array-ify": {
|
"array-ify": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
@ -11742,6 +11995,11 @@
|
||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"highlight.js": {
|
||||||
|
"version": "11.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
|
||||||
|
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ=="
|
||||||
|
},
|
||||||
"homedir-polyfill": {
|
"homedir-polyfill": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||||
|
@ -12976,6 +13234,14 @@
|
||||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"linkify-it": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
|
||||||
|
"requires": {
|
||||||
|
"uc.micro": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"version": "13.1.0",
|
"version": "13.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.1.0.tgz",
|
||||||
|
@ -13183,6 +13449,11 @@
|
||||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"lodash.flow": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
|
||||||
|
"integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw=="
|
||||||
|
},
|
||||||
"lodash.isfunction": {
|
"lodash.isfunction": {
|
||||||
"version": "3.0.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
"resolved": "https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
||||||
|
@ -13363,6 +13634,95 @@
|
||||||
"integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
|
"integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"markdown-it": {
|
||||||
|
"version": "12.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
|
||||||
|
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^2.0.1",
|
||||||
|
"entities": "~2.1.0",
|
||||||
|
"linkify-it": "^3.0.1",
|
||||||
|
"mdurl": "^1.0.1",
|
||||||
|
"uc.micro": "^1.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"entities": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"markdown-it-abbr": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg=="
|
||||||
|
},
|
||||||
|
"markdown-it-anchor": {
|
||||||
|
"version": "8.6.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.6.tgz",
|
||||||
|
"integrity": "sha512-jRW30YGywD2ESXDc+l17AiritL0uVaSnWsb26f+68qaW9zgbIIr1f4v2Nsvc0+s0Z2N3uX6t/yAw7BwCQ1wMsA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"markdown-it-deflist": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg=="
|
||||||
|
},
|
||||||
|
"markdown-it-emoji": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ=="
|
||||||
|
},
|
||||||
|
"markdown-it-footnote": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w=="
|
||||||
|
},
|
||||||
|
"markdown-it-highlightjs": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-highlightjs/-/markdown-it-highlightjs-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-ex+Lq3cVkprh0GpGwFyc53A/rqY6GGzopPCG1xMsf8Ya3XtGC8Uw9tChN1rWbpyDae7tBBhVHVcMM29h4Btamw==",
|
||||||
|
"requires": {
|
||||||
|
"highlight.js": "^11.3.1",
|
||||||
|
"lodash.flow": "^3.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"markdown-it-ins": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-32SSfZqSzqyAmmQ4SHvhxbFqSzPDqsZgMHDwxqPzp+v+t8RsmqsBZRG+RfRQskJko9PfKC2/oxyOs4Yg/CfiRw=="
|
||||||
|
},
|
||||||
|
"markdown-it-mark": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A=="
|
||||||
|
},
|
||||||
|
"markdown-it-sub": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q=="
|
||||||
|
},
|
||||||
|
"markdown-it-sup": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ=="
|
||||||
|
},
|
||||||
|
"markdown-it-task-lists": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="
|
||||||
|
},
|
||||||
|
"markdown-it-toc-done-right": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UB/IbzjWazwTlNAX0pvWNlJS8NKsOQ4syrXZQ/C72j+jirrsjVRT627lCaylrKJFBQWfRsPmIVQie8x38DEhAQ=="
|
||||||
|
},
|
||||||
|
"mdurl": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="
|
||||||
|
},
|
||||||
"meow": {
|
"meow": {
|
||||||
"version": "8.1.2",
|
"version": "8.1.2",
|
||||||
"resolved": "https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz",
|
"resolved": "https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz",
|
||||||
|
@ -14934,6 +15294,11 @@
|
||||||
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
|
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
|
"uc.micro": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||||
|
},
|
||||||
"ufo": {
|
"ufo": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz",
|
||||||
|
@ -15351,6 +15716,26 @@
|
||||||
"is-plain-object": "3.0.1"
|
"is-plain-object": "3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue3-markdown-it": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-mTvHu0zl7jrh7ojgaZ+tTpCLiS4CVg4bTgTu4KGhw/cRRY5YgIG8QgFAPu6kCzSW6Znc9a52Beb6hFvF4hSMkQ==",
|
||||||
|
"requires": {
|
||||||
|
"markdown-it": "^12.3.2",
|
||||||
|
"markdown-it-abbr": "^1.0.4",
|
||||||
|
"markdown-it-anchor": "^8.4.1",
|
||||||
|
"markdown-it-deflist": "^2.1.0",
|
||||||
|
"markdown-it-emoji": "^2.0.0",
|
||||||
|
"markdown-it-footnote": "^3.0.3",
|
||||||
|
"markdown-it-highlightjs": "^3.6.0",
|
||||||
|
"markdown-it-ins": "^3.0.1",
|
||||||
|
"markdown-it-mark": "^3.0.1",
|
||||||
|
"markdown-it-sub": "^1.0.0",
|
||||||
|
"markdown-it-sup": "^1.0.0",
|
||||||
|
"markdown-it-task-lists": "^2.1.1",
|
||||||
|
"markdown-it-toc-done-right": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"ant-design-vue": "^3.2.15",
|
"ant-design-vue": "^3.2.15",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"echarts": "^5.4.1",
|
"echarts": "^5.4.1",
|
||||||
|
"event-source-polyfill": "^1.0.31",
|
||||||
"jetlinks-store": "^0.0.3",
|
"jetlinks-store": "^0.0.3",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
"less": "^4.1.3",
|
"less": "^4.1.3",
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
@ -22,3 +22,54 @@ export const saveMetadata = (id: string, data: string) => server.put(`/device/in
|
||||||
* @returns 设备详情
|
* @returns 设备详情
|
||||||
*/
|
*/
|
||||||
export const detail = (id: string) => server.get<DeviceInstance>(`/device-instance/${id}/detail`)
|
export const detail = (id: string) => server.get<DeviceInstance>(`/device-instance/${id}/detail`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数据
|
||||||
|
* @param data 分页搜索数据
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const query = (data?: Record<string, any>) => server.post('/device-instance/_query', data)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除设备
|
||||||
|
* @param id 设备ID
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const _delete = (id: string) => server.remove(`/device-instance/${id}`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用设备
|
||||||
|
* @param id 设备ID
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const _deploy = (id: string) => server.post(`/device-instance/${id}/deploy`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用设备
|
||||||
|
* @param id 设备ID
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const _undeploy = (id: string) => server.post(`/device-instance/${id}/undeploy`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量激活设备
|
||||||
|
* @param data 设备id数组
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const batchDeployDevice = (data: string[]) => server.put(`/device-instance/batch/_deploy`, data)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量注销设备
|
||||||
|
* @param data 设备id数组
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const batchUndeployDevice = (data: string[]) => server.put(`/device-instance/batch/_unDeploy`, data)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
* @param data 设备id数组
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const batchDeleteDevice = (data: string[]) => server.put(`/device-instance/batch/_delete`, data)
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
import server from '@/utils/request';
|
|
||||||
|
|
||||||
export const getProviders = () => server.get(`/gateway/device/providers`);
|
|
||||||
|
|
||||||
export const detail = (id) => server.get(`/gateway/device/${id}`);
|
|
||||||
|
|
||||||
export const getNetworkList = (networkType, data, params) =>
|
|
||||||
server.get(
|
|
||||||
`/network/config/${networkType}/_alive?include=${params.include}`,
|
|
||||||
data,
|
|
||||||
);
|
|
||||||
|
|
||||||
export const getProtocolList = (transport, params) =>
|
|
||||||
server.get(`/protocol/supports/${transport ? transport : ''}`, params);
|
|
||||||
|
|
||||||
export const getConfigView = (id, transport) =>
|
|
||||||
server.get(`/protocol/${id}/transport/${transport}`);
|
|
||||||
|
|
||||||
export const getChildConfigView = (id) =>
|
|
||||||
server.get(`/protocol/${id}/transports`);
|
|
||||||
|
|
||||||
export const save = (data) => server.post(`/gateway/device`, data);
|
|
||||||
|
|
||||||
export const update = (data) => server.patch(`/gateway/device`, data);
|
|
||||||
|
|
||||||
export const list = (data) =>
|
|
||||||
server.post(`/gateway/device/detail/_query`, data);
|
|
||||||
|
|
||||||
export const undeploy = (id) => server.post(`/gateway/device/${id}/_shutdown`);
|
|
||||||
|
|
||||||
export const deploy = (id) => server.post(`/gateway/device/${id}/_startup`);
|
|
||||||
|
|
||||||
export const del = (id) => server.remove(`/gateway/device/${id}`);
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import server from '@/utils/request';
|
||||||
|
|
||||||
|
export const getProviders = () => server.get(`/gateway/device/providers`);
|
||||||
|
|
||||||
|
export const detail = (id: string) => server.get(`/gateway/device/${id}`);
|
||||||
|
|
||||||
|
export const getNetworkList = (
|
||||||
|
networkType: string,
|
||||||
|
data: Object,
|
||||||
|
params: Object,
|
||||||
|
) =>
|
||||||
|
server.get(
|
||||||
|
`/network/config/${networkType}/_alive?include=${params.include}`,
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getProtocolList = (transport: string, params: Object) =>
|
||||||
|
server.get(`/protocol/supports/${transport ? transport : ''}`, params);
|
||||||
|
|
||||||
|
export const getConfigView = (id: string, transport: string) =>
|
||||||
|
server.get(`/protocol/${id}/transport/${transport}`);
|
||||||
|
|
||||||
|
export const getChildConfigView = (id: string) =>
|
||||||
|
server.get(`/protocol/${id}/transports`);
|
||||||
|
|
||||||
|
export const save = (data: Object) => server.post(`/gateway/device`, data);
|
||||||
|
|
||||||
|
export const update = (data: Object) => server.patch(`/gateway/device`, data);
|
||||||
|
|
||||||
|
export const list = (data: Object) =>
|
||||||
|
server.post(`/gateway/device/detail/_query`, data);
|
||||||
|
|
||||||
|
export const undeploy = (id: string) =>
|
||||||
|
server.post(`/gateway/device/${id}/_shutdown`);
|
||||||
|
|
||||||
|
export const deploy = (id: string) =>
|
||||||
|
server.post(`/gateway/device/${id}/_startup`);
|
||||||
|
|
||||||
|
export const del = (id: string) => server.remove(`/gateway/device/${id}`);
|
||||||
|
|
||||||
|
export const getResourcesCurrent = () =>
|
||||||
|
server.get(`/network/resources/alive/_current`);
|
||||||
|
|
||||||
|
export const getClusters = () =>
|
||||||
|
server.get(`network/resources/clusters`);
|
|
@ -3,4 +3,5 @@ import { BASE_API_PATH } from '@/utils/variable';
|
||||||
|
|
||||||
export const NETWORK_CERTIFICATE_UPLOAD = `${BASE_API_PATH}/network/certificate/upload`;
|
export const NETWORK_CERTIFICATE_UPLOAD = `${BASE_API_PATH}/network/certificate/upload`;
|
||||||
|
|
||||||
export const save = (data) => server.post(`/network/certificate`, data);
|
|
||||||
|
export const save = (data: object) => server.post(`/network/certificate`, data);
|
|
@ -0,0 +1,8 @@
|
||||||
|
import server from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询数据
|
||||||
|
* @param data 分页搜索数据
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const query = (data: Record<string, any>) => server.post('/dueros/product/_query', data)
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { patch, post, get } from '@/utils/request'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// 列表
|
||||||
|
list: (data: any) => post(`/notifier/template/_query`, data),
|
||||||
|
// 详情
|
||||||
|
detail: (id: string): any => get(`/notifier/template/${id}`),
|
||||||
|
// 新增
|
||||||
|
save: (data: any) => post(`/notifier/template`, data),
|
||||||
|
// 修改
|
||||||
|
update: (data: any) => patch(`/notifier/template`, data)
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import server from '@/utils/request';
|
||||||
|
|
||||||
|
// 保存
|
||||||
|
export const save_api = (data: any) => server.post(`/system/config/scope/_save`, data)
|
||||||
|
// 获取详情
|
||||||
|
export const getDetails_api = (data: any) => server.post(`/system/config/scopes`, data)
|
|
@ -1,7 +0,0 @@
|
||||||
import { createFromIconfontCN } from '@ant-design/icons-vue';
|
|
||||||
|
|
||||||
const AliIcon = createFromIconfontCN({
|
|
||||||
scriptUrl: '/icons/iconfont.js', // 在 iconfont.cn 上生成
|
|
||||||
});
|
|
||||||
|
|
||||||
export default AliIcon
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { createFromIconfontCN } from '@ant-design/icons-vue';
|
||||||
|
import * as $Icon from '@ant-design/icons-vue';
|
||||||
|
import { createVNode } from 'vue';
|
||||||
|
|
||||||
|
const AliIcon = createFromIconfontCN({
|
||||||
|
scriptUrl: '/icons/iconfont.js', // 在 iconfont.cn 上生成
|
||||||
|
});
|
||||||
|
|
||||||
|
const AntdIcon = (props: {type: string}) => {
|
||||||
|
const {type} = props;
|
||||||
|
let antIcon: {[key: string]: any} = $Icon
|
||||||
|
return createVNode(antIcon[type])
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconKeys = [
|
||||||
|
'EyeOutlined',
|
||||||
|
'EditOutlined',
|
||||||
|
'PlusOutlined',
|
||||||
|
'DeleteOutlined',
|
||||||
|
'CheckCircleOutlined',
|
||||||
|
'StopOutlined',
|
||||||
|
'CheckOutlined',
|
||||||
|
'CloseOutlined',
|
||||||
|
'DownOutlined',
|
||||||
|
'ImportOutlined',
|
||||||
|
'ExportOutlined',
|
||||||
|
'SyncOutlined',
|
||||||
|
'ExclamationCircleOutlined'
|
||||||
|
]
|
||||||
|
|
||||||
|
const Icon = (props: {type: string}) => {
|
||||||
|
if(iconKeys.includes(props.type)) return <AntdIcon {...props} />
|
||||||
|
return <AliIcon {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Icon
|
|
@ -6,8 +6,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { StatusColorEnum } from '@/utils/consts.ts';
|
// import { StatusColorEnum } from '@/utils/consts.ts';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
text: {
|
text: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -15,10 +14,10 @@ const props = defineProps({
|
||||||
status: {
|
status: {
|
||||||
type: String || Number,
|
type: String || Number,
|
||||||
default: 'default',
|
default: 'default',
|
||||||
validator: (value) => {
|
// validator: (value) => {
|
||||||
// 这个值必须匹配下列字符串中的一个
|
// // 这个值必须匹配下列字符串中的一个
|
||||||
return Object.keys(StatusColorEnum).includes(value);
|
// return Object.keys(StatusColorEnum).includes(value);
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 自定义status值颜色
|
* 自定义status值颜色
|
||||||
|
|
|
@ -108,7 +108,6 @@ const props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
statusText: {
|
statusText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '正常',
|
default: '正常',
|
||||||
|
|
|
@ -75,6 +75,7 @@ const JTable = defineComponent<JTableProps>({
|
||||||
],
|
],
|
||||||
emits: [
|
emits: [
|
||||||
'modelChange', // 切换卡片和表格
|
'modelChange', // 切换卡片和表格
|
||||||
|
'reload' // 刷新数据
|
||||||
],
|
],
|
||||||
props: {
|
props: {
|
||||||
request: {
|
request: {
|
||||||
|
@ -139,7 +140,7 @@ const JTable = defineComponent<JTableProps>({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as any,
|
} as any,
|
||||||
setup(props: JTableProps ,{ slots, emit }){
|
setup(props: JTableProps ,{ slots, emit, expose }){
|
||||||
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
|
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
|
||||||
const _model = ref<keyof typeof ModelEnum>(props.model ? props.model : ModelEnum.CARD); // 模式切换
|
const _model = ref<keyof typeof ModelEnum>(props.model ? props.model : ModelEnum.CARD); // 模式切换
|
||||||
const column = ref<number>(props.gridColumn || 4);
|
const column = ref<number>(props.gridColumn || 4);
|
||||||
|
@ -203,9 +204,13 @@ const JTable = defineComponent<JTableProps>({
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEffect(() => {
|
watch(
|
||||||
handleSearch(props.params)
|
() => props.params,
|
||||||
})
|
(newValue) => {
|
||||||
|
handleSearch(newValue)
|
||||||
|
},
|
||||||
|
{deep: true, immediate: true}
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
|
@ -217,6 +222,23 @@ const JTable = defineComponent<JTableProps>({
|
||||||
window.onresize = null
|
window.onresize = null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新数据
|
||||||
|
* @param _params
|
||||||
|
*/
|
||||||
|
const reload = (_params?: Record<string, any>) => {
|
||||||
|
handleSearch({
|
||||||
|
..._params,
|
||||||
|
pageSize: 12,
|
||||||
|
pageIndex: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出方法
|
||||||
|
*/
|
||||||
|
expose({ reload })
|
||||||
|
|
||||||
return () => <Spin spinning={loading.value}>
|
return () => <Spin spinning={loading.value}>
|
||||||
<div class={styles["jtable-body"]}>
|
<div class={styles["jtable-body"]}>
|
||||||
<div class={styles["jtable-body-header"]}>
|
<div class={styles["jtable-body-header"]}>
|
||||||
|
@ -248,7 +270,7 @@ const JTable = defineComponent<JTableProps>({
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
emit('cancelSelect')
|
emit('cancelSelect')
|
||||||
}}
|
}}
|
||||||
closeText={<a>取消选择</a>}
|
closeText={<a-button type="link">取消选择</a-button>}
|
||||||
/>
|
/>
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,11 @@ export default [
|
||||||
},
|
},
|
||||||
// end: 测试用, 可删除
|
// end: 测试用, 可删除
|
||||||
|
|
||||||
|
// 设备管理
|
||||||
|
{
|
||||||
|
path: '/device/Instance',
|
||||||
|
component: () => import('@/views/device/Instance/index.vue')
|
||||||
|
},
|
||||||
// link 运维管理
|
// link 运维管理
|
||||||
{
|
{
|
||||||
path: '/link/log',
|
path: '/link/log',
|
||||||
|
@ -89,9 +94,14 @@ export default [
|
||||||
},
|
},
|
||||||
// system 系统管理
|
// system 系统管理
|
||||||
{
|
{
|
||||||
path:'/system/api',
|
path:'/system/Basis',
|
||||||
components: ()=>import('@/views/system/apiPage/index')
|
component: ()=>import('@/views/system/Basis/index.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path:'/system/api',
|
||||||
|
component: ()=>import('@/views/system/apiPage/index.vue')
|
||||||
|
},
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
{
|
{
|
||||||
path: '/init-home',
|
path: '/init-home',
|
||||||
|
@ -102,4 +112,13 @@ export default [
|
||||||
path: '/iot-card/home',
|
path: '/iot-card/home',
|
||||||
component: () => import('@/views/iot-card/Home/index.vue')
|
component: () => import('@/views/iot-card/Home/index.vue')
|
||||||
},
|
},
|
||||||
|
// 北向输出
|
||||||
|
{
|
||||||
|
path: '/northbound/DuerOS',
|
||||||
|
component: () => import('@/views/northbound/DuerOS/index.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/northbound/AliCloud',
|
||||||
|
component: () => import('@/views/northbound/AliCloud/index.vue')
|
||||||
|
},
|
||||||
]
|
]
|
|
@ -0,0 +1,64 @@
|
||||||
|
export default function encodeQuery(params: any) {
|
||||||
|
if (!params) return {};
|
||||||
|
const queryParam = {
|
||||||
|
// pageIndex: 0,
|
||||||
|
current: params.current,
|
||||||
|
};
|
||||||
|
const { terms, sorts } = params;
|
||||||
|
Object.keys(params).forEach((key: string) => {
|
||||||
|
if (key === 'terms') {
|
||||||
|
let index = 0;
|
||||||
|
if (!terms) return;
|
||||||
|
Object.keys(terms).forEach((k: string) => {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
terms[k] === '' ||
|
||||||
|
terms[k] === undefined ||
|
||||||
|
terms[k].length === 0 ||
|
||||||
|
terms[k] === {} ||
|
||||||
|
terms[k] === null
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (k.indexOf('$LIKE') > -1 && terms[k].toString().indexOf('%') === -1) {
|
||||||
|
terms[k] = `%${terms[k]}%`;
|
||||||
|
}
|
||||||
|
if (k.indexOf('$IN') > -1) {
|
||||||
|
terms[k] = terms[k].toString();
|
||||||
|
} else if (k.indexOf('$START') > -1) {
|
||||||
|
terms[k] = `%${terms[k]}`;
|
||||||
|
} else if (k.indexOf('$END') > -1) {
|
||||||
|
terms[k] = `${terms[k]}%`;
|
||||||
|
}
|
||||||
|
if (k.indexOf('@') > -1) {
|
||||||
|
const temp = k.split('@');
|
||||||
|
// eslint-disable-next-line prefer-destructuring
|
||||||
|
queryParam[`terms[${index}].column`] = temp[0];
|
||||||
|
// eslint-disable-next-line prefer-destructuring
|
||||||
|
queryParam[`terms[${index}].type`] = temp[1];
|
||||||
|
} else {
|
||||||
|
queryParam[`terms[${index}].column`] = k;
|
||||||
|
}
|
||||||
|
queryParam[`terms[${index}].value`] = terms[k];
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (key === 'sorts') {
|
||||||
|
// 当前Ant Design排序只支持单字段排序
|
||||||
|
if (!sorts) return;
|
||||||
|
Object.keys(sorts).forEach((s, index) => {
|
||||||
|
queryParam[`sorts[${index}].name`] = s;
|
||||||
|
queryParam[`sorts[${index}].order`] = sorts[s].replace('end', '');
|
||||||
|
});
|
||||||
|
// if (Object.keys(sorts).length > 0) {
|
||||||
|
// queryParam[`sorts[0].name`] = sorts.field;
|
||||||
|
// queryParam[`sorts[0].order`] = (sorts.order || '').replace('end', '');
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
queryParam[key] = params[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// queryParam.pageIndex = current - 1;
|
||||||
|
|
||||||
|
return queryParam;
|
||||||
|
}
|
|
@ -1,3 +1,7 @@
|
||||||
|
import moment from "moment";
|
||||||
|
import { LocalStore } from "./comm";
|
||||||
|
import { TOKEN_KEY } from "./variable";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 把数据下载成JSON
|
* 把数据下载成JSON
|
||||||
* @param record
|
* @param record
|
||||||
|
@ -19,3 +23,33 @@ export const downloadObject = (record: Record<string, any>, fileName: string, fo
|
||||||
//移除
|
//移除
|
||||||
document.body.removeChild(ghostLink);
|
document.body.removeChild(ghostLink);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param url 下载链接
|
||||||
|
* @param params 参数
|
||||||
|
*/
|
||||||
|
export const downloadFile = (url: string, params?: Record<string, any>) => {
|
||||||
|
const formElement = document.createElement('form');
|
||||||
|
formElement.style.display = 'display:none;';
|
||||||
|
formElement.method = 'GET';
|
||||||
|
formElement.action = url;
|
||||||
|
// 添加参数
|
||||||
|
if (params) {
|
||||||
|
Object.keys(params).forEach((key: string) => {
|
||||||
|
const inputElement = document.createElement('input');
|
||||||
|
inputElement.type = 'hidden';
|
||||||
|
inputElement.name = key;
|
||||||
|
inputElement.value = params[key];
|
||||||
|
formElement.appendChild(inputElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const inputElement = document.createElement('input');
|
||||||
|
inputElement.type = 'hidden';
|
||||||
|
inputElement.name = ':X_Access_Token';
|
||||||
|
inputElement.value = LocalStore.get(TOKEN_KEY);
|
||||||
|
formElement.appendChild(inputElement);
|
||||||
|
document.body.appendChild(formElement);
|
||||||
|
formElement.submit();
|
||||||
|
document.body.removeChild(formElement);
|
||||||
|
};
|
|
@ -0,0 +1,75 @@
|
||||||
|
<template>
|
||||||
|
<a-modal :maskClosable="false" width="800px" :visible="true" title="导出" @ok="handleOk" @cancel="handleCancel">
|
||||||
|
<div style="background-color: rgb(236, 237, 238)">
|
||||||
|
<p style="padding: 10px">
|
||||||
|
<AIcon type="ExclamationCircleOutlined" />
|
||||||
|
选择单个产品时可导出其下属设备的详细数据,不选择产品时导出所有设备的基础数据。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 20px">
|
||||||
|
<a-form :layout="'vertical'">
|
||||||
|
<a-form-item label="产品">
|
||||||
|
<a-select showSearch v-model:value="modelRef.product" placeholder="请选择产品">
|
||||||
|
<a-select-option :value="item.id" v-for="item in productList" :key="item.id" :title="item.name"></a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="文件格式">
|
||||||
|
<a-radio-group button-style="solid" v-model:value="modelRef.fileType" placeholder="请选择文件格式">
|
||||||
|
<a-radio-button value="xlsx">xlsx</a-radio-button>
|
||||||
|
<a-radio-button value="csv">csv</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { queryNoPagingPost } from '@/api/device/product'
|
||||||
|
import { downloadFile } from '@/utils/utils'
|
||||||
|
import encodeQuery from '@/utils/encodeQuery'
|
||||||
|
import { BASE_API_PATH } from '@/utils/variable'
|
||||||
|
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const modelRef = reactive({
|
||||||
|
product: undefined,
|
||||||
|
fileType: 'xlsx'
|
||||||
|
});
|
||||||
|
|
||||||
|
const productList = ref<Record<string, any>[]>([])
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
() => {
|
||||||
|
queryNoPagingPost({paging: false}).then(resp => {
|
||||||
|
if(resp.status === 200){
|
||||||
|
productList.value = resp.result as Record<string, any>[]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{immediate: true, deep: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleOk = () => {
|
||||||
|
const params = encodeQuery(props.data);
|
||||||
|
if(modelRef.product){
|
||||||
|
downloadFile(
|
||||||
|
`${BASE_API_PATH}/device/instance/${modelRef.product}/export.${modelRef.fileType}`,
|
||||||
|
params
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
downloadFile(`${BASE_API_PATH}/device/instance/export.${modelRef.fileType}`, params);
|
||||||
|
}
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<template>
|
||||||
|
<a-modal :maskClosable="false" width="800px" :visible="true" title="导入" @ok="handleOk" @cancel="handleCancel">
|
||||||
|
123
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const handleOk = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
const handleCancel = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,51 @@
|
||||||
|
<template>
|
||||||
|
<a-modal :maskClosable="false" width="800px" :visible="true" title="当前进度" @ok="handleOk" @cancel="handleCancel">
|
||||||
|
<div>
|
||||||
|
<a-badge v-if="flag" status="processing" text="进行中" />
|
||||||
|
<a-badge v-else status="success" text="已完成" />
|
||||||
|
</div>
|
||||||
|
<p>总数量:{{count}}</p>
|
||||||
|
<a></a>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { downloadFile } from '@/utils/utils'
|
||||||
|
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
const props = defineProps({
|
||||||
|
api: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const eventSource = ref<Record<string, any>>({})
|
||||||
|
const count = ref<number>(0)
|
||||||
|
const flag = ref<boolean>(false)
|
||||||
|
const errMessage = ref<string>('')
|
||||||
|
const isSource = ref<boolean>(false)
|
||||||
|
const id = ref<string>('')
|
||||||
|
|
||||||
|
const handleOk = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.api,
|
||||||
|
() => {
|
||||||
|
getData()
|
||||||
|
},
|
||||||
|
{deep: true, immediate: true}
|
||||||
|
)
|
||||||
|
</script>
|
|
@ -0,0 +1,397 @@
|
||||||
|
<template>
|
||||||
|
<JTable
|
||||||
|
ref="instanceRef"
|
||||||
|
:columns="columns"
|
||||||
|
:request="query"
|
||||||
|
:defaultParams="{sorts: [{name: 'createTime', order: 'desc'}]}"
|
||||||
|
:rowSelection="{
|
||||||
|
selectedRowKeys: _selectedRowKeys,
|
||||||
|
onChange: onSelectChange
|
||||||
|
}"
|
||||||
|
@cancelSelect="cancelSelect"
|
||||||
|
:params="params"
|
||||||
|
>
|
||||||
|
<template #headerTitle>
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="handleAdd">新增</a-button>
|
||||||
|
<a-dropdown>
|
||||||
|
<a-button>批量操作 <AIcon type="DownOutlined" /></a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu>
|
||||||
|
<a-menu-item>
|
||||||
|
<a-button @click="exportVisible = true"><AIcon type="ExportOutlined" />批量导出设备</a-button>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item>
|
||||||
|
<a-button @click="importVisible = true"><AIcon type="ImportOutlined" />批量导入设备</a-button>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item>
|
||||||
|
<a-popconfirm @confirm="activeAllDevice" title="确认激活全部设备?">
|
||||||
|
<a-button type="primary" ghost><AIcon type="CheckCircleOutlined" />激活全部设备</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item>
|
||||||
|
<a-button @click="syncDeviceStatus" type="primary"><AIcon type="SyncOutlined" />同步设备状态</a-button>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item v-if="_selectedRowKeys.length">
|
||||||
|
<a-popconfirm @confirm="delSelectedDevice" title="已启用的设备无法删除,确认删除选中的禁用状态设备?">
|
||||||
|
<a-button type="primary" danger><AIcon type="DeleteOutlined" />删除选中设备</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item v-if="_selectedRowKeys.length" title="确认激活选中设备?">
|
||||||
|
<a-popconfirm @confirm="activeSelectedDevice" >
|
||||||
|
<a-button type="primary"><AIcon type="CheckOutlined" />激活选中设备</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item v-if="_selectedRowKeys.length">
|
||||||
|
<a-popconfirm @confirm="disabledSelectedDevice" title="确认禁用选中设备?">
|
||||||
|
<a-button type="primary" danger><AIcon type="StopOutlined" />禁用选中设备</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
<template #card="slotProps">
|
||||||
|
<CardBox
|
||||||
|
:value="slotProps"
|
||||||
|
@click="handleClick"
|
||||||
|
:actions="getActions(slotProps, 'card')"
|
||||||
|
v-bind="slotProps"
|
||||||
|
:active="_selectedRowKeys.includes(slotProps.id)"
|
||||||
|
:status="slotProps.state.value"
|
||||||
|
:statusText="slotProps.state.text"
|
||||||
|
:statusNames="{
|
||||||
|
online: 'success',
|
||||||
|
offline: 'error',
|
||||||
|
notActive: 'warning',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #img>
|
||||||
|
<slot name="img">
|
||||||
|
<img :src="getImage('/device/instance/device-card.png')" />
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<h3 @click="handleView(slotProps.id)">{{ slotProps.name }}</h3>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div class="card-item-content-text">设备类型</div>
|
||||||
|
<div>{{slotProps.deviceType.text}}</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div class="card-item-content-text">产品名称</div>
|
||||||
|
<div>{{slotProps.productName}}</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
<template #actions="item">
|
||||||
|
<a-tooltip v-bind="item.tooltip" :title="item.disabled && item.tooltip.title">
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="item.popConfirm"
|
||||||
|
v-bind="item.popConfirm"
|
||||||
|
:disabled="item.disabled"
|
||||||
|
>
|
||||||
|
<a-button :disabled="item.disabled">
|
||||||
|
<AIcon type="DeleteOutlined" v-if="item.key === 'delete'" />
|
||||||
|
<template v-else>
|
||||||
|
<AIcon :type="item.icon" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<template v-else>
|
||||||
|
<a-button :disabled="item.disabled" @click="item.onClick">
|
||||||
|
<AIcon type="DeleteOutlined" v-if="item.key === 'delete'" />
|
||||||
|
<template v-else>
|
||||||
|
<AIcon :type="item.icon" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
|
</template>
|
||||||
|
<template #state="slotProps">
|
||||||
|
<a-badge :text="slotProps.state.text" :status="statusMap.get(slotProps.state.value)" />
|
||||||
|
</template>
|
||||||
|
<template #action="slotProps">
|
||||||
|
<a-space :size="16">
|
||||||
|
<a-tooltip
|
||||||
|
v-for="i in getActions(slotProps, 'table')"
|
||||||
|
:key="i.key"
|
||||||
|
v-bind="i.tooltip"
|
||||||
|
>
|
||||||
|
<a-popconfirm v-if="i.popConfirm" v-bind="i.popConfirm" :disabled="i.disabled">
|
||||||
|
<a-button
|
||||||
|
:disabled="i.disabled"
|
||||||
|
style="padding: 0"
|
||||||
|
type="link"
|
||||||
|
><AIcon :type="i.icon"
|
||||||
|
/></a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<a-button
|
||||||
|
style="padding: 0"
|
||||||
|
type="link"
|
||||||
|
v-else
|
||||||
|
@click="i.onClick && i.onClick(slotProps)"
|
||||||
|
>
|
||||||
|
<a-button
|
||||||
|
:disabled="i.disabled"
|
||||||
|
style="padding: 0"
|
||||||
|
type="link"
|
||||||
|
><AIcon :type="i.icon"
|
||||||
|
/></a-button>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</JTable>
|
||||||
|
<Import v-if="importVisible" @close="importVisible = false" />
|
||||||
|
<Export v-if="exportVisible" @close="exportVisible = false" :data="params" />
|
||||||
|
<Process v-if="operationVisible" @close="operationVisible = false" :api="api" :type="type" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { query, _delete, _deploy, _undeploy, batchUndeployDevice, batchDeployDevice, batchDeleteDevice } from '@/api/device/instance'
|
||||||
|
import type { ActionsType } from '@/components/Table/index.vue'
|
||||||
|
import { getImage, LocalStore } from '@/utils/comm';
|
||||||
|
import { message } from "ant-design-vue";
|
||||||
|
import Import from './Import/index.vue'
|
||||||
|
import Export from './Export/index.vue'
|
||||||
|
import Process from './Process/index.vue'
|
||||||
|
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
|
||||||
|
|
||||||
|
const instanceRef = ref<Record<string, any>>({});
|
||||||
|
const params = ref<Record<string, any>>({pageIndex: 0, pageSize: 12})
|
||||||
|
const _selectedRowKeys = ref<string[]>([])
|
||||||
|
const importVisible = ref<boolean>(false)
|
||||||
|
const exportVisible = ref<boolean>(false)
|
||||||
|
const current = ref<Record<string, any>>({})
|
||||||
|
const operationVisible = ref<boolean>(false)
|
||||||
|
const api = ref<string>('')
|
||||||
|
const type = ref<string>('')
|
||||||
|
|
||||||
|
const statusMap = new Map();
|
||||||
|
statusMap.set('online', 'processing');
|
||||||
|
statusMap.set('offline', 'error');
|
||||||
|
statusMap.set('notActive', 'warning');
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'ID',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '设备名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品名称',
|
||||||
|
dataIndex: 'productName',
|
||||||
|
key: 'productName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
key: 'createTime',
|
||||||
|
scopedSlots: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'state',
|
||||||
|
key: 'state',
|
||||||
|
scopedSlots: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '说明',
|
||||||
|
dataIndex: 'describe',
|
||||||
|
key: 'describe'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 250,
|
||||||
|
scopedSlots: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const paramsFormat = (config: any, _terms: any, name?: string) => {
|
||||||
|
if (config?.terms && Array.isArray(config.terms) && config?.terms.length > 0) {
|
||||||
|
(config?.terms || []).map((item: any, index: number) => {
|
||||||
|
if (item?.type) {
|
||||||
|
_terms[`${name ? `${name}.` : ''}terms[${index}].type`] = item.type;
|
||||||
|
}
|
||||||
|
paramsFormat(item, _terms, `${name ? `${name}.` : ''}terms[${index}]`);
|
||||||
|
});
|
||||||
|
} else if (!config?.terms && Object.keys(config).length > 0) {
|
||||||
|
Object.keys(config).forEach((key) => {
|
||||||
|
if (config[key]) {
|
||||||
|
_terms[`${name ? `${name}.` : ''}${key}`] = config[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleParams = (config: any) => {
|
||||||
|
const _terms: any = {};
|
||||||
|
paramsFormat(config, _terms);
|
||||||
|
const url = new URLSearchParams();
|
||||||
|
Object.keys(_terms).forEach((key) => {
|
||||||
|
url.append(key, _terms[key]);
|
||||||
|
});
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增
|
||||||
|
*/
|
||||||
|
const handleAdd = () => {
|
||||||
|
message.warn('新增')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看
|
||||||
|
*/
|
||||||
|
const handleView = (dt: any) => {
|
||||||
|
// message.warn('查看')
|
||||||
|
}
|
||||||
|
|
||||||
|
const getActions = (data: Partial<Record<string, any>>, type: 'card' | 'table'): ActionsType[] => {
|
||||||
|
if(!data) return []
|
||||||
|
const actions = [
|
||||||
|
{
|
||||||
|
key: 'view',
|
||||||
|
text: "查看",
|
||||||
|
tooltip: {
|
||||||
|
title: '查看'
|
||||||
|
},
|
||||||
|
icon: 'EyeOutlined',
|
||||||
|
onClick: () => {
|
||||||
|
handleView(data)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'edit',
|
||||||
|
text: "编辑",
|
||||||
|
tooltip: {
|
||||||
|
title: '编辑'
|
||||||
|
},
|
||||||
|
icon: 'EditOutlined',
|
||||||
|
onClick: () => {
|
||||||
|
message.warn('edit')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'action',
|
||||||
|
text: data.state.value !== 'notActive' ? "禁用" : "启用",
|
||||||
|
tooltip: {
|
||||||
|
title: data.state.value !== 'notActive' ? "禁用" : "启用",
|
||||||
|
},
|
||||||
|
icon: data.state.value !== 'notActive' ? 'StopOutlined' : 'CheckCircleOutlined',
|
||||||
|
popConfirm: {
|
||||||
|
title: `确认${data.state.value !== 'notActive' ? "禁用" : "启用"}?`,
|
||||||
|
onConfirm: async () => {
|
||||||
|
let response = undefined
|
||||||
|
if(data.state.value !== 'notActive') {
|
||||||
|
response = await _undeploy(data.id)
|
||||||
|
} else {
|
||||||
|
response = await _deploy(data.id)
|
||||||
|
}
|
||||||
|
if(response && response.status === 200) {
|
||||||
|
message.success('操作成功!')
|
||||||
|
instanceRef.value?.reload()
|
||||||
|
} else {
|
||||||
|
message.error('操作失败!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delete',
|
||||||
|
text: "删除",
|
||||||
|
disabled: data.state.value !== 'notActive',
|
||||||
|
tooltip: {
|
||||||
|
title: data.state.value !== 'notActive' ? '已启用的设备不能删除' : '删除'
|
||||||
|
},
|
||||||
|
popConfirm: {
|
||||||
|
title: '确认删除?',
|
||||||
|
onConfirm: async () => {
|
||||||
|
const resp = await _delete(data.id)
|
||||||
|
if(resp.status === 200) {
|
||||||
|
message.success('操作成功!')
|
||||||
|
instanceRef.value?.reload()
|
||||||
|
} else {
|
||||||
|
message.error('操作失败!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: 'DeleteOutlined'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
if(type === 'card') return actions.filter((i: ActionsType) => i.key !== 'view')
|
||||||
|
return actions
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSelectChange = (keys: string[]) => {
|
||||||
|
_selectedRowKeys.value = [...keys]
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelSelect = () => {
|
||||||
|
_selectedRowKeys.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = (dt: any) => {
|
||||||
|
if(_selectedRowKeys.value.includes(dt.id)) {
|
||||||
|
const _index = _selectedRowKeys.value.findIndex(i => i === dt.id)
|
||||||
|
_selectedRowKeys.value.splice(_index, 1)
|
||||||
|
} else {
|
||||||
|
_selectedRowKeys.value = [..._selectedRowKeys.value, dt.id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeAllDevice = () => {
|
||||||
|
type.value = 'active'
|
||||||
|
const activeAPI = `/${BASE_API_PATH}/device-instance/deploy?:X_Access_Token=${LocalStore.get(TOKEN_KEY)}&${handleParams(params)}`;
|
||||||
|
api.value = activeAPI
|
||||||
|
operationVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const syncDeviceStatus = () => {
|
||||||
|
type.value = 'sync'
|
||||||
|
const syncAPI = `/${BASE_API_PATH}/device-instance/state/_sync?:X_Access_Token=${LocalStore.get(TOKEN_KEY)}&${handleParams(params)}`;
|
||||||
|
api.value = syncAPI
|
||||||
|
operationVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const delSelectedDevice = async () => {
|
||||||
|
const resp = await batchDeleteDevice(_selectedRowKeys.value)
|
||||||
|
if(resp.status === 200){
|
||||||
|
message.success('操作成功!')
|
||||||
|
_selectedRowKeys.value = []
|
||||||
|
instanceRef.value?.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeSelectedDevice = async () => {
|
||||||
|
const resp = await batchDeployDevice(_selectedRowKeys.value)
|
||||||
|
if(resp.status === 200){
|
||||||
|
message.success('操作成功!')
|
||||||
|
_selectedRowKeys.value = []
|
||||||
|
instanceRef.value?.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const disabledSelectedDevice = async () => {
|
||||||
|
const resp = await batchUndeployDevice(_selectedRowKeys.value)
|
||||||
|
if(resp.status === 200){
|
||||||
|
message.success('操作成功!')
|
||||||
|
_selectedRowKeys.value = []
|
||||||
|
instanceRef.value?.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -6,11 +6,11 @@ import { recommendList, bootConfig } from "../index";
|
||||||
// 权限控制
|
// 权限控制
|
||||||
const hasPermission = usePermissionStore().hasPermission;
|
const hasPermission = usePermissionStore().hasPermission;
|
||||||
const productPermission = (action: string) =>
|
const productPermission = (action: string) =>
|
||||||
hasPermission(`device/Product:${action}"`);
|
hasPermission(`device/Product:${action}`);
|
||||||
const devicePermission = (action: string) =>
|
const devicePermission = (action: string) =>
|
||||||
hasPermission(`device/Instance:${action}"`);
|
hasPermission(`device/Instance:${action}`);
|
||||||
const rulePermission = (action: string) =>
|
const rulePermission = (action: string) =>
|
||||||
hasPermission(`rule-engine/Instance:${action}"`);
|
hasPermission(`rule-engine/Instance:${action}`);
|
||||||
|
|
||||||
|
|
||||||
// 物联网引导-数据
|
// 物联网引导-数据
|
||||||
|
|
|
@ -0,0 +1,748 @@
|
||||||
|
<template>
|
||||||
|
<div style="margin-top: 10px">
|
||||||
|
<a-steps :current="stepCurrent">
|
||||||
|
<a-step v-for="item in steps" :key="item" :title="item" />
|
||||||
|
</a-steps>
|
||||||
|
<div class="steps-content">
|
||||||
|
<div class="steps-box" v-if="current === 0">
|
||||||
|
<div class="alert">
|
||||||
|
<question-circle-outlined />
|
||||||
|
配置设备信令参数
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a-form
|
||||||
|
:model="formState"
|
||||||
|
name="basic"
|
||||||
|
autocomplete="off"
|
||||||
|
layout="vertical"
|
||||||
|
@finish="onFinish"
|
||||||
|
>
|
||||||
|
<a-row :gutter="[24, 24]">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="SIP 域"
|
||||||
|
name="domain"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入SIP 域!',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="formState.domain"
|
||||||
|
placeholder="请输入SIP 域"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="SIP ID"
|
||||||
|
name="sipId"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入SIP ID!',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="formState.sipId"
|
||||||
|
placeholder="请输入SIP ID"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
name="shareCluster"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择集群!',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
集群
|
||||||
|
<span style="color: red; margin: 0 4px 0 -2px"
|
||||||
|
>*</span
|
||||||
|
>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
<p>
|
||||||
|
共享配置:集群下所有节点共用同一配置
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
独立配置:集群下不同节点使用不同配置
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<question-circle-outlined />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-radio-group
|
||||||
|
v-model:value="formState.shareCluster"
|
||||||
|
>
|
||||||
|
<a-radio :value="true">共享配置</a-radio>
|
||||||
|
<a-radio :value="false">独立配置</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
<div v-if="formState.shareCluster">
|
||||||
|
<a-row :gutter="[24, 24]">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="SIP 地址"
|
||||||
|
name="sip"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择端口!',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-select
|
||||||
|
v-model:value="formState.sip1"
|
||||||
|
style="width: 50%"
|
||||||
|
:disabled="true"
|
||||||
|
>
|
||||||
|
<a-select-option value="0.0.0.0"
|
||||||
|
>0.0.0.0</a-select-option
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
<a-select
|
||||||
|
v-model:value="formState.sip"
|
||||||
|
:options="sipList"
|
||||||
|
style="width: 50%"
|
||||||
|
placeholder="请选择端口"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="公网 Host"
|
||||||
|
name="public"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择端口!',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input
|
||||||
|
style="width: 50%"
|
||||||
|
v-model:value="
|
||||||
|
formState.public1
|
||||||
|
"
|
||||||
|
placeholder="请输入IP地址"
|
||||||
|
/>
|
||||||
|
<a-input-number
|
||||||
|
style="width: 50%"
|
||||||
|
placeholder="请输入端口"
|
||||||
|
v-model:value="formState.public"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</a-form>
|
||||||
|
<div v-if="!formState.shareCluster">
|
||||||
|
<a-form
|
||||||
|
ref="formRef2"
|
||||||
|
layout="vertical"
|
||||||
|
name="dynamic_form_nest_item"
|
||||||
|
:model="dynamicValidateForm"
|
||||||
|
@finish="onFinish2"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="(
|
||||||
|
user, index
|
||||||
|
) in dynamicValidateForm.users"
|
||||||
|
:key="user.id"
|
||||||
|
>
|
||||||
|
<a-collapse v-model:activeKey="activeKey">
|
||||||
|
<a-collapse-panel
|
||||||
|
:key="user.id"
|
||||||
|
:header="`#${index + 1}.节点`"
|
||||||
|
>
|
||||||
|
|
||||||
|
<template #extra>
|
||||||
|
<delete-outlined
|
||||||
|
@click="removeUser(user)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<a-row :gutter="[24, 24]">
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item
|
||||||
|
label="节点名称"
|
||||||
|
:name="[
|
||||||
|
'users',
|
||||||
|
index,
|
||||||
|
'first',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="
|
||||||
|
user.first
|
||||||
|
"
|
||||||
|
:options="clustersList"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="7">
|
||||||
|
<a-form-item
|
||||||
|
:name="[
|
||||||
|
'users',
|
||||||
|
index,
|
||||||
|
'last',
|
||||||
|
]"
|
||||||
|
:rules="{
|
||||||
|
required: true,
|
||||||
|
message:
|
||||||
|
'请选择SIP 地址',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
SIP 地址
|
||||||
|
<span
|
||||||
|
style="
|
||||||
|
color: red;
|
||||||
|
margin: 0 4px 0 -2px;
|
||||||
|
"
|
||||||
|
>*</span
|
||||||
|
>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
<p>
|
||||||
|
绑定到服务器上的网卡地址,绑定到所有网卡:0.0.0.0
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<question-circle-outlined />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-select
|
||||||
|
v-model:value="
|
||||||
|
user.last
|
||||||
|
"
|
||||||
|
style="width: 50%"
|
||||||
|
:options="sipList"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
<a-select
|
||||||
|
v-model:value="
|
||||||
|
user.last1
|
||||||
|
"
|
||||||
|
:options="sipList"
|
||||||
|
style="width: 50%"
|
||||||
|
placeholder="请选择端口"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item
|
||||||
|
:name="[
|
||||||
|
'users',
|
||||||
|
index,
|
||||||
|
'last2',
|
||||||
|
]"
|
||||||
|
:rules="{
|
||||||
|
required: true,
|
||||||
|
message:
|
||||||
|
'请输入公网 Host',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
公网 Host
|
||||||
|
<span
|
||||||
|
style="
|
||||||
|
color: red;
|
||||||
|
margin: 0 4px 0 -2px;
|
||||||
|
"
|
||||||
|
>*</span
|
||||||
|
>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
<p>
|
||||||
|
监听指定端口的请求
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<question-circle-outlined />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input
|
||||||
|
style="width: 50%"
|
||||||
|
v-model:value="
|
||||||
|
user.last2
|
||||||
|
"
|
||||||
|
placeholder="请输入IP地址"
|
||||||
|
/>
|
||||||
|
<a-input-number
|
||||||
|
style="width: 50%"
|
||||||
|
placeholder="请输入端口"
|
||||||
|
v-model:value="
|
||||||
|
user.last3
|
||||||
|
"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
|
</div>
|
||||||
|
<a-form-item>
|
||||||
|
<a-button
|
||||||
|
style="margin-top: 10px"
|
||||||
|
type="dashed"
|
||||||
|
block
|
||||||
|
@click="addUser"
|
||||||
|
>
|
||||||
|
<PlusOutlined />
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-button type="primary" html-type="submit"
|
||||||
|
>Submit</a-button
|
||||||
|
>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="steps-box" v-else>
|
||||||
|
<div
|
||||||
|
class="card-last"
|
||||||
|
:style="`max-height:${
|
||||||
|
clientHeight > 900 ? 750 : clientHeight * 0.7
|
||||||
|
}px`"
|
||||||
|
>
|
||||||
|
<a-row :gutter="[24, 24]">
|
||||||
|
<a-col :span="12">
|
||||||
|
<title-component data="基本信息" />
|
||||||
|
<div>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
label="名称"
|
||||||
|
v-bind="validateInfos.name"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.name"
|
||||||
|
allowClear
|
||||||
|
placeholder="请输入名称"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="说明"
|
||||||
|
v-bind="validateInfos.description"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
placeholder="请输入说明"
|
||||||
|
:rows="4"
|
||||||
|
v-model:value="form.description"
|
||||||
|
show-count
|
||||||
|
:maxlength="200"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div class="config-right">
|
||||||
|
<div class="config-right-item">
|
||||||
|
<div class="config-right-item-title">
|
||||||
|
接入方式
|
||||||
|
</div>
|
||||||
|
<div class="config-right-item-context">
|
||||||
|
{{ provider.name }}
|
||||||
|
</div>
|
||||||
|
<div class="config-right-item-context">
|
||||||
|
{{ provider.description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="config-right-item">
|
||||||
|
<div class="config-right-item-title">
|
||||||
|
消息协议
|
||||||
|
</div>
|
||||||
|
<div class="config-right-item-context">
|
||||||
|
{{
|
||||||
|
procotolList.find(
|
||||||
|
(i) => i.id === procotolCurrent,
|
||||||
|
).name
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="config-right-item-context"
|
||||||
|
v-if="config.document"
|
||||||
|
>
|
||||||
|
<Markdown :source="config.document" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="config-right-item"
|
||||||
|
v-if="
|
||||||
|
networkList.find(
|
||||||
|
(i) => i.id === networkCurrent,
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
networkList.find(
|
||||||
|
(i) => i.id === networkCurrent,
|
||||||
|
).addresses || []
|
||||||
|
).length > 0
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="config-right-item-title">
|
||||||
|
网络组件
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="i in (networkList.find(
|
||||||
|
(i) => i.id === networkCurrent,
|
||||||
|
) &&
|
||||||
|
networkList.find(
|
||||||
|
(i) => i.id === networkCurrent,
|
||||||
|
).addresses) ||
|
||||||
|
[]"
|
||||||
|
:key="i.address"
|
||||||
|
>
|
||||||
|
<a-badge
|
||||||
|
:color="
|
||||||
|
i.health === -1
|
||||||
|
? 'red'
|
||||||
|
: 'green'
|
||||||
|
"
|
||||||
|
:text="i.address"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="config-right-item"
|
||||||
|
v-if="
|
||||||
|
config.routes &&
|
||||||
|
config.routes.length > 0
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="config-right-item-title">
|
||||||
|
{{
|
||||||
|
data.provider ===
|
||||||
|
'mqtt-server-gateway' ||
|
||||||
|
data.provider ===
|
||||||
|
'mqtt-client-gateway'
|
||||||
|
? 'topic'
|
||||||
|
: 'URL信息'
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<a-table
|
||||||
|
:pagination="false"
|
||||||
|
:rowKey="generateUUID()"
|
||||||
|
:data-source="config.routes || []"
|
||||||
|
bordered
|
||||||
|
:columns="columnsMQTT"
|
||||||
|
:scroll="{ y: 300 }"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
#bodyCell="{ column, text, record }"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
column.dataIndex ===
|
||||||
|
'stream'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="
|
||||||
|
record.upstream &&
|
||||||
|
record.downstream
|
||||||
|
"
|
||||||
|
>上行、下行</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-else-if="record.upstream"
|
||||||
|
>上行</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-else-if="
|
||||||
|
record.downstream
|
||||||
|
"
|
||||||
|
>下行</span
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="steps-action">
|
||||||
|
<a-button
|
||||||
|
v-if="[0, 1].includes(current)"
|
||||||
|
type="primary"
|
||||||
|
@click="next"
|
||||||
|
>
|
||||||
|
下一步
|
||||||
|
</a-button>
|
||||||
|
<a-button v-if="current === 2" type="primary" @click="saveData">
|
||||||
|
保存
|
||||||
|
</a-button>
|
||||||
|
<a-button v-if="current > 0" style="margin-left: 8px" @click="prev">
|
||||||
|
上一步
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="AccessNetwork">
|
||||||
|
import { message, Form } from 'ant-design-vue';
|
||||||
|
import type { FormInstance } from 'ant-design-vue';
|
||||||
|
import Markdown from 'vue3-markdown-it';
|
||||||
|
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { getResourcesCurrent, getClusters } from '@/api/link/accessConfig';
|
||||||
|
|
||||||
|
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
first: string;
|
||||||
|
last1: string;
|
||||||
|
last: string;
|
||||||
|
last2: string;
|
||||||
|
last3: string;
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeKey = ref([]);
|
||||||
|
|
||||||
|
const formRef2 = ref<FormInstance>();
|
||||||
|
const dynamicValidateForm = reactive<{ users: User[] }>({
|
||||||
|
users: [],
|
||||||
|
});
|
||||||
|
const removeUser = (item: User) => {
|
||||||
|
let index = dynamicValidateForm.users.indexOf(item);
|
||||||
|
if (index !== -1) {
|
||||||
|
dynamicValidateForm.users.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const addUser = () => {
|
||||||
|
dynamicValidateForm.users.push({
|
||||||
|
first: '',
|
||||||
|
last1: '',
|
||||||
|
last: '',
|
||||||
|
last2: '',
|
||||||
|
last3: '',
|
||||||
|
id: Date.now(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const onFinish2 = (values) => {
|
||||||
|
console.log('Received values of form:', values);
|
||||||
|
console.log('dynamicValidateForm.users:', dynamicValidateForm.users);
|
||||||
|
};
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
provider: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const clientHeight = document.body.clientHeight;
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const useForm = Form.useForm;
|
||||||
|
|
||||||
|
const current = ref(0);
|
||||||
|
const stepCurrent = ref(0);
|
||||||
|
const steps = ref(['信令配置', '完成']);
|
||||||
|
const form = reactive({
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const sipList = ref([]);
|
||||||
|
const clustersList = ref([]);
|
||||||
|
|
||||||
|
const { resetFields, validate, validateInfos } = useForm(
|
||||||
|
form,
|
||||||
|
reactive({
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请输入名称', trigger: 'blur' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const saveData = () => {
|
||||||
|
validate()
|
||||||
|
.then(async (values) => {
|
||||||
|
console.log(333, values);
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
const next = async () => {
|
||||||
|
console.log(22, current.value);
|
||||||
|
};
|
||||||
|
const prev = () => {
|
||||||
|
current.value = current.value - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface FormState {
|
||||||
|
domain: string;
|
||||||
|
sipId: string;
|
||||||
|
shareCluster: boolean;
|
||||||
|
sip1: string;
|
||||||
|
sip: string;
|
||||||
|
public1: string;
|
||||||
|
public: string;
|
||||||
|
}
|
||||||
|
const formState = reactive<FormState>({
|
||||||
|
domain: '',
|
||||||
|
sipId: '',
|
||||||
|
shareCluster: true,
|
||||||
|
sip1: '0.0.0.0',
|
||||||
|
sip: '',
|
||||||
|
public1: '',
|
||||||
|
public: '',
|
||||||
|
});
|
||||||
|
const onFinish = (values: any) => {
|
||||||
|
console.log('Success:', values);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getResourcesCurrent().then((resp) => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
const data: any = resp.result.find((i) => i.host === '0.0.0.0');
|
||||||
|
const list = data.portList.map((i) => {
|
||||||
|
const label = `${i.transports.join('/')} (${i.port})`;
|
||||||
|
const value = {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: i.port,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
value: JSON.stringify(value),
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
sipList.value = list;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(1);
|
||||||
|
|
||||||
|
getClusters().then((resp) => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
const list = resp.result.map((i) => ({
|
||||||
|
value: i.id,
|
||||||
|
label: i.name,
|
||||||
|
}));
|
||||||
|
clustersList.value = list;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
current,
|
||||||
|
(v) => {
|
||||||
|
// if (props.provider.channel !== 'child-device') {
|
||||||
|
// stepCurrent.value = v;
|
||||||
|
// } else {
|
||||||
|
// stepCurrent.value = v - 1;
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.steps-content {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
.steps-box {
|
||||||
|
min-height: 400px;
|
||||||
|
.card-item {
|
||||||
|
padding-right: 5px;
|
||||||
|
max-height: 480px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.card-last {
|
||||||
|
padding-right: 5px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.steps-action {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
height: 40px;
|
||||||
|
padding-left: 10px;
|
||||||
|
color: rgba(0, 0, 0, 0.55);
|
||||||
|
line-height: 40px;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
margin: 15px 0;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.other {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.item {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-right {
|
||||||
|
padding: 20px;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
|
||||||
|
.config-right-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.config-right-item-title {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-right-item-context {
|
||||||
|
margin: 5px 0;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div v-if="channel==='fixed-media'" class="card-last">
|
<div v-if="channel === 'fixed-media'" class="card-last">
|
||||||
<a-row :gutter="[24, 24]">
|
<a-row :gutter="[24, 24]">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<title-component data="基本信息" />
|
<title-component data="基本信息" />
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
:rules="[
|
:rules="[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入证书名称',
|
message: '请输入名称',
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
@ -68,13 +68,16 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>123</div>
|
<div v-else>
|
||||||
|
<GB28181 :data="props.data" :provider="props.provider"></GB28181>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="AccessMedia">
|
<script lang="ts" setup name="AccessMedia">
|
||||||
import { message, Form } from 'ant-design-vue';
|
import { message, Form } from 'ant-design-vue';
|
||||||
import type { FormInstance } from 'ant-design-vue';
|
import type { FormInstance } from 'ant-design-vue';
|
||||||
|
import GB28181 from './GB28181.vue';
|
||||||
|
|
||||||
interface FormState {
|
interface FormState {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -102,7 +105,6 @@ const formState = reactive<FormState>({
|
||||||
const onFinish = (values: any) => {
|
const onFinish = (values: any) => {
|
||||||
console.log('Success:', values);
|
console.log('Success:', values);
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="steps-content">
|
<div class="steps-content">
|
||||||
<div class="steps-box" v-if="current === 0">
|
<div class="steps-box" v-if="current === 0">
|
||||||
<div class="alert">
|
<div class="alert">
|
||||||
<a-icon type="info-circle" style="margin-right: 10px" />
|
<question-circle-outlined />
|
||||||
选择与设备通信的网络组件
|
选择与设备通信的网络组件
|
||||||
</div>
|
</div>
|
||||||
<div class="search">
|
<div class="search">
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="steps-box" v-else-if="current === 1">
|
<div class="steps-box" v-else-if="current === 1">
|
||||||
<div class="alert">
|
<div class="alert">
|
||||||
<a-icon type="info-circle" style="margin-right: 10px" />
|
<question-circle-outlined />
|
||||||
使用选择的消息协议,对网络组件通信数据进行编解码、认证等操作
|
使用选择的消息协议,对网络组件通信数据进行编解码、认证等操作
|
||||||
</div>
|
</div>
|
||||||
<div class="search">
|
<div class="search">
|
||||||
|
@ -330,7 +330,7 @@ import AccessCard from './AccessCard/index.vue';
|
||||||
import { message, Form } from 'ant-design-vue';
|
import { message, Form } from 'ant-design-vue';
|
||||||
import type { FormInstance, TableColumnType } from 'ant-design-vue';
|
import type { FormInstance, TableColumnType } from 'ant-design-vue';
|
||||||
import Markdown from 'vue3-markdown-it';
|
import Markdown from 'vue3-markdown-it';
|
||||||
|
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
|
||||||
//测试数据1
|
//测试数据1
|
||||||
const resultList1 = [
|
const resultList1 = [
|
||||||
{
|
{
|
||||||
|
@ -582,7 +582,7 @@ const { resetFields, validate, validateInfos } = useForm(
|
||||||
form,
|
form,
|
||||||
reactive({
|
reactive({
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '请输入证书名称', trigger: 'blur' },
|
{ required: true, message: '请输入名称', trigger: 'blur' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<div>123</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,154 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<JTable
|
||||||
|
:columns="columns"
|
||||||
|
:request="request"
|
||||||
|
>
|
||||||
|
<template #headerTitle>
|
||||||
|
<a-button type="primary" @click="add">新增</a-button>
|
||||||
|
</template>
|
||||||
|
<template #card="slotProps">
|
||||||
|
<CardBox
|
||||||
|
:value="slotProps"
|
||||||
|
@click="handleClick"
|
||||||
|
:actions="getActions(slotProps)"
|
||||||
|
v-bind="slotProps"
|
||||||
|
:status="slotProps.state ? 'success' : 'error'"
|
||||||
|
>
|
||||||
|
<template #img>
|
||||||
|
<slot name="img">
|
||||||
|
<img :src="getImage('/device-product.png')" />
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<h3>{{slotProps.name}}</h3>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="12">
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
设备类型
|
||||||
|
</div>
|
||||||
|
<div>直连设备</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
<template #actions="item">
|
||||||
|
<a-popconfirm v-if="item.popConfirm" v-bind="item.popConfirm">
|
||||||
|
<a-button :disabled="item.disabled">
|
||||||
|
<DeleteOutlined v-if="item.key === 'delete'" />
|
||||||
|
<template v-else>
|
||||||
|
<AIcon :type="item.icon" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<template v-else>
|
||||||
|
<a-button :disabled="item.disabled">
|
||||||
|
<DeleteOutlined v-if="item.key === 'delete'" />
|
||||||
|
<template v-else>
|
||||||
|
<AIcon :type="item.icon" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
|
</template>
|
||||||
|
<template #id="slotProps">
|
||||||
|
<a>{{slotProps.id}}</a>
|
||||||
|
</template>
|
||||||
|
<template #action="slotProps">
|
||||||
|
<a-space :size="16">
|
||||||
|
<a-tooltip v-for="i in getActions(slotProps)" :key="i.key" v-bind="i.tooltip">
|
||||||
|
<a-popconfirm v-if="i.popConfirm" v-bind="i.popConfirm">
|
||||||
|
<a-button :disabled="i.disabled" style="padding: 0" type="link"><AIcon :type="i.icon" /></a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<a-button style="padding: 0" type="link" v-else @click="i.onClick && i.onClick(slotProps)">
|
||||||
|
<a-button :disabled="i.disabled" style="padding: 0" type="link"><AIcon :type="i.icon" /></a-button>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</JTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { query } from '@/api/northbound/dueros'
|
||||||
|
import type { ActionsType } from '@/components/Table/index.vue'
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
import { DeleteOutlined } from '@ant-design/icons-vue'
|
||||||
|
import { message } from "ant-design-vue";
|
||||||
|
|
||||||
|
const request = (data: any) => query({})
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ID',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'id',
|
||||||
|
scopedSlots: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '分类',
|
||||||
|
dataIndex: 'classifiedName',
|
||||||
|
key: 'classifiedName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 250,
|
||||||
|
scopedSlots: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const handleClick = (dt: any) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
|
||||||
|
if(!data){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'edit',
|
||||||
|
text: "编辑",
|
||||||
|
tooltip: {
|
||||||
|
title: '编辑'
|
||||||
|
},
|
||||||
|
icon: 'icon-rizhifuwu'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'import',
|
||||||
|
text: "导入",
|
||||||
|
tooltip: {
|
||||||
|
title: '导入'
|
||||||
|
},
|
||||||
|
disabled: true,
|
||||||
|
icon: 'icon-xiazai'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delete',
|
||||||
|
text: "删除",
|
||||||
|
tooltip: {
|
||||||
|
title: !!data?.state ? '正常的产品不能删除' : '删除'
|
||||||
|
},
|
||||||
|
popConfirm: {
|
||||||
|
title: '确认删除?'
|
||||||
|
},
|
||||||
|
icon: 'icon-huishouzhan'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const add = () => {
|
||||||
|
message.warn('123')
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,48 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const AliyunSms = () => {
|
||||||
|
const accessKey = getImage(
|
||||||
|
'/notice/doc/config/aliyun-sms-voice/AccesskeyIDSecret.jpg',
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<div class={'url'}>
|
||||||
|
阿里云管理控制台:
|
||||||
|
<a
|
||||||
|
href="https://home.console.aliyun.com"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
https://home.console.aliyun.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1.概述</h1>
|
||||||
|
<div>
|
||||||
|
通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2>1、RegionID</h2>
|
||||||
|
<div>
|
||||||
|
阿里云内部给每台机器设置的唯一编号。请根据购买的阿里云服务器地址进行填写。
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
阿里云地域和可用区对照表地址:https://help.aliyun.com/document_detail/40654.html?spm=a2c6h.13066369.0.0.54a174710O7rWH
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>2、AccesskeyID/Secret</h2>
|
||||||
|
<div>
|
||||||
|
<div>用于程序通知方式调用云服务费API的用户标识和秘钥</div>
|
||||||
|
<div>
|
||||||
|
获取路径:“阿里云管理控制台”--“用户头像”--“”--“AccessKey管理”--“查看”
|
||||||
|
</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={accessKey} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default AliyunSms;
|
|
@ -0,0 +1,45 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const AliyunVoice = () => {
|
||||||
|
const accessKey = getImage(
|
||||||
|
'/notice/doc/config/aliyun-sms-voice/AccesskeyIDSecret.jpg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<div class={'url'}>
|
||||||
|
阿里云管理控制台:
|
||||||
|
<a
|
||||||
|
href="https://home.console.aliyun.com"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
https://home.console.aliyun.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2>1、RegionID</h2>
|
||||||
|
<div>
|
||||||
|
阿里云服务地域与对应的RegionID。请根据购买的阿里云服务器地域进行选择。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>2、AccesskeyID/Secret</h2>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
用于程序通知方式调用云服务费API的用户标识和秘钥获取路径:“阿里云管理控制台”--“用户头像”--“”--“AccessKey管理”--“查看”
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={accessKey} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default AliyunVoice;
|
|
@ -1,5 +1,5 @@
|
||||||
import { Image } from 'ant-design-vue';
|
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
const DingTalk = () => {
|
const DingTalk = () => {
|
||||||
|
@ -9,6 +9,7 @@ const DingTalk = () => {
|
||||||
const appSecret = getImage(
|
const appSecret = getImage(
|
||||||
'/notice/doc/config/dingTalk-message/02-AppSecret.jpg',
|
'/notice/doc/config/dingTalk-message/02-AppSecret.jpg',
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={'doc'}>
|
<div class={'doc'}>
|
||||||
<div class={'url'}>
|
<div class={'url'}>
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const DingTalkRebot = () => {
|
||||||
|
const groupSetting = getImage(
|
||||||
|
'/notice/doc/config/dingTalk-rebot/01-group-setting.jpg',
|
||||||
|
);
|
||||||
|
const rebot = getImage('/notice/doc/config/dingTalk-rebot/02-rebot.jpg');
|
||||||
|
const webhook = getImage(
|
||||||
|
'/notice/doc/config/dingTalk-rebot/03-Webhook.jpg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2> 1、WebHook</h2>
|
||||||
|
<div>
|
||||||
|
在钉钉群内每创建一个钉钉群自定义机器人都会产生唯一的WebHook地址。
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
获取路径:“钉钉桌面客户端”--“群设置”--“智能群助手”--“机器人信息”
|
||||||
|
</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={rebot} />
|
||||||
|
</div>
|
||||||
|
<h2>1、登录钉钉桌面客户端,进入群设置</h2>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={groupSetting} />
|
||||||
|
</div>
|
||||||
|
<h2>2、点击智能群助手,查看机器人信息</h2>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={webhook} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default DingTalkRebot;
|
|
@ -0,0 +1,27 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const Email = () => {
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<h2>1、 服务器地址</h2>
|
||||||
|
<div>
|
||||||
|
下拉可选择国内常用的邮箱服务配置,也支持手动输入其他地址。
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
系统使用POP协议。POP允许电子邮件客户端下载服务器上的邮件,但是您在电子邮件客户端的操作(如:移动邮件、标记已读等),这时不会反馈到服务器上。
|
||||||
|
</div>
|
||||||
|
<h2>2、发件人</h2>
|
||||||
|
<div>用于发送邮件时“发件人“信息的显示</div>
|
||||||
|
<h2>3、 用户名</h2>
|
||||||
|
<div>用该账号进行发送邮件。</div>
|
||||||
|
<h2>4、密码</h2>
|
||||||
|
<div>用于账号身份认证,认证通过后可通过该账号进行发送邮件。</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Email;
|
|
@ -0,0 +1,23 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const Webhook = () => {
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
webhook是一个接收HTTP请求的URL(本平台默认只支持HTTP
|
||||||
|
POST请求),实现了Webhook的第三方系统可以基于该URL订阅本平台系统信息,本平台按配置把特定的事件结果推送到指定的地址,便于系统做后续处理。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<h2>1、Webhook</h2>
|
||||||
|
<div>Webhook地址。</div>
|
||||||
|
|
||||||
|
<h2>2、请求头</h2>
|
||||||
|
<div>
|
||||||
|
支持根据系统提供的接口设置不同的请求头。如 Accept-Language
|
||||||
|
、Content-Type
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Webhook;
|
|
@ -0,0 +1,51 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const WeixinApp = () => {
|
||||||
|
const appId = getImage('/notice/doc/config/weixin-official/01-AppID.jpg');
|
||||||
|
const appSecret = getImage(
|
||||||
|
'/notice/doc/config/weixin-official/02-AppSecret.jpg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<div class={'url'}>
|
||||||
|
微信公众平台:
|
||||||
|
<a
|
||||||
|
href="https://mp.weixin.qq.com/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
https://mp.weixin.qq.com/
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2>1、AppID</h2>
|
||||||
|
<div>微信服务号的唯一专属编号。</div>
|
||||||
|
<div>
|
||||||
|
获取路径:“微信公众平台”管理后台--“设置与开发”--“基本配置”
|
||||||
|
</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={appId} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>2、AppSecret</h2>
|
||||||
|
<div>
|
||||||
|
<div>公众号开发者身份的密码</div>
|
||||||
|
<div>
|
||||||
|
获取路径:“微信公众平台”管理后台--“设置与开发”--“基本配置”
|
||||||
|
</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={appSecret} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default WeixinApp;
|
|
@ -0,0 +1,51 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const WeixinCorp = () => {
|
||||||
|
const corpId = getImage(
|
||||||
|
'/notice/doc/config/weixin-corp/01-corpId.jpg',
|
||||||
|
);
|
||||||
|
const corpSecret = getImage(
|
||||||
|
'/notice/doc/config/weixin-corp/02-corpSecret.jpg',
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div class={'doc'}>
|
||||||
|
<div class={'url'}>
|
||||||
|
企业微信管理后台:
|
||||||
|
<a
|
||||||
|
href="https://work.weixin.qq.com"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
https://work.weixin.qq.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
|
||||||
|
</div>
|
||||||
|
<h1>2.通知配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2>1、corpId</h2>
|
||||||
|
<div>企业号的唯一专属编号。</div>
|
||||||
|
<div>获取路径:“企业微信”管理后台--“我的企业”--“企业ID”</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={corpId} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>2、corpSecret</h2>
|
||||||
|
<div>
|
||||||
|
<div>应用的唯一secret,一个企业微信中可以有多个corpSecret</div>
|
||||||
|
<div>
|
||||||
|
获取路径:“企业微信”--“应用与小程序”--“自建应用”中获取
|
||||||
|
</div>
|
||||||
|
<div class={'image'}>
|
||||||
|
<Image width="100%" src={corpSecret} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default WeixinCorp;
|
|
@ -1,6 +1,46 @@
|
||||||
import DingTalk from './DingTalk';
|
import DingTalk from './DingTalk';
|
||||||
|
import DingTalkRebot from './DingTalkRebot';
|
||||||
|
import AliyunSms from './AliyunSms';
|
||||||
|
import AliyunVoice from './AliyunVoice';
|
||||||
|
import Email from './Email';
|
||||||
|
import Webhook from './Webhook';
|
||||||
|
import WeixinApp from './WeixinApp';
|
||||||
|
import WeixinCorp from './WeixinCorp';
|
||||||
|
|
||||||
const Doc = () => {
|
export default defineComponent({
|
||||||
return <DingTalk />;
|
name: 'Doc',
|
||||||
};
|
props: {
|
||||||
export default Doc;
|
docData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const docMap = {
|
||||||
|
weixin: {
|
||||||
|
corpMessage: <WeixinCorp />,
|
||||||
|
officialMessage: <WeixinApp />,
|
||||||
|
},
|
||||||
|
dingTalk: {
|
||||||
|
dingTalkMessage: <DingTalk />,
|
||||||
|
dingTalkRobotWebHook: <DingTalkRebot />,
|
||||||
|
},
|
||||||
|
voice: {
|
||||||
|
aliyun: <AliyunVoice />,
|
||||||
|
},
|
||||||
|
sms: {
|
||||||
|
aliyunSms: <AliyunSms />,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
embedded: <Email />,
|
||||||
|
},
|
||||||
|
webhook: {
|
||||||
|
http: <Webhook />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
docMap?.[props.docData.type]?.[props.docData.provider]
|
||||||
|
)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -268,7 +268,7 @@
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12" :push="2">
|
<a-col :span="12" :push="2">
|
||||||
<Doc />
|
<Doc :docData="formData" />
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
@ -320,6 +320,7 @@ const formData = ref<ConfigFormData>({
|
||||||
provider: 'dingTalkMessage',
|
provider: 'dingTalkMessage',
|
||||||
type: 'dingTalk',
|
type: 'dingTalk',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 根据通知方式展示对应的字段
|
// 根据通知方式展示对应的字段
|
||||||
watch(
|
watch(
|
||||||
() => formData.value.type,
|
() => formData.value.type,
|
||||||
|
@ -408,9 +409,9 @@ watch(
|
||||||
|
|
||||||
const getDetail = async () => {
|
const getDetail = async () => {
|
||||||
const res = await configApi.detail(route.params.id as string);
|
const res = await configApi.detail(route.params.id as string);
|
||||||
console.log('res: ', res);
|
// console.log('res: ', res);
|
||||||
formData.value = res.result;
|
formData.value = res.result;
|
||||||
console.log('formData.value: ', formData.value);
|
// console.log('formData.value: ', formData.value);
|
||||||
};
|
};
|
||||||
getDetail();
|
getDetail();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const AliyunSms = () => {
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<div class="url">
|
||||||
|
阿里云短信服务平台:
|
||||||
|
<a
|
||||||
|
href="https://dysms.console.aliyun.com"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
https://dysms.console.aliyun.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
使用阿里云短信时需先在阿里云短信服务平台创建短信模板。
|
||||||
|
</div>
|
||||||
|
<h1>2.模板配置说明</h1>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2> 1、绑定配置</h2>
|
||||||
|
<div> 使用固定的通知配置发送此通知模板</div>
|
||||||
|
<h2> 2、模板</h2>
|
||||||
|
<div> 阿里云短信平台自定义的模板名称</div>
|
||||||
|
<h2> 3、收信人</h2>
|
||||||
|
<div>
|
||||||
|
{' '}
|
||||||
|
当前仅支持国内手机号,此处若不填,则在模板调试和配置告警通知时手动填写
|
||||||
|
</div>
|
||||||
|
<h2> 4、签名</h2>
|
||||||
|
<div> 用于短信内容签名信息显示,需在阿里云短信进行配置。</div>
|
||||||
|
<h2> 5、变量属性</h2>
|
||||||
|
<div>
|
||||||
|
需要在当前页面手动设置与阿里云短信模板中一样的变量,否则会导致发送异常。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default AliyunSms;
|
|
@ -0,0 +1,43 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const AliyunVoice = () => {
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<div class="url">
|
||||||
|
阿里云语音服务平台:
|
||||||
|
<a href="https://account.console.aliyun.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
https://account.console.aliyun.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
使用阿里云语音时需先在阿里云语音服务平台创建语音模板。
|
||||||
|
</div>
|
||||||
|
<h1>2.模板配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2>1、绑定配置</h2>
|
||||||
|
<div> 使用固定的通知配置发送此通知模板</div>
|
||||||
|
<h2>2、类型</h2>
|
||||||
|
<div> 阿里云语音通知类型,当类型为验证码类型时可配置变量。</div>
|
||||||
|
<h2> 3、模板ID</h2>
|
||||||
|
<div> 阿里云语音对每一条语音通知分配的唯一ID标识</div>
|
||||||
|
<h2> 4、被叫号码</h2>
|
||||||
|
<div> 当前仅支持国内手机号,此处若不填,则在模板调试和配置告警通知时手动填写。</div>
|
||||||
|
<div>若您使用的语音通知文件为公共模式外呼,则该参数值不填。</div>
|
||||||
|
<div>若您使用的语音通知文件为专属模式外呼,则必须传入已购买的号码,仅支持一个号码。</div>
|
||||||
|
<h2> 5、被叫显号</h2>
|
||||||
|
<div> 用户呼叫号码显示,必须是在阿里云购买的号码。</div>
|
||||||
|
<h2> 6、播放次数</h2>
|
||||||
|
<div> 最多可播放3次</div>
|
||||||
|
<h2> 7、模板内容</h2>
|
||||||
|
<div>
|
||||||
|
仅当通知类型为验证码类型时可进行配置,变量标识需要阿里云模板中的标识一致,支持填写带变量的动态模板。
|
||||||
|
变量填写规范示例:${'{name}'}
|
||||||
|
。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知是填写。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default AliyunVoice;
|
|
@ -0,0 +1,54 @@
|
||||||
|
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const DingTalk = () => {
|
||||||
|
const agentId = getImage('/notice/doc/template/dingTalk-message/01-Agentid.jpg');
|
||||||
|
// const userId = getImage('/notice/doc/template/dingTalk-message/02-user-id.jpg');
|
||||||
|
// const dept = getImage('/notice/doc/template/dingTalk-message/03-dept.jpg');
|
||||||
|
const a = '{name}';
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<div class="url">
|
||||||
|
钉钉开放平台:
|
||||||
|
<a href="https://open-dev.dingtalk.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
https://open-dev.dingtalk.com
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
钉钉管理后台:
|
||||||
|
<a href="https://www.dingtalk.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
https://www.dingtalk.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
<div>使用钉钉消息通知时需在钉钉开放平台中创建好对应的应用</div>
|
||||||
|
</div>
|
||||||
|
<h1> 2.模板配置说明</h1>
|
||||||
|
<h2> 1、绑定配置</h2>
|
||||||
|
<div> 使用固定的通知配置发送此通知模板</div>
|
||||||
|
<h2> 2、Agentid</h2>
|
||||||
|
<div> 应用唯一标识</div>
|
||||||
|
<div> 获取路径:“钉钉开放平台”--“应用开发”--“查看应用”</div>
|
||||||
|
<div class="image">
|
||||||
|
<Image width="100%" src={agentId} />
|
||||||
|
</div>
|
||||||
|
<h2> 3、收信人、收信部门</h2>
|
||||||
|
<div>若不填写收信人,则在模板调试和配置告警通知时手动填写。</div>
|
||||||
|
{/*<div> 收信人ID获取路径:“钉钉管理后台”--“通讯录”--“查看用户”</div>*/}
|
||||||
|
{/*<div> 收信部门ID获取路径:“钉钉管理后台”--“通讯录”--“编辑部门”</div>*/}
|
||||||
|
{/*<div class="image">*/}
|
||||||
|
{/* <Image width="100%" src={userId} />*/}
|
||||||
|
{/* <Image width="100%" src={dept} />*/}
|
||||||
|
{/*</div>*/}
|
||||||
|
<h2> 4、模板内容</h2>
|
||||||
|
<div>
|
||||||
|
支持填写带变量的动态模板。变量填写规范示例:${a}
|
||||||
|
。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default DingTalk;
|
|
@ -0,0 +1,35 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const DingTalkRebot = () => {
|
||||||
|
const b = '{name}';
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<div class="url">
|
||||||
|
钉钉开放平台:
|
||||||
|
<a href="https://open-dev.dingtalk.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
https://open-dev.dingtalk.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
使用钉钉群机器人消息通知时需在钉钉开放平台中创建好对应的机器人,再到钉钉客户端在对应的群中绑定智能机器人。
|
||||||
|
</div>
|
||||||
|
<h1>2.模板配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2> 1、绑定配置</h2>
|
||||||
|
<div> 使用固定的通知配置发送此通知模板</div>
|
||||||
|
<h2> 2、消息类型</h2>
|
||||||
|
<div> 目前支持text、markdown、link3种。</div>
|
||||||
|
<h2> 3、模板内容</h2>
|
||||||
|
<div>
|
||||||
|
支持填写带变量的动态模板。变量填写规范示例:${b}
|
||||||
|
。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default DingTalkRebot;
|
|
@ -0,0 +1,30 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const Email = () => {
|
||||||
|
const a = '{标题}';
|
||||||
|
const b = '{name}';
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
服务器地址支持自定义输入。
|
||||||
|
</div>
|
||||||
|
<h1>2.模板配置说明</h1>
|
||||||
|
<div>
|
||||||
|
{/* <h2> 1、服务器地址</h2>
|
||||||
|
<div>服务器地址支持自定义输入</div> */}
|
||||||
|
<h2> 1、标题</h2>
|
||||||
|
<div>支持输入变量,变量格式${a}</div>
|
||||||
|
<h2> 2、收件人</h2>
|
||||||
|
<div> 支持录入多个邮箱地址,可填写变量参数。</div>
|
||||||
|
<h2> 3、模板内容</h2>
|
||||||
|
<div>
|
||||||
|
支持填写带变量的动态模板。变量填写规范示例:${b}
|
||||||
|
。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Email;
|
|
@ -0,0 +1,18 @@
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const Webhook = () => {
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
</div>
|
||||||
|
<h1>2.模板配置说明</h1>
|
||||||
|
<div>
|
||||||
|
1、请求体 请求体中的数据来自于发送通知时指定的所有变量,也可通过自定义的方式进行变量配置。
|
||||||
|
使用webhook通知时,系统会将该事件通过您指定的URL地址,以POST方式发送。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Webhook;
|
|
@ -0,0 +1,58 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const WeixinApp = () => {
|
||||||
|
const appId = getImage('/notice/doc/template/weixin-official/02-mini-Program-Appid.png');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<div class="url">
|
||||||
|
企业微信管理后台:
|
||||||
|
<a href="https://work.weixin.qq.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
https://work.weixin.qq.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
</div>
|
||||||
|
<h1>2.模板配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2>1、绑定配置</h2>
|
||||||
|
<div>使用固定的通知配置发送此通知模板</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>2、用户标签</h2>
|
||||||
|
<div>以标签的维度通知该标签下所有用户</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>3、消息模板</h2>
|
||||||
|
<div>微信公众号中配置的消息模板</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>4、模板跳转链接</h2>
|
||||||
|
<div>点击消息之后进行页面跳转</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>5、跳转小程序Appid</h2>
|
||||||
|
<div>点击消息之后打开对应的小程序</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>6、跳转小程序具体路径</h2>
|
||||||
|
<div>点击消息之后跳转到小程序的具体页面</div>
|
||||||
|
<div class="image">
|
||||||
|
<Image width="100%" src={appId} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>7、模板内容</h2>
|
||||||
|
<div>
|
||||||
|
支持填写带变量的动态模板。变量填写规范示例:${name}
|
||||||
|
。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default WeixinApp;
|
|
@ -0,0 +1,48 @@
|
||||||
|
import './index.less';
|
||||||
|
import { Image } from 'ant-design-vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
|
||||||
|
const WeixinCorp = () => {
|
||||||
|
const agentId = getImage('/notice/doc/template/weixin-corp/01-Agentid.jpg');
|
||||||
|
const userId = getImage('/notice/doc/template/weixin-corp/02-userID.jpg');
|
||||||
|
const toDept = getImage('/notice/doc/template/weixin-corp/03-toDept.jpg');
|
||||||
|
const toTags = getImage('/notice/doc/template/weixin-corp/04-toTags.jpg');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="doc">
|
||||||
|
<div class="url">
|
||||||
|
企业微信管理后台:
|
||||||
|
<a href="https://work.weixin.qq.com" target="_blank" rel="noopener noreferrer">
|
||||||
|
https://work.weixin.qq.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>1. 概述</h1>
|
||||||
|
<div>
|
||||||
|
通知模板结合通知配置为告警消息通知提供支撑。通知模板只能调用同一类型的通知配置服务。
|
||||||
|
</div>
|
||||||
|
<h1>2.模版配置说明</h1>
|
||||||
|
<div>
|
||||||
|
<h2> 1、绑定配置</h2>
|
||||||
|
<div> 使用固定的通知配置发送此通知模板</div>
|
||||||
|
<h2> 2、Agentid</h2>
|
||||||
|
<div> 应用唯一标识</div>
|
||||||
|
<div> 获取路径:“企业微信”管理后台--“应用管理”--“应用”--“查看应用”</div>
|
||||||
|
<div class="image">
|
||||||
|
<Image width="100%" src={agentId} />
|
||||||
|
</div>
|
||||||
|
<h2> 3、收信人ID、收信部门ID、标签推送</h2>
|
||||||
|
<div>
|
||||||
|
接收通知的3种方式,3个字段若在此页面都没有填写,则在模板调试和配置告警通知时需要手动填写
|
||||||
|
</div>
|
||||||
|
<div> 收信人ID获取路径:【通讯录】-{'>'}【成员信息】查看成员账号</div>
|
||||||
|
<div> 收信组织ID获取路径:【通讯录】-{'>'}【部门信息】查看部门ID</div>
|
||||||
|
<div class="image">
|
||||||
|
<Image width="100%" src={userId} />
|
||||||
|
<Image width="100%" src={toDept} />
|
||||||
|
<Image width="100%" src={toTags} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default WeixinCorp;
|
|
@ -0,0 +1,39 @@
|
||||||
|
.doc {
|
||||||
|
height: 750px;
|
||||||
|
padding: 24px;
|
||||||
|
overflow-y: auto;
|
||||||
|
color: rgba(#000, 0.8);
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
|
||||||
|
.url {
|
||||||
|
padding: 8px 16px;
|
||||||
|
color: #2f54eb;
|
||||||
|
background-color: rgba(#a7bdf7, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 16px 0;
|
||||||
|
color: rgba(#000, 0.85);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 6px 0;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
import DingTalk from './DingTalk';
|
||||||
|
import DingTalkRebot from './DingTalkRebot';
|
||||||
|
import AliyunSms from './AliyunSms';
|
||||||
|
import AliyunVoice from './AliyunVoice';
|
||||||
|
import Email from './Email';
|
||||||
|
import Webhook from './Webhook';
|
||||||
|
import WeixinApp from './WeixinApp';
|
||||||
|
import WeixinCorp from './WeixinCorp';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Doc',
|
||||||
|
props: {
|
||||||
|
docData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const docMap = {
|
||||||
|
weixin: {
|
||||||
|
corpMessage: <WeixinCorp />,
|
||||||
|
officialMessage: <WeixinApp />,
|
||||||
|
},
|
||||||
|
dingTalk: {
|
||||||
|
dingTalkMessage: <DingTalk />,
|
||||||
|
dingTalkRobotWebHook: <DingTalkRebot />,
|
||||||
|
},
|
||||||
|
voice: {
|
||||||
|
aliyun: <AliyunVoice />,
|
||||||
|
},
|
||||||
|
sms: {
|
||||||
|
aliyunSms: <AliyunSms />,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
embedded: <Email />,
|
||||||
|
},
|
||||||
|
webhook: {
|
||||||
|
http: <Webhook />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
docMap?.[props.docData.type]?.[props.docData.provider]
|
||||||
|
)
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,8 +1,433 @@
|
||||||
<!-- 通知模板详情 -->
|
<!-- 通知模板详情 -->
|
||||||
<template>
|
<template>
|
||||||
<div class="page-container">通知模板详情</div>
|
<div class="page-container">
|
||||||
|
<a-card>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="10">
|
||||||
|
<a-form layout="vertical">
|
||||||
|
<a-form-item
|
||||||
|
label="通知方式"
|
||||||
|
v-bind="validateInfos.type"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="formData.type"
|
||||||
|
placeholder="请选择通知方式"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="(item, index) in NOTICE_METHOD"
|
||||||
|
:key="index"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="名称" v-bind="validateInfos.name">
|
||||||
|
<a-input
|
||||||
|
v-model:value="formData.name"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="类型"
|
||||||
|
v-bind="validateInfos.provider"
|
||||||
|
v-if="formData.type !== 'email'"
|
||||||
|
>
|
||||||
|
<RadioCard
|
||||||
|
:options="msgType"
|
||||||
|
v-model="formData.provider"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 钉钉 -->
|
||||||
|
<template v-if="formData.type === 'dingTalk'">
|
||||||
|
<template
|
||||||
|
v-if="formData.provider === 'dingTalkMessage'"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
label="AppKey"
|
||||||
|
v-bind="
|
||||||
|
validateInfos['configuration.appKey']
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.appKey
|
||||||
|
"
|
||||||
|
placeholder="请输入AppKey"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="AppSecret"
|
||||||
|
v-bind="
|
||||||
|
validateInfos['configuration.appSecret']
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.appSecret
|
||||||
|
"
|
||||||
|
placeholder="请输入AppSecret"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
formData.provider === 'dingTalkRobotWebHook'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
label="webHook"
|
||||||
|
v-bind="validateInfos['configuration.url']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.url
|
||||||
|
"
|
||||||
|
placeholder="请输入webHook"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<!-- 微信 -->
|
||||||
|
<template v-if="formData.type === 'weixin'">
|
||||||
|
<a-form-item
|
||||||
|
label="corpId"
|
||||||
|
v-bind="validateInfos['configuration.corpId']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.corpId
|
||||||
|
"
|
||||||
|
placeholder="请输入corpId"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="corpSecret"
|
||||||
|
v-bind="
|
||||||
|
validateInfos['configuration.corpSecret']
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.corpSecret
|
||||||
|
"
|
||||||
|
placeholder="请输入corpSecret"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<!-- 邮件 -->
|
||||||
|
<template v-if="formData.type === 'email'">
|
||||||
|
<a-form-item
|
||||||
|
label="服务器地址"
|
||||||
|
v-bind="validateInfos['configuration.host']"
|
||||||
|
>
|
||||||
|
<a-space>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.host
|
||||||
|
"
|
||||||
|
placeholder="请输入服务器地址"
|
||||||
|
/>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.port
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<a-checkbox
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.ssl
|
||||||
|
"
|
||||||
|
>
|
||||||
|
开启SSL
|
||||||
|
</a-checkbox>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="发件人"
|
||||||
|
v-bind="validateInfos['configuration.sender']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.sender
|
||||||
|
"
|
||||||
|
placeholder="请输入发件人"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="用户名"
|
||||||
|
v-bind="validateInfos['configuration.username']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.username
|
||||||
|
"
|
||||||
|
placeholder="请输入用户名"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="密码"
|
||||||
|
v-bind="validateInfos['configuration.password']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.password
|
||||||
|
"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<!-- 语音/短信 -->
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
formData.type === 'voice' ||
|
||||||
|
formData.type === 'sms'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
label="AccessKeyId"
|
||||||
|
v-bind="
|
||||||
|
validateInfos['configuration.accessKeyId']
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.accessKeyId
|
||||||
|
"
|
||||||
|
placeholder="请输入AccessKeyId"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label="Secret"
|
||||||
|
v-bind="validateInfos['configuration.secret']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.secret
|
||||||
|
"
|
||||||
|
placeholder="Secret"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<!-- webhook -->
|
||||||
|
<template v-if="formData.type === 'webhook'">
|
||||||
|
<a-form-item
|
||||||
|
label="Webhook"
|
||||||
|
v-bind="validateInfos['configuration.url']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="formData.configuration.url"
|
||||||
|
placeholder="请输入Webhook"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="请求头">
|
||||||
|
<!-- <EditTable
|
||||||
|
v-model:headers="
|
||||||
|
formData.configuration.headers
|
||||||
|
"
|
||||||
|
/> -->
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<a-form-item label="说明">
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="formData.description"
|
||||||
|
show-count
|
||||||
|
:maxlength="200"
|
||||||
|
:rows="5"
|
||||||
|
placeholder="请输入说明"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :wrapper-col="{ offset: 0, span: 3 }">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleSubmit"
|
||||||
|
:loading="btnLoading"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12" :push="2">
|
||||||
|
<Doc :docData="formData" />
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
import { Form } from 'ant-design-vue';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { TemplateFormData } from '../types';
|
||||||
|
import {
|
||||||
|
NOTICE_METHOD,
|
||||||
|
CONFIG_FIELD_MAP,
|
||||||
|
MSG_TYPE,
|
||||||
|
} from '@/views/notice/const';
|
||||||
|
// import EditTable from './components/EditTable.vue';
|
||||||
|
import configApi from '@/api/notice/config';
|
||||||
|
import Doc from './doc/index';
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const useForm = Form.useForm;
|
||||||
|
|
||||||
|
// 消息类型
|
||||||
|
const msgType = ref([
|
||||||
|
{
|
||||||
|
label: '钉钉消息',
|
||||||
|
value: 'dingTalkMessage',
|
||||||
|
logo: getImage('/notice/dingtalk.png'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '群机器人消息',
|
||||||
|
value: 'dingTalkRobotWebHook',
|
||||||
|
logo: getImage('/notice/dingTalk-rebot.png'),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref<TemplateFormData>({
|
||||||
|
description: '',
|
||||||
|
name: '',
|
||||||
|
provider: '',
|
||||||
|
type: NOTICE_METHOD[2].value,
|
||||||
|
template: {
|
||||||
|
subject: '',
|
||||||
|
sendTo: [],
|
||||||
|
attachments: [],
|
||||||
|
message: '',
|
||||||
|
text: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 根据通知方式展示对应的字段
|
||||||
|
watch(
|
||||||
|
() => formData.value.type,
|
||||||
|
(val) => {
|
||||||
|
formData.value.configuration = CONFIG_FIELD_MAP[val];
|
||||||
|
msgType.value = MSG_TYPE[val];
|
||||||
|
|
||||||
|
formData.value.provider = msgType.value[0].value;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 验证规则
|
||||||
|
const formRules = ref({
|
||||||
|
type: [{ required: true, message: '请选择通知方式' }],
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请输入名称' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
provider: [{ required: true, message: '请选择类型' }],
|
||||||
|
// 钉钉
|
||||||
|
'configuration.appKey': [
|
||||||
|
{ required: true, message: '请输入AppKey' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
'configuration.appSecret': [
|
||||||
|
{ required: true, message: '请输入AppSecret' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
// 'configuration.url': [{ required: true, message: '请输入WebHook' }],
|
||||||
|
// 微信
|
||||||
|
'configuration.corpId': [
|
||||||
|
{ required: true, message: '请输入corpId' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
'configuration.corpSecret': [
|
||||||
|
{ required: true, message: '请输入corpSecret' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
// 阿里云语音/短信
|
||||||
|
'configuration.regionId': [
|
||||||
|
{ required: true, message: '请输入RegionId' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
'configuration.accessKeyId': [
|
||||||
|
{ required: true, message: '请输入AccessKeyId' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
'configuration.secret': [
|
||||||
|
{ required: true, message: '请输入Secret' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
// 邮件
|
||||||
|
'configuration.host': [{ required: true, message: '请输入服务器地址' }],
|
||||||
|
'configuration.sender': [{ required: true, message: '请输入发件人' }],
|
||||||
|
'configuration.username': [
|
||||||
|
{ required: true, message: '请输入用户名' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
'configuration.password': [
|
||||||
|
{ required: true, message: '请输入密码' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
// webhook
|
||||||
|
'configuration.url': [
|
||||||
|
{ required: true, message: '请输入Webhook' },
|
||||||
|
{
|
||||||
|
pattern:
|
||||||
|
/^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/,
|
||||||
|
message: 'Webhook需要是一个合法的URL',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: [{ max: 200, message: '最多可输入200个字符' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const { resetFields, validate, validateInfos, clearValidate } = useForm(
|
||||||
|
formData.value,
|
||||||
|
formRules.value,
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => formData.value.type,
|
||||||
|
() => {
|
||||||
|
clearValidate();
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const getDetail = async () => {
|
||||||
|
const res = await configApi.detail(route.params.id as string);
|
||||||
|
// console.log('res: ', res);
|
||||||
|
formData.value = res.result;
|
||||||
|
// console.log('formData.value: ', formData.value);
|
||||||
|
};
|
||||||
|
getDetail();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单提交
|
||||||
|
*/
|
||||||
|
const btnLoading = ref<boolean>(false);
|
||||||
|
const handleSubmit = () => {
|
||||||
|
validate()
|
||||||
|
.then(async () => {
|
||||||
|
// console.log('formData.value: ', formData.value);
|
||||||
|
btnLoading.value = true;
|
||||||
|
let res;
|
||||||
|
if (!formData.value.id) {
|
||||||
|
res = await configApi.save(formData.value);
|
||||||
|
} else {
|
||||||
|
res = await configApi.update(formData.value);
|
||||||
|
}
|
||||||
|
// console.log('res: ', res);
|
||||||
|
if (res?.success) {
|
||||||
|
message.success('保存成功');
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
btnLoading.value = false;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log('err: ', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.page-container {
|
||||||
|
background: #f0f2f5;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
export interface IHeaders {
|
||||||
|
id?: number;
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAttachments {
|
||||||
|
location: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
interface IVariableDefinitions {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
format: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TemplateFormData = {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
provider: string;
|
||||||
|
description: string;
|
||||||
|
id?: string;
|
||||||
|
creatorId?: string;
|
||||||
|
createTime?: number;
|
||||||
|
configId?: string;
|
||||||
|
template: {
|
||||||
|
// 钉钉消息
|
||||||
|
agentId?: string;
|
||||||
|
message?: string;
|
||||||
|
// 钉钉机器人
|
||||||
|
messageType?: string;
|
||||||
|
markdown?: {
|
||||||
|
text: string;
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
link?: {
|
||||||
|
title: string;
|
||||||
|
picUrl: string;
|
||||||
|
messageUrl: string;
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
|
// 微信
|
||||||
|
agentId?: string;
|
||||||
|
// message?: string;
|
||||||
|
toParty?: string;
|
||||||
|
toUser?: string;
|
||||||
|
toTag?: string;
|
||||||
|
// 邮件
|
||||||
|
subject?: string;
|
||||||
|
sendTo?: string[];
|
||||||
|
attachments?: IAttachments[];
|
||||||
|
// message?: string;
|
||||||
|
text?: string;
|
||||||
|
// 语音
|
||||||
|
templateType?: string;
|
||||||
|
templateCode?: string;
|
||||||
|
ttsCode?: string;
|
||||||
|
// message?: string;
|
||||||
|
playTimes?: number;
|
||||||
|
calledShowNumbers?: string;
|
||||||
|
calledNumber?: string;
|
||||||
|
// 短信
|
||||||
|
code?: string;
|
||||||
|
// message?: string;
|
||||||
|
phoneNumber?: string;
|
||||||
|
signName?: string;
|
||||||
|
// webhook
|
||||||
|
contextAsBody?: boolean;
|
||||||
|
body?: string;
|
||||||
|
};
|
||||||
|
variableDefinitions: IVariableDefinitions[];
|
||||||
|
|
||||||
|
};
|
|
@ -124,3 +124,71 @@ export const CONFIG_FIELD_MAP = {
|
||||||
headers: [],
|
headers: [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 模板
|
||||||
|
export const TEMPLATE_FIELD_MAP = {
|
||||||
|
dingTalk: {
|
||||||
|
dingTalkMessage: {
|
||||||
|
agentId: '',
|
||||||
|
message: '',
|
||||||
|
},
|
||||||
|
dingTalkRobotWebHook: {
|
||||||
|
message: '',
|
||||||
|
messageType: '',
|
||||||
|
markdown: {
|
||||||
|
text: '',
|
||||||
|
title: '',
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
title: '',
|
||||||
|
picUrl: '',
|
||||||
|
messageUrl: '',
|
||||||
|
text: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
weixin: {
|
||||||
|
corpMessage: {
|
||||||
|
agentId: '',
|
||||||
|
message: '',
|
||||||
|
toParty: '',
|
||||||
|
toUser: '',
|
||||||
|
toTag: '',
|
||||||
|
},
|
||||||
|
officialMessage: {},
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
embedded: {
|
||||||
|
subject: '',
|
||||||
|
sendTo: [],
|
||||||
|
attachments: [],
|
||||||
|
message: '',
|
||||||
|
text: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
voice: {
|
||||||
|
aliyun: {
|
||||||
|
templateType: '',
|
||||||
|
templateCode: '',
|
||||||
|
ttsCode: '',
|
||||||
|
message: '',
|
||||||
|
playTimes: undefined,
|
||||||
|
calledShowNumbers: '',
|
||||||
|
calledNumber: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sms: {
|
||||||
|
aliyunSms: {
|
||||||
|
code: '',
|
||||||
|
message: '',
|
||||||
|
phoneNumber: '',
|
||||||
|
signName: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
webhook: {
|
||||||
|
http: {
|
||||||
|
contextAsBody: false,
|
||||||
|
body: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
import type { Rule } from 'ant-design-vue/es/form';
|
||||||
|
|
||||||
|
/**基本信息表单 */
|
||||||
|
export interface formValueType {
|
||||||
|
title: string; // 系统名称
|
||||||
|
headerTheme: string; // 主题色
|
||||||
|
apiKey: string; // 高德 API key
|
||||||
|
'base-path': string; // 系统后台访问的URL
|
||||||
|
logo:string,
|
||||||
|
ico:string,
|
||||||
|
backgroud:string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface formType {
|
||||||
|
formValue: formValueType,
|
||||||
|
rulesFrom: Record<string, Rule[]>
|
||||||
|
logoLoading: boolean,
|
||||||
|
backLoading: boolean,
|
||||||
|
iconLoading: boolean,
|
||||||
|
saveLoading: boolean,
|
||||||
|
clickSave?: Function,
|
||||||
|
getDetails: Function
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片上传表单
|
||||||
|
*/
|
||||||
|
export interface uploaderType {
|
||||||
|
imageTypes: Array<string>;
|
||||||
|
iconTypes: Array<string>,
|
||||||
|
beforeLogoUpload: (file: UploadProps['beforeUpload']) => void
|
||||||
|
handleChangeLogo: (info: UploadChangeParam) => void
|
||||||
|
beforeBackUpload: (file: UploadProps['beforeUpload']) => void
|
||||||
|
changeBackUpload: (info: UploadChangeParam) => void
|
||||||
|
beforeIconUpload: (file: UploadProps['beforeUpload']) => void
|
||||||
|
changeIconUpload: (info: UploadChangeParam) => void
|
||||||
|
}
|
|
@ -0,0 +1,627 @@
|
||||||
|
<template>
|
||||||
|
<a-card class="basis-container">
|
||||||
|
<a-form
|
||||||
|
layout="vertical"
|
||||||
|
ref="formBasicRef"
|
||||||
|
:rules="rulesFrom"
|
||||||
|
:model="formValue"
|
||||||
|
>
|
||||||
|
<a-row :span="24" :gutter="24">
|
||||||
|
<a-col :span="10">
|
||||||
|
<a-form-item label="系统名称" name="title">
|
||||||
|
<a-input
|
||||||
|
v-model:value="formValue.title"
|
||||||
|
:maxlength="64"
|
||||||
|
placeholder="请输入系统名称"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="主题色" name="headerTheme">
|
||||||
|
<a-select v-model:value="formValue.headerTheme">
|
||||||
|
<a-select-option value="light"
|
||||||
|
>白色</a-select-option
|
||||||
|
>
|
||||||
|
<a-select-option value="dark">黑色</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<template #label>
|
||||||
|
<span>高德API Key</span>
|
||||||
|
<a-tooltip title="配置后平台可调用高德地图GIS服务">
|
||||||
|
<img
|
||||||
|
class="img-style"
|
||||||
|
:src="getImage('/init-home/mark.png')"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="formValue.apiKey"
|
||||||
|
placeholder="请输入高德API Key"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item name="'base-path'">
|
||||||
|
<template #label>
|
||||||
|
<span>base-path</span>
|
||||||
|
<a-tooltip title="系统后台访问的url">
|
||||||
|
<img
|
||||||
|
class="img-style"
|
||||||
|
:src="getImage('/init-home/mark.png')"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="formValue['base-path']"
|
||||||
|
placeholder="请输入高德API Key"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-row :gutter="24" :span="24">
|
||||||
|
<a-col>
|
||||||
|
<a-form-item label="系统logo">
|
||||||
|
<div class="upload-image-warp-logo">
|
||||||
|
<div class="upload-image-border-logo">
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
:action="action"
|
||||||
|
:headers="headers"
|
||||||
|
:showUploadList="false"
|
||||||
|
:beforeUpload="
|
||||||
|
uploader.beforeLogoUpload
|
||||||
|
"
|
||||||
|
@change="uploader.handleChangeLogo"
|
||||||
|
:accept="
|
||||||
|
uploader.imageTypes.toString()
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="upload-image-content-logo"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="loading-logo"
|
||||||
|
v-if="form.logoLoading"
|
||||||
|
>
|
||||||
|
<LoadingOutlined
|
||||||
|
style="font-size: 28px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="upload-image"
|
||||||
|
style="height: 100%"
|
||||||
|
v-if="formValue.logo"
|
||||||
|
:style="
|
||||||
|
formValue.logo
|
||||||
|
? `background-image: url(${formValue.logo});`
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
v-if="formValue.logo"
|
||||||
|
class="upload-image-mask"
|
||||||
|
>
|
||||||
|
点击修改
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div
|
||||||
|
v-if="form.logoLoading"
|
||||||
|
>
|
||||||
|
<LoadingOutlined
|
||||||
|
style="
|
||||||
|
font-size: 28px;
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<PlusOutlined
|
||||||
|
style="
|
||||||
|
font-size: 28px;
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
<div v-if="form.logoLoading">
|
||||||
|
<div class="upload-loading-mask">
|
||||||
|
<LoadingOutlined
|
||||||
|
style="font-size: 28px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="upload-tips">推荐尺寸200*200</div>
|
||||||
|
<div class="upload-tips">支持jpg,png</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col>
|
||||||
|
<a-form-item>
|
||||||
|
<template #label>
|
||||||
|
<span>浏览器页签</span>
|
||||||
|
<a-tooltip
|
||||||
|
title="浏览器tab页中显示的图片元素"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="img-style"
|
||||||
|
:src="
|
||||||
|
getImage('/init-home/mark.png')
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<div class="upload-image-warp-logo">
|
||||||
|
<div class="upload-image-border-logo">
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
:action="action"
|
||||||
|
:headers="headers"
|
||||||
|
:showUploadList="false"
|
||||||
|
:beforeUpload="
|
||||||
|
uploader.beforeIconUpload
|
||||||
|
"
|
||||||
|
@change="uploader.changeIconUpload"
|
||||||
|
:accept="
|
||||||
|
uploader.imageTypes.toString()
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="upload-image-content-logo"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="form.iconLoading"
|
||||||
|
class="loading-icon"
|
||||||
|
>
|
||||||
|
<LoadingOutlined
|
||||||
|
style="font-size: 28px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="upload-image-icon"
|
||||||
|
v-if="formValue.ico"
|
||||||
|
:style="
|
||||||
|
formValue.ico
|
||||||
|
? `background-image: url(${formValue.ico});`
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
v-if="formValue.ico"
|
||||||
|
class="upload-image-mask"
|
||||||
|
>
|
||||||
|
点击修改
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div>
|
||||||
|
<PlusOutlined
|
||||||
|
style="
|
||||||
|
font-size: 28px;
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="upload-tips">推荐尺寸64*64</div>
|
||||||
|
<div class="upload-tips">支持icon格式</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="14">
|
||||||
|
<a-form-item label="登录背景图">
|
||||||
|
<div class="upload-image-warp-back">
|
||||||
|
<div class="upload-image-border-back">
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
:action="action"
|
||||||
|
:headers="headers"
|
||||||
|
:beforeUpload="uploader.beforeBackUpload"
|
||||||
|
:showUploadList="false"
|
||||||
|
@change="uploader.changeBackUpload"
|
||||||
|
:accept="uploader.imageTypes.toString()"
|
||||||
|
>
|
||||||
|
<div class="upload-image-content-back">
|
||||||
|
<div
|
||||||
|
v-if="form.backLoading"
|
||||||
|
class="loading-back"
|
||||||
|
>
|
||||||
|
<LoadingOutlined
|
||||||
|
style="font-size: 28px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="upload-image"
|
||||||
|
v-if="formValue.backgroud"
|
||||||
|
:style="
|
||||||
|
formValue.backgroud
|
||||||
|
? `background-image: url(${formValue.backgroud});`
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
v-if="formValue.backgroud"
|
||||||
|
class="upload-image-mask"
|
||||||
|
>
|
||||||
|
点击修改
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div>
|
||||||
|
<PlusOutlined
|
||||||
|
style="font-size: 28px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="upload-tips">
|
||||||
|
支持4M以内的图片:支持jpg、png
|
||||||
|
</div>
|
||||||
|
<div class="upload-tips">建议尺寸1400x1080</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="form.clickSave"
|
||||||
|
:disabled="
|
||||||
|
form.saveLoading ||
|
||||||
|
form.logoLoading ||
|
||||||
|
form.iconLoading ||
|
||||||
|
form.backLoading
|
||||||
|
"
|
||||||
|
>保存</a-button
|
||||||
|
>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="Basis">
|
||||||
|
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { formType, uploaderType } from './index';
|
||||||
|
import { getImage } from '@/utils/comm.ts';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
|
||||||
|
import { LocalStore } from '@/utils/comm';
|
||||||
|
|
||||||
|
import { save_api, getDetails_api } from '@/api/system/basis';
|
||||||
|
import { usePermissionStore } from '@/store/permission';
|
||||||
|
|
||||||
|
const action = ref<string>(`${BASE_API_PATH}/file/static`);
|
||||||
|
const headers = ref({ [TOKEN_KEY]: LocalStore.get(TOKEN_KEY) });
|
||||||
|
const formBasicRef = ref();
|
||||||
|
const form = reactive<formType>({
|
||||||
|
formValue: {
|
||||||
|
title: '',
|
||||||
|
headerTheme: 'light',
|
||||||
|
apiKey: '',
|
||||||
|
'base-path': `${window.location.origin}/api`,
|
||||||
|
logo: '/public/logo.png',
|
||||||
|
ico: '/public/favicon.ico',
|
||||||
|
backgroud: '/public/images/login.png',
|
||||||
|
},
|
||||||
|
rulesFrom: {
|
||||||
|
title: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择本地地址',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headerTheme: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择主题色',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'base-path': [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入base-path',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
logoLoading: false, // logo加载状态
|
||||||
|
backLoading: false, // 背景图加载状态
|
||||||
|
iconLoading: false, // 页签加载状态
|
||||||
|
saveLoading: false,
|
||||||
|
getDetails: () => {
|
||||||
|
const params = ['front', 'amap', 'paths'];
|
||||||
|
getDetails_api(params).then((resp: any) => {
|
||||||
|
console.log(resp);
|
||||||
|
|
||||||
|
const basis = resp.result?.filter(
|
||||||
|
(item: any) => item.scope === 'front',
|
||||||
|
);
|
||||||
|
const api = resp.result?.filter(
|
||||||
|
(item: any) => item.scope === 'amap',
|
||||||
|
);
|
||||||
|
const basePath = resp.result?.filter(
|
||||||
|
(item: any) => item.scope === 'paths',
|
||||||
|
);
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
form.formValue = {
|
||||||
|
...basis[0].properties,
|
||||||
|
apiKey: api[0].properties.apiKey,
|
||||||
|
'base-path': basePath[0].properties['base-path'],
|
||||||
|
logo: form.formValue.logo || '/public/logo.png',
|
||||||
|
ico: form.formValue.ico || '/public/favicon.ico',
|
||||||
|
backgroud:
|
||||||
|
form.formValue.backgroud || '/public/images/login.png',
|
||||||
|
};
|
||||||
|
// localStorage.setItem(
|
||||||
|
// SystemConst.AMAP_KEY,
|
||||||
|
// api[0].properties.apiKey,
|
||||||
|
// );
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clickSave: () => {
|
||||||
|
const hasPermission = usePermissionStore().hasPermission;
|
||||||
|
if(hasPermission(`system/Basis:update`) ){
|
||||||
|
formBasicRef.value.validate().then(() => {
|
||||||
|
form.saveLoading = true;
|
||||||
|
const params = [
|
||||||
|
{
|
||||||
|
scope: 'front',
|
||||||
|
properties: {
|
||||||
|
...form.formValue,
|
||||||
|
apiKey: '',
|
||||||
|
'base-path': '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scope: 'amap',
|
||||||
|
properties: {
|
||||||
|
apiKey: form.formValue.apiKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scope: 'paths',
|
||||||
|
properties: {
|
||||||
|
'base-path': form.formValue['base-path'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
save_api(params)
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
message.success('保存成功');
|
||||||
|
form.getDetails();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => (form.saveLoading = false));
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
message.warning('暂无权限,请联系管理员');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { formValue, rulesFrom } = toRefs(form);
|
||||||
|
|
||||||
|
const uploader: uploaderType = {
|
||||||
|
imageTypes: ['image/jpeg', 'image/png'],
|
||||||
|
iconTypes: ['image/x-icon'],
|
||||||
|
// logo格式校验
|
||||||
|
beforeLogoUpload: (file) => {
|
||||||
|
const isType = uploader.imageTypes.includes(file.type);
|
||||||
|
if (!isType) {
|
||||||
|
message.error(`请上传.jpg.png.jfif.pjp.pjpeg.jpeg格式的图片`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isSize = file.size / 1024 / 1024 < 4;
|
||||||
|
if (!isSize) {
|
||||||
|
message.error(`图片大小必须小于${4}M`);
|
||||||
|
}
|
||||||
|
return isType && isSize;
|
||||||
|
},
|
||||||
|
// logo上传改变事件
|
||||||
|
handleChangeLogo: (info) => {
|
||||||
|
if (info.file.status === 'uploading') {
|
||||||
|
form.logoLoading = true;
|
||||||
|
} else if (info.file.status === 'done') {
|
||||||
|
info.file.url = info.file.response?.result;
|
||||||
|
form.logoLoading = false;
|
||||||
|
form.formValue.logo = info.file.response?.result;
|
||||||
|
} else if (info.file.status === 'error') {
|
||||||
|
console.log(info.file);
|
||||||
|
form.logoLoading = false;
|
||||||
|
message.error('系统logo上传失败,请稍后再试');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 背景图片上传之前
|
||||||
|
beforeBackUpload: (file) => {
|
||||||
|
const isType = uploader.imageTypes.includes(file.type);
|
||||||
|
if (!isType) {
|
||||||
|
message.error(`请上传.jpg.png.jfif.pjp.pjpeg.jpeg格式的图片`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isSize = file.size / 1024 / 1024 < 4;
|
||||||
|
if (!isSize) {
|
||||||
|
message.error(`图片大小必须小于${4}M`);
|
||||||
|
}
|
||||||
|
return isType && isSize;
|
||||||
|
},
|
||||||
|
// 背景图片发生改变
|
||||||
|
changeBackUpload: (info) => {
|
||||||
|
if (info.file.status === 'uploading') {
|
||||||
|
form.backLoading = true;
|
||||||
|
} else if (info.file.status === 'done') {
|
||||||
|
console.log(info);
|
||||||
|
|
||||||
|
info.file.url = info.file.response?.result;
|
||||||
|
form.backLoading = false;
|
||||||
|
form.formValue.backgroud = info.file.response?.result;
|
||||||
|
} else if (info.file.status === 'error') {
|
||||||
|
console.log(info.file);
|
||||||
|
form.logoLoading = false;
|
||||||
|
message.error('背景图上传失败,请稍后再试');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 上传之前
|
||||||
|
beforeIconUpload: (file) => {
|
||||||
|
const isType = uploader.iconTypes.includes(file.type);
|
||||||
|
if (!isType) {
|
||||||
|
message.error(`请上传ico格式的图片`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isSize = file.size / 1024 / 1024 < 1;
|
||||||
|
if (!isSize) {
|
||||||
|
message.error(`图片大小必须小于${1}M`);
|
||||||
|
}
|
||||||
|
return isType && isSize;
|
||||||
|
},
|
||||||
|
// 图标发生改变
|
||||||
|
changeIconUpload: (info) => {
|
||||||
|
if (info.file.status === 'uploading') {
|
||||||
|
form.iconLoading = true;
|
||||||
|
} else if (info.file.status === 'done') {
|
||||||
|
info.file.url = info.file.response?.result;
|
||||||
|
form.iconLoading = true;
|
||||||
|
form.formValue.ico = info.file.response?.result;
|
||||||
|
} else if (info.file.status === 'error') {
|
||||||
|
console.log(info.file);
|
||||||
|
form.logoLoading = false;
|
||||||
|
message.error('浏览器页签上传失败,请稍后再试');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
form.getDetails();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.basis-container {
|
||||||
|
.img-style {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.upload-image-warp-logo {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
.upload-image-border-logo {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
transition: all 0.3s;
|
||||||
|
width: 160px;
|
||||||
|
height: 150px;
|
||||||
|
&:hover {
|
||||||
|
border: 1px dashed #1890ff;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.upload-image-content-logo {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 160px;
|
||||||
|
height: 150px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.06);
|
||||||
|
cursor: pointer;
|
||||||
|
.loading-logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
.loading-icon {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-image-icon {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50%;
|
||||||
|
background-size: inherit;
|
||||||
|
}
|
||||||
|
.upload-image-mask {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.35);
|
||||||
|
}
|
||||||
|
&:hover .upload-image-mask {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.upload-image-warp-back {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
.upload-image-border-back {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
transition: all 0.3s;
|
||||||
|
width: 570px;
|
||||||
|
height: 415px;
|
||||||
|
&:hover {
|
||||||
|
border: 1px dashed #1890ff;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.upload-image-content-back {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 570px;
|
||||||
|
height: 415px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.06);
|
||||||
|
cursor: pointer;
|
||||||
|
.loading-back {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.upload-image-mask {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.35);
|
||||||
|
}
|
||||||
|
&:hover .upload-image-mask {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.upload-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50%;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
.upload-tips {
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5715;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
72
yarn.lock
72
yarn.lock
|
@ -796,6 +796,11 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/webxr" "*"
|
"@types/webxr" "*"
|
||||||
|
|
||||||
|
"@types/web-bluetooth@^0.0.16":
|
||||||
|
version "0.0.16"
|
||||||
|
resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz"
|
||||||
|
integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
|
||||||
|
|
||||||
"@types/webxr@*":
|
"@types/webxr@*":
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
resolved "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.0.tgz"
|
resolved "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.0.tgz"
|
||||||
|
@ -1003,6 +1008,28 @@
|
||||||
three "0.143.0"
|
three "0.143.0"
|
||||||
uppercamelcase "^1.1.0"
|
uppercamelcase "^1.1.0"
|
||||||
|
|
||||||
|
"@vueuse/core@^9.10.0":
|
||||||
|
version "9.10.0"
|
||||||
|
resolved "https://registry.npmjs.org/@vueuse/core/-/core-9.10.0.tgz#2ef6e55ca773c5b2db1e3f13b8292af96dd32214"
|
||||||
|
integrity sha512-CxMewME07qeuzuT/AOIQGv0EhhDoojniqU6pC3F8m5VC76L47UT18DcX88kWlP3I7d3qMJ4u/PD8iSRsy3bmNA==
|
||||||
|
dependencies:
|
||||||
|
"@types/web-bluetooth" "^0.0.16"
|
||||||
|
"@vueuse/metadata" "9.10.0"
|
||||||
|
"@vueuse/shared" "9.10.0"
|
||||||
|
vue-demi "*"
|
||||||
|
|
||||||
|
"@vueuse/metadata@9.10.0":
|
||||||
|
version "9.10.0"
|
||||||
|
resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.10.0.tgz"
|
||||||
|
integrity sha512-G5VZhgTCapzU9rv0Iq2HBrVOSGzOKb+OE668NxhXNcTjUjwYxULkEhAw70FtRLMZc+hxcFAzDZlKYA0xcwNMuw==
|
||||||
|
|
||||||
|
"@vueuse/shared@9.10.0":
|
||||||
|
version "9.10.0"
|
||||||
|
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-9.10.0.tgz"
|
||||||
|
integrity sha512-vakHJ2ZRklAzqmcVBL38RS7BxdBA4+5poG9NsSyqJxrt9kz0zX3P5CXMy0Hm6LFbZXUgvKdqAS3pUH1zX/5qTQ==
|
||||||
|
dependencies:
|
||||||
|
vue-demi "*"
|
||||||
|
|
||||||
JSONStream@^1.0.4:
|
JSONStream@^1.0.4:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz"
|
resolved "https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz"
|
||||||
|
@ -2030,7 +2057,7 @@ entities@^2.0.0:
|
||||||
|
|
||||||
entities@~2.1.0:
|
entities@~2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmmirror.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
|
resolved "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz"
|
||||||
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
|
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
|
||||||
|
|
||||||
errno@^0.1.1:
|
errno@^0.1.1:
|
||||||
|
@ -2115,6 +2142,11 @@ esutils@^2.0.2:
|
||||||
resolved "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz"
|
resolved "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz"
|
||||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||||
|
|
||||||
|
event-source-polyfill@^1.0.31:
|
||||||
|
version "1.0.31"
|
||||||
|
resolved "https://registry.npmmirror.com/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz#45fb0a6fc1375b2ba597361ba4287ffec5bf2e0c"
|
||||||
|
integrity sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==
|
||||||
|
|
||||||
execa@^0.7.0:
|
execa@^0.7.0:
|
||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.npmmirror.com/execa/-/execa-0.7.0.tgz"
|
resolved "https://registry.npmmirror.com/execa/-/execa-0.7.0.tgz"
|
||||||
|
@ -2505,7 +2537,7 @@ header-case@^2.0.4:
|
||||||
|
|
||||||
highlight.js@^11.3.1:
|
highlight.js@^11.3.1:
|
||||||
version "11.7.0"
|
version "11.7.0"
|
||||||
resolved "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
|
resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz"
|
||||||
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
|
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
|
||||||
|
|
||||||
homedir-polyfill@^1.0.0:
|
homedir-polyfill@^1.0.0:
|
||||||
|
@ -3013,7 +3045,7 @@ lines-and-columns@^1.1.6:
|
||||||
|
|
||||||
linkify-it@^3.0.1:
|
linkify-it@^3.0.1:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.npmmirror.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e"
|
resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz"
|
||||||
integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==
|
integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
uc.micro "^1.0.1"
|
uc.micro "^1.0.1"
|
||||||
|
@ -3095,7 +3127,7 @@ lodash.camelcase@^4.3.0:
|
||||||
|
|
||||||
lodash.flow@^3.5.0:
|
lodash.flow@^3.5.0:
|
||||||
version "3.5.0"
|
version "3.5.0"
|
||||||
resolved "https://registry.npmmirror.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
|
resolved "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz"
|
||||||
integrity sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==
|
integrity sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==
|
||||||
|
|
||||||
lodash.isfunction@^3.0.9:
|
lodash.isfunction@^3.0.9:
|
||||||
|
@ -3262,32 +3294,32 @@ map-obj@^4.0.0:
|
||||||
|
|
||||||
markdown-it-abbr@^1.0.4:
|
markdown-it-abbr@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz#d66b5364521cbb3dd8aa59dadfba2fb6865c8fd8"
|
resolved "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz"
|
||||||
integrity sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg==
|
integrity sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg==
|
||||||
|
|
||||||
markdown-it-anchor@^8.4.1:
|
markdown-it-anchor@^8.4.1:
|
||||||
version "8.6.6"
|
version "8.6.6"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-anchor/-/markdown-it-anchor-8.6.6.tgz#4a12e358c9c2167ee28cb7a5f10e29d6f1ffd7ca"
|
resolved "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.6.tgz"
|
||||||
integrity sha512-jRW30YGywD2ESXDc+l17AiritL0uVaSnWsb26f+68qaW9zgbIIr1f4v2Nsvc0+s0Z2N3uX6t/yAw7BwCQ1wMsA==
|
integrity sha512-jRW30YGywD2ESXDc+l17AiritL0uVaSnWsb26f+68qaW9zgbIIr1f4v2Nsvc0+s0Z2N3uX6t/yAw7BwCQ1wMsA==
|
||||||
|
|
||||||
markdown-it-deflist@^2.1.0:
|
markdown-it-deflist@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz#50d7a56b9544cd81252f7623bd785e28a8dcef5c"
|
resolved "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz"
|
||||||
integrity sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg==
|
integrity sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg==
|
||||||
|
|
||||||
markdown-it-emoji@^2.0.0:
|
markdown-it-emoji@^2.0.0:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz#cd42421c2fda1537d9cc12b9923f5c8aeb9029c8"
|
resolved "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz"
|
||||||
integrity sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ==
|
integrity sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ==
|
||||||
|
|
||||||
markdown-it-footnote@^3.0.3:
|
markdown-it-footnote@^3.0.3:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz#e0e4c0d67390a4c5f0c75f73be605c7c190ca4d8"
|
resolved "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz"
|
||||||
integrity sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w==
|
integrity sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w==
|
||||||
|
|
||||||
markdown-it-highlightjs@^3.6.0:
|
markdown-it-highlightjs@^3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-highlightjs/-/markdown-it-highlightjs-3.6.0.tgz#b567408c633d71e5e4cc33e1d0121a44447d2f29"
|
resolved "https://registry.npmjs.org/markdown-it-highlightjs/-/markdown-it-highlightjs-3.6.0.tgz"
|
||||||
integrity sha512-ex+Lq3cVkprh0GpGwFyc53A/rqY6GGzopPCG1xMsf8Ya3XtGC8Uw9tChN1rWbpyDae7tBBhVHVcMM29h4Btamw==
|
integrity sha512-ex+Lq3cVkprh0GpGwFyc53A/rqY6GGzopPCG1xMsf8Ya3XtGC8Uw9tChN1rWbpyDae7tBBhVHVcMM29h4Btamw==
|
||||||
dependencies:
|
dependencies:
|
||||||
highlight.js "^11.3.1"
|
highlight.js "^11.3.1"
|
||||||
|
@ -3295,37 +3327,37 @@ markdown-it-highlightjs@^3.6.0:
|
||||||
|
|
||||||
markdown-it-ins@^3.0.1:
|
markdown-it-ins@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-ins/-/markdown-it-ins-3.0.1.tgz#c09356b917cf1dbf73add0b275d67ab8c73d4b4d"
|
resolved "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.1.tgz"
|
||||||
integrity sha512-32SSfZqSzqyAmmQ4SHvhxbFqSzPDqsZgMHDwxqPzp+v+t8RsmqsBZRG+RfRQskJko9PfKC2/oxyOs4Yg/CfiRw==
|
integrity sha512-32SSfZqSzqyAmmQ4SHvhxbFqSzPDqsZgMHDwxqPzp+v+t8RsmqsBZRG+RfRQskJko9PfKC2/oxyOs4Yg/CfiRw==
|
||||||
|
|
||||||
markdown-it-mark@^3.0.1:
|
markdown-it-mark@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz#51257db58787d78aaf46dc13418d99a9f3f0ebd3"
|
resolved "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz"
|
||||||
integrity sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==
|
integrity sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==
|
||||||
|
|
||||||
markdown-it-sub@^1.0.0:
|
markdown-it-sub@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz#375fd6026eae7ddcb012497f6411195ea1e3afe8"
|
resolved "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz"
|
||||||
integrity sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==
|
integrity sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==
|
||||||
|
|
||||||
markdown-it-sup@^1.0.0:
|
markdown-it-sup@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz#cb9c9ff91a5255ac08f3fd3d63286e15df0a1fc3"
|
resolved "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz"
|
||||||
integrity sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==
|
integrity sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==
|
||||||
|
|
||||||
markdown-it-task-lists@^2.1.1:
|
markdown-it-task-lists@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz#f68f4d2ac2bad5a2c373ba93081a1a6848417088"
|
resolved "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz"
|
||||||
integrity sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==
|
integrity sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==
|
||||||
|
|
||||||
markdown-it-toc-done-right@^4.2.0:
|
markdown-it-toc-done-right@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.2.0.tgz#3ccdce22d5022ffae7b991d07261b1b1de5459d0"
|
resolved "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.2.0.tgz"
|
||||||
integrity sha512-UB/IbzjWazwTlNAX0pvWNlJS8NKsOQ4syrXZQ/C72j+jirrsjVRT627lCaylrKJFBQWfRsPmIVQie8x38DEhAQ==
|
integrity sha512-UB/IbzjWazwTlNAX0pvWNlJS8NKsOQ4syrXZQ/C72j+jirrsjVRT627lCaylrKJFBQWfRsPmIVQie8x38DEhAQ==
|
||||||
|
|
||||||
markdown-it@^12.3.2:
|
markdown-it@^12.3.2:
|
||||||
version "12.3.2"
|
version "12.3.2"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90"
|
resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz"
|
||||||
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
|
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse "^2.0.1"
|
argparse "^2.0.1"
|
||||||
|
@ -3336,7 +3368,7 @@ markdown-it@^12.3.2:
|
||||||
|
|
||||||
mdurl@^1.0.1:
|
mdurl@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.npmmirror.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz"
|
||||||
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
|
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
|
||||||
|
|
||||||
meow@^8.0.0:
|
meow@^8.0.0:
|
||||||
|
@ -4761,7 +4793,7 @@ typescript@^4.6.4, typescript@^4.9.3:
|
||||||
|
|
||||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.npmmirror.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
|
resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz"
|
||||||
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
|
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
|
||||||
|
|
||||||
ufo@^1.0.0:
|
ufo@^1.0.0:
|
||||||
|
@ -5077,7 +5109,7 @@ vue-types@^3.0.0:
|
||||||
|
|
||||||
vue3-markdown-it@^1.0.10:
|
vue3-markdown-it@^1.0.10:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.npmmirror.com/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz#c4b0e94990b3f9d66123ef5b775cd7ea177c609b"
|
resolved "https://registry.npmjs.org/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz"
|
||||||
integrity sha512-mTvHu0zl7jrh7ojgaZ+tTpCLiS4CVg4bTgTu4KGhw/cRRY5YgIG8QgFAPu6kCzSW6Znc9a52Beb6hFvF4hSMkQ==
|
integrity sha512-mTvHu0zl7jrh7ojgaZ+tTpCLiS4CVg4bTgTu4KGhw/cRRY5YgIG8QgFAPu6kCzSW6Znc9a52Beb6hFvF4hSMkQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
markdown-it "^12.3.2"
|
markdown-it "^12.3.2"
|
||||||
|
|
Loading…
Reference in New Issue