├── tcis
├── __init__.py
├── wsgi.py
└── urls.py
├── project_ci
├── __init__.py
├── migrations
│ └── __init__.py
├── tests.py
├── admin
│ └── __init__.py
├── models
│ └── __init__.py
├── signals
│ └── __init__.py
├── views
│ └── __init__.py
├── permissions
│ └── __init__.py
├── serializers
│ └── __init__.py
├── apps.py
└── urls.py
├── tcis_server
├── __init__.py
├── migrations
│ └── __init__.py
├── tests.py
├── admin
│ └── __init__.py
├── models
│ ├── __init__.py
│ └── server.py
├── views
│ └── __init__.py
├── permissions
│ └── __init__.py
├── serializers
│ └── __init__.py
├── signals
│ └── __init__.py
└── apps.py
├── project
├── migrations
│ ├── __init__.py
│ ├── 0005_auto_20171117_1255.py
│ ├── 0004_auto_20171117_1254.py
│ └── 0003_auto_20171115_1244.py
├── __init__.py
├── tests.py
├── permissions
│ └── __init__.py
├── serializers
│ ├── __init__.py
│ ├── project_member.py
│ ├── project_meeting.py
│ ├── project_task.py
│ └── project.py
├── signals
│ ├── __init__.py
│ ├── project.py
│ ├── project_task.py
│ └── project_member.py
├── apps.py
├── views
│ ├── __init__.py
│ ├── project_task_member.py
│ └── project.py
├── admin
│ ├── __init__.py
│ ├── project_task_type.py
│ ├── project.py
│ ├── project_member.py
│ └── project_task.py
├── models
│ ├── __init__.py
│ ├── project_meeting.py
│ ├── project_task_type.py
│ ├── project_task_history.py
│ ├── project_member.py
│ ├── project.py
│ └── project_task.py
└── urls.py
├── tcis_base
├── migrations
│ └── __init__.py
├── tests.py
├── signals
│ └── __init__.py
├── permissions
│ └── __init__.py
├── apps.py
├── __init__.py
├── views
│ ├── __init__.py
│ ├── index.py
│ ├── group.py
│ ├── permission.py
│ └── user.py
├── serializers
│ ├── __init__.py
│ ├── tcis_meeting.py
│ ├── user.py
│ ├── group.py
│ ├── permission.py
│ └── meeting_member.py
├── admin
│ ├── __init__.py
│ ├── meeting_member.py
│ ├── tcis_meeting.py
│ ├── position.py
│ ├── department.py
│ └── user.py
├── models
│ ├── __init__.py
│ ├── position.py
│ ├── department.py
│ ├── tcis_meeting.py
│ ├── meeting_member.py
│ └── user.py
├── paginations.py
└── urls.py
├── web
├── src
│ ├── pages
│ │ ├── project_ci
│ │ │ ├── list.vue
│ │ │ ├── form.vue
│ │ │ └── project_ci_home.vue
│ │ ├── system
│ │ │ ├── user
│ │ │ │ ├── change_password.vue
│ │ │ │ ├── user_form.vue
│ │ │ │ └── user_home.vue
│ │ │ ├── group
│ │ │ │ ├── group_info.vue
│ │ │ │ ├── group_list.vue
│ │ │ │ ├── group_card.vue
│ │ │ │ ├── group_kanban.vue
│ │ │ │ ├── group_detail_home.vue
│ │ │ │ └── group_form.vue
│ │ │ └── permission
│ │ │ │ ├── permission_list.vue
│ │ │ │ └── permission_home.vue
│ │ ├── project
│ │ │ ├── project_task_detail_home.vue
│ │ │ ├── project_form.vue
│ │ │ ├── project_kanban.vue
│ │ │ ├── project_task_kanban.vue
│ │ │ ├── project_list.vue
│ │ │ ├── project_task_gantt.vue
│ │ │ ├── project_member_list.vue
│ │ │ ├── project_task_card.vue
│ │ │ └── project_home.vue
│ │ ├── project_bug
│ │ │ ├── project_bug_detail_home.vue
│ │ │ ├── project_bug_kanban.vue
│ │ │ ├── project_bug_card.vue
│ │ │ └── project_bug_list.vue
│ │ ├── project_test
│ │ │ ├── project_test_detail_home.vue
│ │ │ ├── project_test_kanban.vue
│ │ │ ├── project_test_card.vue
│ │ │ ├── project_test_list.vue
│ │ │ └── project_test_card_echart.vue
│ │ ├── base
│ │ │ ├── footer.vue
│ │ │ ├── home.vue
│ │ │ ├── header.vue
│ │ │ └── aside.vue
│ │ └── common
│ │ │ ├── middle_router_view.vue
│ │ │ ├── time_axis.vue
│ │ │ ├── page_404.vue
│ │ │ ├── top_create.vue
│ │ │ ├── tcis_select.vue
│ │ │ ├── form_top.vue
│ │ │ ├── pagination.vue
│ │ │ └── view_switch.vue
│ ├── store
│ │ ├── getters.js
│ │ ├── mutations-types.js
│ │ ├── actions.js
│ │ ├── mutations.js
│ │ ├── state.js
│ │ └── index.js
│ ├── assets
│ │ └── page_404.jpg
│ ├── config
│ │ └── settings.js
│ ├── utils
│ │ ├── filters.js
│ │ ├── url_code.js
│ │ └── local_store.js
│ ├── App.vue
│ ├── styles
│ │ └── index.scss
│ ├── main.js
│ ├── server_address.js
│ └── router.js
├── config
│ ├── prod.env.js
│ ├── dev.env.js
│ └── index.js
├── .gitignore
├── index.html
├── build
│ ├── dev-client.js
│ ├── vue-loader.conf.js
│ ├── build.js
│ ├── webpack.dev.conf.js
│ ├── check-versions.js
│ ├── webpack.base.conf.js
│ ├── utils.js
│ └── dev-server.js
├── README.md
└── package.json
├── project_bug
├── migrations
│ ├── __init__.py
│ ├── 0003_auto_20171115_1324.py
│ ├── 0001_initial.py
│ └── 0002_auto_20171115_1151.py
├── __init__.py
├── tests.py
├── permissions
│ └── __init__.py
├── signals
│ └── __init__.py
├── admin
│ ├── __init__.py
│ └── project_bug.py
├── views
│ └── __init__.py
├── models
│ ├── __init__.py
│ └── project_bug.py
├── serializers
│ ├── __init__.py
│ └── project_bug.py
├── apps.py
└── urls.py
├── project_test
├── migrations
│ ├── __init__.py
│ ├── 0003_auto_20171115_1200.py
│ ├── 0004_auto_20171115_1324.py
│ ├── 0001_initial.py
│ └── 0002_auto_20171115_1151.py
├── __init__.py
├── tests.py
├── permissions
│ └── __init__.py
├── signals
│ ├── __init__.py
│ └── project_test_case.py
├── apps.py
├── admin
│ ├── __init__.py
│ ├── project_test.py
│ ├── project_test_type.py
│ ├── project_test_case.py
│ └── project_test_case_history.py
├── views
│ ├── __init__.py
│ ├── project_test_type.py
│ ├── project_tase_case.py
│ ├── project_test_case_history.py
│ └── project_test.py
├── models
│ ├── __init__.py
│ ├── project_test_type.py
│ ├── project_test.py
│ ├── project_test_case.py
│ └── project_test_case_history.py
├── serializers
│ ├── __init__.py
│ ├── project_test.py
│ ├── project_test_case.py
│ ├── project_test_type.py
│ └── project_test_case_history.py
└── urls.py
├── performance_appraisal
├── migrations
│ └── __init__.py
├── __init__.py
├── tests.py
├── admin
│ └── __init__.py
├── models
│ └── __init__.py
├── views
│ └── __init__.py
├── permissions
│ └── __init__.py
├── serializers
│ └── __init__.py
├── signals
│ └── __init__.py
├── apps.py
└── urls.py
├── db.sqlite3
├── static
├── fonts
│ └── element-icons.27c7209.ttf
└── js
│ ├── 16.16887684d55ab321b8c9.js
│ ├── 17.049d493d51aa03865805.js
│ ├── 18.2ea16126bf605bbc7af2.js
│ ├── 15.4a0f80754bf9336425cb.js
│ ├── 14.a6ab56ad507ed6cf2077.js
│ ├── 13.3a548fc888b607f48c6a.js
│ ├── 12.b1b737b799e9a743298f.js
│ ├── 18.2ea16126bf605bbc7af2.js.map
│ ├── 17.049d493d51aa03865805.js.map
│ ├── 16.16887684d55ab321b8c9.js.map
│ ├── manifest.56a3f94c7823145ecc26.js
│ ├── 15.4a0f80754bf9336425cb.js.map
│ ├── 14.a6ab56ad507ed6cf2077.js.map
│ └── 13.3a548fc888b607f48c6a.js.map
├── requirements.txt
├── .gitignore
├── common
└── __init__.py
├── README.md
├── templates
└── index.html
└── manage.py
/tcis/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/project_ci/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tcis_server/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/project/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/project_ci/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tcis_base/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/src/pages/project_ci/list.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/project_bug/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/project_test/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tcis_server/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/performance_appraisal/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/src/pages/system/user/change_password.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_task_detail_home.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/src/pages/project_bug/project_bug_detail_home.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | }
--------------------------------------------------------------------------------
/web/src/pages/project_test/project_test_detail_home.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itcloudy/tcis/HEAD/db.sqlite3
--------------------------------------------------------------------------------
/project/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | default_app_config = 'project.apps.ProjectConfig'
3 |
--------------------------------------------------------------------------------
/project_bug/__init__.py:
--------------------------------------------------------------------------------
1 | default_app_config = 'project_bug.apps.ProjectBugConfig'
--------------------------------------------------------------------------------
/project_test/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | default_app_config = 'project_test.apps.ProjectTestConfig'
--------------------------------------------------------------------------------
/web/src/pages/base/footer.vue:
--------------------------------------------------------------------------------
1 |
2 | Footer
3 |
4 |
--------------------------------------------------------------------------------
/web/src/store/mutations-types.js:
--------------------------------------------------------------------------------
1 | export const GLOBAL_SET_USERINFO = 'GLOBAL_SET_USERINFO' // 设置用户信息
--------------------------------------------------------------------------------
/web/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/web/src/assets/page_404.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itcloudy/tcis/HEAD/web/src/assets/page_404.jpg
--------------------------------------------------------------------------------
/web/src/store/actions.js:
--------------------------------------------------------------------------------
1 | import * as types from './mutations-types'
2 |
3 | export default {
4 |
5 | }
--------------------------------------------------------------------------------
/web/src/pages/common/middle_router_view.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/web/src/pages/project_ci/form.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | project ci info
4 |
5 |
6 |
--------------------------------------------------------------------------------
/web/src/pages/project_ci/project_ci_home.vue:
--------------------------------------------------------------------------------
1 |
2 | project ci kanban
3 |
4 |
--------------------------------------------------------------------------------
/performance_appraisal/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | default_app_config = 'performance_appraisal.apps.PerformanceAppraisalConfig'
3 |
4 |
--------------------------------------------------------------------------------
/static/fonts/element-icons.27c7209.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itcloudy/tcis/HEAD/static/fonts/element-icons.27c7209.ttf
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==1.11.7
2 | django-suit==0.2.25
3 | djangorestframework==3.7.3
4 | channels==1.1.8
5 | django_filter==1.1.0
--------------------------------------------------------------------------------
/web/src/config/settings.js:
--------------------------------------------------------------------------------
1 | var settings = {
2 | baseUrl: "/",
3 | db_prefix: "tcis",
4 | };
5 | module.exports = settings;
6 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_form.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/project/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/project_ci/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/tcis_base/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/project_bug/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/project_test/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/tcis_server/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # sphinx build directories
2 | _build/
3 |
4 | # dotfiles
5 | .*
6 | !.gitignore
7 | !.mailmap
8 | # compiled python files
9 | *.py[co]
10 | /node_modules/
--------------------------------------------------------------------------------
/performance_appraisal/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.test import TestCase
5 |
6 | # Create your tests here.
7 |
--------------------------------------------------------------------------------
/project_ci/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
--------------------------------------------------------------------------------
/project_ci/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:31
9 | """
--------------------------------------------------------------------------------
/project_ci/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 16:32
9 | """
--------------------------------------------------------------------------------
/project_ci/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
--------------------------------------------------------------------------------
/tcis_base/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 16:32
9 | """
--------------------------------------------------------------------------------
/tcis_server/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:49
9 | """
--------------------------------------------------------------------------------
/tcis_server/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:49
9 | """
--------------------------------------------------------------------------------
/tcis_server/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:49
9 | """
--------------------------------------------------------------------------------
/project/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:26
9 | """
--------------------------------------------------------------------------------
/project_bug/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:26
9 | """
--------------------------------------------------------------------------------
/project_bug/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 16:32
9 | """
--------------------------------------------------------------------------------
/project_ci/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:26
9 | """
--------------------------------------------------------------------------------
/project_ci/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 10:07
9 | """
--------------------------------------------------------------------------------
/tcis_base/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:26
9 | """
--------------------------------------------------------------------------------
/tcis_server/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:50
9 | """
--------------------------------------------------------------------------------
/tcis_server/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:50
9 | """
--------------------------------------------------------------------------------
/tcis_server/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:50
9 | """
--------------------------------------------------------------------------------
/performance_appraisal/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 9:58
9 | """
--------------------------------------------------------------------------------
/performance_appraisal/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 9:58
9 | """
--------------------------------------------------------------------------------
/performance_appraisal/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 9:58
9 | """
--------------------------------------------------------------------------------
/project_test/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:26
9 | """
--------------------------------------------------------------------------------
/static/js/16.16887684d55ab321b8c9.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([16],{A7zi:function(l,n,u){var o=u("VU/8")(null,null,null,null,null);l.exports=o.exports}});
2 | //# sourceMappingURL=16.16887684d55ab321b8c9.js.map
--------------------------------------------------------------------------------
/static/js/17.049d493d51aa03865805.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([17],{wRKD:function(l,n,u){var o=u("VU/8")(null,null,null,null,null);l.exports=o.exports}});
2 | //# sourceMappingURL=17.049d493d51aa03865805.js.map
--------------------------------------------------------------------------------
/static/js/18.2ea16126bf605bbc7af2.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([18],{hFY9:function(l,n,u){var o=u("VU/8")(null,null,null,null,null);l.exports=o.exports}});
2 | //# sourceMappingURL=18.2ea16126bf605bbc7af2.js.map
--------------------------------------------------------------------------------
/performance_appraisal/permissions/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/10 9:26
9 | """
--------------------------------------------------------------------------------
/performance_appraisal/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 10:07
9 | """
--------------------------------------------------------------------------------
/performance_appraisal/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 16:32
9 | """
--------------------------------------------------------------------------------
/web/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/project_ci/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class ProjectCiConfig(AppConfig):
8 | name = 'project_ci'
9 |
--------------------------------------------------------------------------------
/tcis_server/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class TcisServerConfig(AppConfig):
8 | name = 'tcis_server'
9 |
--------------------------------------------------------------------------------
/common/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/11 11:00
9 | """
10 | from .parent_tree import *
--------------------------------------------------------------------------------
/project_bug/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 | from .project_bug import *
--------------------------------------------------------------------------------
/project_bug/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 | from .project_bug import *
11 |
--------------------------------------------------------------------------------
/project_bug/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:31
9 | """
10 |
11 | from .project_bug import *
--------------------------------------------------------------------------------
/project_bug/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 10:07
9 | """
10 | from .project_bug import *
--------------------------------------------------------------------------------
/web/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/tcis_base/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class TcisBaseConfig(AppConfig):
8 | name = 'tcis_base'
9 | verbose_name = u'基本配置'
10 |
--------------------------------------------------------------------------------
/project_test/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 16:32
9 | """
10 | from .project_test_case import *
11 |
12 |
--------------------------------------------------------------------------------
/project_bug/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class ProjectBugConfig(AppConfig):
8 | name = 'project_bug'
9 | verbose_name = u'项目Bug'
10 |
--------------------------------------------------------------------------------
/web/src/pages/common/time_axis.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/tcis_base/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 |
11 | default_app_config = 'tcis_base.apps.TcisBaseConfig'
12 |
13 |
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | tcis_web
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/web/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | import * as types from './mutations-types'
2 |
3 | export default {
4 | [types.GLOBAL_SET_USERINFO](state, userinfo) {
5 | state.userinfo = userinfo;
6 | state.isBackgroundUser = userinfo.isBackground;
7 | },
8 |
9 | }
--------------------------------------------------------------------------------
/project_ci/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:urls.py
8 | @date:2017/11/8 10:07
9 | """
10 |
11 | from django.conf.urls import url
12 | from . import views
13 |
14 | urlpatterns = []
--------------------------------------------------------------------------------
/performance_appraisal/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class PerformanceAppraisalConfig(AppConfig):
8 | name = 'performance_appraisal'
9 | verbose_name = u'绩效考核'
10 |
--------------------------------------------------------------------------------
/performance_appraisal/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:urls.py
8 | @date:2017/11/8 10:06
9 | """
10 | from django.conf.urls import url
11 | from . import views
12 |
13 | urlpatterns = [
14 |
15 | ]
--------------------------------------------------------------------------------
/project/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 10:07
9 | """
10 |
11 | from .project import *
12 | from .project_member import *
13 | from .project_task import *
14 |
--------------------------------------------------------------------------------
/project/signals/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 16:32
9 | """
10 | from .project import *
11 | from .project_member import *
12 | from .project_task import *
13 |
14 |
15 |
--------------------------------------------------------------------------------
/web/src/utils/filters.js:
--------------------------------------------------------------------------------
1 | export default function stringTimeFormat(timeString) {
2 | let date = new Date(timeString);
3 | let time = date.toLocaleString();
4 | time = time.replace(/\//g, "-");
5 | time = time.replace("上午", "");
6 | time = time.replace("下午", "");
7 | return time;
8 | }
--------------------------------------------------------------------------------
/tcis_base/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 |
11 | from .index import *
12 | from .user import *
13 | from .group import *
14 | from .permission import *
15 |
--------------------------------------------------------------------------------
/project/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class ProjectConfig(AppConfig):
8 | name = 'project'
9 | verbose_name = u'项目'
10 |
11 | def ready(self):
12 | import project.signals
13 |
14 |
--------------------------------------------------------------------------------
/project/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 |
11 |
12 | from .project import *
13 | from .project_task import *
14 | from .project_task_member import *
15 |
16 |
--------------------------------------------------------------------------------
/web/src/pages/common/page_404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/project/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 | from .project import *
11 | from .project_member import *
12 | from .project_task import *
13 | from .project_task_type import *
14 |
--------------------------------------------------------------------------------
/web/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | 'use strict'
3 | require('eventsource-polyfill')
4 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
5 |
6 | hotClient.subscribe(function (event) {
7 | if (event.action === 'reload') {
8 | window.location.reload()
9 | }
10 | })
11 |
--------------------------------------------------------------------------------
/project_test/apps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.apps import AppConfig
5 |
6 |
7 | class ProjectTestConfig(AppConfig):
8 | name = 'project_test'
9 | verbose_name = u'项目测试'
10 |
11 | def ready(self):
12 | import project_test.signals
13 |
14 |
--------------------------------------------------------------------------------
/tcis_base/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 10:07
9 | """
10 | from .user import *
11 | from .group import *
12 | from .tcis_meeting import TcisMeetingSerializer
13 | from .permission import *
--------------------------------------------------------------------------------
/web/src/pages/system/user/user_form.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
16 |
17 |
--------------------------------------------------------------------------------
/static/js/15.4a0f80754bf9336425cb.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([15],{OEdk:function(e,n){e.exports={render:function(){var e=this,n=e.$createElement;return(e._self._c||n)("router-view")},staticRenderFns:[]}},cBoM:function(e,n,r){var t=r("VU/8")(null,r("OEdk"),null,null,null);e.exports=t.exports}});
2 | //# sourceMappingURL=15.4a0f80754bf9336425cb.js.map
--------------------------------------------------------------------------------
/project_test/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 | from .project_test_case_history import *
11 | from .project_test import *
12 | from .project_test_type import *
13 | from .project_test_case import *
--------------------------------------------------------------------------------
/project_test/views/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 | from .project_test import *
11 | from .project_tase_case import *
12 | from .project_test_case_history import *
13 | from .project_test_type import *
14 |
--------------------------------------------------------------------------------
/static/js/14.a6ab56ad507ed6cf2077.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([14],{C2W4:function(n,e){n.exports={render:function(){var n=this,e=n.$createElement;return(n._self._c||e)("p",[n._v(" project ci info")])},staticRenderFns:[]}},obhH:function(n,e,t){var r=t("VU/8")(null,t("C2W4"),null,null,null);n.exports=r.exports}});
2 | //# sourceMappingURL=14.a6ab56ad507ed6cf2077.js.map
--------------------------------------------------------------------------------
/tcis_base/admin/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:35
9 | """
10 | from .department import *
11 | from .user import *
12 | from .position import *
13 | from .tcis_meeting import *
14 | from .meeting_member import *
15 |
16 |
--------------------------------------------------------------------------------
/static/js/13.3a548fc888b607f48c6a.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([13],{"0Qf1":function(n,e,t){var r=t("VU/8")(null,t("SIth"),null,null,null);n.exports=r.exports},SIth:function(n,e){n.exports={render:function(){var n=this,e=n.$createElement;return(n._self._c||e)("p",[n._v("project ci kanban ")])},staticRenderFns:[]}}});
2 | //# sourceMappingURL=13.3a548fc888b607f48c6a.js.map
--------------------------------------------------------------------------------
/tcis_base/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:31
9 | """
10 |
11 | from .user import *
12 | from .department import *
13 | from .position import *
14 | from .tcis_meeting import *
15 | from .meeting_member import *
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 项目说明
2 | 是一个用于管理软件项目开发的app,包括项目管理,项目任务管理,项目测试管理,项目bug管理
3 |
4 | ## 说明
5 | * 后台 框架为djangorestframework
6 | * 前端 基于vue2.0
7 |
8 | * tcis_base:基础模块,用户改进,部门,职位,会议
9 | * tcis_server:服务器管理
10 | * performance_appraisal:绩效考核
11 | * project:项目管理:项目,任务,项目会议
12 | * project_ci:持续集成
13 | * project_test:测试管理:用例
14 | * projct_bug:项目bug管理
15 |
--------------------------------------------------------------------------------
/project_test/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:31
9 | """
10 | from .project_test_case import *
11 | from .project_test import *
12 | from .project_test_type import *
13 | from .project_test_case_history import *
14 |
15 |
--------------------------------------------------------------------------------
/project_test/serializers/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/9 10:07
9 | """
10 | from .project_test import *
11 | from .project_test_case_history import *
12 | from .project_test_case import *
13 | from .project_test_type import *
14 |
--------------------------------------------------------------------------------
/web/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
19 |
--------------------------------------------------------------------------------
/web/src/utils/url_code.js:
--------------------------------------------------------------------------------
1 | export default function urlCode(data) {
2 | let urlQueryList = [];
3 | if (typeof(data) == 'undefined' || data == null || typeof(data) != 'object') {
4 | return '';
5 | }
6 | for (let k in data) {
7 | urlQueryList.push("" + k + "=" + encodeURI(data[k]))
8 | }
9 | return urlQueryList.join("&");
10 | }
--------------------------------------------------------------------------------
/tcis_base/views/index.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:index.py
8 | @date:2017/11/8 13:55
9 | """
10 | from django.shortcuts import render
11 |
12 |
13 | def index(request):
14 | """
15 | 首页
16 | :param request:
17 | :return:
18 | """
19 | return render(request, 'index.html')
20 |
--------------------------------------------------------------------------------
/project_bug/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:urls.py
8 | @date:2017/11/8 10:06
9 | """
10 | from rest_framework import routers
11 | from .views import *
12 |
13 | router = routers.DefaultRouter()
14 |
15 | router.register(r'project_bug', ProjectBugViewSet, 'project_bug')
16 |
17 | urlpatterns = router.urls
18 |
--------------------------------------------------------------------------------
/tcis_base/paginations.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:paginations.py
8 | @date:2017/11/9 11:15
9 | """
10 | from rest_framework import pagination
11 |
12 |
13 | class DefaultPagination(pagination.PageNumberPagination):
14 | page_size = 20
15 | max_page_size = 10000
16 | page_size_query_param = 'page_size'
17 |
--------------------------------------------------------------------------------
/web/src/store/state.js:
--------------------------------------------------------------------------------
1 | import localStore from 'utils/local_store';
2 | const state = {
3 | //登录成功后的用户信息
4 | userinfo: JSON.parse(localStore.get('userinfo')) || {},
5 | //后台获得的菜单(后台菜单)
6 | backgroundMenus: JSON.parse(localStore.get('backgroundMenus')) || {},
7 | // 加载路由完成
8 | loadRoutersDone: false,
9 | //可以访问后台
10 | isBackgroundUser: false,
11 | };
12 | export default state
--------------------------------------------------------------------------------
/project/models/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:__init__.py.py
8 | @date:2017/11/8 9:31
9 | """
10 | from .project import *
11 | from .project_member import *
12 | from .project_task import *
13 | from .project_meeting import *
14 | from .project_task_type import *
15 | from .project_task_history import *
16 |
17 |
18 |
--------------------------------------------------------------------------------
/project_test/admin/project_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test.py
8 | @date:2017/11/15 11:52
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectTest
12 |
13 |
14 | @admin.register(ProjectTest)
15 | class ProjectTestAdmin(admin.ModelAdmin):
16 | list_display = ['project', 'name', 'type']
17 |
--------------------------------------------------------------------------------
/project_test/admin/project_test_type.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_type.py
8 | @date:2017/11/15 11:53
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectTestType
12 |
13 |
14 | @admin.register(ProjectTestType)
15 | class ProjectTestTypeAdmin(admin.ModelAdmin):
16 | list_display = ['name']
17 |
18 |
--------------------------------------------------------------------------------
/tcis_base/serializers/tcis_meeting.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:tcis_meeting.py
8 | @date:2017/11/15 11:14
9 | """
10 | from rest_framework import serializers
11 | from ..models import TcisMeeting
12 |
13 |
14 | class TcisMeetingSerializer(serializers.ModelSerializer):
15 | class Meta:
16 | model = TcisMeeting
17 | depth = 2
18 |
19 |
--------------------------------------------------------------------------------
/tcis_base/serializers/user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:user.py
8 | @date:2017/11/10 9:10
9 | """
10 | from rest_framework import serializers
11 | from ..models import User
12 |
13 |
14 | class UserSerializer(serializers.ModelSerializer):
15 | class Meta:
16 | model = User
17 | depth = 2
18 | exclude = ('password',)
19 |
20 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 | tcis_web
--------------------------------------------------------------------------------
/project/admin/project_task_type.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task_type.py
8 | @date:2017/11/15 12:42
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectTaskType
12 |
13 |
14 | @admin.register(ProjectTaskType)
15 | class ProjectTaskTypeAdmin(admin.ModelAdmin):
16 | """
17 | 项目管理后台
18 | """
19 | list_display = ["name"]
20 |
--------------------------------------------------------------------------------
/project_test/admin/project_test_case.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_case.py
8 | @date:2017/11/15 11:53
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectTestCase
12 |
13 |
14 | @admin.register(ProjectTestCase)
15 | class ProjectTestCaseAdmin(admin.ModelAdmin):
16 | list_display = ['project', 'task', 'test', "name", "type"]
17 |
18 |
--------------------------------------------------------------------------------
/tcis_base/serializers/group.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:group.py
8 | @date:2017/11/13 17:15
9 | """
10 | from django.contrib.auth.models import Group
11 | from rest_framework import serializers
12 |
13 |
14 | class GroupSerializer(serializers.ModelSerializer):
15 |
16 | class Meta:
17 | model = Group
18 | depth = 2
19 | fields = "__all__"
20 |
21 |
--------------------------------------------------------------------------------
/tcis/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for tcis project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tcis.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/project_test/admin/project_test_case_history.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_case_history.py
8 | @date:2017/11/15 11:53
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectTestCaseHistory
12 |
13 |
14 | @admin.register(ProjectTestCaseHistory)
15 | class ProjectTestCaseHistoryAdmin(admin.ModelAdmin):
16 | list_display = ['case', 'user']
17 |
18 |
--------------------------------------------------------------------------------
/project_test/serializers/project_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test.py
8 | @date:2017/11/15 13:19
9 | """
10 |
11 | from rest_framework import serializers
12 | from ..models import ProjectTest
13 |
14 |
15 | class ProjectTestSerializer(serializers.ModelSerializer):
16 | class Meta:
17 | model = ProjectTest
18 | depth = 1
19 | fields = "__all__"
20 |
--------------------------------------------------------------------------------
/project_test/serializers/project_test_case.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_case.py
8 | @date:2017/11/15 15:10
9 | """
10 | from rest_framework import serializers
11 | from ..models import ProjectTestCase
12 |
13 |
14 | class ProjectTestCaseSerializer(serializers.ModelSerializer):
15 | class Meta:
16 | model = ProjectTestCase
17 | depth = 1
18 | fields = "__all__"
--------------------------------------------------------------------------------
/tcis_base/serializers/permission.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:permission.py
8 | @date:2017/11/15 17:54
9 | """
10 | from django.contrib.auth.models import Permission
11 | from rest_framework import serializers
12 |
13 |
14 | class PermissionSerializer(serializers.ModelSerializer):
15 |
16 | class Meta:
17 | model = Permission
18 | depth = 2
19 | fields = "__all__"
20 |
--------------------------------------------------------------------------------
/project_test/serializers/project_test_type.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_type.py
8 | @date:2017/11/15 15:10
9 | """
10 | from rest_framework import serializers
11 | from ..models import ProjectTestType
12 |
13 |
14 | class ProjectTestTypeSerializer(serializers.ModelSerializer):
15 | class Meta:
16 | model = ProjectTestType
17 | depth = 1
18 | fields = "__all__"
19 |
--------------------------------------------------------------------------------
/tcis_base/admin/meeting_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:meeting_member.py
8 | @date:2017/11/15 11:06
9 | """
10 | from django.contrib import admin
11 |
12 | from ..models import MeetingMember
13 |
14 |
15 | @admin.register(MeetingMember)
16 | class MeetingMemberAdmin(admin.ModelAdmin):
17 | """会议管理"""
18 | list_display = ['meeting', "user", "state"]
19 | list_filter = ["user", "state"]
20 |
--------------------------------------------------------------------------------
/tcis_base/views/group.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:group.py
8 | @date:2017/11/13 17:16
9 | """
10 | from rest_framework import viewsets
11 | from django.contrib.auth.models import Group
12 | from ..serializers import GroupSerializer
13 |
14 |
15 | class GroupViewSet(viewsets.ModelViewSet):
16 | """
17 | 用户
18 | """
19 | queryset = Group.objects.all()
20 | serializer_class = GroupSerializer
21 |
22 |
--------------------------------------------------------------------------------
/tcis_server/models/server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:server.py
8 | @date:2017/11/10 10:07
9 | """
10 | from django.db import models
11 |
12 |
13 | class Server(models.Model):
14 | """
15 | 服务器管理
16 | """
17 | name = models.CharField(max_length=20, verbose_name=u"服务器名称")
18 | ip = models.IPAddressField(verbose_name=u"服务器IP地址")
19 | system = models.CharField(max_length=20, verbose_name=u"服务器系统")
--------------------------------------------------------------------------------
/project/admin/project.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project.py
8 | @date:2017/11/9 9:04
9 | """
10 |
11 | from django.contrib import admin
12 | from ..models import Project
13 |
14 |
15 | @admin.register(Project)
16 | class ProjectAdmin(admin.ModelAdmin):
17 | """
18 | 项目管理后台
19 | """
20 | list_display = ["name", "manager", "active", "parent", "start_date", "end_date", "parent_left", "parent_right"]
21 |
22 |
--------------------------------------------------------------------------------
/project_test/serializers/project_test_case_history.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_case_history.py
8 | @date:2017/11/15 15:10
9 | """
10 | from rest_framework import serializers
11 | from ..models import ProjectTestCaseHistory
12 |
13 |
14 | class ProjectTestCaseHistorySerializer(serializers.ModelSerializer):
15 | class Meta:
16 | model = ProjectTestCaseHistory
17 | depth = 1
18 | fields = "__all__"
19 |
--------------------------------------------------------------------------------
/tcis_base/admin/tcis_meeting.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:tcis_meeting.py
8 | @date:2017/11/15 10:51
9 | """
10 | from django.contrib import admin
11 |
12 | from ..models import TcisMeeting
13 |
14 |
15 | @admin.register(TcisMeeting)
16 | class TcisMeetingAdmin(admin.ModelAdmin):
17 | """会议管理"""
18 | list_display = ['title', "moderator", "recorder", 'start_time', 'end_time']
19 | list_filter = ["moderator", "recorder"]
20 |
21 |
--------------------------------------------------------------------------------
/project/migrations/0005_auto_20171117_1255.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-17 04:55
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('project', '0004_auto_20171117_1254'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterModelTable(
16 | name='projectmeeting',
17 | table='project_meeting',
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/web/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 |
6 | module.exports = {
7 | loaders: utils.cssLoaders({
8 | sourceMap: isProduction
9 | ? config.build.productionSourceMap
10 | : config.dev.cssSourceMap,
11 | extract: isProduction
12 | }),
13 | transformToRequire: {
14 | video: 'src',
15 | source: 'src',
16 | img: 'src',
17 | image: 'xlink:href'
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/web/README.md:
--------------------------------------------------------------------------------
1 | # tcis_web
2 |
3 | > tcis
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 | ```
20 |
21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
22 |
--------------------------------------------------------------------------------
/project/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:urls.py
8 | @date:2017/11/8 10:06
9 | """
10 | from django.conf.urls import url
11 | from rest_framework import routers
12 | from .views import *
13 |
14 | router = routers.DefaultRouter()
15 |
16 | router.register(r'project', ProjectViewSet, 'project')
17 | router.register(r'project_task', ProjectTaskViewSet, 'project_task')
18 | router.register(r'project_member', ProjectMemberViewSet, 'project_member')
19 |
20 | urlpatterns = router.urls
21 |
--------------------------------------------------------------------------------
/web/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | // 根级state、actions、getters、mutations
5 | import state from './state';
6 | import actions from './actions';
7 | import getters from './getters';
8 | import mutations from './mutations';
9 |
10 |
11 | Vue.use(Vuex)
12 | const debug = process.env.NODE_ENV !== 'production'
13 |
14 | export default new Vuex.Store({
15 | state,
16 | actions,
17 | getters,
18 | mutations,
19 | modules: {
20 | // adminPartner, //合作伙伴
21 |
22 | },
23 | strict: debug,
24 | })
25 |
--------------------------------------------------------------------------------
/project/signals/project.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project.py
8 | @date:2017/11/9 16:45
9 | """
10 | from django.db.models.signals import pre_save
11 | from django.dispatch import receiver
12 | from ..models import Project
13 |
14 |
15 | @receiver(pre_save, sender=Project)
16 | def save_project(sender, instance, *args, **kwargs):
17 | """
18 |
19 | :param sender:
20 | :param instance:
21 | :param args:
22 | :param kwargs:
23 | :return:
24 | """
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/project/admin/project_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_member.py
8 | @date:2017/11/9 16:23
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectMember
12 |
13 |
14 | @admin.register(ProjectMember)
15 | class ProjectMemberAdmin(admin.ModelAdmin):
16 | """
17 | 项目管理后台
18 | """
19 | list_display = ["project", "member", "active", "position"]
20 |
21 | fieldsets = [
22 | (None, {
23 | 'fields': ['project', 'member']})
24 | ]
25 |
--------------------------------------------------------------------------------
/project/signals/project_task.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task.py
8 | @date:2017/11/9 16:46
9 | """
10 |
11 | from django.db.models.signals import pre_save
12 | from django.dispatch import receiver
13 | from ..models import ProjectTask
14 |
15 |
16 | @receiver(pre_save, sender=ProjectTask)
17 | def save_project_task(sender, instance, *args, **kwargs):
18 | """
19 |
20 | :param sender:
21 | :param instance:
22 | :param args:
23 | :param kwargs:
24 | :return:
25 | """
26 |
--------------------------------------------------------------------------------
/project/serializers/project_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_member.py
8 | @date:2017/11/10 11:49
9 | """
10 | from rest_framework import serializers
11 | from ..models import ProjectMember
12 |
13 |
14 | class ProjectMemberSerializer(serializers.ModelSerializer):
15 | parent_left = serializers.IntegerField(read_only=True)
16 | parent_right = serializers.IntegerField(read_only=True)
17 |
18 | class Meta:
19 | model = ProjectMember
20 | depth = 1
21 | fields = "__all__"
22 |
--------------------------------------------------------------------------------
/project_bug/admin/project_bug.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_bug.py
8 | @date:2017/11/9 16:23
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectBug
12 |
13 |
14 | @admin.register(ProjectBug)
15 | class ProjectBugAdmin(admin.ModelAdmin):
16 | """
17 | 项目管理后台
18 | """
19 | search_fields = ["project", "name", "handler", "state"]
20 | list_display = ["project", "name", "handler", "state"]
21 | list_filter = ['project', "handler", "state", 'tester', 'checker']
22 |
23 |
--------------------------------------------------------------------------------
/tcis_base/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:urls.py
8 | @date:2017/11/8 10:07
9 | """
10 |
11 | from django.conf.urls import url
12 | from .views import *
13 | from rest_framework import routers
14 |
15 |
16 | urlpatterns = [
17 | url(r'^$', index, name="index"),
18 | ]
19 | router = routers.DefaultRouter()
20 |
21 | router.register(r'user', UserViewSet, 'user')
22 | router.register(r'group', GroupViewSet, 'group')
23 | router.register(r'permission', PermissionViewSet, 'permission')
24 | urlpatterns += router.urls
25 |
--------------------------------------------------------------------------------
/tcis_base/serializers/meeting_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:meeting_member.py
8 | @date:2017/11/15 11:16
9 | """
10 | from rest_framework import serializers
11 | from ..models import MeetingMember
12 | from .user import UserSerializer
13 | from .tcis_meeting import TcisMeetingSerializer
14 |
15 |
16 | class MeetingMemberSerializer(serializers.ModelSerializer):
17 | meeting = TcisMeetingSerializer()
18 | user = UserSerializer()
19 |
20 | class Meta:
21 | model = MeetingMember
22 | depth = 2
23 |
--------------------------------------------------------------------------------
/project/models/project_meeting.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_meeting.py
8 | @date:2017/11/15 10:48
9 | """
10 | from django.db import models
11 |
12 |
13 | class ProjectMeeting(models.Model):
14 | """
15 | 项目会议
16 | """
17 | meeting = models.ForeignKey('tcis_base.TcisMeeting', verbose_name=u"会议")
18 | project = models.ForeignKey("Project", verbose_name=u"项目")
19 |
20 | class Meta:
21 | db_table = "project_meeting"
22 | verbose_name = u'项目会议'
23 | verbose_name_plural = u"项目会议管理"
24 |
--------------------------------------------------------------------------------
/tcis_base/admin/position.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:position.py
8 | @date:2017/11/9 16:47
9 | """
10 | from django.contrib import admin
11 |
12 | from ..models import Position
13 |
14 |
15 | @admin.register(Position)
16 | class PositionAdmin(admin.ModelAdmin):
17 | """
18 | 用户后台信息管理
19 | """
20 | search_fields = ['name']
21 | list_display = ['name', "description"]
22 | list_filter = ['name']
23 |
24 | fieldsets = [
25 | (None,{
26 | 'fields': ['name', 'description'],
27 | }),
28 |
29 | ]
30 |
31 |
--------------------------------------------------------------------------------
/project/serializers/project_meeting.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_meeting.py
8 | @date:2017/11/15 11:12
9 | """
10 | from rest_framework import serializers
11 | from ..models import ProjectMeeting
12 | from .project import ProjectSerializer
13 | from tcis_base.serializers import TcisMeetingSerializer
14 |
15 |
16 | class ProjectMeetingSerializer(serializers.ModelSerializer):
17 | meeting = TcisMeetingSerializer()
18 | project = ProjectSerializer()
19 |
20 | class Meta:
21 | model = ProjectMeeting
22 | depth = 2
23 | fields = "__all__"
24 |
--------------------------------------------------------------------------------
/project_test/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:urls.py
8 | @date:2017/11/8 10:07
9 | """
10 | from rest_framework import routers
11 | from .views import *
12 |
13 | router = routers.DefaultRouter()
14 |
15 | router.register(r'project_test', ProjectTestViewSet, 'project_test')
16 | router.register(r'project_test_case', ProjectTestCaseViewSet, 'project_test_case')
17 | router.register(r'project_test_case_history', ProjectTestCaseHistoryViewSet, 'project_test_case_history')
18 | router.register(r'project_test_type', ProjectTestTypeViewSet, 'project_test_type')
19 |
20 | urlpatterns = router.urls
21 |
--------------------------------------------------------------------------------
/project/serializers/project_task.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task.py
8 | @date:2017/11/10 11:49
9 | """
10 |
11 | from rest_framework import serializers
12 | from ..models import ProjectTask
13 | from tcis_base.serializers import UserSerializer
14 |
15 |
16 | class ProjectTaskSerializer(serializers.ModelSerializer):
17 | parent_left = serializers.IntegerField(read_only=True)
18 | parent_right = serializers.IntegerField(read_only=True)
19 | handler = UserSerializer()
20 |
21 | class Meta:
22 | model = ProjectTask
23 | depth = 1
24 | fields = "__all__"
25 |
--------------------------------------------------------------------------------
/project_test/models/project_test_type.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:test_type.py
8 | @date:2017/11/15 11:24
9 | """
10 | from django.db import models
11 |
12 |
13 | class ProjectTestType(models.Model):
14 | """
15 | 测试类型
16 | """
17 | name = models.CharField(verbose_name=u"测试类型", max_length=20, unique=True)
18 |
19 | def __unicode__(self):
20 | return self.name
21 |
22 | def __str__(self):
23 | return self.name
24 |
25 | class Meta:
26 | db_table = "project_test_type"
27 | verbose_name = u'测试类型'
28 | verbose_name_plural = u"测试类型"
29 |
--------------------------------------------------------------------------------
/project/models/project_task_type.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task_type.py
8 | @date:2017/11/15 11:30
9 | """
10 | from django.db import models
11 |
12 |
13 | class ProjectTaskType(models.Model):
14 | """
15 | 任务类型
16 | """
17 | name = models.CharField(verbose_name=u"任务类型", max_length=20, unique=True)
18 |
19 | def __unicode__(self):
20 | return self.name
21 |
22 | def __str__(self):
23 | return self.name
24 |
25 | class Meta:
26 | db_table = "project_task_type"
27 | verbose_name = u'任务类型'
28 | verbose_name_plural = u"任务类型管理"
29 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_kanban.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
24 |
--------------------------------------------------------------------------------
/project_test/signals/project_test_case.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:test_case.py
8 | @date:2017/11/15 13:06
9 | """
10 | from django.db.models.signals import pre_save
11 | from django.dispatch import receiver
12 | from ..models import ProjectTestCase
13 |
14 |
15 | @receiver(pre_save, sender=ProjectTestCase)
16 | def save_test_case(sender, instance, *args, **kwargs):
17 | """
18 |
19 | :param sender:
20 | :param instance:
21 | :param args:
22 | :param kwargs:
23 | :return:
24 | """
25 | if instance and instance.test and instance.test.type:
26 | instance.type = instance.test.type
27 |
--------------------------------------------------------------------------------
/project/migrations/0004_auto_20171117_1254.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-17 04:54
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('project', '0003_auto_20171115_1244'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterModelOptions(
16 | name='projectmeeting',
17 | options={'verbose_name': '项目会议', 'verbose_name_plural': '项目会议管理'},
18 | ),
19 | migrations.AlterModelTable(
20 | name='projectmeeting',
21 | table='project_member',
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/tcis_base/models/position.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:position.py
8 | @date:2017/11/8 11:07
9 | """
10 |
11 | from django.db import models
12 |
13 |
14 | class Position(models.Model):
15 | """
16 | 职位
17 | """
18 | name = models.CharField(max_length=20, verbose_name=u"职位", unique=True, null=False)
19 | description = models.TextField(verbose_name=u"职位描述", null=True, blank=True)
20 |
21 | def __unicode__(self):
22 | return self.name
23 |
24 | def __str__(self):
25 | return self.name
26 |
27 | class Meta:
28 | verbose_name = u'职位'
29 | verbose_name_plural = u'职位管理'
--------------------------------------------------------------------------------
/project/migrations/0003_auto_20171115_1244.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 04:44
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('project', '0002_auto_20171115_1151'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterModelOptions(
16 | name='projecttasktype',
17 | options={'verbose_name': '任务类型', 'verbose_name_plural': '任务类型管理'},
18 | ),
19 | migrations.AlterModelTable(
20 | name='projecttasktype',
21 | table='project_task_type',
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/project/signals/project_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project.py
8 | @date:2017/11/9 16:34
9 | """
10 | from django.db.models.signals import pre_save
11 | from django.dispatch import receiver
12 | from ..models import ProjectMember
13 |
14 |
15 | @receiver(pre_save, sender=ProjectMember)
16 | def save_project_member(sender, instance, *args, **kwargs):
17 | """
18 |
19 | :param sender:
20 | :param instance:
21 | :param args:
22 | :param kwargs:
23 | :return:
24 | """
25 | if instance and instance.member and instance.member.position:
26 | instance.position = instance.member.position
27 |
28 |
29 |
--------------------------------------------------------------------------------
/web/src/pages/base/home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
28 |
--------------------------------------------------------------------------------
/web/src/pages/common/top_create.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 创建
4 |
5 |
6 |
24 |
30 |
--------------------------------------------------------------------------------
/tcis_base/admin/department.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:department.py
8 | @date:2017/11/9 16:49
9 | """
10 | from django.contrib import admin
11 |
12 | from ..models import Department
13 |
14 |
15 | @admin.register(Department)
16 | class DepartmentAdmin(admin.ModelAdmin):
17 | """
18 | 用户后台信息管理
19 | """
20 | search_fields = ['name', "parent", "charge"]
21 | list_display = ['name', "parent", "charge"]
22 | list_filter = ['name']
23 |
24 | fieldsets = [
25 | (u"基本信息",{
26 | 'fields': ['name', 'parent', "charge"],
27 | }),
28 | (u"其他信息", {
29 | 'fields': ['description'],
30 | }),
31 |
32 | ]
33 |
--------------------------------------------------------------------------------
/project_test/views/project_test_type.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_type.py
8 | @date:2017/11/15 15:08
9 | """
10 | from rest_framework import status, permissions
11 | from rest_framework.decorators import list_route
12 | from rest_framework import viewsets
13 | from django.db.models import Count
14 | from project_test.models import ProjectTestType
15 | from rest_framework.response import Response
16 | from tcis_base.models import User
17 | from ..serializers import *
18 |
19 |
20 | class ProjectTestTypeViewSet(viewsets.ModelViewSet):
21 | """
22 | 项目管理
23 | """
24 | queryset = ProjectTestType.objects.all()
25 | serializer_class = ProjectTestTypeSerializer
--------------------------------------------------------------------------------
/project_test/views/project_tase_case.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_tase_case.py
8 | @date:2017/11/15 15:08
9 | """
10 | from rest_framework import status, permissions
11 | from rest_framework.decorators import list_route
12 | from rest_framework import viewsets
13 | from django.db.models import Count
14 | from project_test.models import ProjectTestCase
15 | from rest_framework.response import Response
16 | from tcis_base.models import User
17 | from ..serializers import *
18 |
19 |
20 | class ProjectTestCaseViewSet(viewsets.ModelViewSet):
21 | """
22 | 项目管理
23 | """
24 | queryset = ProjectTestCase.objects.all()
25 | serializer_class = ProjectTestCaseSerializer
26 |
27 |
--------------------------------------------------------------------------------
/project_bug/serializers/project_bug.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task.py
8 | @date:2017/11/10 11:49
9 | """
10 |
11 | from rest_framework import serializers
12 | from ..models import ProjectBug
13 | from tcis_base.serializers import UserSerializer
14 | from project.serializers import ProjectSerializer, ProjectTaskSerializer
15 |
16 |
17 | class ProjectBugSerializer(serializers.ModelSerializer):
18 | handler = UserSerializer()
19 | tester = UserSerializer()
20 | checker = UserSerializer()
21 | project = ProjectSerializer()
22 | task = ProjectTaskSerializer()
23 |
24 | class Meta:
25 | model = ProjectBug
26 | depth = 1
27 | fields = "__all__"
28 |
--------------------------------------------------------------------------------
/project_test/models/project_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:test.py
8 | @date:2017/11/15 11:21
9 | """
10 | from django.db import models
11 |
12 |
13 | class ProjectTest(models.Model):
14 | """
15 | 测试用例
16 | """
17 | project = models.ForeignKey("project.Project", verbose_name=u"项目名称")
18 | name = models.CharField(max_length=50, verbose_name=u'测试名称')
19 | type = models.ForeignKey("ProjectTestType", verbose_name=u"测试类型")
20 |
21 | def __unicode__(self):
22 | return self.name
23 |
24 | def __str__(self):
25 | return self.name
26 |
27 | class Meta:
28 | db_table = "project_test"
29 | verbose_name = u'测试'
30 | verbose_name_plural = u"测试管理"
31 |
--------------------------------------------------------------------------------
/project_test/views/project_test_case_history.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test_case_history.py
8 | @date:2017/11/15 15:08
9 | """
10 | from rest_framework import status, permissions
11 | from rest_framework.decorators import list_route
12 | from rest_framework import viewsets
13 | from django.db.models import Count
14 | from project_test.models import ProjectTestCaseHistory
15 | from rest_framework.response import Response
16 | from tcis_base.models import User
17 | from ..serializers import *
18 |
19 |
20 | class ProjectTestCaseHistoryViewSet(viewsets.ModelViewSet):
21 | """
22 | 项目管理
23 | """
24 | queryset = ProjectTestCaseHistory.objects.all()
25 | serializer_class = ProjectTestCaseHistorySerializer
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tcis.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError:
10 | # The above import may fail for some other reason. Ensure that the
11 | # issue is really that Django is missing to avoid masking other
12 | # exceptions on Python 2.
13 | try:
14 | import django
15 | except ImportError:
16 | raise ImportError(
17 | "Couldn't import Django. Are you sure it's installed and "
18 | "available on your PYTHONPATH environment variable? Did you "
19 | "forget to activate a virtual environment?"
20 | )
21 | raise
22 | execute_from_command_line(sys.argv)
23 |
--------------------------------------------------------------------------------
/tcis_base/models/department.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:department.py
8 | @date:2017/11/8 10:17
9 | """
10 | from django.db import models
11 |
12 |
13 | class Department(models.Model):
14 | """
15 | 部门管理
16 | """
17 | name = models.CharField(max_length=20, verbose_name=u"部门", null=False)
18 | parent = models.ForeignKey('self', verbose_name=u"上级部门", null=True, blank=True)
19 | charge = models.ForeignKey('User', related_name='charge', verbose_name=u'负责人', null=True, blank=True)
20 | description = models.TextField(verbose_name=u"部门职责",null=True, blank=True)
21 |
22 | def __unicode__(self):
23 | return self.name
24 |
25 | def __str__(self):
26 | return self.name
27 |
28 | class Meta:
29 | verbose_name = u'部门'
30 | verbose_name_plural = u'部门管理'
--------------------------------------------------------------------------------
/project/models/project_task_history.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task_history.py
8 | @date:2017/11/15 11:27
9 | """
10 | from django.db import models
11 |
12 |
13 | class ProjectTaskHistory(models.Model):
14 | """
15 | 任务历史
16 | """
17 | task = models.ForeignKey("ProjectTask", verbose_name=u"任务")
18 | description = models.TextField(verbose_name=u"任务描述", null=True, blank=True)
19 | user = models.ForeignKey("tcis_base.User", verbose_name=u"修改员")
20 |
21 | def __unicode__(self):
22 | return self.task.name + "(" + self.user.username_zh or self.user.username + ")"
23 |
24 | def __str__(self):
25 | return self.task.name + "(" + self.user.username_zh or self.user.username + ")"
26 |
27 | class Meta:
28 | db_table = "project_task_history"
29 | verbose_name = u'任务历史'
30 | verbose_name_plural = u"任务历史管理"
31 |
--------------------------------------------------------------------------------
/tcis_base/models/tcis_meeting.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:tcis_meeting.py
8 | @date:2017/11/15 10:50
9 | """
10 | from django.db import models
11 |
12 |
13 | class TcisMeeting(models.Model):
14 | """
15 | 会议
16 | """
17 | title = models.CharField(max_length=100, verbose_name=u"会议主题")
18 | recorder = models.ForeignKey('User', related_name='recorder', verbose_name=u"记录员", null=True, blank=True)
19 | moderator = models.ForeignKey("User", related_name='moderator', verbose_name=u"主持人",null=True, blank=True)
20 | start_time = models.DateTimeField(verbose_name=u"开始时间")
21 | end_time = models.DateTimeField(verbose_name=u"结束时间")
22 |
23 | def __unicode__(self):
24 | return self.title
25 |
26 | def __str__(self):
27 | return self.title
28 |
29 | class Meta:
30 | verbose_name = u'会议'
31 | verbose_name_plural = u'会议管理'
32 |
--------------------------------------------------------------------------------
/web/src/styles/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0rem;
3 | }
4 |
5 | .el-aside {
6 | color: #333;
7 | }
8 |
9 | .el-header {
10 | background-color: #B3C0D1;
11 | color: #333;
12 | line-height: 60px;
13 | }
14 |
15 | // 详情页面样式
16 | .form-read-only {
17 | font-size: 0;
18 | }
19 |
20 | .form-read-only label {
21 | width: 80px;
22 | color: #99a9bf;
23 | }
24 |
25 | .form-read-only .el-form-item {
26 | margin-right: 0;
27 | margin-bottom: 0;
28 | width: 272px;
29 | }
30 |
31 | .tree-form-top {
32 | padding-left: 15px;
33 | padding-right: 15px;
34 | padding-bottom: 20px;
35 | }
36 |
37 | .el-select .el-input__inner {
38 | padding-right: 10px;
39 | }
40 |
41 | .form-tab-top-info {
42 | padding-bottom: 5px;
43 | }
44 |
45 | .tcis-tabs {
46 | margin-top: 10px;
47 | }
48 |
49 | .main-content {
50 | border-top: solid #99a9bf;
51 | padding-top: 10px;
52 | }
53 |
54 | .table-btn {
55 | margin: 2px;
56 | }
--------------------------------------------------------------------------------
/project_test/models/project_test_case.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:test_case.py
8 | @date:2017/11/14 10:30
9 | """
10 |
11 | from django.db import models
12 |
13 |
14 | class ProjectTestCase(models.Model):
15 | """
16 | 测试用例
17 | """
18 | project = models.ForeignKey("project.Project", verbose_name=u"项目名称")
19 | task = models.ForeignKey("project.ProjectTask", verbose_name=u"项目任务")
20 | test = models.ForeignKey("ProjectTest", verbose_name=u"测试")
21 | name = models.CharField(max_length=100, verbose_name=u"测试用例名称")
22 | type = models.ForeignKey("ProjectTestType", verbose_name=u"测试类型")
23 |
24 | def __unicode__(self):
25 | return self.name
26 |
27 | def __str__(self):
28 | return self.name
29 |
30 | class Meta:
31 | db_table = "project_test_case"
32 | verbose_name = u'测试用例'
33 | verbose_name_plural = u"测试用例"
34 |
35 |
36 |
--------------------------------------------------------------------------------
/project_test/models/project_test_case_history.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:test_case_history.py
8 | @date:2017/11/15 11:26
9 | """
10 |
11 | from django.db import models
12 |
13 |
14 | class ProjectTestCaseHistory(models.Model):
15 | """
16 | 测试用例历史
17 | """
18 | case = models.ForeignKey("ProjectTestCase", verbose_name=u"测试用例")
19 | description = models.TextField(verbose_name=u"任务描述", null=True, blank=True)
20 | user = models.ForeignKey("tcis_base.User", verbose_name=u"修改员")
21 |
22 | def __unicode__(self):
23 | return self.case.name + "(" + self.user.username_zh or self.user.username + ")"
24 |
25 | def __str__(self):
26 | return self.case.name + "(" + self.user.username_zh or self.user.username + ")"
27 |
28 | class Meta:
29 | db_table = "project_test_case_history"
30 | verbose_name = u'测试用例历史'
31 | verbose_name_plural = u"测试用例历史管理"
32 |
33 |
--------------------------------------------------------------------------------
/web/src/pages/common/tcis_select.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
29 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/tcis_base/models/meeting_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:meeting_member.py
8 | @date:2017/11/15 11:02
9 | """
10 | from django.db import models
11 |
12 |
13 | class MeetingMember(models.Model):
14 | """
15 | 参会人
16 | """
17 | STATES = (
18 | ('draft', u'通知'),
19 | ('confirm', u"已知"),
20 | ('done', u"总结确认")
21 | )
22 | meeting = models.ForeignKey('TcisMeeting', related_name='meeting', verbose_name=u"会议")
23 | user = models.ForeignKey("User", related_name='user', verbose_name=u"参会人")
24 | state = models.CharField(max_length=20, verbose_name=u"状态", choices=STATES, default='draft')
25 |
26 | def __unicode__(self):
27 | return self.meeting.name + "(" + self.user.name + ")"
28 |
29 | def __str__(self):
30 | return self.meeting.name + "(" + self.user.name + ")"
31 |
32 | class Meta:
33 | verbose_name = u'参会人'
34 | verbose_name_plural = u'参会人管理'
35 |
--------------------------------------------------------------------------------
/project/models/project_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_member.py
8 | @date:2017/11/8 10:59
9 | """
10 |
11 | from django.db import models
12 |
13 |
14 | class ProjectMember(models.Model):
15 | """
16 | 项目成员
17 | """
18 | project = models.ForeignKey("Project", related_name="members", verbose_name=u"项目")
19 | member = models.ForeignKey("tcis_base.User", verbose_name=u"项目成员")
20 | position = models.ForeignKey('tcis_base.Position', verbose_name=u"职位", null=True, blank=True)
21 | active = models.BooleanField(default=True, verbose_name=u"是否有效")
22 |
23 | def __unicode__(self):
24 | return self.project.name + ":" + self.member.username_zh
25 |
26 | def __str__(self):
27 | return self.project.name + ":" + self.member.username_zh
28 |
29 | class Meta:
30 | unique_together = [("project", "member")]
31 | db_table = "project_member"
32 | verbose_name = u'项目成员'
33 | verbose_name_plural = u"项目成员管理"
34 |
--------------------------------------------------------------------------------
/tcis_base/models/user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:user.py
8 | @date:2017/11/8 9:58
9 | """
10 |
11 | from django.db import models
12 | from django.contrib.auth.models import AbstractUser
13 |
14 |
15 | class User(AbstractUser):
16 | """
17 | 用户信息扩展
18 | """
19 | mobile = models.CharField(max_length=20, verbose_name=u'电话', null=True, blank=True, unique=True, default='')
20 | short_phone = models.CharField(max_length=10, verbose_name=u'短号', null=True, blank=True, default='')
21 | username_zh = models.CharField(max_length=20, verbose_name=u'中文名称', null=True, blank=True, default='')
22 | department = models.ForeignKey('Department', verbose_name=u'部门', null=True, blank=True)
23 | position = models.ForeignKey("Position", verbose_name=u"职位", null=True, blank=True)
24 |
25 | def __unicode__(self):
26 | return self.username_zh or self.username
27 |
28 | def __str__(self):
29 | return self.username_zh or self.username
30 |
31 | class Meta:
32 | verbose_name = u'用户'
33 | verbose_name_plural = u'用户管理'
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/static/js/12.b1b737b799e9a743298f.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([12],{"0MuP":function(e,n,t){n=e.exports=t("FZ+f")(!0),n.push([e.i,"#page-404[data-v-098261dd]{-webkit-box-pack:center center;-ms-flex-pack:center center;justify-content:center center}","",{version:3,sources:["F:/selenium_work/tcis/web/src/pages/common/page_404.vue"],names:[],mappings:"AACA,2BACE,+BAAgC,AAC5B,4BAA6B,AACzB,6BAA+B,CACxC",file:"page_404.vue",sourcesContent:["\n#page-404[data-v-098261dd] {\n -webkit-box-pack: center center;\n -ms-flex-pack: center center;\n justify-content: center center;\n}\n"],sourceRoot:""}])},"5nwg":function(e,n){e.exports={render:function(){var e=this,n=e.$createElement;e._self._c;return e._m(0)},staticRenderFns:[function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("div",{attrs:{id:"page-404"}},[t("img",{attrs:{src:"@/assets/page_404.jpg",alt:"page not found"}})])}]}},ImMB:function(e,n,t){function r(e){t("mlER")}var c=t("VU/8")(null,t("5nwg"),r,"data-v-098261dd",null);e.exports=c.exports},mlER:function(e,n,t){var r=t("0MuP");"string"==typeof r&&(r=[[e.i,r,""]]),r.locals&&(e.exports=r.locals);t("rjj0")("1b09a3f3",r,!0)}});
2 | //# sourceMappingURL=12.b1b737b799e9a743298f.js.map
--------------------------------------------------------------------------------
/project/serializers/project.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project.py
8 | @date:2017/11/9 10:20
9 | """
10 | from rest_framework import serializers
11 | from ..models import Project
12 | from tcis_base.serializers import UserSerializer
13 | import datetime
14 |
15 |
16 | class ProjectSerializer(serializers.ModelSerializer):
17 | manager = UserSerializer()
18 | percentage = serializers.SerializerMethodField(read_only=True)
19 | parent_left = serializers.IntegerField(read_only=True)
20 | parent_right = serializers.IntegerField(read_only=True)
21 |
22 |
23 | def get_percentage(self, obj):
24 | """
25 | 获得时间进度百分比
26 | :param obj:
27 | :return:
28 | """
29 | percentage = 0
30 | if obj.start_date and obj.end_date:
31 | all_days = (obj.end_date - obj.start_date).days
32 | past_days = (datetime.date.today() - obj.start_date).days
33 | percentage = int(past_days * 100 / all_days)
34 | return percentage
35 |
36 | class Meta:
37 | model = Project
38 | depth = 2
39 | fields = "__all__"
40 |
41 |
42 |
--------------------------------------------------------------------------------
/project/views/project_task_member.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task.py
8 | @date:2017/11/10 14:15
9 | """
10 | from rest_framework import viewsets
11 | from ..models import ProjectMember,Project
12 | from ..serializers import *
13 |
14 |
15 | class ProjectMemberViewSet(viewsets.ModelViewSet):
16 | """
17 | 项目管理
18 | """
19 | queryset = ProjectMember.objects.all()
20 | serializer_class = ProjectMemberSerializer
21 |
22 | def get_queryset(self):
23 | """
24 | 过滤
25 | :return:
26 | """
27 | check_child = self.request.query_params.get("check_child")
28 | project_id = self.request.query_params.get("project_id")
29 | project_ids = [project_id]
30 | if check_child == 'true':
31 | project = Project.objects.get(id=project_id)
32 | projects = Project.objects.filter(parent_left__gte=project.parent_left, parent_right__lte=project.parent_right)
33 | project_ids = [line.id for line in projects]
34 |
35 | self.queryset = self.queryset.filter(project_id__in=project_ids)
36 | return self.queryset
37 |
38 |
--------------------------------------------------------------------------------
/web/src/pages/common/form_top.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 创建
4 | 编辑
5 | 保存
6 | 取消
7 |
8 |
9 |
25 |
32 |
--------------------------------------------------------------------------------
/web/src/utils/local_store.js:
--------------------------------------------------------------------------------
1 | import {
2 | db_prefix
3 | } from 'config/settings';
4 |
5 | class LocalStore {
6 | constructor() {
7 | this.localStore = window.localStorage;
8 | this.prefix = db_prefix;
9 | }
10 | set(key, value, fn) {
11 | try {
12 | value = JSON.stringify(value);
13 | } catch (e) {
14 | value = value;
15 | }
16 |
17 | this.localStore.setItem(this.prefix + key, value);
18 |
19 | fn && fn();
20 | }
21 | get(key, fn) {
22 | if (!key) {
23 | throw new Error('没有找到key。');
24 | return;
25 | }
26 | if (typeof key === 'object') {
27 | throw new Error('key不能是一个对象。');
28 | return;
29 | }
30 | var value = this.localStore.getItem(this.prefix + key);
31 | if (value !== null) {
32 | try {
33 | value = JSON.parse(value);
34 | } catch (e) {
35 | value = value;
36 | }
37 | }
38 |
39 | return value;
40 | }
41 | remove(key) {
42 | this.localStore.removeItem(this.prefix + key);
43 | }
44 | }
45 | const localStore = new LocalStore();
46 | export default localStore
47 |
--------------------------------------------------------------------------------
/project_test/migrations/0003_auto_20171115_1200.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 04:00
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('project_test', '0002_auto_20171115_1151'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterModelOptions(
16 | name='test',
17 | options={'verbose_name': '测试', 'verbose_name_plural': '测试管理'},
18 | ),
19 | migrations.AlterModelOptions(
20 | name='testcase',
21 | options={'verbose_name': '测试用例', 'verbose_name_plural': '测试用例'},
22 | ),
23 | migrations.AlterModelOptions(
24 | name='testtype',
25 | options={'verbose_name': '测试类型', 'verbose_name_plural': '测试类型'},
26 | ),
27 | migrations.AlterModelTable(
28 | name='test',
29 | table='test',
30 | ),
31 | migrations.AlterModelTable(
32 | name='testcase',
33 | table='test_case',
34 | ),
35 | migrations.AlterModelTable(
36 | name='testtype',
37 | table='test_type',
38 | ),
39 | ]
40 |
--------------------------------------------------------------------------------
/static/js/18.2ea16126bf605bbc7af2.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/18.2ea16126bf605bbc7af2.js","webpack:///./src/pages/project/project_task_detail_home.vue"],"names":["webpackJsonp","hFY9","module","exports","__webpack_require__","Component"],"mappings":"AAAAA,cAAc,KAERC,KACA,SAAUC,EAAQC,EAASC,GCHjC,GAAAC,GAAAD,EAAA,QAEA,KAEA,KAEA,KAEA,KAEA,KAGAF,GAAAC,QAAAE,EAAAF","file":"static/js/18.2ea16126bf605bbc7af2.js","sourcesContent":["webpackJsonp([18],{\n\n/***/ \"hFY9\":\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(\"VU/8\")(\n /* script */\n null,\n /* template */\n null,\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// static/js/18.2ea16126bf605bbc7af2.js","var Component = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n null,\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/pages/project/project_task_detail_home.vue\n// module id = hFY9\n// module chunks = 18"],"sourceRoot":""}
--------------------------------------------------------------------------------
/web/src/pages/system/group/group_info.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{group.name}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
34 |
37 |
--------------------------------------------------------------------------------
/static/js/17.049d493d51aa03865805.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/17.049d493d51aa03865805.js","webpack:///./src/pages/project_bug/project_bug_detail_home.vue"],"names":["webpackJsonp","wRKD","module","exports","__webpack_require__","Component"],"mappings":"AAAAA,cAAc,KAERC,KACA,SAAUC,EAAQC,EAASC,GCHjC,GAAAC,GAAAD,EAAA,QAEA,KAEA,KAEA,KAEA,KAEA,KAGAF,GAAAC,QAAAE,EAAAF","file":"static/js/17.049d493d51aa03865805.js","sourcesContent":["webpackJsonp([17],{\n\n/***/ \"wRKD\":\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(\"VU/8\")(\n /* script */\n null,\n /* template */\n null,\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// static/js/17.049d493d51aa03865805.js","var Component = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n null,\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/pages/project_bug/project_bug_detail_home.vue\n// module id = wRKD\n// module chunks = 17"],"sourceRoot":""}
--------------------------------------------------------------------------------
/web/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, function (err, stats) {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false,
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/static/js/16.16887684d55ab321b8c9.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/16.16887684d55ab321b8c9.js","webpack:///./src/pages/project_test/project_test_detail_home.vue"],"names":["webpackJsonp","A7zi","module","exports","__webpack_require__","Component"],"mappings":"AAAAA,cAAc,KAERC,KACA,SAAUC,EAAQC,EAASC,GCHjC,GAAAC,GAAAD,EAAA,QAEA,KAEA,KAEA,KAEA,KAEA,KAGAF,GAAAC,QAAAE,EAAAF","file":"static/js/16.16887684d55ab321b8c9.js","sourcesContent":["webpackJsonp([16],{\n\n/***/ \"A7zi\":\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(\"VU/8\")(\n /* script */\n null,\n /* template */\n null,\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// static/js/16.16887684d55ab321b8c9.js","var Component = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n null,\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/pages/project_test/project_test_detail_home.vue\n// module id = A7zi\n// module chunks = 16"],"sourceRoot":""}
--------------------------------------------------------------------------------
/web/src/pages/common/pagination.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
35 |
41 |
--------------------------------------------------------------------------------
/project/admin/project_task.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task.py
8 | @date:2017/11/9 16:23
9 | """
10 | from django.contrib import admin
11 | from ..models import ProjectTask
12 |
13 |
14 | @admin.register(ProjectTask)
15 | class ProjectTaskAdmin(admin.ModelAdmin):
16 | """
17 | 项目管理后台
18 | """
19 | search_fields = ["project", "name", "parent", "active", "handler", "state"]
20 | list_display = ["name", "project", "parent", "active", "handler", "state","start_time","end_time", 'real_end_time']
21 | list_filter = ['project', 'parent', "active", "handler", "state"]
22 |
23 | actions = ['set_disable', 'set_active']
24 |
25 | def set_disable(self, request, queryset):
26 | """
27 | 设置项目任务无效
28 | :param request:
29 | :param queryset:
30 | :return:
31 | """
32 | queryset.update(is_active=False)
33 |
34 | set_disable.short_description = u'设置项目任务无效'
35 |
36 | def set_active(self, request, queryset):
37 | """
38 | 设置项目任务有效
39 | :param request:
40 | :param queryset:
41 | :return:
42 | """
43 | queryset.update(is_active=True)
44 |
45 | set_active.short_description = u'设置项目任务有效'
46 |
47 |
48 |
--------------------------------------------------------------------------------
/web/src/pages/system/permission/permission_list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
14 |
15 |
18 |
19 |
22 |
23 | {{scope.row.content_type.app_label}}
24 |
25 |
26 |
27 |
28 |
29 |
46 |
--------------------------------------------------------------------------------
/web/src/pages/system/group/group_list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 | 权限信息:
11 |
12 | {{ permission.name }}
13 |
14 |
15 |
16 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
43 |
--------------------------------------------------------------------------------
/project_bug/migrations/0003_auto_20171115_1324.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 05:24
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | ('project_bug', '0002_auto_20171115_1151'),
14 | ]
15 |
16 | operations = [
17 | migrations.AlterField(
18 | model_name='projectbug',
19 | name='checker',
20 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='checker', to=settings.AUTH_USER_MODEL, verbose_name='验证员'),
21 | ),
22 | migrations.AlterField(
23 | model_name='projectbug',
24 | name='handler',
25 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='handler', to=settings.AUTH_USER_MODEL, verbose_name='处理员'),
26 | ),
27 | migrations.AlterField(
28 | model_name='projectbug',
29 | name='tester',
30 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tester', to=settings.AUTH_USER_MODEL, verbose_name='测试员'),
31 | ),
32 | ]
33 |
--------------------------------------------------------------------------------
/web/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const baseWebpackConfig = require('./webpack.base.conf')
7 | const HtmlWebpackPlugin = require('html-webpack-plugin')
8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
9 |
10 | // add hot-reload related code to entry chunks
11 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
12 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
13 | })
14 |
15 | module.exports = merge(baseWebpackConfig, {
16 | module: {
17 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
18 | },
19 | // cheap-module-eval-source-map is faster for development
20 | devtool: '#cheap-module-eval-source-map',
21 | plugins: [
22 | new webpack.DefinePlugin({
23 | 'process.env': config.dev.env
24 | }),
25 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
26 | new webpack.HotModuleReplacementPlugin(),
27 | new webpack.NoEmitOnErrorsPlugin(),
28 | // https://github.com/ampedandwired/html-webpack-plugin
29 | new HtmlWebpackPlugin({
30 | filename: 'index.html',
31 | template: 'index.html',
32 | inject: true
33 | }),
34 | new FriendlyErrorsPlugin()
35 | ]
36 | })
37 |
--------------------------------------------------------------------------------
/web/src/main.js:
--------------------------------------------------------------------------------
1 | import babelpolyfill from 'babel-polyfill'
2 | import Vue from 'vue'
3 | import App from './App'
4 | import router from './router';
5 | import ElementUI from 'element-ui'
6 | import 'element-ui/lib/theme-chalk/index.css'
7 | import store from './store'
8 | import Vuex from 'vuex'
9 |
10 | import NProgress from 'nprogress'
11 | import 'nprogress/nprogress.css'
12 | import localStore from '@/utils/local_store';
13 | import stringTimeFormat from '@/utils/filters';
14 | import axios from 'axios';
15 | const XSRFCOOKIENAME = 'csrftoken';
16 | const XSRFHEADERNAME = 'X_CSRFTOKEN';
17 | axios.defaults.xsrfCookieName = XSRFCOOKIENAME;
18 | axios.defaults.xsrfHeaderName = XSRFHEADERNAME;
19 |
20 | Vue.prototype.$ajax = axios;
21 |
22 |
23 | import echarts from 'echarts';
24 | import "@/styles/index.scss";
25 | Vue.prototype.$echarts = echarts;
26 | Vue.filter('stringTimeFormat', stringTimeFormat);
27 |
28 | Vue.use(ElementUI)
29 |
30 | Vue.use(Vuex)
31 |
32 | router.beforeEach((to, from, next) => {
33 | // NProgress.start();
34 | if (to.path == '/login') {
35 | localStore.remove('userinfo');
36 | next();
37 | } else {
38 | let user = JSON.parse(localStore.get('userinfo'));
39 | if (!user) {
40 | next({ path: '/login' });
41 | } else {
42 | next();
43 | }
44 | }
45 | });
46 |
47 | new Vue({
48 | router,
49 | store,
50 | render: h => h(App)
51 | }).$mount('#app')
--------------------------------------------------------------------------------
/project_bug/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 03:51
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | initial = True
11 |
12 | dependencies = [
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='ProjectBug',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('name', models.CharField(max_length=50, verbose_name='Bug名称')),
21 | ('description', models.TextField(verbose_name='Bug描述')),
22 | ('state', models.CharField(choices=[('draft', '草稿'), ('confirm', '已确认'), ('appointed', '已指派'), ('processing', '处理中'), ('refuse', '已拒绝'), ('hold', '挂起'), ('solved', '已解决'), ('done', '完成'), ('close', '关闭')], default='draft', max_length=10, verbose_name='状态')),
23 | ('level', models.IntegerField(choices=[(1, '致命'), (2, '重大'), (3, '次要'), (4, '一般'), (5, '建议')], default=4, verbose_name='级别')),
24 | ('open_times', models.IntegerField(default=1, verbose_name='打开次数')),
25 | ],
26 | options={
27 | 'verbose_name': '项目Bug',
28 | 'verbose_name_plural': '项目Bug管理',
29 | 'db_table': 'project_bug',
30 | },
31 | ),
32 | ]
33 |
--------------------------------------------------------------------------------
/project_test/migrations/0004_auto_20171115_1324.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 05:24
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('project_test', '0003_auto_20171115_1200'),
12 | ]
13 |
14 | operations = [
15 | migrations.RenameModel(
16 | old_name='Test',
17 | new_name='ProjectTest',
18 | ),
19 | migrations.RenameModel(
20 | old_name='TestCase',
21 | new_name='ProjectTestCase',
22 | ),
23 | migrations.RenameModel(
24 | old_name='TestCaseHistory',
25 | new_name='ProjectTestCaseHistory',
26 | ),
27 | migrations.RenameModel(
28 | old_name='TestType',
29 | new_name='ProjectTestType',
30 | ),
31 | migrations.AlterModelTable(
32 | name='projecttest',
33 | table='project_test',
34 | ),
35 | migrations.AlterModelTable(
36 | name='projecttestcase',
37 | table='project_test_case',
38 | ),
39 | migrations.AlterModelTable(
40 | name='projecttestcasehistory',
41 | table='project_test_case_history',
42 | ),
43 | migrations.AlterModelTable(
44 | name='projecttesttype',
45 | table='project_test_type',
46 | ),
47 | ]
48 |
--------------------------------------------------------------------------------
/web/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 | function exec (cmd) {
7 | return require('child_process').execSync(cmd).toString().trim()
8 | }
9 |
10 | const versionRequirements = [
11 | {
12 | name: 'node',
13 | currentVersion: semver.clean(process.version),
14 | versionRequirement: packageConfig.engines.node
15 | }
16 | ]
17 |
18 | if (shell.which('npm')) {
19 | versionRequirements.push({
20 | name: 'npm',
21 | currentVersion: exec('npm --version'),
22 | versionRequirement: packageConfig.engines.npm
23 | })
24 | }
25 |
26 | module.exports = function () {
27 | const warnings = []
28 | for (let i = 0; i < versionRequirements.length; i++) {
29 | const mod = versionRequirements[i]
30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
31 | warnings.push(mod.name + ': ' +
32 | chalk.red(mod.currentVersion) + ' should be ' +
33 | chalk.green(mod.versionRequirement)
34 | )
35 | }
36 | }
37 |
38 | if (warnings.length) {
39 | console.log('')
40 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
41 | console.log()
42 | for (let i = 0; i < warnings.length; i++) {
43 | const warning = warnings[i]
44 | console.log(' ' + warning)
45 | }
46 | console.log()
47 | process.exit(1)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tcis_base/admin/user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:user.py
8 | @date:2017/11/9 9:31
9 | """
10 | from django.contrib import admin
11 |
12 | from ..models import User
13 |
14 |
15 | @admin.register(User)
16 | class UserAdmin(admin.ModelAdmin):
17 | """
18 | 用户后台信息管理
19 | """
20 | search_fields = ['username', 'mobile', 'department', 'position']
21 | list_display = ['username', 'username_zh', 'department', 'position', 'mobile', 'is_active']
22 | list_filter = ['department', 'position']
23 |
24 | fieldsets = [
25 | (u'基本信息', {
26 | 'fields': ['username', 'username_zh', 'is_active', 'email', 'mobile'],
27 | }),
28 | (u'部门信息', {
29 | 'fields': ['department', 'position'],
30 | }),
31 | (u"权限信息", {
32 | 'fields': ["groups"],
33 | })
34 | ]
35 |
36 | actions = ['set_disable', 'set_active']
37 |
38 | def set_disable(self, request, queryset):
39 | """
40 | 设置用户无效
41 | :param request:
42 | :param queryset:
43 | :return:
44 | """
45 | queryset.update(is_active=False)
46 |
47 | set_disable.short_description = u'设置用户无效'
48 |
49 | def set_active(self, request, queryset):
50 | """
51 | 设置用户有效
52 | :param request:
53 | :param queryset:
54 | :return:
55 | """
56 | queryset.update(is_active=True)
57 |
58 | set_active.short_description = u'设置用户有效'
--------------------------------------------------------------------------------
/web/src/server_address.js:
--------------------------------------------------------------------------------
1 | // 服务器端地址
2 |
3 | export const SERVER_USER = "/user/"; //用户
4 | export const SERVER_USER_LOGIN = "/user/login/"; //用户登录
5 | export const SERVER_USER_LOGOUT = "/user/logout/"; //用户登出
6 | export const SERVER_USER_RESET_PASSWORD = "/user/reset_password/"; //重置密码
7 | export const SERVER_USER_ACTIVE = '/user/user_active/'; // 无效用户
8 | export const SERVER_GROUP = "/group/"; //用户组
9 | export const SERVER_PERMISSION = "/permission/"; //用户权限
10 | export const SERVER_PERMISSION_ALL = "/permission/get_all_permission/"; //所有用户权限
11 | export const SERVER_PERMISSION_TRANSLATE = "/permission/translate_all_permission/"; //权限翻译
12 |
13 | export const SERVER_PROJECT = "/project/project/"; //项目
14 | export const SERVER_PROJECT_ALL = "/project/project/get_all_project/"; //所有项目
15 | export const SERVER_PROJECT_TASK = "/project/project_task/"; //项目任务
16 | export const SERVER_PROJECT_TASK_INFO = '/project/project_task/project_task_kanban/'; //项目任务信息
17 | export const SERVER_PROJECT_TASK_GANTT = '/project/project_task/project_task_gantt/'; //项目任务甘特图
18 | export const SERVER_PROJECT_MEMBER = "/project/project_member/"; //项目组成员
19 | export const SERVER_PROJECT_BUG = "/project_bug/project_bug/"; //项目bug
20 | export const SERVER_PROJECT_BUG_INFO = "/project_bug/project_bug/project_bug_kanban/"; //项目bug信息
21 |
22 | export const SERVER_PROJECT_TEST = "/project_test/project_test/"; //项目test
23 | export const SERVER_PROJECT_TEST_INFO = "/project_test/project_test/project_test_kanban/"; //项目test信息
24 | export const SERVER_PROJECT_TEST_TYPE = "/project_test/project_test_type/"; //项目test类型
--------------------------------------------------------------------------------
/web/src/pages/system/group/group_card.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{group.name}}
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
40 |
46 |
47 |
--------------------------------------------------------------------------------
/web/src/pages/system/group/group_kanban.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
50 |
--------------------------------------------------------------------------------
/project/models/project.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project.py
8 | @date:2017/11/8 10:34
9 | """
10 | from django.db import models
11 | from common import parent_tree
12 |
13 |
14 | class Project(models.Model):
15 | """
16 | 项目表
17 | """
18 | name = models.CharField(max_length=50, verbose_name=u'项目名称', unique=True, null=False)
19 | active = models.BooleanField(default=True, verbose_name=u"是否有效")
20 | start_date = models.DateField(verbose_name=u"开始时间", null=True, blank=True)
21 | end_date = models.DateField(verbose_name=u"结束时间", null=True, blank=True)
22 | manager = models.ForeignKey('tcis_base.User', verbose_name=u"项目经理",null=True, blank=True)
23 | parent_left = models.IntegerField(verbose_name=u"左", unique=True, null=True, blank=True)
24 | parent_right = models.IntegerField(verbose_name=u"右", unique=True, null=True, blank=True)
25 | parent = models.ForeignKey("self", related_name="childs", verbose_name=u"上级项目", null=True, blank=True)
26 | description = models.TextField(verbose_name=u"项目描述", null=True, blank=True)
27 |
28 | def __unicode__(self):
29 | return self.name
30 |
31 | def __str__(self):
32 | return self.name
33 |
34 | class Meta:
35 | db_table = "project"
36 | verbose_name = u'项目'
37 | verbose_name_plural = u"项目管理"
38 |
39 | def save(self, force_insert=False, force_update=False, using=None,
40 | update_fields=None):
41 | obj = parent_tree(self, Project)
42 | return super(Project, obj).save(force_insert, force_update, using, update_fields)
43 |
--------------------------------------------------------------------------------
/project_test/views/project_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_test.py
8 | @date:2017/11/10 14:15
9 | """
10 | from rest_framework import status, permissions
11 | from rest_framework.decorators import list_route
12 | from rest_framework import viewsets
13 | from django.db.models import Count
14 | from project.models import Project
15 | from project_test.models import ProjectTest
16 | from rest_framework.response import Response
17 | from tcis_base.models import User
18 | from ..serializers import *
19 |
20 |
21 | class ProjectTestViewSet(viewsets.ModelViewSet):
22 | """
23 | 项目管理
24 | """
25 | queryset = ProjectTest.objects.all()
26 | serializer_class = ProjectTestSerializer
27 |
28 | def get_queryset(self):
29 | project_id = self.request.query_params.get("project_id")
30 | type_id = self.request.query_params.get("type_id")
31 | if project_id:
32 | self.queryset = self.queryset.filter(project_id=project_id)
33 | if type_id:
34 | self.queryset = self.queryset.filter(type_id=type_id)
35 |
36 | return self.queryset
37 |
38 | @list_route(["get"],
39 | permission_classes=[permissions.AllowAny])
40 | def project_test_kanban(self, request):
41 | projects = Project.objects.all()
42 | project_list = []
43 | for project in projects:
44 | project_list.append({
45 | "id": project.id,
46 | "name": project.name
47 | })
48 | return Response(project_list, status=status.HTTP_200_OK)
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/project/views/project.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project.py
8 | @date:2017/11/8 16:50
9 | """
10 | from rest_framework import viewsets
11 | from ..models import Project
12 | from ..serializers import *
13 | from rest_framework.decorators import list_route
14 | from rest_framework import status, permissions
15 | from rest_framework.response import Response
16 |
17 |
18 | class ProjectViewSet(viewsets.ModelViewSet):
19 | """
20 | 项目管理
21 | """
22 | queryset = Project.objects.all()
23 | serializer_class = ProjectSerializer
24 |
25 | def get_queryset(self):
26 | """
27 | 过滤
28 | :return:
29 | """
30 | check_child = self.request.query_params.get("check_child")
31 | project_id = self.request.query_params.get("project_id")
32 | if project_id:
33 | if check_child == "true":
34 | parent = Project.objects.get(id=project_id)
35 | self.queryset = self.queryset.filter(parent_left__gt=parent.parent_left,
36 | parent_right__lt=parent.parent_right)
37 | return self.queryset
38 |
39 | @list_route(["get"],
40 | permission_classes=[permissions.AllowAny])
41 | def get_all_project(self, request):
42 | projects = Project.objects.all()
43 | project_list = []
44 | for project in projects:
45 | project_list.append({
46 | "id": project.id,
47 | "name": project.name
48 | })
49 | return Response(project_list, status=status.HTTP_200_OK)
50 |
51 |
--------------------------------------------------------------------------------
/tcis_base/views/permission.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:permission.py
8 | @date:2017/11/15 17:55
9 | """
10 | from rest_framework import viewsets
11 | from django.contrib.auth.models import Permission
12 | from ..serializers import PermissionSerializer
13 | from rest_framework import status, permissions
14 | from rest_framework.response import Response
15 | from rest_framework.decorators import list_route
16 |
17 |
18 | class PermissionViewSet(viewsets.ModelViewSet):
19 | """
20 | 用户权限
21 | """
22 | queryset = Permission.objects.all()
23 | serializer_class = PermissionSerializer
24 |
25 | @list_route(["get"],
26 | permission_classes=[permissions.AllowAny])
27 | def get_all_permission(self, request):
28 | """
29 | 过滤
30 | :return:
31 | """
32 | all_permissions = []
33 | for line in self.queryset:
34 | all_permissions.append({
35 | "id": line.id,
36 | "name": line.name
37 | })
38 | return Response(all_permissions, status=status.HTTP_200_OK)
39 |
40 | @list_route(["get"],
41 | permission_classes=[permissions.AllowAny])
42 | def translate_all_permission(self, request):
43 | """
44 | 翻译
45 | :return:
46 | """
47 | for permission in self.queryset:
48 | permission.name = permission.name.replace("Can add ", u"可创建:")
49 | permission.name = permission.name.replace("Can change ", u"可修改:")
50 | permission.name = permission.name.replace("Can delete ", u"可删除:")
51 | permission.save()
52 |
53 | return Response([], status=status.HTTP_200_OK)
54 |
--------------------------------------------------------------------------------
/web/config/index.js:
--------------------------------------------------------------------------------
1 |
2 | 'use strict'
3 | // Template version: 1.1.3
4 | // see http://vuejs-templates.github.io/webpack for documentation.
5 |
6 | const path = require('path')
7 |
8 | module.exports = {
9 | build: {
10 | env: require('./prod.env'),
11 | //index: path.resolve(__dirname, '../dist/index.html'),
12 | //assetsRoot: path.resolve(__dirname, '../dist'),
13 | index: path.resolve(__dirname, '../../templates/index.html'),
14 | assetsRoot: path.resolve(__dirname, '../../'),
15 | assetsSubDirectory: 'static',
16 | assetsPublicPath: '/',
17 | productionSourceMap: true,
18 | // Gzip off by default as many popular static hosts such as
19 | // Surge or Netlify already gzip all static assets for you.
20 | // Before setting to `true`, make sure to:
21 | // npm install --save-dev compression-webpack-plugin
22 | productionGzip: false,
23 | productionGzipExtensions: ['js', 'css'],
24 | // Run the build command with an extra argument to
25 | // View the bundle analyzer report after build finishes:
26 | // `npm run build --report`
27 | // Set to `true` or `false` to always turn it on or off
28 | bundleAnalyzerReport: process.env.npm_config_report
29 | },
30 | dev: {
31 | env: require('./dev.env'),
32 | port: process.env.PORT || 8080,
33 | autoOpenBrowser: true,
34 | assetsSubDirectory: 'static',
35 | assetsPublicPath: '/',
36 | proxyTable: {},
37 | // CSS Sourcemaps off by default because relative paths are "buggy"
38 | // with this option, according to the CSS-Loader README
39 | // (https://github.com/webpack/css-loader#sourcemaps)
40 | // In our experience, they generally work as expected,
41 | // just be aware of this issue when enabling this option.
42 | cssSourceMap: false
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/web/src/pages/base/header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{userinfo.username_zh || userinfo.username}}
5 |
6 |
7 | 退出
8 | 个人信息
9 | 进入后台
10 |
11 |
12 |
13 |
14 |
15 |
50 |
51 |
--------------------------------------------------------------------------------
/web/src/pages/project_bug/project_bug_kanban.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
52 |
--------------------------------------------------------------------------------
/project_bug/models/project_bug.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_bug.py
8 | @date:2017/11/8 10:51
9 | """
10 |
11 | from django.db import models
12 |
13 |
14 | class ProjectBug(models.Model):
15 | """
16 | 项目bug管理
17 | """
18 |
19 | STATES = (
20 | ('draft', u'草稿'),
21 | ('confirm', u"已确认"),
22 | ('appointed', u"已指派"),
23 | ('processing', u"处理中"),
24 | ('refuse', u"已拒绝"),
25 | ('hold', u"挂起"),
26 | ('solved', u"已解决"),
27 | ('done', u"完成"),
28 | ('close', u"关闭")
29 | )
30 | LEVELS = (
31 | (1, u"致命"),
32 | (2, u"重大"),
33 | (3, u"次要"),
34 | (4, u"一般"),
35 | (5, u"建议")
36 | )
37 | project = models.ForeignKey("project.Project", verbose_name=u"项目名称")
38 | task = models.ForeignKey('project.ProjectTask', verbose_name=u"项目任务", null=True, blank=True)
39 | name = models.CharField(max_length=50, verbose_name=u"Bug名称")
40 | description = models.TextField(verbose_name=u"Bug描述")
41 | state = models.CharField(max_length=10, verbose_name=u"状态", choices=STATES, default='draft')
42 | level = models.IntegerField(verbose_name=u"级别", choices=LEVELS, default=4)
43 | tester = models.ForeignKey("tcis_base.User", related_name="tester", verbose_name=u"测试员", null=True, blank=True)
44 | handler = models.ForeignKey("tcis_base.User", related_name="handler", verbose_name=u"处理员", null=True, blank=True)
45 | checker = models.ForeignKey('tcis_base.User', related_name="checker", verbose_name=u"验证员", null=True, blank=True)
46 | open_times = models.IntegerField(verbose_name=u"打开次数", default=1)
47 |
48 | class Meta:
49 | db_table = "project_bug"
50 | verbose_name = u'项目Bug'
51 | verbose_name_plural = u"项目Bug管理"
52 |
53 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_task_kanban.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
52 |
--------------------------------------------------------------------------------
/static/js/manifest.56a3f94c7823145ecc26.js:
--------------------------------------------------------------------------------
1 | !function(e){function n(c){if(r[c])return r[c].exports;var t=r[c]={i:c,l:!1,exports:{}};return e[c].call(t.exports,t,t.exports,n),t.l=!0,t.exports}var c=window.webpackJsonp;window.webpackJsonp=function(r,a,o){for(var f,b,i,u=0,d=[];u
2 |
5 |
6 |
55 |
--------------------------------------------------------------------------------
/project/models/project_task.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:project_task.py
8 | @date:2017/11/8 10:51
9 | """
10 | from django.db import models
11 |
12 |
13 | class ProjectTask(models.Model):
14 | """
15 | 项目任务管理
16 | """
17 | STATES = (
18 | ('draft', u'草稿'),
19 | ('confirm', u"已确认"),
20 | ('appointed', u"已指派"),
21 | ('processing', u"处理中"),
22 | ('hold', u"挂起"),
23 | ('done', u"完成")
24 | )
25 | LEVELS = (
26 | (1, u"非常紧急"),
27 | (2, u"紧急"),
28 | (3, u"一般"),
29 | (4, u"次要"),
30 | )
31 |
32 | project = models.ForeignKey("Project", verbose_name=u"项目")
33 | type = models.ForeignKey("ProjectTaskType", verbose_name=u"任务类型")
34 | name = models.CharField(max_length=50, verbose_name=u'项目任务名称', null=True)
35 | active = models.BooleanField(default=True, verbose_name=u"是否有效")
36 | description = models.TextField(verbose_name=u"任务描述", null=True, blank=True)
37 | handler = models.ForeignKey('tcis_base.User', verbose_name=u"处理人", null=True, blank=True)
38 | parent = models.ForeignKey('self', verbose_name=u"上级任务", null=True, blank=True)
39 | state = models.CharField(max_length=20, verbose_name=u"状态", choices=STATES, default='draft')
40 | need_time = models.FloatField(verbose_name=u"估计时长(h)", default=1)
41 | start_time = models.DateTimeField(verbose_name=u"开始时间", null=True, blank=True)
42 | end_time = models.DateTimeField(verbose_name=u"计划完成时间", null=True, blank=True)
43 | real_end_time = models.DateTimeField(verbose_name=u"实际完成时间", null=True, blank=True)
44 | level = models.IntegerField(verbose_name=u"级别", choices=LEVELS, default=3)
45 |
46 | def __unicode__(self):
47 | return self.project.name + ":" + self.name
48 |
49 | def __str__(self):
50 | return self.project.name + ":" + self.name
51 |
52 | class Meta:
53 | db_table = "project_task"
54 | verbose_name = u'项目任务'
55 | verbose_name_plural = u"项目任务管理"
56 |
--------------------------------------------------------------------------------
/tcis/urls.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """tcis URL Configuration
4 |
5 | The `urlpatterns` list routes URLs to views. For more information please see:
6 | https://docs.djangoproject.com/en/1.11/topics/http/urls/
7 | Examples:
8 | Function views
9 | 1. Add an import: from my_app import views
10 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
11 | Class-based views
12 | 1. Add an import: from other_app.views import Home
13 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
14 | Including another URLconf
15 | 1. Import the include() function: from django.conf.urls import url, include
16 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
17 | """
18 | from django.conf import settings
19 | from django.conf.urls import url,include
20 | from django.contrib import admin
21 | from django.conf.urls.static import static
22 |
23 |
24 | urlpatterns = [
25 | # 系统后台
26 | url(r'^admin/', admin.site.urls),
27 | # 接口
28 | url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
29 | # 项目管理
30 | url(r'^project/', include('project.urls', namespace='project', app_name='project manage')),
31 | # 项目bug管理
32 | url(r'^project_bug/', include('project_bug.urls', namespace='project_bug', app_name='project bug manage')),
33 | # 项目持续集成
34 | url(r'^project_ci/', include('project_ci.urls', namespace='project_ci',
35 | app_name='project continuous integration')),
36 | # 项目测试
37 | url(r'^project_test/', include('project_test.urls', namespace='project_test', app_name='project test')),
38 | # 绩效考核
39 | url(r'^performance_appraisal/', include('performance_appraisal.urls', namespace='performance_appraisal', app_name='performance appraisal')),
40 |
41 | # 基础
42 | url(r'', include('tcis_base.urls', namespace='tcis_base',
43 | app_name='test continuous integration system base manage')),
44 |
45 | ]
46 | urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
47 |
--------------------------------------------------------------------------------
/project_test/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 03:51
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | initial = True
12 |
13 | dependencies = [
14 | ]
15 |
16 | operations = [
17 | migrations.CreateModel(
18 | name='Test',
19 | fields=[
20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21 | ('name', models.CharField(max_length=50, verbose_name='测试名称')),
22 | ],
23 | ),
24 | migrations.CreateModel(
25 | name='TestCase',
26 | fields=[
27 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
28 | ('name', models.CharField(max_length=100, verbose_name='测试用例名称')),
29 | ],
30 | ),
31 | migrations.CreateModel(
32 | name='TestCaseHistory',
33 | fields=[
34 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
35 | ('description', models.TextField(blank=True, null=True, verbose_name='任务描述')),
36 | ('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project_test.TestCase', verbose_name='测试用例')),
37 | ],
38 | options={
39 | 'verbose_name': '测试用例历史',
40 | 'verbose_name_plural': '测试用例历史管理',
41 | 'db_table': 'test_case_history',
42 | },
43 | ),
44 | migrations.CreateModel(
45 | name='TestType',
46 | fields=[
47 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
48 | ('name', models.CharField(max_length=20, unique=True, verbose_name='测试类型')),
49 | ],
50 | ),
51 | ]
52 |
--------------------------------------------------------------------------------
/web/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | module.exports = {
12 | entry: {
13 | app: './src/main.js'
14 | },
15 | output: {
16 | path: config.build.assetsRoot,
17 | filename: '[name].js',
18 | publicPath: process.env.NODE_ENV === 'production'
19 | ? config.build.assetsPublicPath
20 | : config.dev.assetsPublicPath
21 | },
22 | resolve: {
23 | extensions: ['.js', '.vue', '.json'],
24 | alias: {
25 | 'vue$': 'vue/dist/vue.esm.js',
26 | '@': resolve('src'),
27 | 'utils': path.resolve(__dirname, '../src/utils'),
28 | 'store': path.resolve(__dirname, '../src/store'),
29 | 'router': path.resolve(__dirname, '../src/router'),
30 | 'pages': path.resolve(__dirname, '../src/pages'),
31 | 'config': path.resolve(__dirname, '../src/config'),
32 | }
33 | },
34 | module: {
35 | rules: [
36 | {
37 | test: /\.vue$/,
38 | loader: 'vue-loader',
39 | options: vueLoaderConfig
40 | },
41 | {
42 | test: /\.js$/,
43 | loader: 'babel-loader',
44 | include: [resolve('src'), resolve('test')]
45 | },
46 | {
47 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
48 | loader: 'url-loader',
49 | options: {
50 | limit: 10000,
51 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
52 | }
53 | },
54 | {
55 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
56 | loader: 'url-loader',
57 | options: {
58 | limit: 10000,
59 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
60 | }
61 | },
62 | {
63 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
64 | loader: 'url-loader',
65 | options: {
66 | limit: 10000,
67 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
68 | }
69 | }
70 | ]
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 | {{ props.row.description }}
15 |
16 |
17 |
18 |
19 |
22 |
23 |
26 |
27 |
29 |
30 | {{scope.row.parent.name}}
31 |
32 |
33 |
35 |
36 | {{scope.row.manager.username_zh}}
37 |
38 |
39 |
42 |
43 |
46 |
47 |
48 |
49 |
50 |
66 |
--------------------------------------------------------------------------------
/web/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tcis_web",
3 | "version": "1.0.0",
4 | "description": "tcis",
5 | "author": "cloudy <272685110@qq.com>",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "start": "npm run dev",
10 | "build": "node build/build.js"
11 | },
12 | "dependencies": {
13 | "axios": "^0.16.2",
14 | "babel-polyfill": "^6.23.0",
15 | "echarts": "^3.6.2",
16 | "element-ui": "^2.0.3",
17 | "lodash": "^4.17.4",
18 | "nprogress": "^0.2.0",
19 | "vue": "^2.5.2",
20 | "vue-router": "^3.0.1",
21 | "vuex": "^2.3.1"
22 | },
23 | "devDependencies": {
24 | "autoprefixer": "^6.7.2",
25 | "babel-core": "^6.22.1",
26 | "babel-loader": "^6.2.10",
27 | "babel-plugin-transform-runtime": "^6.22.0",
28 | "babel-preset-env": "^1.3.2",
29 | "babel-preset-stage-2": "^6.22.0",
30 | "babel-register": "^6.22.0",
31 | "chalk": "^1.1.3",
32 | "connect-history-api-fallback": "^1.3.0",
33 | "copy-webpack-plugin": "^4.0.1",
34 | "css-loader": "^0.28.0",
35 | "eventsource-polyfill": "^0.9.6",
36 | "express": "^4.14.1",
37 | "extract-text-webpack-plugin": "^2.0.0",
38 | "file-loader": "^0.11.1",
39 | "friendly-errors-webpack-plugin": "^1.1.3",
40 | "html-webpack-plugin": "^2.28.0",
41 | "http-proxy-middleware": "^0.17.3",
42 | "lodash": "^4.17.4",
43 | "node-sass": "^4.5.3",
44 | "opn": "^4.0.2",
45 | "optimize-css-assets-webpack-plugin": "^1.3.0",
46 | "ora": "^1.2.0",
47 | "rimraf": "^2.6.0",
48 | "sass-loader": "^6.0.6",
49 | "semver": "^5.3.0",
50 | "shelljs": "^0.7.6",
51 | "url-loader": "^0.5.8",
52 | "vue-loader": "^12.1.0",
53 | "vue-style-loader": "^3.0.1",
54 | "vue-template-compiler": "^2.3.3",
55 | "webpack": "^2.6.1",
56 | "webpack-bundle-analyzer": "^2.2.1",
57 | "webpack-dev-middleware": "^1.10.0",
58 | "webpack-hot-middleware": "^2.18.0",
59 | "webpack-merge": "^4.1.0"
60 | },
61 | "engines": {
62 | "node": ">= 4.0.0",
63 | "npm": ">= 3.0.0"
64 | },
65 | "browserslist": [
66 | "> 1%",
67 | "last 2 versions",
68 | "not ie <= 8"
69 | ]
70 | }
71 |
--------------------------------------------------------------------------------
/web/src/pages/common/view_switch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{viewLabel[view]}}
5 |
6 |
7 |
8 |
58 |
66 |
67 |
--------------------------------------------------------------------------------
/web/src/pages/project_bug/project_bug_card.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{project.name}}
6 |
7 |
8 | Bug列表
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
51 |
57 |
58 |
--------------------------------------------------------------------------------
/web/src/pages/project_test/project_test_card.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{projectTest.name}}
6 |
7 |
8 | 测试列表
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
51 |
57 |
58 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_task_gantt.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
58 |
--------------------------------------------------------------------------------
/web/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 |
6 | exports.assetsPath = function (_path) {
7 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
8 | ? config.build.assetsSubDirectory
9 | : config.dev.assetsSubDirectory
10 | return path.posix.join(assetsSubDirectory, _path)
11 | }
12 |
13 | exports.cssLoaders = function (options) {
14 | options = options || {}
15 |
16 | const cssLoader = {
17 | loader: 'css-loader',
18 | options: {
19 | minimize: process.env.NODE_ENV === 'production',
20 | sourceMap: options.sourceMap
21 | }
22 | }
23 |
24 | // generate loader string to be used with extract text plugin
25 | function generateLoaders (loader, loaderOptions) {
26 | const loaders = [cssLoader]
27 | if (loader) {
28 | loaders.push({
29 | loader: loader + '-loader',
30 | options: Object.assign({}, loaderOptions, {
31 | sourceMap: options.sourceMap
32 | })
33 | })
34 | }
35 |
36 | // Extract CSS when that option is specified
37 | // (which is the case during production build)
38 | if (options.extract) {
39 | return ExtractTextPlugin.extract({
40 | use: loaders,
41 | fallback: 'vue-style-loader'
42 | })
43 | } else {
44 | return ['vue-style-loader'].concat(loaders)
45 | }
46 | }
47 |
48 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
49 | return {
50 | css: generateLoaders(),
51 | postcss: generateLoaders(),
52 | less: generateLoaders('less'),
53 | sass: generateLoaders('sass', { indentedSyntax: true }),
54 | scss: generateLoaders('sass'),
55 | stylus: generateLoaders('stylus'),
56 | styl: generateLoaders('stylus')
57 | }
58 | }
59 |
60 | // Generate loaders for standalone style files (outside of .vue)
61 | exports.styleLoaders = function (options) {
62 | const output = []
63 | const loaders = exports.cssLoaders(options)
64 | for (const extension in loaders) {
65 | const loader = loaders[extension]
66 | output.push({
67 | test: new RegExp('\\.' + extension + '$'),
68 | use: loader
69 | })
70 | }
71 | return output
72 | }
73 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_member_list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
15 |
16 | {{scope.row.project.name}}
17 |
18 |
19 |
21 |
22 | {{scope.row.member.username_zh}}
23 |
24 |
25 |
27 |
28 | {{scope.row.position.name}}
29 |
30 |
31 |
33 |
34 | 是
35 | 否
36 |
37 |
38 |
39 |
40 | 无效
45 |
46 |
47 |
48 |
49 |
50 |
65 |
--------------------------------------------------------------------------------
/project_test/migrations/0002_auto_20171115_1151.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.7 on 2017-11-15 03:51
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | initial = True
13 |
14 | dependencies = [
15 | ('project', '0002_auto_20171115_1151'),
16 | ('project_test', '0001_initial'),
17 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
18 | ]
19 |
20 | operations = [
21 | migrations.AddField(
22 | model_name='testcasehistory',
23 | name='user',
24 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='修改员'),
25 | ),
26 | migrations.AddField(
27 | model_name='testcase',
28 | name='project',
29 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project.Project', verbose_name='项目名称'),
30 | ),
31 | migrations.AddField(
32 | model_name='testcase',
33 | name='task',
34 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project.ProjectTask', verbose_name='项目任务'),
35 | ),
36 | migrations.AddField(
37 | model_name='testcase',
38 | name='test',
39 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project_test.Test', verbose_name='测试'),
40 | ),
41 | migrations.AddField(
42 | model_name='testcase',
43 | name='type',
44 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project_test.TestType', verbose_name='测试类型'),
45 | ),
46 | migrations.AddField(
47 | model_name='test',
48 | name='project',
49 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project.Project', verbose_name='项目名称'),
50 | ),
51 | migrations.AddField(
52 | model_name='test',
53 | name='type',
54 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project_test.TestType', verbose_name='测试类型'),
55 | ),
56 | ]
57 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_task_card.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{project.name}}
6 |
7 |
8 | 任务列表
9 | 甘特图
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
52 |
58 |
59 |
--------------------------------------------------------------------------------
/web/src/pages/system/group/group_detail_home.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
69 |
70 |
--------------------------------------------------------------------------------
/static/js/15.4a0f80754bf9336425cb.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/15.4a0f80754bf9336425cb.js","webpack:///./src/pages/common/middle_router_view.vue?a933","webpack:///./src/pages/common/middle_router_view.vue"],"names":["webpackJsonp","OEdk","module","exports","render","_vm","this","_h","$createElement","_self","_c","staticRenderFns","cBoM","__webpack_require__","Component"],"mappings":"AAAAA,cAAc,KAERC,KACA,SAAUC,EAAQC,GCHxBD,EAAAC,SAAgBC,OAAA,WAAmB,GAAAC,GAAAC,KAAaC,EAAAF,EAAAG,cAChD,QAD0EH,EAAAI,MAAAC,IAAAH,GAC1E,gBACCI,qBDSKC,KACA,SAAUV,EAAQC,EAASU,GEZjC,GAAAC,GAAAD,EAAA,QAEA,KAEAA,EAAA,QAEA,KAEA,KAEA,KAGAX,GAAAC,QAAAW,EAAAX","file":"static/js/15.4a0f80754bf9336425cb.js","sourcesContent":["webpackJsonp([15],{\n\n/***/ \"OEdk\":\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('router-view')\n},staticRenderFns: []}\n\n/***/ }),\n\n/***/ \"cBoM\":\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(\"VU/8\")(\n /* script */\n null,\n /* template */\n __webpack_require__(\"OEdk\"),\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// static/js/15.4a0f80754bf9336425cb.js","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('router-view')\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-1e14a3c6\",\"hasScoped\":false,\"transformToRequire\":{\"video\":\"src\",\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"}}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/pages/common/middle_router_view.vue\n// module id = OEdk\n// module chunks = 15","var Component = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n require(\"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1e14a3c6\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":\\\"src\\\",\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./middle_router_view.vue\"),\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/pages/common/middle_router_view.vue\n// module id = cBoM\n// module chunks = 15"],"sourceRoot":""}
--------------------------------------------------------------------------------
/static/js/14.a6ab56ad507ed6cf2077.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/14.a6ab56ad507ed6cf2077.js","webpack:///./src/pages/project_ci/form.vue?53ae","webpack:///./src/pages/project_ci/form.vue"],"names":["webpackJsonp","C2W4","module","exports","render","_vm","this","_h","$createElement","_self","_c","_v","staticRenderFns","obhH","__webpack_require__","Component"],"mappings":"AAAAA,cAAc,KAERC,KACA,SAAUC,EAAQC,GCHxBD,EAAAC,SAAgBC,OAAA,WAAmB,GAAAC,GAAAC,KAAaC,EAAAF,EAAAG,cAChD,QAD0EH,EAAAI,MAAAC,IAAAH,GAC1E,KAAAF,EAAAM,GAAA,uBACCC,qBDSKC,KACA,SAAUX,EAAQC,EAASW,GEZjC,GAAAC,GAAAD,EAAA,QAEA,KAEAA,EAAA,QAEA,KAEA,KAEA,KAGAZ,GAAAC,QAAAY,EAAAZ","file":"static/js/14.a6ab56ad507ed6cf2077.js","sourcesContent":["webpackJsonp([14],{\n\n/***/ \"C2W4\":\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('p', [_vm._v(\" project ci info\")])\n},staticRenderFns: []}\n\n/***/ }),\n\n/***/ \"obhH\":\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(\"VU/8\")(\n /* script */\n null,\n /* template */\n __webpack_require__(\"C2W4\"),\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// static/js/14.a6ab56ad507ed6cf2077.js","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('p', [_vm._v(\" project ci info\")])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-c6602a50\",\"hasScoped\":false,\"transformToRequire\":{\"video\":\"src\",\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"}}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/pages/project_ci/form.vue\n// module id = C2W4\n// module chunks = 14","var Component = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n require(\"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-c6602a50\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":\\\"src\\\",\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./form.vue\"),\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/pages/project_ci/form.vue\n// module id = obhH\n// module chunks = 14"],"sourceRoot":""}
--------------------------------------------------------------------------------
/static/js/13.3a548fc888b607f48c6a.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///static/js/13.3a548fc888b607f48c6a.js","webpack:///./src/pages/project_ci/project_ci_home.vue","webpack:///./src/pages/project_ci/project_ci_home.vue?50dd"],"names":["webpackJsonp","0Qf1","module","exports","__webpack_require__","Component","SIth","render","_vm","this","_h","$createElement","_self","_c","_v","staticRenderFns"],"mappings":"AAAAA,cAAc,KAERC,OACA,SAAUC,EAAQC,EAASC,GCHjC,GAAAC,GAAAD,EAAA,QAEA,KAEAA,EAAA,QAEA,KAEA,KAEA,KAGAF,GAAAC,QAAAE,EAAAF,SDUMG,KACA,SAAUJ,EAAQC,GExBxBD,EAAAC,SAAgBI,OAAA,WAAmB,GAAAC,GAAAC,KAAaC,EAAAF,EAAAG,cAChD,QAD0EH,EAAAI,MAAAC,IAAAH,GAC1E,KAAAF,EAAAM,GAAA,yBACCC","file":"static/js/13.3a548fc888b607f48c6a.js","sourcesContent":["webpackJsonp([13],{\n\n/***/ \"0Qf1\":\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(\"VU/8\")(\n /* script */\n null,\n /* template */\n __webpack_require__(\"SIth\"),\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n\n/***/ \"SIth\":\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('p', [_vm._v(\"project ci kanban \")])\n},staticRenderFns: []}\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// static/js/13.3a548fc888b607f48c6a.js","var Component = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n require(\"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-5772708e\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":\\\"src\\\",\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./project_ci_home.vue\"),\n /* styles */\n null,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/pages/project_ci/project_ci_home.vue\n// module id = 0Qf1\n// module chunks = 13","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('p', [_vm._v(\"project ci kanban \")])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-5772708e\",\"hasScoped\":false,\"transformToRequire\":{\"video\":\"src\",\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"}}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/pages/project_ci/project_ci_home.vue\n// module id = SIth\n// module chunks = 13"],"sourceRoot":""}
--------------------------------------------------------------------------------
/web/src/pages/project_bug/project_bug_list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 | {{ props.row.description }}
14 |
15 |
16 |
17 |
18 |
21 |
22 |
24 |
25 | {{scope.row.project.name}}
26 |
27 |
28 |
31 |
32 |
34 |
35 | {{scope.row.tester.name}}
36 |
37 |
38 |
40 |
41 | {{scope.row.handler.name}}
42 |
43 |
44 |
46 |
47 | {{scope.row.checker.name}}
48 |
49 |
50 |
52 |
53 | {{scope.row.handler.name}}
54 |
55 |
56 |
59 |
60 |
63 |
64 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
89 |
--------------------------------------------------------------------------------
/web/src/pages/project_test/project_test_list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 | {{ props.row.description }}
15 |
16 |
17 |
18 |
19 |
22 |
23 |
25 |
26 | {{scope.row.project.name}}
27 |
28 |
29 |
32 |
33 |
35 |
36 | {{scope.row.tester.name}}
37 |
38 |
39 |
41 |
42 | {{scope.row.handler.name}}
43 |
44 |
45 |
47 |
48 | {{scope.row.checker.name}}
49 |
50 |
51 |
53 |
54 | {{scope.row.handler.name}}
55 |
56 |
57 |
60 |
61 |
64 |
65 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
90 |
--------------------------------------------------------------------------------
/web/src/pages/base/aside.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 系统设置
6 | 用户管理
7 | 用户组管理
8 | 权限查看
9 |
10 |
11 | 项目管理
12 | 项目管理
13 | 任务管理
14 |
15 |
16 | Bug管理
17 | Bug管理
18 |
19 |
20 | 测试管理
21 | 看板
22 |
23 |
24 | 持续集成
25 | 看板
26 |
27 |
28 | 服务器管理
29 | 看板
30 |
31 |
32 |
33 |
34 |
35 |
71 |
--------------------------------------------------------------------------------
/web/src/pages/project/project_home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
81 |
--------------------------------------------------------------------------------
/web/src/pages/system/permission/permission_home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
翻译
10 |
11 |
12 |
13 |
14 |
15 |
83 |
--------------------------------------------------------------------------------
/tcis_base/views/user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | """
4 | @project:tcis
5 | @author:cloudy
6 | @site:
7 | @file:login.py
8 | @date:2017/11/11 14:52
9 | """
10 |
11 | from rest_framework import status, permissions
12 | from rest_framework import viewsets
13 | from rest_framework.decorators import list_route
14 | from rest_framework.response import Response
15 | from django.contrib.auth import login, logout
16 | from django.contrib.auth.forms import AuthenticationForm
17 | from ..serializers import UserSerializer
18 | from ..models import User
19 |
20 |
21 | class UserViewSet(viewsets.ModelViewSet):
22 | """
23 | 用户
24 | """
25 | queryset = User.objects.all()
26 | serializer_class = UserSerializer
27 |
28 | @list_route(["post"], permission_classes=[permissions.AllowAny])
29 | def login(self, request):
30 | """
31 | 用户登录
32 | :param request:
33 | :return:
34 | """
35 |
36 | if not request.user.is_authenticated:
37 | form = AuthenticationForm(request, request.data)
38 | if form.is_valid():
39 | user = form.user_cache
40 | login(request, user)
41 | return Response(UserSerializer(instance=user).data)
42 | return Response(u"用户名或密码错误",
43 | status=status.HTTP_403_FORBIDDEN)
44 | return Response(UserSerializer(instance=request.user).data)
45 |
46 | @list_route(["get"], permission_classes=[permissions.AllowAny])
47 | def logout(self, request):
48 | """
49 | 用户登出
50 | :param request:
51 | :return:
52 | """
53 | logout(request)
54 |
55 | return Response(u"退出成功", status.HTTP_200_OK)
56 |
57 | @list_route(["post"], permission_classes=[permissions.IsAdminUser])
58 | def reset_password(self, request):
59 | """
60 | 用户登出
61 | :param request:
62 | :return:
63 | """
64 |
65 | post_data = request.data
66 | password = post_data.get("password", None)
67 | confirm_password = post_data.get("confirm_password", None)
68 | user_id = post_data.get("user_id", None)
69 | if password != confirm_password:
70 | return Response(u"密码不一致", status.HTTP_400_BAD_REQUEST)
71 | try:
72 | user = User.objects.get(id=user_id)
73 | user.set_password(password)
74 | user.save()
75 | except Exception:
76 | return Response(u"用户不存在", status.HTTP_400_BAD_REQUEST)
77 | return Response(u"修改成功", status.HTTP_200_OK)
78 |
79 | @list_route(['post'], permission_classes=[permissions.IsAdminUser])
80 | def user_active(self, request):
81 | """
82 | 用户是否有效操作
83 | :param request:
84 | :return:
85 | """
86 | user_ids = request.data.get("user_ids", [])
87 | try:
88 | is_active = request.data.is_active
89 | User.objects.filter(id__in=user_ids).update(is_active=is_active)
90 | return Response(u"修改成功", status.HTTP_200_OK)
91 | except Exception:
92 | return Response(u"缺少必须数据", status.HTTP_400_BAD_REQUEST)
93 |
94 |
--------------------------------------------------------------------------------
/web/src/pages/system/group/group_form.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
88 |
89 |
--------------------------------------------------------------------------------
/web/src/pages/system/user/user_home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
14 |
15 |
16 |
17 |
95 |
--------------------------------------------------------------------------------
/web/build/dev-server.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | const config = require('../config')
5 | if (!process.env.NODE_ENV) {
6 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
7 | }
8 |
9 | const opn = require('opn')
10 | const path = require('path')
11 | const express = require('express')
12 | const webpack = require('webpack')
13 | const proxyMiddleware = require('http-proxy-middleware')
14 | const webpackConfig = require('./webpack.dev.conf')
15 |
16 | // default port where dev server listens for incoming traffic
17 | const port = process.env.PORT || config.dev.port
18 | // automatically open browser, if not set will be false
19 | const autoOpenBrowser = !!config.dev.autoOpenBrowser
20 | // Define HTTP proxies to your custom API backend
21 | // https://github.com/chimurai/http-proxy-middleware
22 | const proxyTable = config.dev.proxyTable
23 |
24 | const app = express()
25 | const compiler = webpack(webpackConfig)
26 |
27 | const devMiddleware = require('webpack-dev-middleware')(compiler, {
28 | publicPath: webpackConfig.output.publicPath,
29 | quiet: true
30 | })
31 |
32 | const hotMiddleware = require('webpack-hot-middleware')(compiler, {
33 | log: false,
34 | heartbeat: 2000
35 | })
36 | // force page reload when html-webpack-plugin template changes
37 | // currently disabled until this is resolved:
38 | // https://github.com/jantimon/html-webpack-plugin/issues/680
39 | // compiler.plugin('compilation', function (compilation) {
40 | // compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
41 | // hotMiddleware.publish({ action: 'reload' })
42 | // cb()
43 | // })
44 | // })
45 |
46 | // enable hot-reload and state-preserving
47 | // compilation error display
48 | app.use(hotMiddleware)
49 |
50 | // proxy api requests
51 | Object.keys(proxyTable).forEach(function (context) {
52 | let options = proxyTable[context]
53 | if (typeof options === 'string') {
54 | options = { target: options }
55 | }
56 | app.use(proxyMiddleware(options.filter || context, options))
57 | })
58 |
59 | // handle fallback for HTML5 history API
60 | app.use(require('connect-history-api-fallback')())
61 |
62 | // serve webpack bundle output
63 | app.use(devMiddleware)
64 |
65 | // serve pure static assets
66 | const staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
67 | app.use(staticPath, express.static('./static'))
68 |
69 | const uri = 'http://localhost:' + port
70 |
71 | var _resolve
72 | var _reject
73 | var readyPromise = new Promise((resolve, reject) => {
74 | _resolve = resolve
75 | _reject = reject
76 | })
77 |
78 | var server
79 | var portfinder = require('portfinder')
80 | portfinder.basePort = port
81 |
82 | console.log('> Starting dev server...')
83 | devMiddleware.waitUntilValid(() => {
84 | portfinder.getPort((err, port) => {
85 | if (err) {
86 | _reject(err)
87 | }
88 | process.env.PORT = port
89 | var uri = 'http://localhost:' + port
90 | console.log('> Listening at ' + uri + '\n')
91 | // when env is testing, don't need open it
92 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
93 | opn(uri)
94 | }
95 | server = app.listen(port)
96 | _resolve()
97 | })
98 | })
99 |
100 | module.exports = {
101 | ready: readyPromise,
102 | close: () => {
103 | server.close()
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/web/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | Vue.use(VueRouter)
5 | const Login = resolve => require(['@/pages/base/login'], resolve);
6 | const Home = resolve => require(['@/pages/base/home'], resolve);
7 | const Page404 = resolve => require(['@/pages/common/page_404'], resolve);
8 |
9 | const MiddleRouterView = resolve => require(['@/pages/common/middle_router_view'], resolve);
10 | // 权限组
11 | const GroupHome = resolve => require(['@/pages/system/group/group_home'], resolve);
12 | const GroupInfo = resolve => require(['@/pages/system/group/group_detail_home'], resolve);
13 |
14 | // 权限明细
15 | const PermissionForm = resolve => require(['@/pages/system/permission/permission_home'], resolve);
16 | // 用户
17 | const UserHome = resolve => require(['@/pages/system/user/user_home'], resolve);
18 | const UserInfo = resolve => require(['@/pages/system/user/user_detail_home'], resolve);
19 | // 项目管理
20 | const ProjectHome = resolve => require(['@/pages/project/project_home'], resolve);
21 | const ProjectInfo = resolve => require(['@/pages/project/project_detail_home'], resolve);
22 | // 项目任务管理
23 | const ProjectTaskHome = resolve => require(['@/pages/project/project_task_home'], resolve);
24 | const ProjectTaskInfo = resolve => require(['@/pages/project/project_task_detail_home'], resolve);
25 |
26 | // 项目bug
27 | const ProjectBugHome = resolve => require(['@/pages/project_bug/project_bug_home'], resolve);
28 | const ProjectBugInfo = resolve => require(['@/pages/project_bug/project_bug_detail_home'], resolve);
29 |
30 | // 项目集成
31 | const ProjectCIHome = resolve => require(['@/pages/project_ci/project_ci_home'], resolve);
32 | const ProjectCIInfo = resolve => require(['@/pages/project_ci/form'], resolve);
33 |
34 | // 项目测试
35 | const ProjectTestHome = resolve => require(['@/pages/project_test/project_test_home'], resolve);
36 | const ProjectTestInfo = resolve => require(['@/pages/project_test/project_test_detail_home'], resolve);
37 |
38 | let routes = [{
39 | path: "/",
40 | name: "home",
41 | component: Home,
42 | children: [
43 | // 用户组
44 | { path: "/group/:id", component: GroupInfo, },
45 | { path: "/group/", component: GroupHome, },
46 |
47 | // 用户
48 | { path: "/user/:id", component: UserInfo, },
49 | { path: "/user/", component: UserHome, },
50 |
51 | // 权限
52 | { path: "/permission/", component: PermissionForm, },
53 | // 项目管理
54 | { path: "/project/:id", component: ProjectInfo, },
55 | { path: "/project/", component: ProjectHome, },
56 | { path: "/project_task/:id", component: ProjectTaskInfo, },
57 | { path: "/project_task/", component: ProjectTaskHome, },
58 | // 项目集成
59 | { path: "/project_ci/:id", component: ProjectCIInfo, },
60 | // Bug管理
61 | { path: "/project_bug/:id", component: ProjectBugInfo, },
62 | { path: "/project_bug/", component: ProjectBugHome, },
63 | // 测试管理
64 | { path: "/project_test/:id", component: ProjectTestInfo, },
65 | { path: "/project_test/", component: ProjectTestHome, },
66 |
67 | ]
68 | },
69 | { path: "/login", name: 'login', component: Login },
70 | // error
71 | { path: "/*", name: 'error', component: Page404 },
72 |
73 | ];
74 |
75 | export default new VueRouter({
76 | // mode: 'history',
77 | base: __dirname,
78 | routes: routes
79 | });
--------------------------------------------------------------------------------
/web/src/pages/project_test/project_test_card_echart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
92 |
--------------------------------------------------------------------------------