├── .gitignore ├── README.md ├── babel.config.js ├── build └── icons │ ├── 1024x1024.png │ ├── 128x128.png │ ├── 16x16.png │ ├── 24x24.png │ ├── 256x256.png │ ├── 32x32.png │ ├── 48x48.png │ ├── 512x512.png │ ├── 64x64.png │ ├── icon.icns │ └── icon.ico ├── jsconfig.json ├── package-lock.json ├── package.json ├── preload.js ├── public ├── favicon.ico └── index.html ├── src ├── app.vue ├── assets │ ├── font │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ ├── logo.png │ └── logo.svg ├── background.js ├── components │ └── icon │ │ └── index.vue ├── config │ ├── axios.js │ └── router.js ├── hook │ ├── index.js │ ├── useDate.js │ └── usePagingSearch.js ├── layout │ └── index.vue ├── main.js ├── service │ ├── black-box.js │ ├── dashboard.js │ └── index.js ├── theme │ ├── index.less │ ├── style.less │ └── variable.less └── view │ ├── batch-verification │ └── index.vue │ ├── black-box-detail │ └── index.vue │ ├── black-box │ ├── black-box-form-dialog │ │ ├── content.vue │ │ └── index.vue │ ├── index.vue │ └── userBlackBoxSearch.js │ ├── collect-information │ └── index.vue │ ├── dashboard │ └── index.vue │ ├── setting │ └── index.vue │ └── white-box-audit │ └── index.vue └── vue.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | #Electron-builder output 26 | /dist_electron -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QingScan 2 | 一个批量漏洞挖掘工具,黏合各种好用的扫描器。 3 | 4 | ## 介绍 5 | 6 | QingScan 是一款聚合扫描器,本身不生产安全扫描功能,但会作为一个安全扫描工具的搬运工; 当添加一个目标后,QingScan会自动调用各种扫描器对目标进行扫描,并将扫描结果录入到QingScan平台中进行聚合展示 7 | 8 | - GitHub:https://github.com/78778443/QingScan 9 | - 码云地址:https://gitee.com/songboy/QingScan 10 | - 详细文档:http://wiki.qingscan.songboy.site 11 | - 哔哩哔哩:https://space.bilibili.com/437273065 12 | - 官网地址:http://qingscan.songboy.site/ 13 | - 桌面版:https://github.com/78778443/QingScanDesk 14 | 15 | ## 界面预览 16 | 17 | df7318509490d5c88b9a3e22a5f3718 18 | 19 | 20 | ## 安装部署 21 | 22 | ### 安装依赖 23 | ``` 24 | npm install 25 | ``` 26 | 27 | ### Compiles and hot-reloads for development 28 | ``` 29 | npm run serve 30 | ``` 31 | 32 | ### Compiles and minifies for production 33 | ``` 34 | npm run build 35 | ``` 36 | 37 | ### Lints and fixes files 38 | ``` 39 | npm run lint 40 | ``` 41 | 42 | ### Customize configuration 43 | See [Configuration Reference](https://cli.vuejs.org/config/). 44 | 45 | 46 | ## 靶场系统 47 | 48 | 您在安装之后请不要对未获得足够授权的目标进行扫描,同时为了让你能够快速上手,我们搭建了一些靶场系统授权你进行安全扫描: 49 | 1. http://txy8g.songboy.site:8888/home/index.php 轻松渗透测试系统测试 50 | 51 | 52 | 53 | ## 联系我们 54 | 55 | 在使用过程中有任何问题,可以通过微信、钉钉、QQ 联系我们 56 | 57 | ![微信交流群](https://user-images.githubusercontent.com/8509054/148176355-a4ad75ee-0dd9-401e-8663-30f36ea86479.png) 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /build/icons/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/1024x1024.png -------------------------------------------------------------------------------- /build/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/128x128.png -------------------------------------------------------------------------------- /build/icons/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/16x16.png -------------------------------------------------------------------------------- /build/icons/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/24x24.png -------------------------------------------------------------------------------- /build/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/256x256.png -------------------------------------------------------------------------------- /build/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/32x32.png -------------------------------------------------------------------------------- /build/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/48x48.png -------------------------------------------------------------------------------- /build/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/512x512.png -------------------------------------------------------------------------------- /build/icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/64x64.png -------------------------------------------------------------------------------- /build/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/icon.icns -------------------------------------------------------------------------------- /build/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/build/icons/icon.ico -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"], 6 | "ajax": ["src/config/ajax.js"] 7 | } 8 | }, 9 | "exclude": ["dist", "node_modules"], 10 | "include": ["src/**/*"] 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qing-scan-desk", 3 | "version": "0.1.0", 4 | "private": true, 5 | "author": "ferqx", 6 | "scripts": { 7 | "serve": "vue-cli-service serve", 8 | "build": "vue-cli-service build", 9 | "lint": "vue-cli-service lint", 10 | "electron:build": "vue-cli-service electron:build", 11 | "electron:serve": "vue-cli-service electron:serve", 12 | "postinstall": "electron-builder install-app-deps", 13 | "postuninstall": "electron-builder install-app-deps", 14 | "electron:generate-icons": "electron-icon-builder --input=./public/favicon.ico --output=build --flatten" 15 | }, 16 | "main": "background.js", 17 | "dependencies": { 18 | "ant-design-vue": "^3.0.0-beta.6", 19 | "axios": "^0.24.0", 20 | "core-js": "^3.6.5", 21 | "normalize.css": "^8.0.1", 22 | "vue": "^3.2.26", 23 | "vue-router": "^4.0.12" 24 | }, 25 | "devDependencies": { 26 | "@vue/cli-plugin-babel": "~4.5.0", 27 | "@vue/cli-plugin-eslint": "~4.5.0", 28 | "@vue/cli-service": "~4.5.0", 29 | "@vue/compiler-sfc": "^3.0.0", 30 | "babel-eslint": "^10.1.0", 31 | "electron": "^16.0.6", 32 | "electron-devtools-installer": "^3.1.0", 33 | "electron-icon-builder": "^2.0.1", 34 | "eslint": "^6.7.2", 35 | "eslint-plugin-vue": "^7.0.0", 36 | "less": "^2.7.3", 37 | "less-loader": "^6.2.0", 38 | "vue-cli-plugin-electron-builder": "~2.1.1" 39 | }, 40 | "eslintConfig": { 41 | "root": true, 42 | "env": { 43 | "node": true 44 | }, 45 | "extends": [ 46 | "plugin:vue/vue3-essential", 47 | "eslint:recommended" 48 | ], 49 | "parserOptions": { 50 | "parser": "babel-eslint" 51 | }, 52 | "rules": {} 53 | }, 54 | "browserslist": [ 55 | "> 1%", 56 | "last 2 versions", 57 | "not dead" 58 | ], 59 | "license": "MIT" 60 | } 61 | -------------------------------------------------------------------------------- /preload.js: -------------------------------------------------------------------------------- 1 | // preload.js 2 | 3 | // All of the Node.js APIs are available in the preload process. 4 | // It has the same sandbox as a Chrome extension. 5 | window.addEventListener('DOMContentLoaded', () => { 6 | const replaceText = (selector, text) => { 7 | const element = document.getElementById(selector); 8 | if (element) element.innerText = text; 9 | }; 10 | 11 | for (const dependency of ['chrome', 'node', 'electron']) { 12 | replaceText(`${dependency}-version`, process.versions[dependency]); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | QingScan 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/app.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 15 | -------------------------------------------------------------------------------- /src/assets/font/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /src/assets/font/demo_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | iconfont Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 36 | 37 | 38 |
39 |

