├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── .travis.yml
├── Dockerfile
├── LICENSE
├── README.md
├── cypress.json
├── docker-compose.yml
├── nginx_ops.conf
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── api
│ ├── app.js
│ ├── cmdb
│ │ ├── adm_user.js
│ │ ├── db.js
│ │ ├── server.js
│ │ ├── server_auth.js
│ │ ├── server_group.js
│ │ ├── server_log.js
│ │ └── tag.js
│ ├── cmdb2
│ │ ├── admin_user.js
│ │ ├── asset_config.js
│ │ ├── audit.js
│ │ ├── db.js
│ │ ├── idc.js
│ │ ├── server.js
│ │ ├── system_user.js
│ │ └── tag.js
│ ├── confd
│ │ ├── conf.js
│ │ └── project.js
│ ├── cron.js
│ ├── dashboard
│ │ └── home.js
│ ├── data.js
│ ├── devops-tools.js
│ ├── domain
│ │ ├── dns.js
│ │ └── domain.js
│ ├── git-repo.js
│ ├── k8s
│ │ ├── app.js
│ │ ├── project.js
│ │ ├── publish.js
│ │ └── task.js
│ ├── mg
│ │ └── resource-mg.js
│ ├── routers.js
│ ├── scheduler
│ │ └── scheduler-task.js
│ ├── task-other.js
│ ├── task.js
│ └── user.js
├── assets
│ ├── icons
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ └── images
│ │ ├── error-page
│ │ ├── error-403.svg
│ │ ├── error-404.svg
│ │ └── error-500.svg
│ │ ├── login-bg.jpg
│ │ ├── login-bg1.jpg
│ │ ├── logo-min.jpg
│ │ ├── logo.png
│ │ ├── qq-fance.png
│ │ ├── qq-fance2.jpg
│ │ └── talkingdata.png
├── components
│ ├── charts
│ │ ├── bar.vue
│ │ ├── index.js
│ │ ├── pie.vue
│ │ └── theme.json
│ ├── common-icon
│ │ ├── common-icon.vue
│ │ └── index.js
│ ├── common
│ │ ├── common.less
│ │ └── util.js
│ ├── count-to
│ │ ├── count-to.vue
│ │ ├── index.js
│ │ └── index.less
│ ├── drag-list
│ │ ├── drag-list.vue
│ │ └── index.js
│ ├── editor
│ │ ├── editor.vue
│ │ └── index.js
│ ├── form-group
│ │ ├── form-group.vue
│ │ └── index.js
│ ├── icons
│ │ ├── icons.vue
│ │ └── index.js
│ ├── info-card
│ │ ├── index.js
│ │ └── infor-card.vue
│ ├── login-form
│ │ ├── index.js
│ │ ├── login-form.vue
│ │ ├── mfa.vue
│ │ └── register.vue
│ ├── main
│ │ ├── components
│ │ │ ├── error-store
│ │ │ │ ├── error-store.vue
│ │ │ │ └── index.js
│ │ │ ├── footer
│ │ │ │ └── copyright.vue
│ │ │ ├── fullscreen
│ │ │ │ ├── fullscreen.vue
│ │ │ │ └── index.js
│ │ │ ├── header-bar
│ │ │ │ ├── custom-bread-crumb
│ │ │ │ │ ├── custom-bread-crumb.less
│ │ │ │ │ ├── custom-bread-crumb.vue
│ │ │ │ │ └── index.js
│ │ │ │ ├── header-bar.less
│ │ │ │ ├── header-bar.vue
│ │ │ │ ├── index.js
│ │ │ │ └── sider-trigger
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── sider-trigger.less
│ │ │ │ │ └── sider-trigger.vue
│ │ │ ├── language
│ │ │ │ ├── index.js
│ │ │ │ └── language.vue
│ │ │ ├── side-menu
│ │ │ │ ├── collapsed-menu.vue
│ │ │ │ ├── index.js
│ │ │ │ ├── item-mixin.js
│ │ │ │ ├── mixin.js
│ │ │ │ ├── side-menu-item.vue
│ │ │ │ ├── side-menu.less
│ │ │ │ └── side-menu.vue
│ │ │ ├── tags-nav
│ │ │ │ ├── index.js
│ │ │ │ ├── tags-nav.less
│ │ │ │ └── tags-nav.vue
│ │ │ └── user
│ │ │ │ ├── index.js
│ │ │ │ ├── user.less
│ │ │ │ └── user.vue
│ │ ├── index.js
│ │ ├── main.less
│ │ └── main.vue
│ ├── markdown
│ │ ├── index.js
│ │ └── markdown.vue
│ ├── parent-view
│ │ ├── index.js
│ │ └── parent-view.vue
│ ├── paste-editor
│ │ ├── index.js
│ │ ├── paste-editor.less
│ │ ├── paste-editor.vue
│ │ └── plugins
│ │ │ └── placeholder.js
│ ├── public
│ │ ├── copyright.vue
│ │ └── editor.vue
│ ├── split-pane
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── index.less
│ │ ├── split.vue
│ │ └── trigger.vue
│ └── tables
│ │ ├── edit.vue
│ │ ├── handle-btns.js
│ │ ├── index.js
│ │ ├── index.less
│ │ └── tables.vue
├── config
│ └── index.js
├── directive
│ ├── directives.js
│ └── index.js
├── index.less
├── libs
│ ├── api.request.js
│ ├── axios.js
│ ├── excel.js
│ ├── tools.js
│ └── util.js
├── locale
│ ├── index.js
│ └── lang
│ │ ├── en-US.js
│ │ ├── zh-CN.js
│ │ └── zh-TW.js
├── main.js
├── plugin
│ ├── error-store
│ │ └── index.js
│ └── index.js
├── router
│ ├── before-close.js
│ ├── index.js
│ └── routers.js
├── store
│ ├── index.js
│ └── module
│ │ ├── app.js
│ │ ├── router.js
│ │ └── user.js
└── view
│ ├── cmdb
│ ├── adm_user
│ │ ├── Add.vue
│ │ └── List.vue
│ ├── common
│ │ └── Api.vue
│ ├── db
│ │ ├── Add.vue
│ │ ├── Detail.vue
│ │ ├── List.vue
│ │ └── multiAdd.vue
│ ├── server
│ │ ├── Add.vue
│ │ ├── Detail.vue
│ │ ├── List.vue
│ │ └── multiAdd.vue
│ ├── server_auth
│ │ ├── Add.vue
│ │ ├── Detail.vue
│ │ └── List.vue
│ ├── server_group
│ │ ├── Add.vue
│ │ └── List.vue
│ ├── server_log
│ │ ├── List.vue
│ │ └── TtyLog.vue
│ ├── tag
│ │ ├── Add.vue
│ │ └── List.vue
│ └── webssh
│ │ ├── Console.vue
│ │ ├── Record.vue
│ │ ├── WebSSH.vue
│ │ └── Xterm.js
│ ├── cmdb2
│ ├── admin_user.vue
│ ├── asset_config.vue
│ ├── asset_idc.vue
│ ├── aws_events.vue
│ ├── db_detail.vue
│ ├── db_mg.vue
│ ├── log_audit.vue
│ ├── multi_add_db.vue
│ ├── multi_add_server.vue
│ ├── operational_audit.vue
│ ├── server_detail.vue
│ ├── server_mg.vue
│ ├── system_user.vue
│ ├── tag_mg.vue
│ ├── web_ssh.vue
│ └── webssh
│ │ ├── Console.vue
│ │ ├── Record.vue
│ │ ├── WebSSH.vue
│ │ ├── Xterm.js
│ │ └── web-ssh.vue
│ ├── components
│ ├── count-to
│ │ └── count-to.vue
│ ├── drag-list
│ │ └── drag-list.vue
│ ├── editor
│ │ └── editor.vue
│ ├── icons
│ │ └── icons.vue
│ ├── markdown
│ │ └── markdown.vue
│ ├── split-pane
│ │ └── split-pane.vue
│ └── tables
│ │ └── tables.vue
│ ├── confd
│ ├── config
│ │ ├── Add.vue
│ │ └── List.vue
│ └── project
│ │ ├── Add.vue
│ │ └── List2.vue
│ ├── cron
│ ├── cron-jobs.vue
│ └── cron-logs.vue
│ ├── devops-tools
│ ├── event-manager.vue
│ ├── fault-manager.vue
│ ├── paid-reminder.vue
│ ├── password-mycrypy.vue
│ ├── project-manager.vue
│ ├── prometheus-alert.vue
│ ├── remind-manager.vue
│ └── zabbix-mg.vue
│ ├── directive
│ └── directive.vue
│ ├── domain-name
│ ├── checkDomain.js
│ ├── cloud-account-mg.vue
│ ├── cloud-domain-manage.vue
│ ├── components
│ │ ├── domain-detail.vue
│ │ └── domain-edit.vue
│ ├── domain-name-manage.vue
│ ├── domain-name-monitor.vue
│ └── domain-records.vue
│ ├── error-page
│ ├── 403.vue
│ ├── 404.vue
│ ├── 500.vue
│ ├── back-btn-group.vue
│ ├── error-content.vue
│ └── error.less
│ ├── error-store
│ └── error-store.vue
│ ├── excel
│ ├── common.less
│ ├── export-excel.vue
│ └── upload-excel.vue
│ ├── i18n
│ └── i18n-page.vue
│ ├── join-page.vue
│ ├── k8s
│ ├── app
│ │ ├── Add.vue
│ │ ├── List.vue
│ │ └── ListDetail.vue
│ ├── project
│ │ ├── Add.vue
│ │ ├── List.vue
│ │ ├── ListDetail.vue
│ │ └── Publish.vue
│ └── publish
│ │ ├── Detail.vue
│ │ ├── List.vue
│ │ └── components
│ │ ├── Console.vue
│ │ ├── baseInfo.vue
│ │ ├── handle.vue
│ │ └── handleResult.vue
│ ├── login
│ ├── login.less
│ └── login.vue
│ ├── multilevel
│ ├── level-2-1.vue
│ ├── level-2-2
│ │ └── level-3-1.vue
│ └── level-2-3.vue
│ ├── publish-store
│ ├── components
│ │ └── task-list.vue
│ ├── project-conf.vue
│ ├── project-create.vue
│ ├── publish-list.vue
│ └── publish
│ │ ├── Detail.vue
│ │ ├── List.vue
│ │ ├── components
│ │ ├── Console.vue
│ │ ├── QAInfo.vue
│ │ ├── baseInfo.vue
│ │ ├── handle.vue
│ │ ├── handleResult.vue
│ │ ├── repoInfo.vue
│ │ └── task-list.vue-bak
│ │ └── detail-bak.vue
│ ├── scheduler
│ ├── args-list.vue
│ ├── command-list.vue
│ ├── task-template.vue
│ └── task-user.vue
│ ├── single-page
│ ├── error-logger.vue
│ └── home
│ │ ├── example.vue
│ │ ├── home.vue
│ │ ├── index.js
│ │ ├── issuesinfo.vue
│ │ ├── logininfo.vue
│ │ └── taskinfo.vue
│ ├── system-manage
│ ├── resource-management.vue
│ ├── system.vue
│ └── systemlog.vue
│ ├── task-order
│ ├── components
│ │ └── task-list.vue
│ ├── history-task-list.vue
│ └── task-order-list.vue
│ ├── tasks-center
│ ├── assets
│ │ ├── auto-rule.vue
│ │ ├── project-mg.vue
│ │ ├── proxy-info.vue
│ │ ├── resource-mg.vue
│ │ ├── tag-model.vue
│ │ └── tree-model.vue
│ ├── code-repository.vue-bak
│ ├── docker-registry.vue
│ ├── git-repo
│ │ └── code-repository.vue
│ ├── publish-config.vue
│ └── task-submit
│ │ ├── asset-purchase-aly.vue
│ │ ├── asset-purchase-aws.vue
│ │ ├── asset-purchase-conf.vue
│ │ ├── asset-purchase-qcloud.vue
│ │ ├── asset-purchase.vue
│ │ ├── common-jobs.vue
│ │ ├── create_task.vue
│ │ ├── k8s-node-add.vue
│ │ ├── mysql-audit.vue
│ │ ├── mysql-optimize.vue
│ │ ├── publish-app.vue
│ │ ├── task-custom-proxy.vue
│ │ ├── task-custom.vue
│ │ └── task-post.vue
│ ├── tools-methods
│ └── tools-methods.vue
│ ├── update
│ ├── update-paste.vue
│ └── update-table.vue
│ └── user-manage
│ ├── components
│ └── func-edit.vue
│ ├── functions.vue
│ ├── role.vue
│ ├── routescomponents.vue
│ └── user.vue
├── swagger-ui
├── favicon-16x16.png
├── favicon-32x32.png
├── index.html
├── oauth2-redirect.html
├── swagger-ui-bundle.js
├── swagger-ui-bundle.js.map
├── swagger-ui-standalone-preset.js
├── swagger-ui-standalone-preset.js.map
├── swagger-ui.css
├── swagger-ui.css.map
├── swagger-ui.js
├── swagger-ui.js.map
└── swagger.json
├── tests
├── e2e
│ ├── .eslintrc
│ ├── plugins
│ │ └── index.js
│ ├── specs
│ │ └── test.js
│ └── support
│ │ ├── commands.js
│ │ └── index.js
└── unit
│ ├── .eslintrc.js
│ └── HelloWorld.spec.js
└── vue.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@vue/app"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/.eslintignore
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | 'extends': [
4 | 'plugin:vue/essential',
5 | '@vue/standard'
6 | ],
7 | rules: {
8 | // allow async-await
9 | 'generator-star-spacing': 'off',
10 | // allow debugger during development
11 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
12 | 'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false }],
13 | 'no-undef': 'off'
14 | },
15 | parserOptions: {
16 | parser: 'babel-eslint'
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | /tests/e2e/videos/
6 | /tests/e2e/screenshots/
7 |
8 | # local env files
9 | .env.local
10 | .env.*.local
11 |
12 | # Log files
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 |
17 | # Editor directories and files
18 | .idea
19 | .vscode
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw*
25 |
26 | build/env.js
27 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: stable
3 | script: npm run lint
4 | notifications:
5 | email: false
6 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM centos:7 as build-stage
2 | # 设置编码
3 | ENV LANG en_US.UTF-8
4 | # 同步时间
5 | ENV TZ=Asia/Shanghai
6 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
7 |
8 | # 1. 安装基本依赖和nginx
9 | RUN yum update -y && yum install epel-release -y && yum update -y && yum install wget nginx git -y
10 | WORKDIR /app
11 |
12 | # 2. 准备node
13 | #RUN wget -q -c https://npm.taobao.org/mirrors/node/v10.16.1/node-v10.16.1-linux-x64.tar.xz && tar xf node-v10.16.1-linux-x64.tar.xz -C /usr/local/
14 | RUN wget -q -c https://nodejs.org/dist/v10.16.1/node-v10.16.1-linux-x64.tar.xz && tar xf node-v10.16.1-linux-x64.tar.xz -C /usr/local/
15 |
16 | RUN rm -rf /usr/local/bin/node && rm -rf /usr/local/bin/npm \
17 | && ln -s /usr/local/node-v10.16.1-linux-x64/bin/node /usr/local/bin/node \
18 | && ln -s /usr/local/node-v10.16.1-linux-x64/bin/node /usr/bin/node \
19 | && ln -s /usr/local/node-v10.16.1-linux-x64/bin/npm /usr/local/bin/npm \
20 | && ln -s /usr/local/node-v10.16.1-linux-x64/bin/npm /usr/bin/npm
21 |
22 | # 4. 复制代码
23 | RUN mkdir -p /app
24 | ADD . /app
25 |
26 | RUN rm -rf /app/node_modules && npm config set registry https://registry.npmjs.org/ \
27 | && npm cache clean --force \
28 | && npm install --ignore-script \
29 | && npm run build
30 |
31 |
32 | ############################
33 |
34 | FROM nginx as production
35 |
36 | MAINTAINER "shenshuo<191715030@qq.com>"
37 |
38 | RUN mkdir -p /var/www/codo
39 |
40 | WORKDIR /var/www/codo/
41 |
42 | COPY nginx_ops.conf /etc/nginx/conf.d/codo_frontend.conf
43 | COPY --from=build-stage /app/dist /var/www/codo
44 |
45 | EXPOSE 80
46 | EXPOSE 443
47 |
48 | STOPSIGNAL SIGTERM
49 |
50 | CMD ["nginx", "-g", "daemon off;"]
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 iView
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Install
2 |
3 | ```bash
4 | // install dependencies
5 | npm install --ignore-script
6 | ```
7 |
8 | ### Run
9 |
10 | #### Development
11 |
12 | ```bash
13 | npm run dev
14 | ```
15 |
16 | #### Production(Build)
17 |
18 | ```bash
19 | npm run build
20 | ```
21 |
22 | ### Docker 方式部署
23 |
24 | **修改`CODO_VER`release为最新的版本,静态文件的最终路径为 `/var/www/codo/`**
25 |
26 | ```bash
27 | echo -e "\033[32m [INFO]: codo(项目前端) Start install. \033[0m"
28 | CODO_VER="codo-beta-0.3.4"
29 | if ! which wget &>/dev/null; then yum install -y wget >/dev/null 2>&1;fi
30 | [ ! -d /var/www ] && mkdir -p /var/www
31 | cd /var/www && wget https://github.com/opendevops-cn/codo/releases/download/${CODO_VER}/${CODO_VER}.tar.gz
32 | tar zxf ${CODO_VER}.tar.gz
33 | if [ $? == 0 ];then
34 | echo -e "\033[32m [INFO]: codo(项目前端) install success. \033[0m"
35 | else
36 | echo -e "\033[31m [ERROR]: codo(项目前端) install faild \033[0m"
37 | exit -8
38 | fi
39 | ```
40 |
41 | **放置`nginx`配置文件,如果想使用https请自行修改nginx的配置文件,也可以参考项目下的`nginx_ops.conf`文件。**
42 |
43 | **如果需要修改前端的访问域名可以直接修改配置文件中的server_name,proxy_pass对应的地址为网关地址,一定要和网关地址端口进行对应。**
44 |
45 | ```bash
46 | mkdir -p /my/nginx/conf.d/
47 | cat >/my/nginx/conf.d/codo-init.conf<<\EOF
48 | server {
49 | listen 80;
50 | server_name demo-init.opendevops.cn;
51 | access_log /var/log/nginx/codo-access.log;
52 | error_log /var/log/nginx/codo-error.log;
53 |
54 | location / {
55 | root /var/www/codo;
56 | index index.html index.htm;
57 | try_files $uri $uri/ /index.html;
58 | }
59 | location /api {
60 | ### ws 支持
61 | proxy_http_version 1.1;
62 | proxy_set_header Upgrade $http_upgrade;
63 | proxy_set_header Connection "upgrade";
64 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
65 |
66 | add_header 'Access-Control-Allow-Origin' '*';
67 | proxy_pass http://gw.opendevops.cn:8888;
68 | }
69 |
70 | location ~ /(.svn|.git|admin|manage|.sh|.bash)$ {
71 | return 403;
72 | }
73 | }
74 | EOF
75 | ```
76 |
77 | ```bash
78 | #bulid 镜像
79 | docker build . -t codo_image
80 | #启动
81 | docker-compose up -d
82 | ```
83 |
84 | - 测试一下 `ls /var/www/codo/index.html` 看下前端文件是不是存在
85 | - 测试一下 `ls /my/nginx/conf.d/codo-init.conf` 看下nginx配置文件是不是存在
86 | - swagger-ui 复制到/var/www/codo/目录即可,详情请参考安装文档。 命令如下:cd /opt/codo/codo && \cp -r swagger-ui/ /var/www/codo/
87 |
88 | ## License
89 |
90 | [MIT](http://opensource.org/licenses/MIT)
91 |
92 | Copyright (c) 2016-present, iView
93 |
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "pluginsFile": "tests/e2e/plugins/index.js"
3 | }
4 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | codo:
2 | restart: unless-stopped
3 | image: codo_image
4 | volumes:
5 | - /var/log/nginx/:/var/log/nginx/
6 | - /var/www/codo/:/var/www/codo/
7 | - /my/nginx/conf.d/:/etc/nginx/conf.d/
8 | - /sys/fs/cgroup:/sys/fs/cgroup
9 | ports:
10 | - "80:80"
11 | - "443:443"
--------------------------------------------------------------------------------
/nginx_ops.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name demo-init.opendevops.cn;
4 | access_log /var/log/nginx/codo-access.log;
5 | error_log /var/log/nginx/codo-error.log;
6 |
7 | location / {
8 | root /var/www/codo;
9 | index index.html index.htm;
10 | try_files $uri $uri/ /index.html;
11 | }
12 | location /api {
13 | ### ws 支持
14 | proxy_http_version 1.1;
15 | proxy_set_header Upgrade $http_upgrade;
16 | proxy_set_header Connection "upgrade";
17 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
18 |
19 | add_header 'Access-Control-Allow-Origin' '*';
20 | proxy_pass http://gw.opendevops.cn:8888;
21 | }
22 |
23 | location ~ /(.svn|.git|admin|manage|.sh|.bash)$ {
24 | return 403;
25 | }
26 | }
27 |
28 | ### 下面是使用https,要注意放置证书
29 | # server {
30 | # listen 80;
31 | # server_name demo-init.opendevops.cn;
32 | # rewrite ^(.*)$ https://$host$1 permanent;
33 | # }
34 |
35 | # server {
36 | # listen 443;
37 | # server_name demo-init.opendevops.cn;
38 | # access_log /var/log/nginx/codo-access.log;
39 | # error_log /var/log/nginx/codo-error.log;
40 | # ssl on;
41 | # index index.html index.htm;
42 | # ssl_certificate opendevops.crt;
43 | # ssl_certificate_key opendevops.key;
44 | # ssl_session_timeout 5m;
45 | # ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS;
46 | # ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
47 | # ssl_prefer_server_ciphers on;
48 |
49 | # location / {
50 | # root /var/www/codo;
51 | # index index.html index.htm;
52 | # try_files $uri $uri/ /index.html;
53 | # }
54 |
55 | # location /api {
56 | # proxy_redirect off;
57 | # proxy_read_timeout 600;
58 | # proxy_http_version 1.1;
59 | # proxy_set_header Upgrade $http_upgrade;
60 | # proxy_set_header Connection "upgrade";
61 | # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
62 |
63 | # add_header 'Access-Control-Allow-Origin' '*';
64 | # proxy_pass http://gw.opendevops.cn:8888;
65 | # }
66 |
67 | # location ~ /(.svn|.git|admin|manage|.sh|.bash)$ {
68 | # return 403;
69 | # }
70 | # }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "codo",
3 | "version": "1.0.0",
4 | "author": "ss<191715030@qq.com>",
5 | "private": false,
6 | "scripts": {
7 | "dev": "vue-cli-service serve --open",
8 | "build": "vue-cli-service build",
9 | "lint": "vue-cli-service lint",
10 | "test:unit": "vue-cli-service test:unit",
11 | "test:e2e": "vue-cli-service test:e2e"
12 | },
13 | "dependencies": {
14 | "@riophae/vue-treeselect": "0.0.38",
15 | "axios": "^0.18.1",
16 | "babel-core": "^6.26.3",
17 | "babel-loader": "^8.0.5",
18 | "clipboard": "^2.0.0",
19 | "clonedeep": "^2.0.0",
20 | "codemirror": "^5.38.0",
21 | "countup": "^1.8.2",
22 | "cropperjs": "^1.2.2",
23 | "dayjs": "^1.7.7",
24 | "echarts": "^4.0.4",
25 | "html2canvas": "^1.0.0-alpha.12",
26 | "iview-area": "^1.5.17",
27 | "js-cookie": "^2.2.0",
28 | "jwt-decode": "^2.2.0",
29 | "qrcode": "^1.3.0",
30 | "qrcodejs2": "0.0.2",
31 | "simplemde": "^1.11.2",
32 | "sortablejs": "^1.7.0",
33 | "view-design": "^4.1.3",
34 | "vue": "^2.5.10",
35 | "vue-clipboard2": "^0.2.1",
36 | "vue-i18n": "^7.8.0",
37 | "vue-qart": "^2.2.0",
38 | "vue-router": "^3.0.1",
39 | "vue-websocket": "^0.2.3",
40 | "vue2-ace-editor": "0.0.13",
41 | "vuedraggable": "^2.16.0",
42 | "vuex": "^3.0.1",
43 | "vuex-persistedstate": "^2.5.4",
44 | "wangeditor": "^3.1.1",
45 | "xlsx": "^0.13.3",
46 | "xterm": "^3.9.1"
47 | },
48 | "devDependencies": {
49 | "@vue/cli-plugin-babel": "^3.0.1",
50 | "@vue/cli-plugin-eslint": "^3.0.1",
51 | "@vue/cli-plugin-unit-mocha": "^3.0.1",
52 | "@vue/cli-service": "^3.0.1",
53 | "@vue/eslint-config-standard": "^3.0.0-beta.10",
54 | "@vue/test-utils": "^1.0.0-beta.10",
55 | "chai": "^4.1.2",
56 | "eslint-plugin-cypress": "^2.0.1",
57 | "less": "^2.7.3",
58 | "less-loader": "^4.0.5",
59 | "lint-staged": "^6.0.0",
60 | "mockjs": "^1.0.1-beta3",
61 | "vue-template-compiler": "^2.5.13"
62 | },
63 | "browserslist": [
64 | "> 1%",
65 | "last 2 versions",
66 | "not ie <= 8"
67 | ],
68 | "gitHooks": {
69 | "pre-commit": "lint-staged"
70 | },
71 | "lint-staged": {
72 | "*.js": [
73 | "vue-cli-service lint",
74 | "git add"
75 | ],
76 | "*.vue": [
77 | "vue-cli-service lint",
78 | "git add"
79 | ]
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CODO
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
28 |
--------------------------------------------------------------------------------
/src/api/app.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getLoglist = (page, limit, key, value, date = ['', '']) => {
4 | return axios.request({
5 | url: '/mg/v2/app/opt_log/',
6 | method: 'get',
7 | params: {
8 | page,
9 | limit,
10 | key,
11 | value,
12 | start_date: date[0],
13 | end_date: date.length > 1 ? date[1] : ''
14 | }
15 | })
16 | }
17 |
18 | // 系统配置项
19 | // 发布应用选择
20 | export const getSysconfig = (value) => {
21 | return axios.request({
22 | url: `/mg/v2/sysconfig/settings/${value}/`,
23 | method: 'get'
24 | })
25 | }
26 |
27 | export const operationSysconfig = (data, meth) => {
28 | return axios.request({
29 | url: '/mg/v2/sysconfig/settings/set/',
30 | method: 'post',
31 | data
32 | })
33 | }
34 | // 检查配置
35 | export const CheckSysconfig = (data) => {
36 | return axios.request({
37 | url: '/mg/v2/sysconfig/check/',
38 | method: 'post',
39 | data
40 | })
41 | }
42 |
--------------------------------------------------------------------------------
/src/api/cmdb/adm_user.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有管理用户
4 | export const getTableData = () => {
5 | return axios.request({
6 | url: '/cmdb/v1/cmdb/adm_user/',
7 | method: 'get'
8 | })
9 | }
10 |
11 | // 添加或修改管理用户
12 | export const Add = (data, url, action) => {
13 | return axios.request({
14 | url: `/cmdb/v1/cmdb/adm_user${url}`,
15 | method: action,
16 | data
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/src/api/cmdb/db.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有主机
4 | export const getDBData = (params) => {
5 | return axios.request({
6 | url: '/cmdb/v1/cmdb/db/',
7 | method: 'get',
8 | params
9 | })
10 | }
11 |
12 | // 添加或修改DB
13 | export const addDBServer = (data, url, action) => {
14 | return axios.request({
15 | url: `/cmdb/v1/cmdb/db${url}`,
16 | method: action,
17 | data
18 | })
19 | }
20 |
21 | // 批量添加主机
22 | export const multiAdd = (data) => {
23 | return axios.request({
24 | url: '/cmdb/v1/cmdb/db_multiadd/',
25 | method: 'post',
26 | data
27 | })
28 | }
29 |
30 | // 批量删除主机
31 | export const delMulti = (data) => {
32 | return axios.request({
33 | url: '/cmdb/v1/cmdb/db_multidel/',
34 | method: 'post',
35 | data
36 | })
37 | }
38 |
39 | // 删除主机
40 | export const delDB = (id) => {
41 | return axios.request({
42 | url: `/cmdb/v1/cmdb/db/${id}`,
43 | method: 'delete'
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/src/api/cmdb/server.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 | import config from '@/config'
3 |
4 | // 获取所有主机
5 | export const getTableData = (params) => {
6 | return axios.request({
7 | url: '/cmdb/v1/cmdb/server/',
8 | method: 'get',
9 | params
10 | })
11 | }
12 | // // 根据条件搜索主机
13 | // export const searchTableData = (key, value) => {
14 | // return axios.request({
15 | // url: `/api/cmdb/server/?${key}=${value}`,
16 | // method: 'get'
17 | // })
18 | // }
19 |
20 | // 获取所有管理用户
21 | export const getAdmUser = () => {
22 | return axios.request({
23 | url: '/cmdb/v1/cmdb/adm_user/',
24 | method: 'get'
25 | })
26 | }
27 |
28 | // 获取所有主机组 getGroupList
29 | export const getGroupList = () => {
30 | return axios.request({
31 | url: '/cmdb/v1/cmdb/server_group/',
32 | method: 'get'
33 | })
34 | }
35 |
36 | // 获取所有主机组 getTagList
37 | export const getTagList = () => {
38 | return axios.request({
39 | url: '/cmdb/v1/cmdb/tag/',
40 | method: 'get'
41 | })
42 | }
43 |
44 | // 添加或修改主机
45 | export const addProject = (data, url, action) => {
46 | return axios.request({
47 | url: `/cmdb/v1/cmdb/server${url}`,
48 | method: action,
49 | data
50 | })
51 | }
52 |
53 | // 批量添加主机
54 | export const multiAdd = (data) => {
55 | return axios.request({
56 | url: '/cmdb/v1/cmdb/server_multiadd/',
57 | method: 'post',
58 | data
59 | })
60 | }
61 |
62 | // 删除主机
63 | export const delServer = (id) => {
64 | return axios.request({
65 | url: `/cmdb/v1/cmdb/server/${id}`,
66 | method: 'delete'
67 | })
68 | }
69 |
70 | // 批量删除主机
71 | export const delMultiServer = (data) => {
72 | return axios.request({
73 | url: '/cmdb/v1/cmdb/server_multidel/',
74 | method: 'post',
75 | data
76 | })
77 | }
78 |
79 | // 更新资产
80 | export const rsyncHostData = (data) => {
81 | return axios.request({
82 | url: '/cmdb/v1/cmdb/server_update/',
83 | method: 'post',
84 | data
85 | })
86 | }
87 |
88 | // 推送公钥
89 | export const rsyncPublicKeyData = (data) => {
90 | return axios.request({
91 | url: '/cmdb/v1/cmdb/server_publickey/',
92 | method: 'post',
93 | data
94 | })
95 | }
96 |
97 | // WEB Socket
98 | // export const webSocketUrl = 'ws://cmdb.opendevops.cn:8002/v1/cmdb/ws/terminal' 内网
99 | // export const webSocketUrl = 'ws://demo.opendevops.cn/api/cmdb/v1/cmdb/ws/terminal' // 外网
100 | const theDomain = process.env.NODE_ENV === 'development' ? 'demo.opendevops.cn' : config.domainName.pro
101 | // const theDomain = process.env.NODE_ENV === 'development' ? config.domainName.dev : config.domainName.pro
102 | const wsuri = '/cmdb/v1/cmdb/ws/terminal'
103 | const ws = config.isHttps ? 'wss' : 'ws'
104 | export const webSocketUrl = ws + '://' + theDomain + '/api' + wsuri
105 |
--------------------------------------------------------------------------------
/src/api/cmdb/server_auth.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有授权规则
4 | export const getTableData = (params) => {
5 | return axios.request({
6 | url: '/cmdb/v1/cmdb/server_auth/',
7 | method: 'get',
8 | params
9 | })
10 | }
11 |
12 | // 添加或修改授权策略
13 | export const addRule = (data, url, action) => {
14 | return axios.request({
15 | url: `/cmdb/v1/cmdb/server_auth${url}`,
16 | method: action,
17 | data
18 | })
19 | }
20 |
21 | // 删除授权策略
22 | export const delRule = (id) => {
23 | return axios.request({
24 | url: `/cmdb/v1/cmdb/server_auth/${id}`,
25 | method: 'delete'
26 | })
27 | }
28 |
29 | // 获取系统用户列表
30 | export const getSystemUser = () => {
31 | return axios.request({
32 | url: '/mg/v2/accounts/user/',
33 | method: 'get',
34 | params: {
35 | 'page': '1',
36 | 'limit': '10000'
37 | }
38 | })
39 | }
40 |
41 | // gw接口登录
42 | export const loginGW = () => {
43 | return axios.request({
44 | url: '/cmdb/v1/accounts/login/',
45 | method: 'post',
46 | data: {
47 | 'username': 'cmdb',
48 | 'password': 'GpJSWhgZs8hfDLR',
49 | 'dynamic': ''
50 | }
51 | })
52 | }
53 |
54 | // 判断当前用户对资产是否有权限
55 | export const checkAuthServer = (sid) => {
56 | return axios.request({
57 | url: '/cmdb/v1/cmdb/server_check_auth/',
58 | method: 'get',
59 | params: {
60 | // 'username': user,
61 | 'sid': sid
62 | }
63 | })
64 | }
65 |
--------------------------------------------------------------------------------
/src/api/cmdb/server_group.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有主机
4 | export const getTableData = () => {
5 | return axios.request({
6 | url: '/cmdb/v1/cmdb/server_group/',
7 | method: 'get'
8 | })
9 | }
10 |
11 | // 添加或修改主机组
12 | export const addServerGroup = (data, url, action) => {
13 | return axios.request({
14 | url: `/cmdb/v1/cmdb/server_group${url}`,
15 | method: action,
16 | data
17 | })
18 | }
19 |
20 | // 删除主机
21 | export const delGroup = (id) => {
22 | return axios.request({
23 | url: `/cmdb/v1/cmdb/server_group/${id}`,
24 | method: 'delete'
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/src/api/cmdb/server_log.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有登录日志
4 | export const getLogData = (params) => {
5 | return axios.request({
6 | url: '/cmdb/v1/cmdb/server_log/',
7 | method: 'get',
8 | params
9 | })
10 | }
11 |
12 | // 获取所有Tty日志
13 | export const getTtyLogData = (lid) => {
14 | return axios.request({
15 | url: `/cmdb/v1/cmdb/server_ttylog/?log_id=${lid}`,
16 | method: 'get'
17 | })
18 | }
19 |
20 | // 获取回放日志
21 | export const getRecordData = (lid) => {
22 | return axios.request({
23 | url: `/cmdb/v1/cmdb/server_recordlog/?log_id=${lid}`,
24 | method: 'get'
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/src/api/cmdb/tag.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有tag
4 | export const getTableData = () => {
5 | return axios.request({
6 | url: '/cmdb/v1/cmdb/tag/',
7 | method: 'get'
8 | })
9 | }
10 |
11 | // 添加或修改tag
12 | export const addTag = (data, url, action) => {
13 | return axios.request({
14 | url: `/cmdb/v1/cmdb/tag${url}`,
15 | method: action,
16 | data
17 | })
18 | }
19 |
20 | // 删除tag
21 | export const delTag = (id) => {
22 | return axios.request({
23 | url: `/cmdb/v1/cmdb/tag/${id}`,
24 | method: 'delete'
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/src/api/cmdb2/admin_user.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 |
4 | export const getAdminUserList = (key, value) => {
5 | return axios.request({
6 | url: '/cmdb2/v1/cmdb/admin_user/',
7 | method: 'get',
8 | params: {
9 | key,
10 | value
11 | }
12 | })
13 | }
14 |
15 | export const operationAdminUser = (data, meth) => {
16 | return axios.request({
17 | url: '/cmdb2/v1/cmdb/admin_user/',
18 | method: meth,
19 | data
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/src/api/cmdb2/asset_config.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 |
4 | // 获取RDS信息
5 | export const handleUpdateredis = () => {
6 | return axios.request({
7 | url: '/cmdb2/v1/cmdb/asset_configs/handler_update_redis/',
8 | method: 'get'
9 |
10 | })
11 | }
12 |
13 | // 获取RDS信息
14 | export const handleUpdaterds = () => {
15 | return axios.request({
16 | url: '/cmdb2/v1/cmdb/asset_configs/handler_update_rds/',
17 | method: 'get'
18 |
19 | })
20 | }
21 |
22 | // 获取EC2信息
23 | export const handleUpdateserver = () => {
24 | return axios.request({
25 | url: '/cmdb2/v1/cmdb/asset_configs/handler_update_server/',
26 | method: 'get'
27 |
28 | })
29 | }
30 |
31 | export const getAssetConfigsList = (key, value) => {
32 | return axios.request({
33 | url: '/cmdb2/v1/cmdb/asset_configs/',
34 | method: 'get',
35 | params: {
36 | key,
37 | value
38 | }
39 | })
40 | }
41 |
42 | export const operationAssetConfigs = (data, meth) => {
43 | return axios.request({
44 | url: '/cmdb2/v1/cmdb/asset_configs/',
45 | method: meth,
46 | data
47 | })
48 | }
49 |
50 |
51 | // 测试用户填写的数据是否正确
52 | export const apiPermission = (data) => {
53 | return axios.request({
54 | url: '/cmdb2/v1/cmdb/asset_configs/api_permission/',
55 | method: 'post',
56 | data
57 | })
58 | }
59 |
60 | // // 测试用户输入的ID/Key/region等信息是否正确(ECS)
61 | // export const ecsAuth = (data) => {
62 | // return axios.request({
63 | // url: '/cmdb2/v1/cmdb/asset_configs/ecs_auth/',
64 | // method: 'post',
65 | // data
66 | // })
67 | // }
68 |
69 | // // 测试用户输入的ID/Key/region等信息是否正确(RDS)
70 | // export const rdsAuth = (data) => {
71 | // return axios.request({
72 | // url: '/cmdb2/v1/cmdb/asset_configs/rds_auth/',
73 | // method: 'post',
74 | // data
75 | // })
76 | // }
77 |
78 | // // 测试用户输入的ID/Key/region等信息是否正确(redis)
79 | // export const redisAuth = (data) => {
80 | // return axios.request({
81 | // url: '/cmdb2/v1/cmdb/asset_configs/redis_auth/',
82 | // method: 'post',
83 | // data
84 | // })
85 | // }
86 |
--------------------------------------------------------------------------------
/src/api/cmdb2/audit.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取IDC list
4 | export const getLoglist = (page, limit, key, value, date = ['', '']) => {
5 | return axios.request({
6 | url: '/cmdb2/v1/cmdb/operational_audit/',
7 | method: 'get',
8 | params: {
9 | page,
10 | limit,
11 | key,
12 | value,
13 | start_date: date[0],
14 | end_date: date.length > 1 ? date[1] : ''
15 | }
16 | })
17 | }
18 |
19 |
20 |
21 | // export const getoperationalAuditlist= (key, value) => {
22 | // return axios.request({
23 | // url: '/cmdb2/v1/cmdb/operational_audit/',
24 | // method: 'get',
25 | // params: {
26 | // key,
27 | // value,
28 | // }
29 | // })
30 | // }
31 |
32 |
33 | // export const getoperationalAuditlist = (page, limit, key, value, date = ['', '']) => {
34 | // return axios.request({
35 | // url: '/cmdb2/v1/cmdb/operational_audit/',
36 | // method: 'get',
37 | // params: {
38 | // page,
39 | // limit,
40 | // key,
41 | // value,
42 | // start_date: date[0],
43 | // end_date: date.length > 1 ? date[1] : ''
44 | // }
45 | // })
46 | // }
--------------------------------------------------------------------------------
/src/api/cmdb2/db.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 | import config from '@/config'
3 |
4 |
5 | //批量添加DB
6 | export const multiAdddb = (data) => {
7 | return axios.request({
8 | url: '/cmdb2//v1/cmdb/db/multi_add/',
9 | method: 'post',
10 | data
11 | })
12 | }
13 |
14 | //获取DBlist
15 | export const getDBlist= ( page, limit, key, value) => {
16 | return axios.request({
17 | url: '/cmdb2/v1/cmdb/db/',
18 | method: 'get',
19 | params: {
20 | key,
21 | value,
22 | page,
23 | limit
24 | }
25 | })
26 | }
27 |
28 | //获取DB详情
29 | export const getDBDetail= ( key, value) => {
30 | return axios.request({
31 | url: '/cmdb2/v1/cmdb/db/',
32 | method: 'get',
33 | params: {
34 | key,
35 | value,
36 | // page,
37 | // limit
38 | }
39 | })
40 | }
41 |
42 | //操作DB
43 | export const operationDB = (data, meth) => {
44 | return axios.request({
45 | url: '/cmdb2/v1/cmdb/db/',
46 | method: meth,
47 | data
48 | })
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/src/api/cmdb2/idc.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取IDC list
4 |
5 | export const getIDClist= (key, value) => {
6 | return axios.request({
7 | url: '/cmdb2/v1/cmdb/idc/',
8 | method: 'get',
9 | params: {
10 | key,
11 | value,
12 | }
13 | })
14 | }
15 |
16 | // 操作IDC管理
17 | export const operationIdc = (data, meth) => {
18 | return axios.request({
19 | url: '/cmdb2/v1/cmdb/idc/',
20 | method: meth,
21 | data
22 | })
23 | }
--------------------------------------------------------------------------------
/src/api/cmdb2/system_user.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 |
4 | export const getSystemUserList = (key, value) => {
5 | return axios.request({
6 | url: '/cmdb2/v1/cmdb/system_user/',
7 | method: 'get',
8 | params: {
9 | key,
10 | value
11 | }
12 | })
13 | }
14 |
15 | export const operationSystemUser = (data, meth) => {
16 | return axios.request({
17 | url: '/cmdb2/v1/cmdb/system_user/',
18 | method: meth,
19 | data
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/src/api/cmdb2/tag.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 | import config from '@/config'
3 |
4 | //触发更新tag_rule
5 | export const handUpdateTagrule = (data) => {
6 | return axios.request({
7 | url: '/cmdb2/v1/cmdb/tag_rule/hand_update/',
8 | method: 'post',
9 | data
10 | })
11 | }
12 |
13 | //GET 更新所有规则
14 | export const handUpdateAlltagrule = () => {
15 | return axios.request({
16 | url: '/cmdb2/v1/cmdb/tag_rule/hand_update/',
17 | method: 'get'
18 | })
19 | }
20 |
21 | // 获取所有tag规则
22 | export const getTagRulelist = (page, limit, key, value, date = ['', '']) => {
23 | return axios.request({
24 | url: '/cmdb2/v1/cmdb/tag_rule/',
25 | method: 'get',
26 | params: {
27 | page,
28 | limit,
29 | key,
30 | value,
31 | start_date: date[0],
32 | end_date: date.length > 1 ? date[1] : ''
33 | }
34 | })
35 | }
36 |
37 | export const operationTagrule = (data, meth) => {
38 | return axios.request({
39 | url: '/cmdb2/v1/cmdb/tag_rule/',
40 | method: meth,
41 | data
42 | })
43 | }
44 |
45 | // 获取所有TAG
46 | export const getTagList = (page, limit, key, value, date = ['', '']) => {
47 | return axios.request({
48 | url: '/cmdb2/v1/cmdb/tag/',
49 | method: 'get',
50 | params: {
51 | page,
52 | limit,
53 | key,
54 | value,
55 | start_date: date[0],
56 | end_date: date.length > 1 ? date[1] : ''
57 | }
58 | })
59 | }
60 |
61 | export const operationTag= (data, meth) => {
62 | return axios.request({
63 | url: '/cmdb2/v1/cmdb/tag/',
64 | method: meth,
65 | data
66 | })
67 | }
--------------------------------------------------------------------------------
/src/api/confd/conf.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 根据project_code获取confTree
4 | export const getConfTree = (name) => {
5 | return axios.request({
6 | url: '/kerrigan/v1/conf/tree/',
7 | method: 'get',
8 | params: {
9 | project_code: name
10 | }
11 | })
12 | }
13 |
14 | export const getConf = (params) => {
15 | return axios.request({
16 | url: '/kerrigan/v1/conf/config/',
17 | method: 'get',
18 | params
19 | })
20 | }
21 |
22 | export const putConf = (data) => {
23 | return axios.request({
24 | url: '/kerrigan/v1/conf/config/',
25 | method: 'put',
26 | data
27 | })
28 | }
29 |
30 | export const postConf = (data) => {
31 | return axios.request({
32 | url: '/kerrigan/v1/conf/config/',
33 | method: 'post',
34 | data
35 | })
36 | }
37 |
38 | export const patchConf = (data) => {
39 | return axios.request({
40 | url: '/kerrigan/v1/conf/config/',
41 | method: 'patch',
42 | data
43 | })
44 | }
45 |
46 | export const deleteConf = (data) => {
47 | return axios.request({
48 | url: '/kerrigan/v1/conf/config/',
49 | method: 'delete',
50 | data
51 | })
52 | }
53 |
54 | export const diffConf = (params) => {
55 | return axios.request({
56 | url: '/kerrigan/v1/conf/diff/',
57 | method: 'get',
58 | params
59 | })
60 | }
61 |
62 | export const getHistory = (params) => {
63 | return axios.request({
64 | url: '/kerrigan/v1/conf/history/',
65 | method: 'get',
66 | params
67 | })
68 | }
69 |
70 | export const backHistory = (data) => {
71 | return axios.request({
72 | url: '/kerrigan/v1/conf/history/',
73 | method: 'patch',
74 | data
75 | })
76 | }
77 |
78 | export const getAuth = (params) => {
79 | return axios.request({
80 | url: '/kerrigan/v1/conf/permissions/',
81 | method: 'get',
82 | params
83 | })
84 | }
85 |
86 | export const setAuth = (data, action) => {
87 | return axios.request({
88 | url: '/kerrigan/v1/conf/permissions/',
89 | method: action,
90 | data
91 | })
92 | }
93 |
--------------------------------------------------------------------------------
/src/api/confd/project.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有项目
4 | export const getProject = (params) => {
5 | return axios.request({
6 | url: '/kerrigan/v1/conf/project/',
7 | method: 'get',
8 | params
9 | })
10 | }
11 |
12 | // 添加项目
13 | export const addProject = (data) => {
14 | return axios.request({
15 | url: '/kerrigan/v1/conf/project/',
16 | method: 'post',
17 | data
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/src/api/cron.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getCronJobslist = (page, limit, value) => {
4 | return axios.request({
5 | url: '/cron//v1/cron/job/',
6 | method: 'get',
7 | params: {
8 | page,
9 | limit,
10 | 'job_id': value
11 | }
12 | })
13 | }
14 |
15 | export const operationCron = (data, meth) => {
16 | return axios.request({
17 | url: '/cron//v1/cron/job/',
18 | method: meth,
19 | data
20 | })
21 | }
22 |
23 | export const getCronLoglist = (page, limit, key, value, date = ['', '']) => {
24 | return axios.request({
25 | url: '/cron//v1/cron/log/',
26 | method: 'get',
27 | params: {
28 | page,
29 | limit,
30 | key,
31 | value,
32 | start_date: date[0],
33 | end_date: date.length > 1 ? date[1] : ''
34 | }
35 | })
36 | }
37 |
--------------------------------------------------------------------------------
/src/api/dashboard/home.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 | import config from '@/config'
3 |
4 |
5 | // 获取Tag,Home仪表盘拼图展示
6 | export const getTagList = () => {
7 | return axios.request({
8 | url: '/cmdb2/v1/cmdb/tag/',
9 | method: 'get',
10 | })
11 | }
12 |
13 | // 任务订单
14 | export const getTaskOrderlist = () => {
15 | return axios.request({
16 | url: '/task/v2/task/list/',
17 | method: 'get'
18 | })
19 | }
20 |
21 |
22 | // 历史任务订单状态+数量
23 | export const getTaskStatementlist = () => {
24 | return axios.request({
25 | url: '/task/v2/task/statement/',
26 | method: 'get'
27 | })
28 | }
--------------------------------------------------------------------------------
/src/api/data.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getTableData = () => {
4 | return axios.request({
5 | url: 'get_table_data',
6 | method: 'get'
7 | })
8 | }
9 |
10 | export const getDragList = () => {
11 | return axios.request({
12 | url: 'get_drag_list',
13 | method: 'get'
14 | })
15 | }
16 |
17 | export const errorReq = () => {
18 | return axios.request({
19 | url: 'error_url',
20 | method: 'post'
21 | })
22 | }
23 |
24 | export const saveErrorLogger = info => {
25 | return axios.request({
26 | url: 'save_error_logger',
27 | data: info,
28 | method: 'post'
29 | })
30 | }
31 |
--------------------------------------------------------------------------------
/src/api/domain/dns.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getDomainname= (key, value) => {
4 | return axios.request({
5 | url: '/dns/v1/dns/bind/domain/',
6 | method: 'get',
7 | params: {
8 | key,
9 | value
10 | }
11 | })
12 | }
13 |
14 | export const operationDomainname= (data, meth) => {
15 | return axios.request({
16 | url: '/dns/v1/dns/bind/domain/',
17 | method: meth,
18 | data
19 | })
20 | }
21 |
22 | export const getDomainzone= (page, limit, zone, key) => {
23 | return axios.request({
24 | url: '/dns/v1/dns/bind/zone/',
25 | method: 'get',
26 | params: {
27 | page,
28 | limit,
29 | zone,
30 | key
31 | }
32 | })
33 | }
34 |
35 | export const operationDomainzone= (data, meth) => {
36 | return axios.request({
37 | url: '/dns/v1/dns/bind/zone/',
38 | method: meth,
39 | data
40 | })
41 | }
42 |
43 | export const getLoglist= (domain) => {
44 | return axios.request({
45 | url: '/dns/v1/dns/bind/log/',
46 | method: 'get',
47 | params: {
48 | domain
49 | }
50 | })
51 | }
52 |
53 | export const getDomainconf= () => {
54 | return axios.request({
55 | url: '/dns/v1/dns/bind/conf/',
56 | method: 'get',
57 | })
58 | }
59 |
--------------------------------------------------------------------------------
/src/api/domain/domain.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getDomain = (search_value) => {
4 | return axios.request({
5 | url: '/dns/v1/dns/cloud/domain/',
6 | method: 'get',
7 | params: {
8 | search_value
9 | }
10 | })
11 | }
12 |
13 | export const operationDomain = (data, method) => {
14 | return axios.request({
15 | url: '/dns/v1/dns/cloud/domain/',
16 | method: method,
17 | data
18 | })
19 | }
20 |
21 | export const syncDomain = (key, value) => {
22 | return axios.request({
23 | url: '/dns/v1/dns/cloud/sync/',
24 | method: 'get'
25 | })
26 | }
27 |
28 | export const getDomainRecords = (page, limit, domain_name, search_value) => {
29 | return axios.request({
30 | url: '/dns/v1/dns/cloud/record/',
31 | method: 'get',
32 | params: {
33 | page,
34 | limit,
35 | domain_name,
36 | search_value
37 | }
38 | })
39 | }
40 |
41 | export const optDomainRecords = (data, method) => {
42 | return axios.request({
43 | url: '/dns/v1/dns/cloud/record/',
44 | method: method,
45 | data
46 | })
47 | }
48 |
49 | export const recordsChangeRemark = (data) => {
50 | return axios.request({
51 | url: '/dns/v1/dns/cloud/remark/',
52 | method: 'post',
53 | data
54 | })
55 | }
56 |
57 | export const getDomainLog = (page, limit, domain_name, search_value) => {
58 | return axios.request({
59 | url: '/dns/v1/dns/cloud/logs/',
60 | method: 'get',
61 | params: {
62 | page,
63 | limit,
64 | domain_name,
65 | search_value
66 | }
67 | })
68 | }
69 | export const getAccountlist = () => {
70 | return axios.request({
71 | url: '/dns/v1/dns/cloud/account/',
72 | method: 'get'
73 | })
74 | }
75 |
76 | export const operationAccount = (data, method) => {
77 | return axios.request({
78 | url: '/dns/v1/dns/cloud/account/',
79 | method: method,
80 | data
81 | })
82 | }
--------------------------------------------------------------------------------
/src/api/git-repo.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getGittree = () => {
4 | return axios.request({
5 | url: '/task/other/v1/git/tree/',
6 | method: 'get'
7 | })
8 | }
9 |
10 | export const getGittree2 = () => {
11 | return axios.request({
12 | url: '/task/other/v1/git/tree2/',
13 | method: 'get'
14 | })
15 | }
16 |
17 | export const getGitrepo = (git_url, group_name, searchVal) => {
18 | return axios.request({
19 | url: '/task/other/v1/git/repo/',
20 | method: 'get',
21 | params: {
22 | git_url,
23 | group_name,
24 | 'search_val': searchVal
25 | }
26 | })
27 | }
28 |
29 | export const optGitrepo = (data, meth) => {
30 | return axios.request({
31 | url: '/task/other/v1/git/repo/',
32 | method: meth,
33 | data
34 | })
35 | }
36 |
37 | export const getGituser = (git_url, group_name) => {
38 | return axios.request({
39 | url: '/task/other/v1/git/user/',
40 | method: 'get',
41 | params: {
42 | git_url,
43 | group_name,
44 | }
45 | })
46 | }
47 |
48 | export const optGithooks = (data, meth) => {
49 | return axios.request({
50 | url: '/task/other/v1/git/hooks/',
51 | method: meth,
52 | data
53 | })
54 | }
55 |
56 | export const getGitHooklog = (search_val, git_url, relative_path, hook_name) => {
57 | return axios.request({
58 | url: '/task/other/v1/git/logs/',
59 | method: 'get',
60 | params: {
61 | search_val,
62 | git_url,
63 | relative_path,
64 | hook_name
65 | }
66 | })
67 | }
68 |
69 | export const optGitHooklog = (data) => {
70 | return axios.request({
71 | url: '/task/other/v1/git/logs/',
72 | method: 'delete',
73 | data
74 | })
75 | }
76 |
77 | export const getGitConflist = () => {
78 | return axios.request({
79 | url: '/task/other/v1/git/conf/',
80 | method: 'get'
81 | })
82 | }
83 |
84 | export const optGitconf = (data, meth) => {
85 | return axios.request({
86 | url: '/task/other/v1/git/conf/',
87 | method: meth,
88 | data
89 | })
90 | }
91 |
92 | export const Gitsync = () => {
93 | return axios.request({
94 | url: '/task/other/v1/git/sync/',
95 | method: 'post'
96 | })
97 | }
98 |
99 | export const getGitRepotags = (git_url, project_id) => {
100 | return axios.request({
101 | url: '/task/other/v1/git/tags/',
102 | method: 'get',
103 | params: {
104 | git_url,
105 | project_id,
106 | }
107 | })
108 | }
--------------------------------------------------------------------------------
/src/api/k8s/app.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有项目
4 | export const getTableData = () => {
5 | return axios.request({
6 | url: '/k8s/v1/k8s/app/',
7 | method: 'get'
8 | })
9 | }
10 |
11 | // 新建项目
12 | export const addApp = (data, url, action) => {
13 | return axios.request({
14 | url: `/k8s/v1/k8s/app${url}`,
15 | method: action,
16 | data
17 | })
18 | }
19 |
20 | // 获取所有APP
21 | export const getAppList = () => {
22 | return axios.request({
23 | url: '/k8s/v1/k8s/app/',
24 | method: 'get'
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/src/api/k8s/project.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有项目
4 | export const getTableData = () => {
5 | return axios.request({
6 | url: '/k8s/v1/k8s/project/',
7 | method: 'get'
8 | })
9 | }
10 |
11 | // 新建项目
12 | export const addProject = (data, url, action) => {
13 | return axios.request({
14 | url: `/k8s/v1/k8s/project${url}`,
15 | method: action,
16 | data
17 | })
18 | }
19 |
20 | // 获取所有Env
21 | export const getEnvList = () => {
22 | return axios.request({
23 | url: '/k8s/v1/k8s/env/',
24 | method: 'get'
25 | })
26 | }
27 |
28 | // 获取所有User
29 | export const getUserList = () => {
30 | return axios.request({
31 | url: '/k8s/v1/k8s/user/',
32 | method: 'get'
33 | })
34 | }
35 |
36 | // 获取所有APP
37 | export const getAppList = () => {
38 | return axios.request({
39 | url: '/k8s/v1/k8s/app/',
40 | method: 'get'
41 | })
42 | }
43 |
--------------------------------------------------------------------------------
/src/api/k8s/publish.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取所有发布信息
4 | export const getTableData = () => {
5 | return axios.request({
6 | url: '/k8s/v1/k8s/publish/',
7 | method: 'get'
8 | })
9 | }
10 |
11 | // 获取发布详情
12 | export const getPublishDetail = (pid) => {
13 | return axios.request({
14 | url: `/k8s/v1/k8s/publish/${pid}/`,
15 | method: 'get'
16 | })
17 | }
18 |
19 | // 对发布任务进行操作
20 | export const publishAction = (pid, data) => {
21 | return axios.request({
22 | url: `/k8s/v1/k8s/publish/${pid}/`,
23 | method: 'patch',
24 | data: data
25 | })
26 | }
27 |
28 | // 新建发布
29 | export const addPublish = (data) => {
30 | return axios.request({
31 | url: '/k8s/v1/k8s/publish/',
32 | method: 'post',
33 | data
34 | })
35 | }
36 |
37 | // 执行发布任务
38 | export const exeJob = (jid) => {
39 | return axios.request({
40 | url: `/k8s/v1/k8s/job/exec/${jid}/`,
41 | method: 'post'
42 | })
43 | }
44 |
45 | // 获取日志信息
46 | export const getLog = (project, jid) => {
47 | return axios.request({
48 | url: '/k8s/v1/k8s/job/log/',
49 | method: 'get',
50 | params: {
51 | project_name: project,
52 | job_id: jid
53 | }
54 | })
55 | }
56 |
--------------------------------------------------------------------------------
/src/api/k8s/task.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | // 获取日志信息
4 | export const getTaskDetail = (publishId, appId, envId) => {
5 | return axios.request({
6 | url: '/k8s/v1/k8s/job/detail/',
7 | method: 'get',
8 | params: {
9 | publish_id: publishId,
10 | app_id: appId,
11 | env_id: envId
12 | }
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/src/api/mg/resource-mg.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 | import config from '@/config'
3 |
4 | //
5 | export const getResourceList = (page, limit, search_value) => {
6 | return axios.request({
7 | url: '/mg/v2/overall/resource/',
8 | method: 'get',
9 | params: {
10 | page,
11 | limit,
12 | search_value
13 | }
14 | })
15 | }
16 |
17 |
18 | export const optResource = (data, meth) => {
19 | return axios.request({
20 | url: '/mg/v2/overall/resource/',
21 | method: meth,
22 | data
23 | })
24 | }
--------------------------------------------------------------------------------
/src/api/routers.js:
--------------------------------------------------------------------------------
1 | import axios from '@/libs/api.request'
2 |
3 | export const getRouterReq = (access) => {
4 | return axios.request({
5 | url: 'get_router',
6 | params: {
7 | access
8 | },
9 | method: 'get'
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/src/assets/icons/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/icons/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/icons/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/icons/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/icons/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/icons/iconfont.woff
--------------------------------------------------------------------------------
/src/assets/images/login-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/login-bg.jpg
--------------------------------------------------------------------------------
/src/assets/images/login-bg1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/login-bg1.jpg
--------------------------------------------------------------------------------
/src/assets/images/logo-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/logo-min.jpg
--------------------------------------------------------------------------------
/src/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/logo.png
--------------------------------------------------------------------------------
/src/assets/images/qq-fance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/qq-fance.png
--------------------------------------------------------------------------------
/src/assets/images/qq-fance2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/qq-fance2.jpg
--------------------------------------------------------------------------------
/src/assets/images/talkingdata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/src/assets/images/talkingdata.png
--------------------------------------------------------------------------------
/src/components/charts/bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
59 |
--------------------------------------------------------------------------------
/src/components/charts/index.js:
--------------------------------------------------------------------------------
1 | import ChartPie from './pie.vue'
2 | import ChartBar from './bar.vue'
3 | export { ChartPie, ChartBar }
4 |
--------------------------------------------------------------------------------
/src/components/charts/pie.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
74 |
--------------------------------------------------------------------------------
/src/components/common-icon/common-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
39 |
40 |
43 |
--------------------------------------------------------------------------------
/src/components/common-icon/index.js:
--------------------------------------------------------------------------------
1 | import CommonIcon from './common-icon.vue'
2 | export default CommonIcon
3 |
--------------------------------------------------------------------------------
/src/components/common/common.less:
--------------------------------------------------------------------------------
1 | .no-select{
2 | -webkit-touch-callout: none;
3 | -webkit-user-select: none;
4 | -khtml-user-select: none;
5 | -moz-user-select: none;
6 | -ms-user-select: none;
7 | user-select: none;
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/common/util.js:
--------------------------------------------------------------------------------
1 | export const showTitle = (item, vm) => {
2 | return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name)
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/count-to/index.js:
--------------------------------------------------------------------------------
1 | import countTo from './count-to.vue'
2 | export default countTo
3 |
--------------------------------------------------------------------------------
/src/components/count-to/index.less:
--------------------------------------------------------------------------------
1 | @prefix: ~"count-to";
2 |
3 | .@{prefix}-wrapper{
4 | .content-outer{
5 | display: inline-block;
6 | .@{prefix}-unit-text{
7 | font-style: normal;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/drag-list/drag-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ itemLeft }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{ itemRight }}
16 |
17 |
18 |
19 |
20 |
21 |
84 |
93 |
--------------------------------------------------------------------------------
/src/components/drag-list/index.js:
--------------------------------------------------------------------------------
1 | import DragList from './drag-list.vue'
2 | export default DragList
3 |
--------------------------------------------------------------------------------
/src/components/editor/editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
70 |
71 |
74 |
--------------------------------------------------------------------------------
/src/components/editor/index.js:
--------------------------------------------------------------------------------
1 | import Editor from './editor.vue'
2 | export default Editor
3 |
--------------------------------------------------------------------------------
/src/components/form-group/index.js:
--------------------------------------------------------------------------------
1 | import FormGroup from './form-group.vue'
2 | export default FormGroup
3 |
--------------------------------------------------------------------------------
/src/components/icons/icons.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
32 |
33 |
36 |
--------------------------------------------------------------------------------
/src/components/icons/index.js:
--------------------------------------------------------------------------------
1 | import Icons from './icons.vue'
2 | export default Icons
3 |
--------------------------------------------------------------------------------
/src/components/info-card/index.js:
--------------------------------------------------------------------------------
1 | import InforCard from './infor-card.vue'
2 | export default InforCard
3 |
--------------------------------------------------------------------------------
/src/components/info-card/infor-card.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
55 |
56 |
95 |
--------------------------------------------------------------------------------
/src/components/login-form/index.js:
--------------------------------------------------------------------------------
1 | import LoginForm from './login-form.vue'
2 | import RegisterForm from './register.vue'
3 | import MFA from './mfa.vue'
4 | export {LoginForm, RegisterForm, MFA}
5 |
--------------------------------------------------------------------------------
/src/components/login-form/login-form.vue:
--------------------------------------------------------------------------------
1 |
2 |
28 |
29 |
95 |
--------------------------------------------------------------------------------
/src/components/login-form/mfa.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
如果手机无法扫描,请手动录入:
7 |
{{mfa}}
8 |
9 |
录入完成,请联系管理员添加权限
10 |
11 |
12 |
13 |
59 |
60 |
62 |
--------------------------------------------------------------------------------
/src/components/main/components/error-store/error-store.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
38 |
39 |
50 |
--------------------------------------------------------------------------------
/src/components/main/components/error-store/index.js:
--------------------------------------------------------------------------------
1 | import ErrorStore from './error-store.vue'
2 | export default ErrorStore
3 |
--------------------------------------------------------------------------------
/src/components/main/components/footer/copyright.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Copyright © 2019 CODO
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/main/components/fullscreen/fullscreen.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
75 |
76 |
85 |
--------------------------------------------------------------------------------
/src/components/main/components/fullscreen/index.js:
--------------------------------------------------------------------------------
1 | import Fullscreen from './fullscreen.vue'
2 | export default Fullscreen
3 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less:
--------------------------------------------------------------------------------
1 | .custom-bread-crumb{
2 | display: inline-block;
3 | vertical-align: top;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ showTitle(item) }}
7 |
8 |
9 |
10 |
11 |
47 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/custom-bread-crumb/index.js:
--------------------------------------------------------------------------------
1 | import customBreadCrumb from './custom-bread-crumb.vue'
2 | export default customBreadCrumb
3 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/header-bar.less:
--------------------------------------------------------------------------------
1 | .header-bar{
2 | width: 100%;
3 | height: 100%;
4 | position: relative;
5 | .custom-content-con{
6 | float: right;
7 | height: auto;
8 | padding-right: 20px;
9 | line-height: 64px;
10 | & > *{
11 | float: right;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/header-bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
35 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/index.js:
--------------------------------------------------------------------------------
1 | import HeaderBar from './header-bar'
2 | export default HeaderBar
3 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/sider-trigger/index.js:
--------------------------------------------------------------------------------
1 | import siderTrigger from './sider-trigger.vue'
2 | export default siderTrigger
3 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/sider-trigger/sider-trigger.less:
--------------------------------------------------------------------------------
1 | .trans{
2 | transition: transform .2s ease;
3 | }
4 | @size: 40px;
5 | .sider-trigger-a{
6 | padding: 6px;
7 | width: @size;
8 | height: @size;
9 | display: inline-block;
10 | text-align: center;
11 | color: #5c6b77;
12 | margin-top: 12px;
13 | i{
14 | .trans;
15 | vertical-align: top;
16 | }
17 | &.collapsed i{
18 | transform: rotateZ(90deg);
19 | .trans;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
28 |
--------------------------------------------------------------------------------
/src/components/main/components/language/index.js:
--------------------------------------------------------------------------------
1 | import Language from './language.vue'
2 | export default Language
3 |
--------------------------------------------------------------------------------
/src/components/main/components/language/language.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
52 |
--------------------------------------------------------------------------------
/src/components/main/components/side-menu/collapsed-menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
52 |
--------------------------------------------------------------------------------
/src/components/main/components/side-menu/index.js:
--------------------------------------------------------------------------------
1 | import SideMenu from './side-menu.vue'
2 | export default SideMenu
3 |
--------------------------------------------------------------------------------
/src/components/main/components/side-menu/item-mixin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | props: {
3 | parentItem: {
4 | type: Object,
5 | default: () => {}
6 | },
7 | theme: String,
8 | iconSize: Number
9 | },
10 | computed: {
11 | parentName () {
12 | return this.parentItem.name
13 | },
14 | children () {
15 | return this.parentItem.children
16 | },
17 | textColor () {
18 | return this.theme === 'dark' ? '#fff' : '#495060'
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/main/components/side-menu/mixin.js:
--------------------------------------------------------------------------------
1 | import CommonIcon from '_c/common-icon'
2 | export default {
3 | components: {
4 | CommonIcon
5 | },
6 | methods: {
7 | showTitle (item) {
8 | return this.$config.useI18n ? this.$t(item.name) : ((item.meta && item.meta.title) || item.name)
9 | },
10 | showChildren (item) {
11 | return item.children && (item.children.length > 1 || (item.meta && item.meta.showAlways))
12 | },
13 | getNameOrHref (item, children0) {
14 | return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name)
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/main/components/side-menu/side-menu-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ showTitle(parentItem) }}
6 |
7 |
8 |
9 |
10 | {{ showTitle(item.children[0]) }}
11 |
12 |
13 |
14 | {{ showTitle(item) }}
15 |
16 |
17 |
18 |
19 |
27 |
--------------------------------------------------------------------------------
/src/components/main/components/side-menu/side-menu.less:
--------------------------------------------------------------------------------
1 | .side-menu-wrapper{
2 | user-select: none;
3 | .menu-collapsed{
4 | padding-top: 10px;
5 |
6 | .ivu-dropdown{
7 | width: 100%;
8 | .ivu-dropdown-rel a{
9 | width: 100%;
10 | }
11 | }
12 | .ivu-tooltip{
13 | width: 100%;
14 | .ivu-tooltip-rel{
15 | width: 100%;
16 | }
17 | .ivu-tooltip-popper .ivu-tooltip-content{
18 | .ivu-tooltip-arrow{
19 | border-right-color: #fff;
20 | }
21 | .ivu-tooltip-inner{
22 | background: #fff;
23 | color: #495060;
24 | }
25 | }
26 | }
27 |
28 |
29 | }
30 | a.drop-menu-a{
31 | display: inline-block;
32 | padding: 6px 15px;
33 | width: 100%;
34 | text-align: center;
35 | color: #495060;
36 | }
37 | }
38 | .menu-title{
39 | padding-left: 6px;
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/main/components/tags-nav/index.js:
--------------------------------------------------------------------------------
1 | import TagsNav from './tags-nav.vue'
2 | export default TagsNav
3 |
--------------------------------------------------------------------------------
/src/components/main/components/tags-nav/tags-nav.less:
--------------------------------------------------------------------------------
1 | .no-select{
2 | -webkit-touch-callout: none;
3 | -webkit-user-select: none;
4 | -khtml-user-select: none;
5 | -moz-user-select: none;
6 | -ms-user-select: none;
7 | user-select: none;
8 | }
9 | .size{
10 | width: 100%;
11 | height: 100%;
12 | }
13 | .tags-nav{
14 | position: relative;
15 | border-top: 1px solid #F0F0F0;
16 | border-bottom: 1px solid #F0F0F0;
17 | .no-select;
18 | .size;
19 | .close-con{
20 | position: absolute;
21 | right: 0;
22 | top: 0;
23 | height: 100%;
24 | width: 32px;
25 | background: #fff;
26 | text-align: center;
27 | z-index: 10;
28 | }
29 | .btn-con{
30 | position: absolute;
31 | top: 0px;
32 | height: 100%;
33 | background: #fff;
34 | padding-top: 3px;
35 | z-index: 10;
36 | button{
37 | padding: 6px 4px;
38 | line-height: 14px;
39 | text-align: center;
40 | }
41 | &.left-btn{
42 | left: 0px;
43 | }
44 | &.right-btn{
45 | right: 32px;
46 | border-right: 1px solid #F0F0F0;
47 | }
48 | }
49 | .scroll-outer{
50 | position: absolute;
51 | left: 28px;
52 | right: 61px;
53 | top: 0;
54 | bottom: 0;
55 | box-shadow: 0px 0 3px 2px rgba(100,100,100,.1) inset;
56 | .scroll-body{
57 | height: ~"calc(100% - 1px)";
58 | display: inline-block;
59 | padding: 1px 4px 0;
60 | position: absolute;
61 | overflow: visible;
62 | white-space: nowrap;
63 | transition: left .3s ease;
64 | .ivu-tag-dot-inner{
65 | transition: background .2s ease;
66 | }
67 | }
68 | }
69 | .contextmenu {
70 | position: absolute;
71 | margin: 0;
72 | padding: 5px 0;
73 | background: #fff;
74 | z-index: 100;
75 | list-style-type: none;
76 | border-radius: 4px;
77 | box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
78 | li {
79 | margin: 0;
80 | padding: 5px 15px;
81 | cursor: pointer;
82 | &:hover {
83 | background: #eee;
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/components/main/components/user/index.js:
--------------------------------------------------------------------------------
1 | import User from './user.vue'
2 | export default User
3 |
--------------------------------------------------------------------------------
/src/components/main/components/user/user.less:
--------------------------------------------------------------------------------
1 | .user{
2 | &-avator-dropdown{
3 | cursor: pointer;
4 | display: inline-block;
5 | // height: 64px;
6 | vertical-align: middle;
7 | // line-height: 64px;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/main/index.js:
--------------------------------------------------------------------------------
1 | import Main from './main.vue'
2 | export default Main
3 |
--------------------------------------------------------------------------------
/src/components/main/main.less:
--------------------------------------------------------------------------------
1 | .main{
2 | .logo-con{
3 | height: 45px !important;
4 | padding: 0px;
5 | img{
6 | height: 100%;
7 | width: 100%;
8 | padding: 0px;
9 | display: block;
10 | }
11 | }
12 | .header-con{
13 | background: #fff;
14 | padding: 0 20px;
15 | height: 60px;
16 | width: 100%;
17 | }
18 | .main-layout-con{
19 | height: 100%;
20 | overflow: hidden;
21 | }
22 | .main-content-con{
23 | height: ~"calc(100% - 60px)";
24 | overflow: hidden;
25 | }
26 | .tag-nav-wrapper{
27 | padding: 0;
28 | height:40px;
29 | background:#F0F0F0;
30 | }
31 | .content-wrapper{
32 | padding: 18px;
33 | height: ~"calc(100% - 80px)";
34 | overflow: auto;
35 | }
36 | .left-sider{
37 | .ivu-layout-sider-children{
38 | overflow-y: scroll;
39 | margin-right: -18px;
40 | }
41 | }
42 | }
43 | .ivu-menu-item > i{
44 | margin-right: 12px !important;
45 | }
46 | .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i {
47 | margin-right: 8px !important;
48 | }
49 | .collased-menu-dropdown{
50 | width: 100%;
51 | margin: 0;
52 | line-height: normal;
53 | padding: 7px 0 6px 16px;
54 | clear: both;
55 | font-size: 12px !important;
56 | white-space: nowrap;
57 | list-style: none;
58 | cursor: pointer;
59 | transition: background 0.2s ease-in-out;
60 | &:hover{
61 | background: rgba(100, 100, 100, 0.1);
62 | }
63 | & * {
64 | color: #515a6e;
65 | }
66 | .ivu-menu-item > i{
67 | margin-right: 12px !important;
68 | }
69 | .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i {
70 | margin-right: 8px !important;
71 | }
72 | }
73 |
74 | .ivu-select-dropdown.ivu-dropdown-transfer{
75 | max-height: 400px;
76 | }
77 |
--------------------------------------------------------------------------------
/src/components/markdown/index.js:
--------------------------------------------------------------------------------
1 | import MarkdownEditor from './markdown.vue'
2 | export default MarkdownEditor
3 |
--------------------------------------------------------------------------------
/src/components/markdown/markdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
63 |
64 |
77 |
--------------------------------------------------------------------------------
/src/components/parent-view/index.js:
--------------------------------------------------------------------------------
1 | import ParentView from './parent-view.vue'
2 | export default ParentView
3 |
--------------------------------------------------------------------------------
/src/components/parent-view/parent-view.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/src/components/paste-editor/index.js:
--------------------------------------------------------------------------------
1 | import PasteEditor from './paste-editor.vue'
2 | export default PasteEditor
3 |
--------------------------------------------------------------------------------
/src/components/paste-editor/paste-editor.less:
--------------------------------------------------------------------------------
1 | .paste-editor-wrapper{
2 | width: 100%;
3 | height: 100%;
4 | border: 1px dashed gainsboro;
5 | textarea.textarea-el{
6 | width: 100%;
7 | height: 100%;
8 | }
9 | .CodeMirror{
10 | height: 100%;
11 | padding: 0;
12 | .CodeMirror-code div .CodeMirror-line > span > span.cm-tab{
13 | &::after{
14 | content: '→';
15 | color: #BFBFBF;
16 | }
17 | }
18 | }
19 | .first-row{
20 | font-weight: 700;
21 | font-size: 14px;
22 | }
23 | .incorrect-row{
24 | background: #F5CBD1;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/paste-editor/plugins/placeholder.js:
--------------------------------------------------------------------------------
1 | export default (codemirror) => {
2 | (function (mod) {
3 | mod(codemirror)
4 | })(function (CodeMirror) {
5 | CodeMirror.defineOption('placeholder', '', function (cm, val, old) {
6 | var prev = old && old !== CodeMirror.Init
7 | if (val && !prev) {
8 | cm.on('blur', onBlur)
9 | cm.on('change', onChange)
10 | cm.on('swapDoc', onChange)
11 | onChange(cm)
12 | } else if (!val && prev) {
13 | cm.off('blur', onBlur)
14 | cm.off('change', onChange)
15 | cm.off('swapDoc', onChange)
16 | clearPlaceholder(cm)
17 | var wrapper = cm.getWrapperElement()
18 | wrapper.className = wrapper.className.replace(' CodeMirror-empty', '')
19 | }
20 |
21 | if (val && !cm.hasFocus()) onBlur(cm)
22 | })
23 |
24 | function clearPlaceholder (cm) {
25 | if (cm.state.placeholder) {
26 | cm.state.placeholder.parentNode.removeChild(cm.state.placeholder)
27 | cm.state.placeholder = null
28 | }
29 | }
30 | function setPlaceholder (cm) {
31 | clearPlaceholder(cm)
32 | var elt = cm.state.placeholder = document.createElement('pre')
33 | elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;'
34 | elt.style.direction = cm.getOption('direction')
35 | elt.className = 'CodeMirror-placeholder'
36 | var placeHolder = cm.getOption('placeholder')
37 | if (typeof placeHolder === 'string') placeHolder = document.createTextNode(placeHolder)
38 | elt.appendChild(placeHolder)
39 | cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild)
40 | }
41 |
42 | function onBlur (cm) {
43 | if (isEmpty(cm)) setPlaceholder(cm)
44 | }
45 | function onChange (cm) {
46 | let wrapper = cm.getWrapperElement()
47 | let empty = isEmpty(cm)
48 | wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + (empty ? ' CodeMirror-empty' : '')
49 |
50 | if (empty) setPlaceholder(cm)
51 | else clearPlaceholder(cm)
52 | }
53 |
54 | function isEmpty (cm) {
55 | return (cm.lineCount() === 1) && (cm.getLine(0) === '')
56 | }
57 | })
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/public/copyright.vue:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
2017-2019 © CODO
15 |
16 |
--------------------------------------------------------------------------------
/src/components/public/editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
96 |
97 |
--------------------------------------------------------------------------------
/src/components/split-pane/index.css:
--------------------------------------------------------------------------------
1 | .ivu-split-wrapper {
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 | }
6 | .ivu-split-pane {
7 | position: absolute;
8 | }
9 | .ivu-split-pane.left-pane,
10 | .ivu-split-pane.right-pane {
11 | top: 0px;
12 | bottom: 0px;
13 | }
14 | .ivu-split-pane.left-pane {
15 | left: 0px;
16 | }
17 | .ivu-split-pane.right-pane {
18 | right: 0px;
19 | }
20 | .ivu-split-pane.top-pane,
21 | .ivu-split-pane.bottom-pane {
22 | left: 0px;
23 | right: 0px;
24 | }
25 | .ivu-split-pane.top-pane {
26 | top: 0px;
27 | }
28 | .ivu-split-pane.bottom-pane {
29 | bottom: 0px;
30 | }
31 | .ivu-split-trigger-con {
32 | position: absolute;
33 | transform: translate(-50%, -50%);
34 | z-index: 10;
35 | }
36 | .ivu-split-trigger-bar-con {
37 | position: absolute;
38 | overflow: hidden;
39 | }
40 | .ivu-split-trigger-bar-con.vertical {
41 | left: 1px;
42 | top: 50%;
43 | height: 32px;
44 | transform: translate(0, -50%);
45 | }
46 | .ivu-split-trigger-bar-con.horizontal {
47 | left: 50%;
48 | top: 1px;
49 | width: 32px;
50 | transform: translate(-50%, 0);
51 | }
52 | .ivu-split-trigger-vertical {
53 | width: 6px;
54 | height: 100%;
55 | background: #F8F8F9;
56 | box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.4);
57 | cursor: col-resize;
58 | }
59 | .ivu-split-trigger-vertical .ivu-split-trigger-bar {
60 | width: 4px;
61 | height: 1px;
62 | background: rgba(23, 35, 61, 0.25);
63 | float: left;
64 | margin-top: 3px;
65 | }
66 | .ivu-split-trigger-horizontal {
67 | height: 6px;
68 | width: 100%;
69 | background: #F8F8F9;
70 | box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.4);
71 | cursor: row-resize;
72 | }
73 | .ivu-split-trigger-horizontal .ivu-split-trigger-bar {
74 | height: 4px;
75 | width: 1px;
76 | background: rgba(23, 35, 61, 0.25);
77 | float: left;
78 | margin-right: 3px;
79 | }
80 | .ivu-split-horizontal .ivu-split-trigger-con {
81 | top: 50%;
82 | height: 100%;
83 | width: 0;
84 | }
85 | .ivu-split-vertical .ivu-split-trigger-con {
86 | left: 50%;
87 | height: 0;
88 | width: 100%;
89 | }
90 | .ivu-split .no-select {
91 | -webkit-touch-callout: none;
92 | -webkit-user-select: none;
93 | -khtml-user-select: none;
94 | -moz-user-select: none;
95 | -ms-user-select: none;
96 | user-select: none;
97 | }
98 |
--------------------------------------------------------------------------------
/src/components/split-pane/index.js:
--------------------------------------------------------------------------------
1 | import Split from './split.vue'
2 | export default Split
3 |
--------------------------------------------------------------------------------
/src/components/split-pane/index.less:
--------------------------------------------------------------------------------
1 | @split-prefix-cls: ~"ivu-split";
2 | @box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.4);
3 | @trigger-bar-background: rgba(23, 35, 61, 0.25);
4 | @trigger-background: #F8F8F9;
5 | @trigger-width: 6px;
6 | @trigger-bar-width: 4px;
7 | @trigger-bar-offset: (@trigger-width - @trigger-bar-width) / 2;
8 | @trigger-bar-interval: 3px;
9 | @trigger-bar-weight: 1px;
10 | @trigger-bar-con-height: (@trigger-bar-weight + @trigger-bar-interval) * 8;
11 |
12 | .@{split-prefix-cls}{
13 | &-wrapper{
14 | position: relative;
15 | width: 100%;
16 | height: 100%;
17 | }
18 | &-pane{
19 | position: absolute;
20 | &.left-pane, &.right-pane{
21 | top: 0px;
22 | bottom: 0px;
23 | }
24 | &.left-pane{
25 | left: 0px;
26 | }
27 | &.right-pane{
28 | right: 0px;
29 | }
30 | &.top-pane, &.bottom-pane{
31 | left: 0px;
32 | right: 0px;
33 | }
34 | &.top-pane{
35 | top: 0px;
36 | }
37 | &.bottom-pane{
38 | bottom: 0px;
39 | }
40 | }
41 | &-trigger{
42 | &-con{
43 | position: absolute;
44 | transform: translate(-50%, -50%);
45 | z-index: 10;
46 | }
47 | &-bar-con{
48 | position: absolute;
49 | overflow: hidden;
50 | &.vertical{
51 | left: @trigger-bar-offset;
52 | top: 50%;
53 | height: @trigger-bar-con-height;
54 | transform: translate(0, -50%);
55 | }
56 | &.horizontal{
57 | left: 50%;
58 | top: @trigger-bar-offset;
59 | width: @trigger-bar-con-height;
60 | transform: translate(-50%, 0);
61 | }
62 | }
63 | &-vertical{
64 | width: @trigger-width;
65 | height: 100%;
66 | background: @trigger-background;
67 | box-shadow: @box-shadow;
68 | cursor: col-resize;
69 | .@{split-prefix-cls}-trigger-bar{
70 | width: @trigger-bar-width;
71 | height: 1px;
72 | background: @trigger-bar-background;
73 | float: left;
74 | margin-top: @trigger-bar-interval;
75 | }
76 | }
77 | &-horizontal{
78 | height: @trigger-width;
79 | width: 100%;
80 | background: @trigger-background;
81 | box-shadow: @box-shadow;
82 | cursor: row-resize;
83 | .@{split-prefix-cls}-trigger-bar{
84 | height: @trigger-bar-width;
85 | width: 1px;
86 | background: @trigger-bar-background;
87 | float: left;
88 | margin-right: @trigger-bar-interval;
89 | }
90 | }
91 | }
92 | &-horizontal{
93 | .@{split-prefix-cls}-trigger-con{
94 | top: 50%;
95 | height: 100%;
96 | width: 0;
97 | }
98 | }
99 | &-vertical{
100 | .@{split-prefix-cls}-trigger-con{
101 | left: 50%;
102 | height: 0;
103 | width: 100%;
104 | }
105 | }
106 | .no-select{
107 | -webkit-touch-callout: none;
108 | -webkit-user-select: none;
109 | -khtml-user-select: none;
110 | -moz-user-select: none;
111 | -ms-user-select: none;
112 | user-select: none;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/components/split-pane/trigger.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
40 |
41 |
44 |
--------------------------------------------------------------------------------
/src/components/tables/edit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ value }}
5 | .
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
46 |
47 |
76 |
--------------------------------------------------------------------------------
/src/components/tables/handle-btns.js:
--------------------------------------------------------------------------------
1 | const btns = {
2 | delete: (h, params, vm) => {
3 | return h('Poptip', {
4 | props: {
5 | confirm: true,
6 | title: '你确定要删除吗?'
7 | },
8 | on: {
9 | 'on-ok': () => {
10 | vm.$emit('on-delete', params)
11 | vm.$emit('input', params.tableData.filter((item, index) => index !== params.row.initRowIndex))
12 | }
13 | }
14 | }, [
15 | h('Button', {
16 | props: {
17 | type: 'text',
18 | ghost: true
19 | }
20 | }, [
21 | h('Icon', {
22 | props: {
23 | type: 'md-trash',
24 | size: 18,
25 | color: '#000000'
26 | }
27 | })
28 | ])
29 | ])
30 | }
31 | }
32 |
33 | export default btns
34 |
--------------------------------------------------------------------------------
/src/components/tables/index.js:
--------------------------------------------------------------------------------
1 | import Tables from './tables.vue'
2 | export default Tables
3 |
--------------------------------------------------------------------------------
/src/components/tables/index.less:
--------------------------------------------------------------------------------
1 | .search-con{
2 | padding: 5px 0;
3 | .search{
4 | &-col{
5 | display: inline-block;
6 | width: 200px;
7 | }
8 | &-input{
9 | display: inline-block;
10 | width: 200px;
11 | margin-left: 2px;
12 | }
13 | &-btn{
14 | margin-left: 2px;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | /**
3 | * @description token在Cookie中存储的天数,默认1天
4 | */
5 | cookieExpires: 7,
6 | /**
7 | * @description 是否使用国际化,默认为false
8 | * 如果不使用,则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'}
9 | * 用来在菜单中显示文字
10 | */
11 | useI18n: true,
12 | /**
13 | * @description api请求基础路径
14 | */
15 | baseUrl: {
16 | // dev: 'https://www.easy-mock.com/mock/5add9213ce4d0e69998a6f51/iview-admin/',
17 | // dev: 'http://172.16.0.223:9800/',
18 | dev: '',
19 | pro: '/api/'
20 | },
21 | domainName: {
22 | // dev: 'https://www.easy-mock.com/mock/5add9213ce4d0e69998a6f51/iview-admin/',
23 | // dev: 'http://172.16.0.223:9800/',
24 | dev: 'demo.opendevops.cn',
25 | pro: window.location.host
26 | },
27 | isHttps: 'https:' == document.location.protocol ? true : false,
28 | /**
29 | * @description 默认打开的首页的路由name值,默认为home
30 | */
31 | homeName: 'home',
32 | /**
33 | * @description 需要加载的插件
34 | */
35 | plugin: {
36 | 'error-store': {
37 | showInHeader: false, // 设为false后不会在顶部显示错误日志徽标
38 | developmentOff: true // 设为true后在开发环境不会收集错误信息,方便开发中排查错误
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/directive/directives.js:
--------------------------------------------------------------------------------
1 | import { on } from '@/libs/tools'
2 | const directives = {
3 | draggable: {
4 | inserted: (el, binding, vnode) => {
5 | let triggerDom = document.querySelector(binding.value.trigger)
6 | triggerDom.style.cursor = 'move'
7 | let bodyDom = document.querySelector(binding.value.body)
8 | let pageX = 0
9 | let pageY = 0
10 | let transformX = 0
11 | let transformY = 0
12 | let canMove = false
13 | const handleMousedown = e => {
14 | let transform = /\(.*\)/.exec(bodyDom.style.transform)
15 | if (transform) {
16 | transform = transform[0].slice(1, transform[0].length - 1)
17 | let splitxy = transform.split('px, ')
18 | transformX = parseFloat(splitxy[0])
19 | transformY = parseFloat(splitxy[1].split('px')[0])
20 | }
21 | pageX = e.pageX
22 | pageY = e.pageY
23 | canMove = true
24 | }
25 | const handleMousemove = e => {
26 | let xOffset = e.pageX - pageX + transformX
27 | let yOffset = e.pageY - pageY + transformY
28 | if (canMove) bodyDom.style.transform = `translate(${xOffset}px, ${yOffset}px)`
29 | }
30 | const handleMouseup = e => {
31 | canMove = false
32 | }
33 | on(triggerDom, 'mousedown', handleMousedown)
34 | on(document, 'mousemove', handleMousemove)
35 | on(document, 'mouseup', handleMouseup)
36 | },
37 | update: (el, binding, vnode) => {
38 | if (!binding.value.recover) return
39 | let bodyDom = document.querySelector(binding.value.body)
40 | bodyDom.style.transform = ''
41 | }
42 | }
43 | }
44 |
45 | export default directives
46 |
--------------------------------------------------------------------------------
/src/directive/index.js:
--------------------------------------------------------------------------------
1 | import directive from './directives'
2 |
3 | const importDirective = Vue => {
4 | /**
5 | * 拖拽指令 v-draggable="options"
6 | * options = {
7 | * trigger: /这里传入作为拖拽触发器的CSS选择器/,
8 | * body: /这里传入需要移动容器的CSS选择器/,
9 | * recover: /拖动结束之后是否恢复到原来的位置/
10 | * }
11 | */
12 | Vue.directive('draggable', directive.draggable)
13 | }
14 |
15 | export default importDirective
16 |
--------------------------------------------------------------------------------
/src/index.less:
--------------------------------------------------------------------------------
1 | @import '~view-design/src/styles/index.less';
2 |
3 | @menu-dark-title: #001529;
4 | @menu-dark-active-bg: #000c17;
5 | @layout-sider-background: #001529;
6 | // @primary-color: #2fb141;
7 |
--------------------------------------------------------------------------------
/src/libs/api.request.js:
--------------------------------------------------------------------------------
1 | import HttpRequest from '@/libs/axios'
2 | import config from '@/config'
3 | const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro
4 |
5 | const axios = new HttpRequest(baseUrl)
6 | export default axios
7 |
--------------------------------------------------------------------------------
/src/locale/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueI18n from 'vue-i18n'
3 | import { localRead } from '@/libs/util'
4 | import customZhCn from './lang/zh-CN'
5 | import customZhTw from './lang/zh-TW'
6 | import customEnUs from './lang/en-US'
7 | import zhCnLocale from 'view-design/src/locale/lang/zh-CN'
8 | import enUsLocale from 'view-design/src/locale/lang/en-US'
9 | import zhTwLocale from 'view-design/src/locale/lang/zh-TW'
10 |
11 | Vue.use(VueI18n)
12 |
13 | // 自动根据浏览器系统语言设置语言
14 | const navLang = navigator.language
15 | const localLang = (navLang === 'zh-CN' || navLang === 'en-US') ? navLang : false
16 | let lang = localLang || localRead('local') || 'zh-CN'
17 |
18 | Vue.config.lang = lang
19 |
20 | // vue-i18n 6.x+写法
21 | Vue.locale = () => {}
22 | const messages = {
23 | 'zh-CN': Object.assign(zhCnLocale, customZhCn),
24 | 'zh-TW': Object.assign(zhTwLocale, customZhTw),
25 | 'en-US': Object.assign(enUsLocale, customEnUs)
26 | }
27 | const i18n = new VueI18n({
28 | locale: lang,
29 | messages
30 | })
31 |
32 | export default i18n
33 |
34 | // vue-i18n 5.x写法
35 | // Vue.locale('zh-CN', Object.assign(zhCnLocale, customZhCn))
36 | // Vue.locale('en-US', Object.assign(zhTwLocale, customZhTw))
37 | // Vue.locale('zh-TW', Object.assign(enUsLocale, customEnUs))
38 |
--------------------------------------------------------------------------------
/src/locale/lang/en-US.js:
--------------------------------------------------------------------------------
1 | export default {
2 | home: 'Home',
3 | components: 'Components',
4 | count_to_page: 'Count-to',
5 | tables_page: 'Table',
6 | split_pane_page: 'Split-pane',
7 | markdown_page: 'Markdown-editor',
8 | editor_page: 'Rich-Text-Editor',
9 | icons_page: 'Custom-icon',
10 | img_cropper_page: 'Image-editor',
11 | update: 'Update',
12 | doc: 'Document',
13 | join_page: 'QQ Group',
14 | update_table_page: 'Update .CSV',
15 | update_paste_page: 'Paste Table Data',
16 | multilevel: 'multilevel',
17 | directive_page: 'Directive',
18 | level_1: 'Level-1',
19 | level_2: 'Level-2',
20 | level_2_1: 'Level-2-1',
21 | level_2_3: 'Level-2-3',
22 | level_2_2: 'Level-2-2',
23 | level_2_2_1: 'Level-2-2-1',
24 | excel: 'Excel',
25 | 'upload-excel': 'Upload Excel',
26 | 'export-excel': 'Export Excel',
27 | tools_methods_page: 'Tools Methods',
28 | drag_list_page: 'Drag-list',
29 | i18n_page: 'Internationalization',
30 | modalTitle: 'Modal Title',
31 | content: 'This is the modal box content.',
32 | buttonText: 'Show Modal',
33 | 'i18n-tip': 'Note: Only this page is multi-language, other pages do not add language content to the multi-language package.',
34 | error_store_page: 'Error Collection',
35 | error_logger_page: 'Error Logger'
36 | }
37 |
--------------------------------------------------------------------------------
/src/locale/lang/zh-TW.js:
--------------------------------------------------------------------------------
1 | export default {
2 | home: '首頁',
3 | components: '组件',
4 | count_to_page: '数字渐变',
5 | tables_page: '多功能表格',
6 | split_pane_page: '分割窗口',
7 | markdown_page: 'Markdown編輯器',
8 | editor_page: '富文本編輯器',
9 | icons_page: '自定義圖標',
10 | img_cropper_page: '圖片編輯器',
11 | update: '上傳數據',
12 | join_page: 'QQ群',
13 | doc: '文檔',
14 | update_table_page: '上傳CSV文件',
15 | update_paste_page: '粘貼表格數據',
16 | multilevel: '多级菜单',
17 | directive_page: '指令',
18 | level_1: 'Level-1',
19 | level_2: 'Level-2',
20 | level_2_1: 'Level-2-1',
21 | level_2_3: 'Level-2-3',
22 | level_2_2: 'Level-2-2',
23 | level_2_2_1: 'Level-2-2-1',
24 | excel: 'Excel',
25 | 'upload-excel': '上傳excel',
26 | 'export-excel': '導出excel',
27 | tools_methods_page: '工具函數',
28 | drag_list_page: '拖拽列表',
29 | i18n_page: '多語言',
30 | modalTitle: '模態框題目',
31 | content: '這是模態框內容',
32 | buttonText: '顯示模態框',
33 | 'i18n-tip': '注:僅此頁做了多語言,其他頁面沒有在多語言包中添加語言內容',
34 | error_store_page: '錯誤收集',
35 | error_logger_page: '錯誤日誌'
36 | }
37 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 | import store from './store'
7 | // import iView from 'iview'
8 | import ViewUI from 'view-design'
9 | import i18n from '@/locale'
10 | import config from '@/config'
11 | import importDirective from '@/directive'
12 | import installPlugin from '@/plugin'
13 | // import 'iview/dist/styles/iview.css'
14 | import 'view-design/dist/styles/iview.css'
15 | import './index.less'
16 | import '@/assets/icons/iconfont.css'
17 | import VueClipboard from 'vue-clipboard2'
18 |
19 | Vue.use(VueClipboard)
20 | // 实际打包时应该不引入mock
21 | /* eslint-disable */
22 | // if (process.env.NODE_ENV !== 'production') require('@/mock')
23 |
24 | Vue.use(ViewUI, {
25 | i18n: (key, value) => i18n.t(key, value)
26 | })
27 | /**
28 | * @description 注册admin内置插件
29 | */
30 | installPlugin(Vue)
31 | /**
32 | * @description 生产环境关掉提示
33 | */
34 | Vue.config.productionTip = false
35 | /**
36 | * @description 全局注册应用配置
37 | */
38 | Vue.prototype.$config = config
39 | /**
40 | * 注册指令
41 | */
42 | importDirective(Vue)
43 |
44 | /* eslint-disable no-new */
45 | new Vue({
46 | el: '#app',
47 | router,
48 | i18n,
49 | store,
50 | render: h => h(App)
51 | })
52 |
--------------------------------------------------------------------------------
/src/plugin/error-store/index.js:
--------------------------------------------------------------------------------
1 | import store from '@/store'
2 | export default {
3 | install (Vue, options) {
4 | if (options.developmentOff && process.env.NODE_ENV === 'development') return
5 | Vue.config.errorHandler = (error, vm, mes) => {
6 | let info = {
7 | type: 'script',
8 | code: 0,
9 | mes: error.message,
10 | url: window.location.href
11 | }
12 | Vue.nextTick(() => {
13 | store.dispatch('addErrorLog', info)
14 | })
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/plugin/index.js:
--------------------------------------------------------------------------------
1 | import config from '@/config'
2 | const { plugin } = config
3 |
4 | export default (Vue) => {
5 | for (let name in plugin) {
6 | const value = plugin[name]
7 | Vue.use(require(`./${name}`).default, typeof value === 'object' ? value : undefined)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/router/before-close.js:
--------------------------------------------------------------------------------
1 | import { Modal } from 'view-design'
2 |
3 | const beforeClose = {
4 | before_close_normal: (resolve) => {
5 | Modal.confirm({
6 | title: '确定要关闭这一页吗',
7 | onOk: () => {
8 | resolve(true)
9 | },
10 | onCancel: () => {
11 | resolve(false)
12 | }
13 | })
14 | }
15 | }
16 |
17 | export default beforeClose
18 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import { routes } from './routers'
4 | import store from '@/store'
5 | // import iView from 'iview'
6 | import ViewUI from 'view-design'
7 | import { getToken, setTitle, setToken } from '@/libs/util'
8 |
9 | Vue.use(Router)
10 | const router = new Router({
11 | routes,
12 | mode: 'history'
13 | })
14 | // const LOGIN_PAGE_NAME = 'login'
15 |
16 | router.beforeEach((to, from, next) => {
17 | to.meta.title && setTitle(to.meta.title)
18 | ViewUI.LoadingBar.start()
19 | const token = getToken()
20 | if (token) {
21 | if (!store.state.router.hasGetRules) {
22 | store.dispatch('authorization').then(rules => {
23 | store.dispatch('concatRoutes', rules).then(routers => {
24 | router.addRoutes(routers)
25 | next({ ...to, replace: true })
26 | }).catch((err) => {
27 | // console.log(err)
28 | setToken('')
29 | next({ name: 'login' })
30 | })
31 | }).catch((err1) => {
32 | // console.log(err1)
33 | setToken('')
34 | next({ name: 'login' })
35 | })
36 | } else {
37 | next()
38 | }
39 | } else {
40 | if (to.name === 'login') next()
41 | else next({ name: 'login' })
42 | }
43 | })
44 |
45 | router.afterEach(to => {
46 | ViewUI.LoadingBar.finish()
47 | window.scrollTo(0, 0)
48 | })
49 |
50 | export default router
51 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import createPersistedState from "vuex-persistedstate"
4 |
5 | import user from './module/user'
6 | import app from './module/app'
7 | import router from './module/router'
8 |
9 | Vue.use(Vuex)
10 |
11 | export default new Vuex.Store({
12 | //解决Vuex持久化插件 把用户数据持久化
13 | plugins: [createPersistedState({
14 | storage: window.sessionStorage,
15 | reducer(val) {
16 | return {
17 | //只储存state中的user
18 | user: val.user
19 | }
20 | }
21 | })],
22 | state: {
23 | //
24 | },
25 | mutations: {
26 | //
27 | },
28 | actions: {
29 | //
30 | },
31 | modules: {
32 | user,
33 | app,
34 | router
35 | }
36 | })
37 |
--------------------------------------------------------------------------------
/src/store/module/router.js:
--------------------------------------------------------------------------------
1 | import { routes, routerMap } from '@/router/routers'
2 | import { getMenuByRouter } from '@/libs/util'
3 |
4 | const state = {
5 | routers: routes,
6 | hasGetRules: false
7 | }
8 |
9 | const getters = {
10 | menuList: state => getMenuByRouter(state.routers, 'all')
11 |
12 | }
13 | const mutations = {
14 | CONCAT_ROUTES (state, routerList) {
15 | state.routers = routerList.concat(routes)
16 | state.hasGetRules = true
17 | }
18 | }
19 |
20 | const getAccesRouterList = (routes, rules) => {
21 | return routes.filter(item => {
22 | if (rules[item.name]) {
23 | if (item.children) item.children = getAccesRouterList(item.children, rules)
24 | return true
25 | } else return false
26 | })
27 | }
28 |
29 | const actions = {
30 | concatRoutes ({ commit }, rules) {
31 | return new Promise((resolve, reject) => {
32 | try {
33 | let routerList = []
34 | // 如果全部是true 直接返回
35 | if (Object.entries(rules).every(item => item[1])) {
36 | routerList = routerMap
37 | } else {
38 | routerList = getAccesRouterList(routerMap, rules)
39 | }
40 |
41 | commit('CONCAT_ROUTES', routerList)
42 | resolve(routerList)
43 | } catch (err) {
44 | reject(err)
45 | }
46 | })
47 | }
48 | }
49 |
50 | export default {
51 | state,
52 | getters,
53 | mutations,
54 | actions
55 | }
56 |
--------------------------------------------------------------------------------
/src/view/cmdb/common/Api.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
45 |
--------------------------------------------------------------------------------
/src/view/cmdb/db/multiAdd.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
19 |
20 |
83 |
--------------------------------------------------------------------------------
/src/view/cmdb/server/multiAdd.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
19 |
20 |
21 |
84 |
--------------------------------------------------------------------------------
/src/view/cmdb/server_auth/Detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 规则ID:
8 | {{formData.id}}
9 |
10 |
11 |
12 | 规则名:
13 | {{formData.name}}
14 |
15 |
16 |
17 | 用户:
18 |
19 | {{item}}
20 |
21 |
22 |
23 |
24 | 主机:
25 |
26 | {{item}}
27 |
28 |
29 |
30 |
31 | 主机组:
32 |
33 | {{item}}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
51 |
--------------------------------------------------------------------------------
/src/view/cmdb/server_log/TtyLog.vue:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
{{ item.datetime }} : {{ item.cmd }}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/view/cmdb/webssh/Console.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/view/cmdb/webssh/WebSSH.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
28 |
--------------------------------------------------------------------------------
/src/view/cmdb/webssh/Xterm.js:
--------------------------------------------------------------------------------
1 | import { Terminal } from 'xterm'
2 | import * as fit from 'xterm/lib/addons/fit/fit'
3 | import * as attach from 'xterm/lib/addons/attach/attach'
4 | Terminal.applyAddon(fit)
5 | Terminal.applyAddon(attach)
6 |
7 | export default Terminal
8 |
--------------------------------------------------------------------------------
/src/view/cmdb2/log_audit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/view/cmdb2/multi_add_server.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
15 |
16 |
17 |
18 |
79 |
--------------------------------------------------------------------------------
/src/view/cmdb2/web_ssh.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | web终端
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/view/cmdb2/webssh/Console.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
75 |
--------------------------------------------------------------------------------
/src/view/cmdb2/webssh/WebSSH.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
28 |
--------------------------------------------------------------------------------
/src/view/cmdb2/webssh/Xterm.js:
--------------------------------------------------------------------------------
1 | import { Terminal } from 'xterm'
2 | import * as fit from 'xterm/lib/addons/fit/fit'
3 | import * as attach from 'xterm/lib/addons/attach/attach'
4 | Terminal.applyAddon(fit)
5 | Terminal.applyAddon(attach)
6 |
7 | export default Terminal
8 |
--------------------------------------------------------------------------------
/src/view/components/drag-list/drag-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 待办事项
9 | {{ left.itemLeft.name }}
10 | 完成事项
11 | {{ right.itemRight.name }}
12 |
13 |
14 |
15 |
21 |
24 |
27 |
28 |
29 |
30 |
62 |
114 |
--------------------------------------------------------------------------------
/src/view/components/editor/editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
34 |
--------------------------------------------------------------------------------
/src/view/components/icons/icons.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <Icons :size="30" type="{{ item }}">
9 | <CommonIcon :size="30" type="_{{ item }}">
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | iView内置图标
18 | <CommonIcon :size="30" type="ionic">
19 |
20 |
21 |
22 |
23 |
24 |
25 | Icons组件支持自定义图标的显示,具体自定义图标字体文件的制作请参考文档。
26 | CommonIcon组件同时支持iView内置图标类型和自定义图标类型,为了区别这两种类型,需要在自定义图标名称前加下划线"_"
27 |
28 |
29 |
30 |
31 |
32 |
55 |
56 |
64 |
--------------------------------------------------------------------------------
/src/view/components/markdown/markdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
21 |
22 |
25 |
--------------------------------------------------------------------------------
/src/view/components/split-pane/split-pane.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
40 |
41 |
80 |
--------------------------------------------------------------------------------
/src/view/components/tables/tables.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
68 |
69 |
72 |
--------------------------------------------------------------------------------
/src/view/confd/project/Add.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
84 |
--------------------------------------------------------------------------------
/src/view/directive/directive.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | <Modal v-draggable="options" v-model="visible">标题</Modal>
15 |
16 | options = {
17 | trigger: '.ivu-modal-body',
18 | body: '.ivu-modal'
19 | }
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 拖动这里即可拖动整个弹窗
28 |
29 |
30 |
31 |
32 |
33 |
58 |
59 |
72 |
--------------------------------------------------------------------------------
/src/view/domain-name/components/domain-detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
基本信息
6 |
7 |
8 | 域名ID:
9 | {{domainData.domain_id}}
10 |
11 |
12 |
13 | 域名:
14 | {{domainData.domain_name}}
15 | 解析数量:
16 | {{domainData.record_count}}
17 |
18 |
19 |
20 | 状态:
21 | {{domainData.domain_state}}
22 | 星标:
23 | {{domainData.star_mark}}
24 |
25 |
26 |
27 | 厂商:
28 | {{domainData.cloud_name}}
29 | 账户别名:
30 | {{domainData.account}}
31 |
32 |
33 |
34 | 过期时间(注)
35 | {{domainData.record_end_time}}
36 |
37 |
38 |
39 | 备注:
40 | {{domainData.remark}}
41 |
42 |
43 |
44 | 最后更新时间:
45 | {{domainData.update_time}}
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/view/domain-name/domain-name-monitor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 将要支持对域名过期,根域名证书过期,以及定期对二级域名/端口证书使用情况进行扫描,查缺补漏, 敬请期待!
5 |
6 |
7 |
8 | p
9 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/src/view/error-page/403.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/src/view/error-page/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/src/view/error-page/500.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/src/view/error-page/back-btn-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
39 |
--------------------------------------------------------------------------------
/src/view/error-page/error-content.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![404]()
5 |
6 |
{{ code }}
7 | {{ desc }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
29 |
--------------------------------------------------------------------------------
/src/view/error-page/error.less:
--------------------------------------------------------------------------------
1 | .error-page{
2 | width: 100%;
3 | height: 100%;
4 | position: relative;
5 | background: #f8f8f9;
6 | .content-con{
7 | width: 700px;
8 | height: 600px;
9 | position: absolute;
10 | left: 50%;
11 | top: 50%;
12 | transform: translate(-50%, -60%);
13 | img{
14 | display: block;
15 | width: 100%;
16 | height: 100%;
17 | }
18 | .text-con{
19 | position: absolute;
20 | left: 0px;
21 | top: 0px;
22 | h4{
23 | position: absolute;
24 | left: 0px;
25 | top: 0px;
26 | font-size: 80px;
27 | font-weight: 700;
28 | color: #348EED;
29 | }
30 | h5{
31 | position: absolute;
32 | width: 700px;
33 | left: 0px;
34 | top: 100px;
35 | font-size: 20px;
36 | font-weight: 700;
37 | color: #67647D;
38 | }
39 | }
40 | .back-btn-group{
41 | position: absolute;
42 | right: 0px;
43 | bottom: 20px;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/view/error-store/error-store.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | iview-admin会自动将你程序中的错误收集起来,你可以将错误日志发给后端保存起来。如果你不需要这个功能,将'./src/config/index.js'里的plugin的'error-store'属性删掉即可。
5 | 另外在开发环境下,你程序中的错误都会被收集起来,这样可能不利于你排查错误,你可以将'./src/config/index.js'的'error-store'的'developmentOff'设为true。
6 | 如果你只是想收集错误日志,不希望登录用户看到错误日志,你可以不提供查看日志的入口,只需将'./src/config/index.js'的'error-store'的'showInHeader'设为false。
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ajax接口请求是请求easy-mock的一个不存在接口,所以服务端会报404错误,错误收集机制会收集这个错误,测试的时候有一定网络延迟,所以点击按钮之后稍等一会才会收集到错误。
16 |
17 |
18 |
19 |
20 |
21 |
22 |
36 |
37 |
40 |
--------------------------------------------------------------------------------
/src/view/excel/common.less:
--------------------------------------------------------------------------------
1 | .margin-top-8{
2 | margin-top: 8px;
3 | }
4 | .margin-top-10{
5 | margin-top: 10px;
6 | }
7 | .margin-top-20{
8 | margin-top: 20px;
9 | }
10 | .margin-left-10{
11 | margin-left: 10px;
12 | }
13 | .margin-bottom-10{
14 | margin-bottom: 10px;
15 | }
16 | .margin-bottom-100{
17 | margin-bottom: 100px;
18 | }
19 | .margin-right-10{
20 | margin-right: 10px;
21 | }
22 | .padding-left-6{
23 | padding-left: 6px;
24 | }
25 | .padding-left-8{
26 | padding-left: 5px;
27 | }
28 | .padding-left-10{
29 | padding-left: 10px;
30 | }
31 | .padding-left-20{
32 | padding-left: 20px;
33 | }
34 | .height-100{
35 | height: 100%;
36 | }
37 | .height-120px{
38 | height: 100px;
39 | }
40 | .height-200px{
41 | height: 200px;
42 | }
43 | .height-492px{
44 | height: 492px;
45 | }
46 | .height-460px{
47 | height: 460px;
48 | }
49 | .line-gray{
50 | height: 0;
51 | border-bottom: 2px solid #dcdcdc;
52 | }
53 | .notwrap{
54 | word-break:keep-all;
55 | white-space:nowrap;
56 | overflow: hidden;
57 | text-overflow: ellipsis;
58 | }
59 | .padding-left-5{
60 | padding-left: 10px;
61 | }
62 | [v-cloak]{
63 | display: none;
64 | }
--------------------------------------------------------------------------------
/src/view/excel/export-excel.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
82 |
--------------------------------------------------------------------------------
/src/view/i18n/i18n-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 | {{ content }}
14 | {{ content }}
15 | {{ content }}
16 |
17 |
{{ $t('i18n-tip') }}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
40 |
41 |
51 |
--------------------------------------------------------------------------------
/src/view/join-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 本群为CoDo(CloudOpenDevOps)用户使用交流群,在这里,可以帮你解决平台使用中的困惑和技巧,同时也希望你能提出宝贵的意见和建议,我们一直在努力优化,欢迎你的加入,共同进步。
9 |
10 |
11 |
12 |
13 |
14 |
15 | 本群为CoDo(CloudOpenDevOps)开发交流群,欢迎有一定开发基础(python、vue、 lua等),并且对本项目感兴趣的开发人员来此交流,共同进步。
16 |
17 |
18 |
19 |
20 |
21 |
22 |
35 |
36 |
47 |
--------------------------------------------------------------------------------
/src/view/k8s/app/ListDetail.vue:
--------------------------------------------------------------------------------
1 |
2 | List Detail.......
3 |
4 |
--------------------------------------------------------------------------------
/src/view/k8s/project/ListDetail.vue:
--------------------------------------------------------------------------------
1 |
2 | List Detail.......
3 |
4 |
--------------------------------------------------------------------------------
/src/view/k8s/publish/components/Console.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
{{ item }}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
56 |
--------------------------------------------------------------------------------
/src/view/k8s/publish/components/handle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 111111
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/view/login/login.less:
--------------------------------------------------------------------------------
1 | .login{
2 | width: 100%;
3 | height: 100%;
4 | background-image: url('../../assets/images/login-bg.jpg');
5 | background-size: cover;
6 | background-position: center;
7 | position: relative;
8 | &-con{
9 | position: absolute;
10 | right: 160px;
11 | top: 50%;
12 | transform: translateY(-60%);
13 | width: 300px;
14 | &-header{
15 | font-size: 16px;
16 | font-weight: 300;
17 | text-align: center;
18 | padding: 30px 0;
19 | }
20 | .form-con{
21 | padding: 10px 0 0;
22 | }
23 | .login-tip{
24 | font-size: 10px;
25 | text-align: center;
26 | color: #c3c3c3;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/view/login/login.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
97 |
98 |
100 |
--------------------------------------------------------------------------------
/src/view/multilevel/level-2-1.vue:
--------------------------------------------------------------------------------
1 |
2 | 多级菜单 -> 二级-1
3 |
4 |
9 |
--------------------------------------------------------------------------------
/src/view/multilevel/level-2-2/level-3-1.vue:
--------------------------------------------------------------------------------
1 |
2 | 多级菜单 -> 二级-2 -> 3级
3 |
4 |
9 |
--------------------------------------------------------------------------------
/src/view/multilevel/level-2-3.vue:
--------------------------------------------------------------------------------
1 |
2 | 多级菜单 -> 二级-3
3 |
4 |
9 |
--------------------------------------------------------------------------------
/src/view/publish-store/publish-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
12 |
13 |
开发中的项目
14 |
15 |
16 |
17 |
18 |
105 |
--------------------------------------------------------------------------------
/src/view/publish-store/publish/components/Console.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
{{ item }}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
56 |
--------------------------------------------------------------------------------
/src/view/publish-store/publish/components/QAInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 配置示例:ops/yanghongfei 环境qa, 配置名称为settings.py 则为 https://domain.com/api/kerrigan/v1/conf/publish/config/?project_code=ops&environment=qa&service=yanghongfei&filename=settings.py
5 | 数据库更新对应的标签为 relative_path/环境名 例如:ops/yanghongfei/qa。
6 |
7 |
8 |
9 |
10 |
11 |
16 | 测试地址
17 | xx
18 | xxxxx
19 | xx2
20 | xxxxx
21 |
22 | 数据库语句路径
23 | 任务详细信息
24 |
25 |
26 | // 可以查询到项目的配置
27 | // 2. 应查询测试任务的订单详情。
28 | 如果有数据更新会通知到DBA
29 | // 3. 如果有订单,则查询测试的接口
30 | // 4. 如果订单完成,才展示通过测试按钮
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/view/publish-store/publish/components/handle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 111111
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/view/single-page/error-logger.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
注:这里只会显示成功保存到服务端的错误日志,而且页面错误日志不会在浏览器持久化存储,刷新页面即会丢失
5 |
6 |
7 |
8 |
9 |
88 |
89 |
92 |
--------------------------------------------------------------------------------
/src/view/single-page/home/example.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
115 |
--------------------------------------------------------------------------------
/src/view/single-page/home/index.js:
--------------------------------------------------------------------------------
1 | import home from './home.vue'
2 | export default home
3 |
--------------------------------------------------------------------------------
/src/view/single-page/home/issuesinfo.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
Zabbix Last 10 issues
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{item.host}}
19 |
20 |
21 | {{item.issue}}
22 |
23 |
24 | {{item.last_change}}
25 |
26 |
27 | Normal
28 | Information
29 | Warning
30 | Average
31 | High
32 | Disaster
33 |
34 |
35 |
36 |
37 |
38 |
39 |
47 |
--------------------------------------------------------------------------------
/src/view/single-page/home/logininfo.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
14 |
44 |
--------------------------------------------------------------------------------
/src/view/single-page/home/taskinfo.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
进行中的任务
12 |
13 |
14 |
15 |
16 |
17 | {{item.id}}
18 |
19 |
20 | {{item.name}}
21 |
22 |
23 | {{item.creator}}
24 |
25 |
26 | 新建
27 | 等待
28 | 运行中
29 | 完成
30 | 错误
31 | 手动
32 | 中止
33 | 定时
34 |
35 |
36 |
37 |
38 |
39 |
40 |
48 |
--------------------------------------------------------------------------------
/src/view/tasks-center/assets/resource-mg.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
24 |
25 |
26 |
27 | {{selectMenu}}
28 |
29 |
30 |
31 |
32 |
33 |
50 |
51 |
--------------------------------------------------------------------------------
/src/view/tasks-center/task-submit/asset-purchase-conf.vue:
--------------------------------------------------------------------------------
1 |
2 | aaa
3 |
4 |
--------------------------------------------------------------------------------
/src/view/tasks-center/task-submit/asset-purchase.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 待完善
4 |
5 |
6 |
7 |
17 |
18 |
21 |
--------------------------------------------------------------------------------
/src/view/tasks-center/task-submit/k8s-node-add.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 待完善
4 |
5 |
6 |
7 |
17 |
18 |
21 |
--------------------------------------------------------------------------------
/src/view/tools-methods/tools-methods.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 动态路由,添加params
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 动态路由,添加query
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 手动关闭页面
30 |
31 |
32 |
33 |
34 |
35 |
36 |
79 |
80 |
83 |
--------------------------------------------------------------------------------
/src/view/update/update-paste.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 | 使用Tab键换列,使用回车键换行
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
62 |
63 |
78 |
--------------------------------------------------------------------------------
/src/view/update/update-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 点击上传Csv文件
8 |
9 | util.js提供两个方法用来实现这个功能:
10 | getArrayFromFile:将Csv文件解析为二维数组
11 | getTableDataFromArray:将二维数组转为表格数据,具体请看文档
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
47 |
48 |
56 |
--------------------------------------------------------------------------------
/swagger-ui/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/swagger-ui/favicon-16x16.png
--------------------------------------------------------------------------------
/swagger-ui/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opendevops-cn/codo/b57acb97c17a36d94d26a9214bbc6c051ce081a4/swagger-ui/favicon-32x32.png
--------------------------------------------------------------------------------
/swagger-ui/oauth2-redirect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
68 |
--------------------------------------------------------------------------------
/swagger-ui/swagger-ui.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
--------------------------------------------------------------------------------
/tests/e2e/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "cypress"
4 | ],
5 | "env": {
6 | "mocha": true,
7 | "cypress/globals": true
8 | },
9 | "rules": {
10 | "strict": "off"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/e2e/plugins/index.js:
--------------------------------------------------------------------------------
1 | // https://docs.cypress.io/guides/guides/plugins-guide.html
2 |
3 | module.exports = (on, config) => Object.assign({}, config, {
4 | fixturesFolder: 'tests/e2e/fixtures',
5 | integrationFolder: 'tests/e2e/specs',
6 | screenshotsFolder: 'tests/e2e/screenshots',
7 | videosFolder: 'tests/e2e/videos',
8 | supportFile: 'tests/e2e/support/index.js'
9 | })
10 |
--------------------------------------------------------------------------------
/tests/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // https://docs.cypress.io/api/introduction/api.html
2 |
3 | describe('My First Test', () => {
4 | it('Visits the app root url', () => {
5 | cy.visit('/')
6 | cy.contains('h1', 'Welcome to Your Vue.js App')
7 | })
8 | })
9 |
--------------------------------------------------------------------------------
/tests/e2e/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add("login", (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This is will overwrite an existing command --
25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26 |
--------------------------------------------------------------------------------
/tests/e2e/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands'
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | mocha: true
4 | },
5 | rules: {
6 | 'import/no-extraneous-dependencies': 'off'
7 | }
8 | }
--------------------------------------------------------------------------------
/tests/unit/HelloWorld.spec.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai'
2 | import { shallow } from '@vue/test-utils'
3 | import HelloWorld from '@/components/HelloWorld.vue'
4 |
5 | describe('HelloWorld.vue', () => {
6 | it('renders props.msg when passed', () => {
7 | const msg = 'new message'
8 | const wrapper = shallow(HelloWorld, {
9 | propsData: { msg }
10 | })
11 | expect(wrapper.text()).to.include(msg)
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | const resolve = dir => {
4 | return path.join(__dirname, dir)
5 | }
6 |
7 | // 项目部署基础
8 | // 默认情况下,我们假设你的应用将被部署在域的根目录下,
9 | // 例如:https://www.my-app.com/
10 | // 默认:'/'
11 | // 如果您的应用程序部署在子路径中,则需要在这指定子路径
12 | // 例如:https://www.foobar.com/my-app/
13 | // 需要将它改为'/my-app/'
14 | const BASE_URL = process.env.NODE_ENV === 'production' ? '/' : '/'
15 |
16 | module.exports = {
17 | // Project deployment base
18 | // By default we assume your app will be deployed at the root of a domain,
19 | // e.g. https://www.my-app.com/
20 | // If your app is deployed at a sub-path, you will need to specify that
21 | // sub-path here. For example, if your app is deployed at
22 | // https://www.foobar.com/my-app/
23 | // then change this to '/my-app/'
24 | baseUrl: BASE_URL,
25 | // tweak internal webpack configuration.
26 | // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
27 | // 如果你不需要使用eslint,把lintOnSave设为false即可
28 | // lintOnSave: true,
29 | lintOnSave: process.env.NODE_ENV !== 'production',
30 | chainWebpack: config => {
31 | config.resolve.alias
32 | .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
33 | .set('_c', resolve('src/components'))
34 | },
35 | // 打包时不生成.map文件
36 | productionSourceMap: true,
37 | // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串
38 | devServer: {
39 | // proxy: 'http://172.16.0.223:9800/'
40 | proxy: 'http://gw.opendevops.cn/api/'
41 | }
42 | }
--------------------------------------------------------------------------------