├── .gitignore ├── README.md ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── css │ │ ├── color.scss │ │ ├── index.scss │ │ ├── sidebar.scss │ │ └── variables.scss │ ├── icon │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ └── logo.png ├── components │ ├── Logo.vue │ ├── MyAside.vue │ ├── MyHeader.vue │ ├── Tags.vue │ ├── autoTable.vue │ ├── errorView.vue │ ├── index.js │ ├── result.vue │ └── tooltipOver.vue ├── element.js ├── index.js ├── main.js ├── router │ └── index.js ├── store │ ├── getters.js │ ├── index.js │ ├── modules │ │ ├── index.js │ │ ├── projectS.js │ │ ├── tags.js │ │ └── user.js │ └── state.js ├── util │ ├── ace-editor.js │ ├── api.js │ ├── axiosConfig.js │ └── common.js └── views │ ├── apiManage │ ├── components │ │ ├── apiEdit.vue │ │ ├── apiMsg.vue │ │ ├── apiSetList.vue │ │ └── importApi.vue │ └── index.vue │ ├── base.vue │ ├── buildInFunc │ ├── components │ │ ├── buildInFuncM.vue │ │ └── funcList.vue │ └── index.vue │ ├── caseManage │ ├── components │ │ ├── apiMsgDataEdit.vue │ │ ├── caseEdit.vue │ │ ├── caseM.vue │ │ ├── caseSetList.vue │ │ └── loadConfigView.vue │ └── index.vue │ ├── h5Page │ ├── components │ │ └── hello.vue │ └── index.vue │ ├── home │ ├── components │ │ └── home.vue │ └── index.vue │ ├── login │ ├── components │ │ └── login.vue │ └── index.vue │ ├── mockManage │ ├── components │ │ ├── mockEditView.vue │ │ └── mockM.vue │ └── index.vue │ ├── projectManage │ ├── components │ │ ├── editView.vue │ │ ├── projectM.vue │ │ └── urlTable.vue │ └── index.vue │ ├── reportManage │ ├── components │ │ └── reportM.vue │ └── index.vue │ ├── reportShow │ ├── components │ │ ├── reportHeader.vue │ │ └── reportShowM.vue │ └── index.vue │ ├── sceneConfig │ ├── components │ │ ├── configEdit.vue │ │ └── configM.vue │ └── index.vue │ ├── taskManage │ ├── components │ │ ├── editView.vue │ │ └── taskM.vue │ └── index.vue │ ├── testTool │ ├── components │ │ ├── fke.vue │ │ ├── testT.vue │ │ └── testToolM.vue │ └── index.vue │ └── userManage │ ├── components │ └── userM.vue │ └── index.vue ├── vue.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Environment 3 | 4 | 1. 首先安装 node 版本10-12即可; 确保 node -V 5 | 2. 安装 yarn 工具包 6 | 3. 命令都是在项目根目录下执行 7 | ``` 8 | npm install -g yarn 9 | 10 | 11 | ``` 12 | 13 | ## 安装依赖 14 | ``` 15 | yarn install 16 | ``` 17 | 18 | ## Develop 19 | yarn serve 20 | 21 | ## Build 22 | yarn build 23 | 24 | ## 登陆地址(ip自己替换) 25 | http://127.0.0.1:8010/#/login 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "price-show", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.24.0", 12 | "core-js": "^3.6.5", 13 | "echarts": "4.8.0", 14 | "element-ui": "^2.15.6", 15 | "node-sass": "4.14.1", 16 | "sass-loader": "8.0.0", 17 | "v-charts": "^1.19.0", 18 | "v-contextmenu": "^2.9.0", 19 | "vue": "^2.6.11", 20 | "vue-codemirror": "4", 21 | "vue-router": "^3.5.3", 22 | "vue-runtime-helpers": "^1.1.2", 23 | "vue2-ace-editor": "^0.0.15", 24 | "vuedraggable": "^2.24.3", 25 | "vuex": "^3.6.2" 26 | }, 27 | "devDependencies": { 28 | "@vue/cli-plugin-babel": "^4.5.0", 29 | "@vue/cli-plugin-eslint": "^4.5.0", 30 | "@vue/cli-service": "^4.5.0", 31 | "babel-eslint": "^10.1.0", 32 | "eslint": "^6.7.2", 33 | "eslint-plugin-vue": "^6.2.2", 34 | "vue-template-compiler": "^2.6.11" 35 | }, 36 | "eslintConfig": { 37 | "root": true, 38 | "env": { 39 | "node": true 40 | }, 41 | "extends": [ 42 | "plugin:vue/essential", 43 | "eslint:recommended" 44 | ], 45 | "parserOptions": { 46 | "parser": "babel-eslint" 47 | }, 48 | "rules": {} 49 | }, 50 | "browserslist": [ 51 | "> 1%", 52 | "last 2 versions", 53 | "not dead" 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 测试平台 4 | 5 | 6 | 7 | 8 | 9 | <%= htmlWebpackPlugin.options.title %> 10 | 11 | 12 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | 31 | -------------------------------------------------------------------------------- /src/assets/css/color.scss: -------------------------------------------------------------------------------- 1 | // 主色 2 | $color-primary: #409EFF; 3 | 4 | // 辅助色 5 | $color-info: #909399; 6 | $color-success: #67C23A; 7 | $color-warning: #E6A23C; 8 | $color-danger: #F56C6C; 9 | 10 | // 文字 11 | $color-text-main: #303133; 12 | $color-text-normal: #606266; 13 | $color-text-sub: #909399; 14 | $color-text-placehoder: #C0C4CC; 15 | 16 | // 边框 17 | $color-border-1: #DCDFE6; 18 | $color-border-2: #E4E7ED; 19 | $color-border-3: #EBEEF5; 20 | $color-border-4: #F2F6FC; 21 | 22 | // 背景 23 | $color-bg: #f8f8f9; 24 | 25 | 26 | // 工具类名统一前缀 27 | $prefix: d2; 28 | 29 | // 禁止用户选中 鼠标变为手形 30 | %unable-select { 31 | user-select: none; 32 | cursor: pointer; 33 | } 34 | 35 | // 填满父元素 36 | // 组要父元素 position: relative | absolute; 37 | %full { 38 | top: 0px; 39 | right: 0px; 40 | bottom: 0px; 41 | left: 0px; 42 | } 43 | 44 | // flex 垂直水平居中 45 | %flex-center-row { 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | flex-direction: row; 50 | } 51 | %flex-center-col { 52 | display: flex; 53 | justify-content: center; 54 | align-items: center; 55 | flex-direction: column; 56 | } 57 | 58 | // 将元素模拟成卡片外观 59 | %card { 60 | border: 1px solid #dddee1; 61 | border-color: #e9eaec; 62 | background: #fff; 63 | border-radius: 4px; 64 | font-size: 14px; 65 | position: relative; 66 | } -------------------------------------------------------------------------------- /src/assets/css/index.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './sidebar.scss'; -------------------------------------------------------------------------------- /src/assets/css/sidebar.scss: -------------------------------------------------------------------------------- 1 | #app { 2 | 3 | .main-container { 4 | min-height: 100%; 5 | transition: margin-left .28s; 6 | margin-left: $sideBarWidth; 7 | position: relative; 8 | } 9 | 10 | .sidebar-container { 11 | transition: width 0.28s; 12 | width: $sideBarWidth !important; 13 | background-color: #545c64; 14 | height: 100%; 15 | position: fixed; 16 | font-size: 0px; 17 | top: 0; 18 | bottom: 0; 19 | left: 0; 20 | z-index: 1001; 21 | overflow: hidden; 22 | box-shadow: 0 1px 8px rgba(0, 21, 41, .05); 23 | 24 | // reset element-ui css 25 | .horizontal-collapse-transition { 26 | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; 27 | } 28 | 29 | .scrollbar-wrapper { 30 | overflow-x: hidden !important; 31 | } 32 | 33 | .el-scrollbar__bar.is-vertical { 34 | right: 0px; 35 | } 36 | 37 | //.el-scrollbar { 38 | // height: 100%; 39 | //} 40 | 41 | 42 | .el-scrollbar { 43 | height: calc(100% - 50px); 44 | } 45 | 46 | 47 | .is-horizontal { 48 | display: none; 49 | } 50 | 51 | a { 52 | display: inline-block; 53 | width: 100%; 54 | overflow: hidden; 55 | } 56 | 57 | .svg-icon { 58 | margin-right: 16px; 59 | } 60 | 61 | .el-menu { 62 | border: none; 63 | height: 100%; 64 | width: 100% !important; 65 | } 66 | 67 | 68 | 69 | .is-active>.el-submenu__title { 70 | // color: $subMenuActiveText !important; 71 | } 72 | 73 | & .nest-menu .el-submenu>.el-submenu__title, 74 | & .el-submenu .el-menu-item { 75 | min-width: $sideBarWidth !important; 76 | &:hover { 77 | 78 | } 79 | } 80 | & .el-menu-item, 81 | & .el-submenu .el-menu-item{ 82 | &.is-active{ 83 | background-color: rgb(67, 74, 80) !important; 84 | border-right: 3px solid #66b1ff; 85 | } 86 | } 87 | } 88 | 89 | .hideSidebar { 90 | .sidebar-container { 91 | width: 54px !important; 92 | } 93 | 94 | .main-container { 95 | margin-left: 54px; 96 | } 97 | 98 | .submenu-title-noDropdown { 99 | padding: 0 !important; 100 | position: relative; 101 | 102 | .el-tooltip { 103 | padding: 0 !important; 104 | 105 | .svg-icon { 106 | margin-left: 20px; 107 | } 108 | } 109 | } 110 | 111 | .el-submenu { 112 | overflow: hidden; 113 | 114 | &>.el-submenu__title { 115 | padding-left: 15px !important; 116 | 117 | .svg-icon { 118 | margin-left: 20px; 119 | } 120 | 121 | .el-submenu__icon-arrow { 122 | display: none; 123 | } 124 | } 125 | } 126 | 127 | .el-menu--collapse { 128 | .el-submenu { 129 | &>.el-submenu__title { 130 | &>span { 131 | height: 0; 132 | width: 0; 133 | overflow: hidden; 134 | visibility: hidden; 135 | display: inline-block; 136 | } 137 | } 138 | } 139 | } 140 | } 141 | 142 | .el-menu--collapse .el-menu .el-submenu { 143 | min-width: $sideBarWidth !important; 144 | } 145 | 146 | // mobile responsive 147 | .mobile { 148 | .main-container { 149 | margin-left: 0px; 150 | } 151 | 152 | .sidebar-container { 153 | transition: transform .28s; 154 | width: $sideBarWidth !important; 155 | } 156 | 157 | &.hideSidebar { 158 | .sidebar-container { 159 | pointer-events: none; 160 | transition-duration: 0.3s; 161 | transform: translate3d(-$sideBarWidth, 0, 0); 162 | } 163 | } 164 | } 165 | 166 | .withoutAnimation { 167 | 168 | .main-container, 169 | .sidebar-container { 170 | transition: none; 171 | } 172 | } 173 | } 174 | 175 | // when menu collapsed 176 | .el-menu--vertical { 177 | &>.el-menu { 178 | .svg-icon { 179 | margin-right: 16px; 180 | } 181 | } 182 | 183 | .nest-menu .el-submenu>.el-submenu__title, 184 | .el-menu-item { 185 | &:hover { 186 | // you can use $subMenuHover 187 | background-color: $menuHover !important; 188 | } 189 | } 190 | 191 | // the scroll bar appears when the subMenu is too long 192 | >.el-menu--popup { 193 | max-height: 100vh; 194 | overflow-y: auto; 195 | 196 | &::-webkit-scrollbar-track-piece { 197 | background: #d3dce6; 198 | } 199 | 200 | &::-webkit-scrollbar { 201 | width: 6px; 202 | } 203 | 204 | &::-webkit-scrollbar-thumb { 205 | background: #99a9bf; 206 | border-radius: 20px; 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/assets/css/variables.scss: -------------------------------------------------------------------------------- 1 | // sidebar 2 | $menuText: #515a6e; 3 | $menuActiveText:#409EFF; 4 | $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951 5 | 6 | $menuBg:#fff; 7 | $menuHover:#263445; 8 | 9 | $subMenuBg:#1f2d3d; 10 | $subMenuHover:#001528; 11 | 12 | $sideBarWidth: 210px; 13 | 14 | // the :export directive is the magic sauce for webpack 15 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 16 | :export { 17 | menuText: $menuText; 18 | menuActiveText: $menuActiveText; 19 | subMenuActiveText: $subMenuActiveText; 20 | menuBg: $menuBg; 21 | menuHover: $menuHover; 22 | subMenuBg: $subMenuBg; 23 | subMenuHover: $subMenuHover; 24 | sideBarWidth: $sideBarWidth; 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/icon/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/icon/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/src/assets/icon/iconfont.eot -------------------------------------------------------------------------------- /src/assets/icon/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/src/assets/icon/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/icon/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/src/assets/icon/iconfont.woff -------------------------------------------------------------------------------- /src/assets/icon/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/src/assets/icon/iconfont.woff2 -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 24 | 25 | 78 | -------------------------------------------------------------------------------- /src/components/MyAside.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 119 | 120 | 279 | -------------------------------------------------------------------------------- /src/components/MyHeader.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 108 | 109 | 133 | -------------------------------------------------------------------------------- /src/components/Tags.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 109 | 110 | 111 | 206 | -------------------------------------------------------------------------------- /src/components/errorView.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 37 | 39 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | // 自定义组件 2 | const requireComponents = require.context('../components', true, /\.vue/) 3 | 4 | // 打印结果 5 | // 遍历出每个组件的路径 6 | const registerComponents = (Vue) => { 7 | requireComponents.keys().forEach(fileName => { 8 | // 组件实例 9 | const reqCom = requireComponents(fileName) 10 | // 截取路径作为组件名 11 | const reqComName = fileName.split('/')[1].replace('.vue', '') 12 | Vue.component(reqComName, reqCom.default || reqCom) 13 | }) 14 | } 15 | 16 | export default registerComponents 17 | 18 | -------------------------------------------------------------------------------- /src/components/result.vue: -------------------------------------------------------------------------------- 1 | 63 | 64 | 118 | 120 | -------------------------------------------------------------------------------- /src/components/tooltipOver.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 63 | 64 | -------------------------------------------------------------------------------- /src/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import { Input, Breadcrumb,Card, BreadcrumbItem, Form, FormItem, Upload, Button, Select, Option, DatePicker, Tabs, TabPane, Drawer, Pagination, Row, Col, Message, Progress, MessageBox, Image } from 'element-ui' 4 | 5 | Vue.use(Input) 6 | .use(Breadcrumb) 7 | .use(BreadcrumbItem) 8 | .use(Form) 9 | .use(FormItem) 10 | .use(Button) 11 | .use(Upload) 12 | .use(Select) 13 | .use(Option) 14 | .use(DatePicker) 15 | .use(Tabs) 16 | .use(TabPane) 17 | .use(Drawer) 18 | .use(Pagination) 19 | .use(Row) 20 | .use(Col) 21 | .use(Progress) 22 | .use(Image) 23 | .use(Card) 24 | 25 | 26 | Vue.prototype.$message = Message 27 | Vue.prototype.$confirm = MessageBox.confirm 28 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pencil1/ApiTestWeb/e7e43dc24984e3c9d73b0a03598a3466c1f67aa6/src/index.js -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import ElementUI from 'element-ui'; 6 | import line from 'v-charts/lib/line.common'; 7 | import pie from 'v-charts/lib/pie.common'; 8 | import ring from 'v-charts/lib/ring.common'; 9 | import api from './util/api'; 10 | import base from './util/common'; 11 | import axios from './util/axiosConfig'; 12 | import contentmenu from 'v-contextmenu'; 13 | import 'v-contextmenu/dist/index.css'; 14 | import registerComponents from '@/components' 15 | import './assets/icon/iconfont.js'; 16 | import './assets/icon/iconfont.css'; 17 | import './assets/css/index.scss'; 18 | import 'element-ui/lib/theme-chalk/index.css' 19 | import aceEditor from './util/ace-editor' 20 | // let aceEditor = require('./util/ace-editorr') 21 | 22 | // Vue.use(aceEditor); 23 | Vue.config.productionTip = false 24 | Vue.prototype.$api = api; 25 | Vue.prototype.$axios = axios; 26 | // 注册全局组件 27 | registerComponents(Vue) 28 | Vue.component('aceEditor', aceEditor); 29 | Vue.component(line.name, line); 30 | Vue.component(pie.name, pie); 31 | Vue.component(ring.name, ring); 32 | 33 | Vue.use(contentmenu); 34 | Vue.use(ElementUI); 35 | Vue.use(base); 36 | 37 | 38 | new Vue({ 39 | router, 40 | store, 41 | render: h => h(App), 42 | }).$mount('#app') 43 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import store from '../store' 4 | const originalPush = Router.prototype.push 5 | const originalReplace = Router.prototype.replace 6 | 7 | Router.prototype.push = function push(location) { 8 | return originalPush.call(this, location).catch(err => err) 9 | } 10 | Router.prototype.replace = function replace(location) { 11 | return originalReplace.call(this, location).catch(err => err) 12 | } 13 | Vue.use(Router) 14 | // import projectManage from '../views/base.vue' 15 | const routes = [ 16 | 17 | { 18 | path: '/login', 19 | name: 'login', 20 | component: () => import('@/views/login'), 21 | meta: { 22 | title: '登录页面', 23 | } 24 | }, 25 | // { 26 | // path: '/home', 27 | // name: 'home', 28 | // component: () => import('@/views/home'), 29 | // meta: { 30 | // title: '首页', 31 | // active: '首页' 32 | // } 33 | // }, 34 | { 35 | path: '', 36 | redirect: '/home', 37 | component: () => import('../views/base.vue'), 38 | 39 | children: [ 40 | { 41 | path: '/home', 42 | name: 'homePage', 43 | 44 | component: () => import('@/views/home'), 45 | meta: { 46 | title: '首页', 47 | } 48 | }, 49 | { 50 | path: '/projectManage', 51 | name: 'project', 52 | component: () => import('@/views/projectManage'), 53 | meta: { 54 | title: '项目管理', 55 | } 56 | }, 57 | { 58 | path: '/apiManage', 59 | name: 'apiManage', 60 | component: () => import('@/views/apiManage'), 61 | meta: { 62 | title: '接口信息', 63 | } 64 | }, 65 | { 66 | path: '/sceneConfig', 67 | name: 'sceneConfig', 68 | component: () => import('@/views/sceneConfig'), 69 | meta: { 70 | title: '业务配置', 71 | } 72 | }, 73 | { 74 | path: '/caseManage', 75 | name: 'caseManage', 76 | component: () => import('@/views/caseManage'), 77 | meta: { 78 | title: '接口用例', 79 | } 80 | }, 81 | { 82 | path: '/buildInFunc', 83 | name: 'buildInFunc', 84 | component: () => import('@/views/buildInFunc'), 85 | meta: { 86 | title: '内置函数', 87 | } 88 | }, 89 | { 90 | path: '/reportManage', 91 | name: 'reportManage', 92 | component: () => import('@/views/reportManage'), 93 | meta: { 94 | title: '测试报告', 95 | } 96 | }, 97 | { 98 | path: '/taskManage', 99 | name: 'taskManage', 100 | component: () => import('@/views/taskManage'), 101 | meta: { 102 | title: '定时任务', 103 | } 104 | }, 105 | { 106 | path: '/mockManage', 107 | name: 'mockManage', 108 | component: () => import('@/views/mockManage'), 109 | meta: { 110 | title: 'mock服务', 111 | } 112 | }, 113 | { 114 | path: '/testTool', 115 | name: 'testTool', 116 | component: () => import('@/views/testTool'), 117 | meta: { 118 | title: '工具页面', 119 | } 120 | }, 121 | { 122 | path: '/userManage', 123 | name: 'userManage', 124 | component: () => import('@/views/userManage'), 125 | meta: { 126 | title: '用户管理', 127 | } 128 | }, 129 | 130 | ], 131 | 132 | }, 133 | { 134 | path: '/reportShow', 135 | name: 'reportShow', 136 | meta: { 137 | title: '報告展示', 138 | }, 139 | component: () => import('@/views/reportShow'), 140 | }, 141 | { 142 | path: '/h5Page', 143 | name: 'h5Page', 144 | component: () => import('@/views/h5Page'), 145 | meta: { 146 | title: 'h5页面', 147 | } 148 | }, 149 | ] 150 | 151 | // 页面刷新时,重新赋值token 152 | if (window.localStorage.getItem('token')) { 153 | store.getters.userInfo.token = window.localStorage.getItem('token') 154 | } 155 | if (window.localStorage.getItem('roles')) { 156 | store.getters.userInfo.roles = window.localStorage.getItem('roles') 157 | } 158 | if (window.localStorage.getItem('name')) { 159 | store.getters.userInfo.name = window.localStorage.getItem('name') 160 | } 161 | if (window.localStorage.getItem('userId')) { 162 | store.state.userId = window.localStorage.getItem('userId') 163 | } 164 | 165 | const router = new Router({ 166 | routes: routes, 167 | // mode: 'history', 168 | }) 169 | 170 | export default router 171 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | userInfo: state => state.user.userInfo, 3 | asideStatus: state => state.user.asideStatus, 4 | cachedViews:state => state.tags.cachedViews, 5 | cacheStatus:state => state.tags.cacheStatus, 6 | } 7 | export default getters 8 | 9 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | // import modules from './modules' 4 | import getters from './getters' 5 | import state from './state' 6 | import axios from 'axios' 7 | import api from '../util/api'; 8 | 9 | //module文件夹下太多文件,导入太麻烦,使用context实现模块化导入 10 | const modulesFiles = require.context('./modules', true, /\.js$/) 11 | 12 | const modules = modulesFiles.keys().reduce((modules, modulePath) => { 13 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') 14 | const value = modulesFiles(modulePath) 15 | modules[moduleName] = value.default 16 | return modules 17 | }, {}) 18 | Vue.use(Vuex) 19 | 20 | 21 | const store = new Vuex.Store({ 22 | 23 | modules, 24 | getters, 25 | state, 26 | 27 | mutations: { 28 | setFuncAddress(state, payload) { 29 | // 变更状态 30 | state.funcAddress = payload 31 | // console.log(store.state.user.userInfo) 32 | }, 33 | SET_ERROR_DATA(state, payload) { 34 | state.errorData = payload 35 | state.showErrorStatus = true 36 | }, 37 | SET_RESULT_DATA(state, payload = null) { 38 | if (payload) { 39 | state.resultData = payload 40 | } 41 | state.showResultStatus = true 42 | }, 43 | 44 | 45 | // setBaseData (state,payload) { 46 | // // 变更状态 47 | // state.baseData = payload.data 48 | // state.userPros = payload.user_pros 49 | // }, 50 | }, 51 | actions: { 52 | async INIT_USER({commit}, token) { 53 | const res = await axios.post(api.loginSsoApi, {'token': token}) 54 | if (res.data.code === 401) { 55 | window.open(store.state.platformsUrl, "_self"); 56 | } else { 57 | store.state.user.userInfo = res.data 58 | let storage = window.localStorage 59 | storage.token = token 60 | storage.name = res.data.nickname 61 | storage.userId = res.data.id 62 | await store.dispatch('GET_FUNC_DATA') 63 | } 64 | }, 65 | async GET_FUNC_DATA({commit}) { 66 | const res = await axios.post(api.findFuncFileApi, {'privates': false}) 67 | commit('setFuncAddress', res.data.data) 68 | }, 69 | 70 | 71 | } 72 | }) 73 | 74 | export default store 75 | -------------------------------------------------------------------------------- /src/store/modules/index.js: -------------------------------------------------------------------------------- 1 | const files = require.context('.', false, /\.js$/) 2 | const modules = {} 3 | 4 | files.keys().forEach(key => { 5 | if (key === './index.js') return 6 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default 7 | }) 8 | 9 | export default modules 10 | -------------------------------------------------------------------------------- /src/store/modules/projectS.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | namespaced: true, 4 | state: { 5 | editShowStatus:false, 6 | 7 | }, 8 | mutations: { 9 | SET_STATUS(state, n) { 10 | state.editShowStatus = n 11 | }, 12 | 13 | }, 14 | actions: { 15 | // async GET_USER({ commit }) { 16 | // members.getUser((res) => { 17 | // commit('SET_USER', res) 18 | // // console.log(res) 19 | // }) 20 | // } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/store/modules/tags.js: -------------------------------------------------------------------------------- 1 | 2 | import Vue from 'vue' 3 | export default { 4 | namespaced: true, 5 | state: { 6 | cacheStatus:true, 7 | cachedViews:[], 8 | }, 9 | mutations: { 10 | SET_USER(state, payload) { 11 | state.userInfo = payload 12 | }, 13 | SET_COLLAPSE(state, n) { 14 | state.asideStatus = n 15 | }, 16 | SET_CACHED(state,n) { 17 | // state.cachedViews = n 18 | state.cachedViews.push(n) 19 | }, 20 | DEL_CACHED(state,name) { 21 | let index = state.cachedViews.indexOf(name); 22 | state.cachedViews.splice(index, 1); 23 | }, 24 | REFRESH(state,n){ 25 | let index = state.cachedViews.indexOf(n); 26 | state.cachedViews.splice(index, 1); 27 | state.cacheStatus = false; 28 | 29 | Vue.nextTick(function () { 30 | state.cacheStatus = true; 31 | state.cachedViews.push(n); 32 | }); 33 | } 34 | }, 35 | actions: { 36 | // async GET_USER({ commit }) { 37 | // members.getUser((res) => { 38 | // commit('SET_USER', res) 39 | // // console.log(res) 40 | // }) 41 | // } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/store/modules/user.js: -------------------------------------------------------------------------------- 1 | // import members from '@/utils/user' 2 | 3 | export default { 4 | namespaced: true, 5 | state: { 6 | userInfo: {'userName':'asd'}, 7 | asideStatus:false, 8 | }, 9 | mutations: { 10 | SET_USER(state, payload) { 11 | state.userInfo = payload 12 | }, 13 | SET_COLLAPSE(state, n) { 14 | state.asideStatus = n 15 | }, 16 | }, 17 | actions: { 18 | // async GET_USER({ commit }) { 19 | // members.getUser((res) => { 20 | // commit('SET_USER', res) 21 | // // console.log(res) 22 | // }) 23 | // } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/store/state.js: -------------------------------------------------------------------------------- 1 | 2 | export const state = { 3 | // userPros:null, 4 | // baseData:[], 5 | funcAddress: [], 6 | tableHeight: parseInt(document.documentElement.clientHeight-230),// 右侧面板最小长度 7 | headerWidth: parseInt(document.documentElement.clientWidth-230),// 右侧面板最小宽度 8 | token: null, 9 | title: '', 10 | roles: null, 11 | userId: null, 12 | errorData: null, 13 | showErrorStatus:false, 14 | resultData: {'details':[{'records':[]}]}, 15 | showResultStatus:false, 16 | platformsUrl:'http://43.138.146.161/#/login' 17 | } 18 | export default state 19 | -------------------------------------------------------------------------------- /src/util/ace-editor.js: -------------------------------------------------------------------------------- 1 | // 这里需要提前引入 2 | let ace = require('brace'); 3 | require('brace/theme/chrome'); 4 | require('brace/ext/language_tools'); 5 | // 格式化 6 | require('brace/snippets/json'); 7 | require('brace/snippets/html'); 8 | require('brace/snippets/javascript'); 9 | require('brace/snippets/xml'); 10 | // 引入格式文件 11 | require('brace/mode/html'); 12 | require('brace/mode/json'); 13 | require('brace/mode/javascript'); 14 | require('brace/mode/xml'); 15 | 16 | // language 17 | module.exports = { 18 | render(h) { 19 | const height = this.height ? this.px(this.height) : '100%'; 20 | const width = this.width ? this.px(this.width) : '100%'; 21 | return h('div', { 22 | attrs: { 23 | style: `height: ${height}; width: ${width}`, 24 | }, 25 | ref: 'editor', 26 | }); 27 | }, 28 | 29 | props: { 30 | value: { 31 | type: String, 32 | default: '', 33 | }, 34 | lang: true, 35 | theme: String, 36 | height: true, 37 | width: true, 38 | options: Object, 39 | readOnly: false, 40 | }, 41 | 42 | data() { 43 | return { 44 | editor: null, 45 | contentBackup: '', 46 | }; 47 | }, 48 | watch: { 49 | readOnly: { 50 | immediate: false, 51 | handler(v) { 52 | this.editor.setReadOnly(v); 53 | }, 54 | }, 55 | value(val) { 56 | if (this.contentBackup !== val) { 57 | this.editor.setValue(val, 1); 58 | this.contentBackup = val; 59 | } 60 | }, 61 | theme(newTheme) { 62 | this.editor.setTheme(`ace/theme/${newTheme}`); 63 | }, 64 | lang(newLang) { 65 | this.editor 66 | .getSession() 67 | .setMode(typeof newLang === 'string' ? `ace/mode/${newLang}` : newLang); 68 | }, 69 | options(newOption) { 70 | this.editor.setOptions(newOption); 71 | }, 72 | height() { 73 | this.$nextTick(() => { 74 | this.editor.resize(); 75 | }); 76 | }, 77 | width() { 78 | this.$nextTick(() => { 79 | this.editor.resize(); 80 | }); 81 | }, 82 | 83 | }, 84 | beforeDestroy() { 85 | this.editor.destroy(); 86 | this.editor.container.remove(); 87 | }, 88 | mounted() { 89 | if (!ace) { 90 | ace = window.ace; 91 | } 92 | const vm = this; 93 | 94 | vm.editor = ace.edit(this.$el); 95 | 96 | const {editor} = vm; 97 | editor.$blockScrolling = Infinity; 98 | this.$emit('init', editor); 99 | this.setLang(); 100 | this.setTheme(); 101 | 102 | this.contentBackup = this.value; 103 | 104 | editor.on('change', () => { 105 | const content = editor.getValue(); 106 | vm.$emit('input', content); 107 | vm.contentBackup = content; 108 | }); 109 | // 监听事件 110 | if (this.$refs.editor) { 111 | const observe = new ResizeObserver((_el) => { 112 | const {target} = _el[0]; 113 | if (target && target.offsetWidth) { 114 | this.editor.resize(); 115 | } 116 | }); 117 | observe.observe(this.$refs.editor); 118 | } 119 | 120 | if (vm.options) editor.setOptions(vm.options); 121 | 122 | this.$emit('input', vm.value); 123 | if (vm.value) editor.setValue(vm.value, 1); 124 | vm.editor.setReadOnly(vm.readOnly); 125 | }, 126 | methods: { 127 | px(n) { 128 | if (/^\d*$/.test(n)) { 129 | return `${n}px`; 130 | } 131 | return n; 132 | }, 133 | setLang() { 134 | const {editor} = this; 135 | const lang = this.lang || 'text'; 136 | editor.getSession().setMode(typeof lang === 'string' ? `ace/mode/${lang}` : lang); 137 | }, 138 | setTheme() { 139 | const theme = this.theme || 'chrome'; 140 | this.editor.setTheme(`ace/theme/${theme}`); 141 | }, 142 | }, 143 | }; 144 | -------------------------------------------------------------------------------- /src/util/api.js: -------------------------------------------------------------------------------- 1 | const baseDataApi = '/api/proGather/list'; 2 | const getFuncAddressApi = '/api/func/getAddress'; 3 | 4 | const findProApi = '/api/project/find'; 5 | const addProApi = '/api/project/add'; 6 | const editProApi = '/api/project/edit'; 7 | const delProApi = '/api/project/del'; 8 | 9 | const findReportApi = '/api/report/find'; 10 | const delReportApi = '/api/report/del'; 11 | 12 | const findApiSetApi = '/api/apiSet/find'; 13 | const addApiSetApi = '/api/apiSet/add'; 14 | const editApiSetApi = '/api/apiSet/edit'; 15 | const delApiSetApi = '/api/apiSet/del'; 16 | const stickApiSetApi = '/api/apiSet/stick'; 17 | 18 | const findConfigApi = '/api/config/find'; 19 | const addConfigApi = '/api/config/add'; 20 | const editConfigApi = '/api/config/edit'; 21 | const delConfigApi = '/api/config/del'; 22 | 23 | const loginApi = '/api/login'; 24 | const loginSsoApi = '/api/loginSso'; 25 | const logoutApi = '/api/logout'; 26 | const registerApi = '/api/register'; 27 | const changePasswordApi = '/api/changePassword'; 28 | const msgApi = '/api/msg'; 29 | 30 | const findApiApi = '/api/apiMsg/find'; 31 | const delApiApi = '/api/apiMsg/del'; 32 | const runApiApi = '/api/apiMsg/run'; 33 | const addApiApi = '/api/apiMsg/add'; 34 | const editAndCopyApiApi = '/api/apiMsg/editAndCopy'; 35 | 36 | const findCaseSetApi = '/api/caseSet/find'; 37 | const delCaseSetApi = '/api/caseSet/del'; 38 | const addCaseSetApi = '/api/caseSet/add'; 39 | const stickCaseSetApi = '/api/caseSet/stick'; 40 | 41 | const startTaskApi = '/api/task/start'; 42 | const pauseTaskApi = '/api/task/pause'; 43 | const resumeTaskApi = '/api/task/resume'; 44 | const removeTaskApi = '/api/task/remove'; 45 | const runTaskApi = '/api/task/run'; 46 | const delTaskApi = '/api/task/del'; 47 | const editTaskApi = '/api/task/edit'; 48 | const addTaskApi = '/api/task/add'; 49 | const findTaskApi = '/api/task/find'; 50 | 51 | const findCaseApi = '/api/case/find'; 52 | const delCaseApi = '/api/case/del'; 53 | const runCaseApi = '/api/report/run'; 54 | const runStepApi = '/api/step/run'; 55 | const editCaseApi = '/api/case/edit'; 56 | const addCaseApi = '/api/case/add'; 57 | const delStepApi = '/api/step/del'; 58 | const addStepApi = '/api/step/add'; 59 | const configDataApi = '/api/config/data'; 60 | 61 | 62 | const fileUploadingApi = '/api/upload'; 63 | const checkFileApi = '/api/checkFile'; 64 | const importApiApi = '/api/apiMsg/fileChange'; 65 | 66 | const findFuncFileApi = '/api/FuncFile/find'; 67 | const addFuncFileApi = '/api/FuncFile/add'; 68 | const checkFuncFileApi = '/api/func/check'; 69 | const saveFuncFileApi = '/api/FuncFile/save'; 70 | const delFuncFileApi = '/api/FuncFile/del'; 71 | const getFuncFileApi = '/api/FuncFile/get'; 72 | 73 | const findUserApi = '/api/user/find'; 74 | const editUserApi = '/api/user/edit'; 75 | const delUserApi = '/api/user/del'; 76 | const changeStatusUserApi = '/api/user/changeStatus'; 77 | 78 | const findMockApiApi = '/mock/mockApi/find'; 79 | const delMockApiApi = '/mock/mockApi/del'; 80 | const addMockApiApi = '/mock/mockApi/add'; 81 | const editMockApi = '/mock/mockApi/edit'; 82 | // const saveTestCaseFileApi = '/api/testCaseFile/save'; 83 | 84 | export default { 85 | // addTestCaseFileApi, 86 | // findTestCaseFileApi, 87 | // delTestCaseFileApi, 88 | // getTestCaseFileApi, 89 | // saveTestCaseFileApi, 90 | addStepApi, 91 | delStepApi, 92 | 93 | findFuncFileApi, 94 | addFuncFileApi, 95 | checkFuncFileApi, 96 | saveFuncFileApi, 97 | delFuncFileApi, 98 | getFuncFileApi, 99 | 100 | baseDataApi, 101 | getFuncAddressApi, 102 | checkFileApi, 103 | 104 | findUserApi, 105 | editUserApi, 106 | delUserApi, 107 | changeStatusUserApi, 108 | 109 | findReportApi, 110 | delReportApi, 111 | 112 | startTaskApi, 113 | pauseTaskApi, 114 | resumeTaskApi, 115 | removeTaskApi, 116 | runTaskApi, 117 | delTaskApi, 118 | editTaskApi, 119 | addTaskApi, 120 | findTaskApi, 121 | 122 | findCaseApi, 123 | delCaseApi, 124 | runCaseApi, 125 | editCaseApi, 126 | addCaseApi, 127 | configDataApi, 128 | runStepApi, 129 | 130 | findCaseSetApi, 131 | delCaseSetApi, 132 | addCaseSetApi, 133 | stickCaseSetApi, 134 | 135 | findProApi, 136 | addProApi, 137 | editProApi, 138 | delProApi, 139 | 140 | findApiSetApi, 141 | addApiSetApi, 142 | editApiSetApi, 143 | delApiSetApi, 144 | stickApiSetApi, 145 | 146 | findConfigApi, 147 | addConfigApi, 148 | editConfigApi, 149 | delConfigApi, 150 | 151 | loginApi, 152 | loginSsoApi, 153 | logoutApi, 154 | registerApi, 155 | changePasswordApi, 156 | msgApi, 157 | 158 | findApiApi, 159 | delApiApi, 160 | runApiApi, 161 | addApiApi, 162 | editAndCopyApiApi, 163 | 164 | fileUploadingApi, 165 | importApiApi, 166 | 167 | findMockApiApi, 168 | delMockApiApi, 169 | addMockApiApi, 170 | editMockApi, 171 | } -------------------------------------------------------------------------------- /src/util/axiosConfig.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import router from "../router"; 3 | import store from '../store' 4 | import { mapMutations } from 'vuex' 5 | // http response 拦截器(所有接收到的请求都要从这儿过一次) 6 | axios.defaults.timeout = 60000; 7 | axios.interceptors.request.use(function (config){ 8 | let storage = window.localStorage 9 | config.headers.token = storage.token 10 | config.headers.userId = storage.userId 11 | config.headers.name = encodeURIComponent(storage.name) 12 | return config 13 | } 14 | 15 | ) 16 | axios.interceptors.response.use( 17 | response => { 18 | if(response.data['msg'] === '登录过期,请重新登录'){window.open(store.state.platformsUrl, "_self");} 19 | else if (response.data['msg'] === '服务器异常,请查看返回的error信息,无法处理则联系管理员'){ 20 | store.commit('SET_ERROR_DATA',response.data['error']) 21 | // console.log(store.state.errorData) 22 | } 23 | return response 24 | }) 25 | 26 | export default axios; 27 | 28 | -------------------------------------------------------------------------------- /src/util/common.js: -------------------------------------------------------------------------------- 1 | exports.install = function (Vue) { 2 | Vue.prototype.sureView = function (func, arg, msg) { 3 | // this.$alert('确认要删除吗?', '确认框', { 4 | // confirmButtonText: '确定', 5 | // callback: action => { 6 | // func(arg); 7 | // } 8 | // }); 9 | this.$confirm('此操作将永久删除' + '' + msg + '' + ',是否继续?', '提示', { 10 | dangerouslyUseHTMLString: true, 11 | confirmButtonText: '确定', 12 | cancelButtonText: '取消', 13 | type: 'warning' 14 | }).then(() => { 15 | func(arg); 16 | }).catch(() => { 17 | }); 18 | }; 19 | Vue.prototype.messageShow = function (_this, response) { 20 | if (response.data['status'] === 0) { 21 | _this.$message({ 22 | showClose: true, 23 | message: response.data['msg'], 24 | type: 'warning' 25 | }); 26 | // if(response.data['error']){ 27 | // return 'error' 28 | // } 29 | return false 30 | } else { 31 | if (response.data['msg']) { 32 | _this.$message({ 33 | showClose: true, 34 | message: response.data['msg'], 35 | type: 'success' 36 | }); 37 | } 38 | return true 39 | } 40 | }; 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /src/views/apiManage/components/apiSetList.vue: -------------------------------------------------------------------------------- 1 | 114 | 115 | 304 | 305 | 325 | -------------------------------------------------------------------------------- /src/views/apiManage/components/importApi.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 108 | -------------------------------------------------------------------------------- /src/views/apiManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | -------------------------------------------------------------------------------- /src/views/base.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 61 | -------------------------------------------------------------------------------- /src/views/buildInFunc/components/buildInFuncM.vue: -------------------------------------------------------------------------------- 1 | 89 | 90 | 181 | 182 | 186 | -------------------------------------------------------------------------------- /src/views/buildInFunc/components/funcList.vue: -------------------------------------------------------------------------------- 1 | 81 | 82 | 276 | 294 | -------------------------------------------------------------------------------- /src/views/buildInFunc/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/caseManage/components/caseSetList.vue: -------------------------------------------------------------------------------- 1 | 114 | 115 | 294 | 295 | 315 | -------------------------------------------------------------------------------- /src/views/caseManage/components/loadConfigView.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 72 | 73 | -------------------------------------------------------------------------------- /src/views/caseManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/h5Page/components/hello.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 31 | 40 | -------------------------------------------------------------------------------- /src/views/h5Page/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/home/components/home.vue: -------------------------------------------------------------------------------- 1 | 94 | 95 | 138 | 141 | -------------------------------------------------------------------------------- /src/views/home/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /src/views/login/components/login.vue: -------------------------------------------------------------------------------- 1 | 67 | 68 | 112 | 113 | 385 | -------------------------------------------------------------------------------- /src/views/login/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /src/views/mockManage/components/mockEditView.vue: -------------------------------------------------------------------------------- 1 | 82 | 83 | 231 | 232 | -------------------------------------------------------------------------------- /src/views/mockManage/components/mockM.vue: -------------------------------------------------------------------------------- 1 | 87 | 88 | 168 | 169 | 172 | -------------------------------------------------------------------------------- /src/views/mockManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | -------------------------------------------------------------------------------- /src/views/projectManage/components/editView.vue: -------------------------------------------------------------------------------- 1 | 173 | 174 | 243 | 245 | -------------------------------------------------------------------------------- /src/views/projectManage/components/urlTable.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 70 | 72 | -------------------------------------------------------------------------------- /src/views/projectManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/reportManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | -------------------------------------------------------------------------------- /src/views/reportShow/components/reportHeader.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 35 | 40 | -------------------------------------------------------------------------------- /src/views/reportShow/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 44 | -------------------------------------------------------------------------------- /src/views/sceneConfig/components/configEdit.vue: -------------------------------------------------------------------------------- 1 | 81 | 82 | 159 | 161 | -------------------------------------------------------------------------------- /src/views/sceneConfig/components/configM.vue: -------------------------------------------------------------------------------- 1 | 80 | 81 | 152 | 154 | -------------------------------------------------------------------------------- /src/views/sceneConfig/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 15 | -------------------------------------------------------------------------------- /src/views/taskManage/components/editView.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 273 | 274 | -------------------------------------------------------------------------------- /src/views/taskManage/components/taskM.vue: -------------------------------------------------------------------------------- 1 | 113 | 114 | 239 | 240 | 243 | -------------------------------------------------------------------------------- /src/views/taskManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/testTool/components/fke.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 66 | -------------------------------------------------------------------------------- /src/views/testTool/components/testT.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 78 | 79 | -------------------------------------------------------------------------------- /src/views/testTool/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /src/views/userManage/components/userM.vue: -------------------------------------------------------------------------------- 1 | 123 | 124 | 265 | 267 | -------------------------------------------------------------------------------- /src/views/userManage/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // const isDev = process.env.NODE_ENV !== 'production' 3 | // console.log(isDev) 4 | // console.log(process.env) 5 | module.exports = { 6 | lintOnSave: true, 7 | productionSourceMap: false, 8 | // 9 | // configureWebpack: { 10 | // externals: { 11 | // 'vue': 'Vue', 12 | // 'element-ui': 'ELEMENT', 13 | // //将需要忽略打包的都写在这个里面,但前提是index.html文件里面必须script引入 14 | // } 15 | // }, 16 | 17 | pages: { 18 | index: { 19 | // components 的入口 20 | entry: 'src/main.js', 21 | // 模板来源 22 | template: 'public/index.html', 23 | favicon: 'public/favicon.ico', 24 | assetsDir: "src/assets", 25 | // 在 dist/index.html 的输出 26 | // filename: 'src/index.html', 27 | // 当使用 title 选项时, 28 | 29 | }, 30 | 31 | }, 32 | devServer: { 33 | host: '0.0.0.0', 34 | // host: '43.138.146.161', 35 | 36 | // host: '122.51.184.120', 37 | // host:'10.100.2.45', 38 | 39 | port: 8020, 40 | proxy: { 41 | '/api/': { 42 | target:process.env.NODE_ENV === 'production' ? 'http://10.0.8.16:8091' : 'http://0.0.0.0:8091', 43 | // target: 'http://122.51.184.120', 44 | // target: 'http://0.0.0.0:8091', 45 | // target: 'http://172.20.0.2:8091', 46 | // target: 'http://172.16.11.228:8081', 47 | changeOrigin: true, 48 | }, 49 | '/mock/': { 50 | target:process.env.NODE_ENV === 'production' ? 'http://10.0.8.16:8091' : 'http://0.0.0.0:8091', 51 | // target: 'http://122.51.184.120', 52 | // target: 'http://0.0.0.0:8091', 53 | // target: 'http://172.20.0.2:8091', 54 | // target: 'http://172.16.11.228:8081', 55 | changeOrigin: true, 56 | }, 57 | }, 58 | }, 59 | css: { 60 | loaderOptions: { 61 | // 设置 scss 公用变量文件 62 | sass: { 63 | // additionalData: `@import '~@/assets/css/color.scss';`, 64 | prependData: `@import '~@/assets/css/color.scss';` 65 | } 66 | } 67 | }, 68 | } --------------------------------------------------------------------------------