40 | 41 | 42 |

43 | 53 |
54 |
55 |
    56 | 57 |
  • 58 | 59 |
    主页
    60 |
    
    61 |
  • 62 | 63 |
  • 64 | 65 |
    扫描
    66 |
    
    67 |
  • 68 | 69 |
  • 70 | 71 |
    系统
    72 |
    
    73 |
  • 74 | 75 |
  • 76 | 77 |
    数据收集
    78 |
    
    79 |
  • 80 | 81 |
  • 82 | 83 |
    风控审计
    84 |
    
    85 |
  • 86 | 87 |
88 |
89 |

Unicode 引用

90 |
91 | 92 |

Unicode 是字体在网页端最原始的应用方式,特点是:

93 |
    94 |
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • 95 |
  • 默认情况下不支持多色,直接添加多色图标会自动去色。
  • 96 |
97 |
98 |

注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)

99 |
100 |

Unicode 使用步骤如下:

101 |

第一步:拷贝项目下面生成的 @font-face

102 |
@font-face {
104 |   font-family: 'iconfont';
105 |   src: url('iconfont.woff2?t=1641634162220') format('woff2'),
106 |        url('iconfont.woff?t=1641634162220') format('woff'),
107 |        url('iconfont.ttf?t=1641634162220') format('truetype'),
108 |        url('iconfont.svg?t=1641634162220#iconfont') format('svg');
109 | }
110 | 
111 |

第二步:定义使用 iconfont 的样式

112 |
.iconfont {
114 |   font-family: "iconfont" !important;
115 |   font-size: 16px;
116 |   font-style: normal;
117 |   -webkit-font-smoothing: antialiased;
118 |   -moz-osx-font-smoothing: grayscale;
119 | }
120 | 
121 |

第三步:挑选相应图标并获取字体编码,应用于页面

122 |
123 | <span class="iconfont">&#x33;</span>
125 | 
126 |
127 |

"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

128 |
129 |
130 |
131 |
132 |
    133 | 134 |
  • 135 | 136 |
    137 | 主页 138 |
    139 |
    .icon-zhuye 140 |
    141 |
  • 142 | 143 |
  • 144 | 145 |
    146 | 扫描 147 |
    148 |
    .icon-saomiao 149 |
    150 |
  • 151 | 152 |
  • 153 | 154 |
    155 | 系统 156 |
    157 |
    .icon-xitong 158 |
    159 |
  • 160 | 161 |
  • 162 | 163 |
    164 | 数据收集 165 |
    166 |
    .icon-shujushouji 167 |
    168 |
  • 169 | 170 |
  • 171 | 172 |
    173 | 风控审计 174 |
    175 |
    .icon-fengkongshenji 176 |
    177 |
  • 178 | 179 |
180 |
181 |

font-class 引用

182 |
183 | 184 |

font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。

185 |

与 Unicode 使用方式相比,具有如下特点:

186 |
    187 |
  • 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  • 188 |
  • 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
  • 189 |
190 |

使用步骤如下:

191 |

第一步:引入项目下面生成的 fontclass 代码:

192 |
<link rel="stylesheet" href="./iconfont.css">
193 | 
194 |

第二步:挑选相应图标并获取类名,应用于页面:

195 |
<span class="iconfont icon-xxx"></span>
196 | 
197 |
198 |

" 199 | iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

200 |
201 |
202 |
203 |
204 |
    205 | 206 |
  • 207 | 210 |
    主页
    211 |
    #icon-zhuye
    212 |
  • 213 | 214 |
  • 215 | 218 |
    扫描
    219 |
    #icon-saomiao
    220 |
  • 221 | 222 |
  • 223 | 226 |
    系统
    227 |
    #icon-xitong
    228 |
  • 229 | 230 |
  • 231 | 234 |
    数据收集
    235 |
    #icon-shujushouji
    236 |
  • 237 | 238 |
  • 239 | 242 |
    风控审计
    243 |
    #icon-fengkongshenji
    244 |
  • 245 | 246 |
247 |
248 |

Symbol 引用

249 |
250 | 251 |

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 252 | 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

253 |
    254 |
  • 支持多色图标了,不再受单色限制。
  • 255 |
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • 256 |
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • 257 |
  • 浏览器渲染 SVG 的性能一般,还不如 png。
  • 258 |
259 |

使用步骤如下:

260 |

第一步:引入项目下面生成的 symbol 代码:

261 |
<script src="./iconfont.js"></script>
262 | 
263 |

第二步:加入通用 CSS 代码(引入一次就行):

264 |
<style>
265 | .icon {
266 |   width: 1em;
267 |   height: 1em;
268 |   vertical-align: -0.15em;
269 |   fill: currentColor;
270 |   overflow: hidden;
271 | }
272 | </style>
273 | 
274 |

第三步:挑选相应图标并获取类名,应用于页面:

275 |
<svg class="icon" aria-hidden="true">
276 |   <use xlink:href="#icon-xxx"></use>
277 | </svg>
278 | 
279 |
280 |
281 | 282 |
283 |
284 | 303 | 304 | 305 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; /* Project id 3126540 */ 3 | src: url('iconfont.woff2?t=1641634162220') format('woff2'), 4 | url('iconfont.woff?t=1641634162220') format('woff'), 5 | url('iconfont.ttf?t=1641634162220') format('truetype'), 6 | url('iconfont.svg?t=1641634162220#iconfont') format('svg'); 7 | } 8 | 9 | .iconfont { 10 | font-family: "iconfont" !important; 11 | font-size: 16px; 12 | font-style: normal; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | } 16 | 17 | .icon-zhuye:before { 18 | content: "\e61d"; 19 | } 20 | 21 | .icon-saomiao:before { 22 | content: "\e600"; 23 | } 24 | 25 | .icon-xitong:before { 26 | content: "\e615"; 27 | } 28 | 29 | .icon-shujushouji:before { 30 | content: "\e644"; 31 | } 32 | 33 | .icon-fengkongshenji:before { 34 | content: "\e68b"; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.js: -------------------------------------------------------------------------------- 1 | !function(e){var t,n,o,a,i,l='',C=(C=document.getElementsByTagName("script"))[C.length-1].getAttribute("data-injectcss"),L=function(e,t){t.parentNode.insertBefore(e,t)};if(C&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console&&console.log(e)}}function d(){i||(i=!0,o())}function c(){try{a.documentElement.doScroll("left")}catch(e){return void setTimeout(c,50)}d()}t=function(){var e,t;(t=document.createElement("div")).innerHTML=l,l=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",t=e,(e=document.body).firstChild?L(t,e.firstChild):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(o=t,a=e.document,i=!1,c(),a.onreadystatechange=function(){"complete"==a.readyState&&(a.onreadystatechange=null,d())})}(window); -------------------------------------------------------------------------------- /src/assets/font/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "3126540", 3 | "name": "QingScan", 4 | "font_family": "iconfont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "6429564", 10 | "name": "主页", 11 | "font_class": "zhuye", 12 | "unicode": "e61d", 13 | "unicode_decimal": 58909 14 | }, 15 | { 16 | "icon_id": "11569568", 17 | "name": "扫描", 18 | "font_class": "saomiao", 19 | "unicode": "e600", 20 | "unicode_decimal": 58880 21 | }, 22 | { 23 | "icon_id": "722465", 24 | "name": "系统", 25 | "font_class": "xitong", 26 | "unicode": "e615", 27 | "unicode_decimal": 58901 28 | }, 29 | { 30 | "icon_id": "25187236", 31 | "name": "数据收集", 32 | "font_class": "shujushouji", 33 | "unicode": "e644", 34 | "unicode_decimal": 58948 35 | }, 36 | { 37 | "icon_id": "25599982", 38 | "name": "风控审计", 39 | "font_class": "fengkongshenji", 40 | "unicode": "e68b", 41 | "unicode_decimal": 59019 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created by iconfont 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/src/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/src/assets/font/iconfont.woff -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/src/assets/font/iconfont.woff2 -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/78778443/QingScanDesk/f61e0dc82a10c7eb26e82279ecd9a2b046a66dab/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import path from 'path'; 4 | import { app, protocol, BrowserWindow } from 'electron'; 5 | import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'; 6 | import installExtension, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer'; 7 | const isDevelopment = process.env.NODE_ENV !== 'production'; 8 | 9 | // Scheme must be registered before the app is ready 10 | protocol.registerSchemesAsPrivileged([ 11 | { scheme: 'app', privileges: { secure: true, standard: true } }, 12 | ]); 13 | 14 | async function createWindow() { 15 | // Create the browser window. 16 | const win = new BrowserWindow({ 17 | width: 1000, 18 | height: 800, 19 | minWidth: 800, 20 | minHeight: 600, 21 | title: 'QingScan', 22 | icon: path.join(__dirname, 'icon.ioc'), 23 | webPreferences: { 24 | webPreferences: { webSecurity: false }, 25 | // Use pluginOptions.nodeIntegration, leave this alone 26 | // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info 27 | nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION, 28 | contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION, 29 | }, 30 | }); 31 | 32 | if (process.env.WEBPACK_DEV_SERVER_URL) { 33 | // Load the url of the dev server if in development mode 34 | await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL); 35 | if (!process.env.IS_TEST) win.webContents.openDevTools(); 36 | } else { 37 | createProtocol('app'); 38 | // Load the index.html when not in development 39 | win.loadURL('app://./index.html'); 40 | } 41 | } 42 | 43 | // Quit when all windows are closed. 44 | app.on('window-all-closed', () => { 45 | // On macOS it is common for applications and their menu bar 46 | // to stay active until the user quits explicitly with Cmd + Q 47 | if (process.platform !== 'darwin') { 48 | app.quit(); 49 | } 50 | }); 51 | 52 | app.on('activate', () => { 53 | // On macOS it's common to re-create a window in the app when the 54 | // dock icon is clicked and there are no other windows open. 55 | if (BrowserWindow.getAllWindows().length === 0) createWindow(); 56 | }); 57 | 58 | // This method will be called when Electron has finished 59 | // initialization and is ready to create browser windows. 60 | // Some APIs can only be used after this event occurs. 61 | app.on('ready', async () => { 62 | if (isDevelopment && !process.env.IS_TEST) { 63 | // Install Vue Devtools 64 | try { 65 | await installExtension(VUEJS3_DEVTOOLS); 66 | } catch (e) { 67 | console.error('Vue Devtools failed to install:', e.toString()); 68 | } 69 | } 70 | createWindow(); 71 | }); 72 | 73 | // Exit cleanly on request from parent process in development mode. 74 | if (isDevelopment) { 75 | if (process.platform === 'win32') { 76 | process.on('message', (data) => { 77 | if (data === 'graceful-exit') { 78 | app.quit(); 79 | } 80 | }); 81 | } else { 82 | process.on('SIGTERM', () => { 83 | app.quit(); 84 | }); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/components/icon/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 19 | -------------------------------------------------------------------------------- /src/config/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { message } from 'ant-design-vue'; 3 | 4 | const host = localStorage.getItem('host'); 5 | const token = localStorage.getItem('token'); 6 | // const isProduction = process.env.NODE_ENV === 'production'; 7 | 8 | axios.interceptors.request.use( 9 | function (config) { 10 | if (!/http/.test(config.url)) { 11 | // 优化双斜杠问题 12 | config.url = (host + `${config.url || ''}`) 13 | .replace(/\/\//g, '/') 14 | .replace('http:/', 'http://') 15 | .replace('https:/', 'https://'); 16 | } 17 | config.headers.token = token; 18 | 19 | return config; 20 | }, 21 | function (error) { 22 | return Promise.reject(error); 23 | } 24 | ); 25 | 26 | axios.interceptors.response.use( 27 | function (response) { 28 | return response.data; 29 | }, 30 | function (error) { 31 | message.warning(error.message); 32 | return Promise.reject(error); 33 | } 34 | ); 35 | 36 | export default axios; 37 | -------------------------------------------------------------------------------- /src/config/router.js: -------------------------------------------------------------------------------- 1 | import * as VueRouter from 'vue-router'; 2 | import Layout from '@/layout/index.vue'; 3 | import Dashboard from '@/view/dashboard/index.vue'; 4 | import BlackBox from '@/view/black-box/index.vue'; 5 | import BatchVerification from '@/view/batch-verification/index.vue'; 6 | import CollectInformation from '@/view/collect-information/index.vue'; 7 | import WhiteBoxAudit from '@/view/white-box-audit/index.vue'; 8 | import BlackBoxDetail from '@/view/black-box-detail/index.vue'; 9 | import Setting from '@/view/setting/index.vue'; 10 | 11 | const routes = [ 12 | { 13 | path: '/', 14 | component: Layout, 15 | redirect: '/dashboard', 16 | children: [ 17 | { 18 | path: '/dashboard', 19 | component: Dashboard, 20 | }, 21 | { 22 | path: '/blackBox', 23 | component: BlackBox, 24 | }, 25 | { 26 | path: '/blackBoxDetail/:id', 27 | component: BlackBoxDetail, 28 | }, 29 | { 30 | path: '/whiteBoxAudit', 31 | component: WhiteBoxAudit, 32 | }, 33 | { 34 | path: '/collectInformation', 35 | component: CollectInformation, 36 | }, 37 | { 38 | path: '/batchVerification', 39 | component: BatchVerification, 40 | }, 41 | { 42 | path: '/setting', 43 | component: Setting, 44 | }, 45 | ], 46 | }, 47 | ]; 48 | 49 | export const router = VueRouter.createRouter({ 50 | history: process.env.WEBPACK_DEV_SERVER_URL 51 | ? VueRouter.createWebHistory() 52 | : VueRouter.createWebHashHistory(), 53 | routes, // (缩写) 相当于 routes: routes 54 | }); 55 | -------------------------------------------------------------------------------- /src/hook/index.js: -------------------------------------------------------------------------------- 1 | export * from './usePagingSearch'; 2 | export * from './useDate'; 3 | 4 | -------------------------------------------------------------------------------- /src/hook/useDate.js: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs'; 2 | 3 | function useDate() { 4 | const dateFormat = (date, format) => { 5 | if (!date) { 6 | return ''; 7 | } 8 | if (!format) { 9 | format = 'YYYY-MM-DD HH:mm:ss'; 10 | } 11 | return dayjs(date).format(format); 12 | }; 13 | return Object.freeze({ dateFormat }); 14 | } 15 | 16 | export { useDate }; 17 | -------------------------------------------------------------------------------- /src/hook/usePagingSearch.js: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue'; 2 | import ajax from 'ajax'; 3 | 4 | /** 5 | * 分页搜索 6 | * @param {*} searchParams 7 | * @returns 8 | */ 9 | function usePagingSearch(url, options) { 10 | const defaultOptions = { 11 | size: options?.size || 10, 12 | method: (options?.method || 'get').toLocaleLowerCase(), 13 | }; 14 | 15 | const page = ref(1); 16 | const size = ref(defaultOptions.size); 17 | const total = ref(0); 18 | const loading = ref(false); 19 | 20 | const requestData = (params = {}) => { 21 | loading.value = true; 22 | 23 | params.page = page.value; 24 | params.size = size.value; 25 | 26 | let requestFn = null; 27 | 28 | if (defaultOptions.method === 'post') { 29 | requestFn = ajax.post.bind(null, url, { data: params }); 30 | } else { 31 | requestFn = ajax.get.bind(null, url, { params }); 32 | } 33 | 34 | return requestFn() 35 | .then((res) => { 36 | total.value = res.data.total; 37 | return res.data; 38 | }) 39 | .finally(() => { 40 | loading.value = false; 41 | }); 42 | }; 43 | return { 44 | requestData, 45 | page, 46 | size, 47 | total, 48 | loading, 49 | }; 50 | } 51 | export { usePagingSearch }; 52 | -------------------------------------------------------------------------------- /src/layout/index.vue: -------------------------------------------------------------------------------- 1 | 49 | 72 | 95 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import Antd from 'ant-design-vue'; 3 | import { router } from '@/config/router'; 4 | import App from './app.vue'; 5 | 6 | import './theme/index.less'; 7 | import './assets/font/iconfont'; 8 | 9 | createApp(App).use(Antd).use(router).mount('#app'); 10 | -------------------------------------------------------------------------------- /src/service/black-box.js: -------------------------------------------------------------------------------- 1 | import ajax from 'ajax'; 2 | 3 | export const DESK_APP_INDEX = '/desk_app/index'; 4 | 5 | export const DESK_APP_ADD = '/desk_app/_add'; 6 | 7 | export const DESK_APP_DETAILS = '/desk_app/details'; 8 | 9 | /** 10 | * 获取黑盒列表数据 11 | * @returns {Promise} 12 | */ 13 | export const requestBlackBoxData = () => { 14 | return ajax.get(DESK_APP_INDEX); 15 | }; 16 | 17 | /** 18 | * 添加黑盒测试目标 19 | * @returns {Promise} 20 | */ 21 | export const addBlackBoxApp = (data) => { 22 | return ajax.post(DESK_APP_ADD, data); 23 | }; 24 | 25 | /** 26 | * 获取黑盒详情 27 | * @param {*} id 28 | * @returns {Promise} 29 | */ 30 | export const requestBlackBoxDetail = (id) => { 31 | return ajax.get(DESK_APP_DETAILS, { params: { id } }).then((res) => res.data); 32 | }; 33 | -------------------------------------------------------------------------------- /src/service/dashboard.js: -------------------------------------------------------------------------------- 1 | import ajax from 'ajax'; 2 | 3 | export const DESK_INDEX_INDEX = '/desk_index/index'; 4 | 5 | /** 6 | * 获取仪表盘数据 7 | * @returns {Promise} 8 | */ 9 | export const getDashboardData = () => { 10 | return ajax.get(DESK_INDEX_INDEX); 11 | }; 12 | -------------------------------------------------------------------------------- /src/service/index.js: -------------------------------------------------------------------------------- 1 | export * from './dashboard'; 2 | export * from './black-box'; 3 | -------------------------------------------------------------------------------- /src/theme/index.less: -------------------------------------------------------------------------------- 1 | @import '~normalize.css/normalize.css'; 2 | @import '~ant-design-vue/dist/antd.less'; 3 | @import './variable.less'; 4 | @import './style.less'; 5 | -------------------------------------------------------------------------------- /src/theme/style.less: -------------------------------------------------------------------------------- 1 | .icon { 2 | width: 1em; 3 | height: 1em; 4 | fill: currentColor; 5 | overflow: hidden; 6 | } 7 | 8 | .page-content { 9 | padding: 16px; 10 | background-color: #fff; 11 | } 12 | 13 | .table-header-actions { 14 | margin-bottom: 10px; 15 | 16 | & > * { 17 | margin-right: 10px; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/theme/variable.less: -------------------------------------------------------------------------------- 1 | @primary-color: #1296db; // 全局主色 2 | @font-size-base: 14px; // 主字号 3 | @border-radius-base: 4px; // 组件/浮层圆角 4 | @layout-header-height: 50px; 5 | @layout-header-padding: 0 16px; 6 | -------------------------------------------------------------------------------- /src/view/batch-verification/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | -------------------------------------------------------------------------------- /src/view/black-box-detail/index.vue: -------------------------------------------------------------------------------- 1 | 256 | 801 | 809 | -------------------------------------------------------------------------------- /src/view/black-box/black-box-form-dialog/content.vue: -------------------------------------------------------------------------------- 1 | 35 | 84 | -------------------------------------------------------------------------------- /src/view/black-box/black-box-form-dialog/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 65 | -------------------------------------------------------------------------------- /src/view/black-box/index.vue: -------------------------------------------------------------------------------- 1 | 33 | 147 | -------------------------------------------------------------------------------- /src/view/black-box/userBlackBoxSearch.js: -------------------------------------------------------------------------------- 1 | import { usePagingSearch } from '@/hook'; 2 | import { DESK_APP_INDEX } from '@/service'; 3 | 4 | export function userBlackBoxSearch() { 5 | return { 6 | ...usePagingSearch(DESK_APP_INDEX), 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /src/view/collect-information/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | -------------------------------------------------------------------------------- /src/view/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 55 | 56 | 71 | -------------------------------------------------------------------------------- /src/view/setting/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 54 | -------------------------------------------------------------------------------- /src/view/white-box-audit/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const webpackConfig = { 4 | resolve: { 5 | alias: { 6 | '@': path.resolve(__dirname, 'src'), 7 | ajax: path.resolve(__dirname, `src/config/axios.js`), 8 | }, 9 | }, 10 | }; 11 | 12 | module.exports = { 13 | devServer: { 14 | // proxy: 'http://txy8g.songboy.site:8010/', 15 | }, 16 | css: { 17 | loaderOptions: { 18 | less: { 19 | lessOptions: { 20 | javascriptEnabled: true, 21 | }, 22 | }, 23 | }, 24 | }, 25 | configureWebpack: webpackConfig, 26 | }; 27 | --------------------------------------------------------------------------------