From ad4e61fee3e32c6bf0f1ed8057d03f867371f194 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 11 Mar 2021 09:42:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E6=96=99=E6=B8=85=E5=8D=95model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/utils/request.js | 2 +- client/src/views/system/dict.vue | 136 +++++++++--------- server/apps/supervision/__init__.py | 0 server/apps/supervision/admin.py | 3 + server/apps/supervision/apps.py | 5 + .../supervision/migrations/0001_initial.py | 56 ++++++++ .../0002_remove_content_belong_to.py | 17 +++ .../apps/supervision/migrations/__init__.py | 0 server/apps/supervision/models.py | 37 +++++ server/apps/supervision/serializers.py | 21 +++ server/apps/supervision/tests.py | 3 + server/apps/supervision/urls.py | 9 ++ server/apps/supervision/views.py | 28 ++++ .../migrations/0007_auto_20210311_0833.py | 25 ++++ .../migrations/0008_auto_20210311_0919.py | 23 +++ server/apps/system/models.py | 11 +- server/apps/system/views.py | 13 ++ server/requirements.txt | Bin 2336 -> 396 bytes server/server/settings.py | 3 +- server/server/urls.py | 8 +- 20 files changed, 322 insertions(+), 78 deletions(-) create mode 100644 server/apps/supervision/__init__.py create mode 100644 server/apps/supervision/admin.py create mode 100644 server/apps/supervision/apps.py create mode 100644 server/apps/supervision/migrations/0001_initial.py create mode 100644 server/apps/supervision/migrations/0002_remove_content_belong_to.py create mode 100644 server/apps/supervision/migrations/__init__.py create mode 100644 server/apps/supervision/models.py create mode 100644 server/apps/supervision/serializers.py create mode 100644 server/apps/supervision/tests.py create mode 100644 server/apps/supervision/urls.py create mode 100644 server/apps/supervision/views.py create mode 100644 server/apps/system/migrations/0007_auto_20210311_0833.py create mode 100644 server/apps/system/migrations/0008_auto_20210311_0919.py diff --git a/client/src/utils/request.js b/client/src/utils/request.js index d4641f5..9c15d5b 100644 --- a/client/src/utils/request.js +++ b/client/src/utils/request.js @@ -77,7 +77,7 @@ service.interceptors.response.use( error => { // console.log(error,response) // for debug Message({ - message: error.message, + message: '服务器错误', type: 'error', duration: 5 * 1000 }) diff --git a/client/src/views/system/dict.vue b/client/src/views/system/dict.vue index 2c56ee5..54ba93e 100644 --- a/client/src/views/system/dict.vue +++ b/client/src/views/system/dict.vue @@ -13,7 +13,6 @@ v-loading="treeLoding" class="filter-tree" :data="dictTypeData" - default-expand-all highlight-current :expand-on-click-node="false" :filter-node-method="filterNode" @@ -46,31 +45,42 @@
字典详情
- 新增 +
+ 新增 +
- + + - + + + + - - + + - +

点击左侧类型查看字典

- + /> --> @@ -115,24 +126,39 @@ -
+ 取消 确认 -
+ + + + + - + - + + + + + + + + + + + -
+ 取消 确认 -
+
@@ -165,20 +191,20 @@ const defaultDict = { name: '', desc: '', sort: 1, - type: null + type: null, + is_used: true, + pid:null } export default { components: { Pagination, Treeselect }, data() { return { - dicttype: defaultDictType, - dict: defaultDict, - dictList: { count: 0 }, + dicttype: Object.assign({}, defaultDictType), + dict: Object.assign({}, defaultDict), + search:'', + dictList: [], listLoading: true, - listQuery: { - page: 1, - page_size: 20 - }, + listQuery: {}, dgV1: false, dgT1: 'new', rule1: { @@ -192,7 +218,7 @@ export default { }, filterDictTypeText: '', treeLoding: false, - dictTypeData: [] + dictTypeData: [], } }, computed: {}, @@ -202,7 +228,6 @@ export default { } }, created() { - this.getList() this.getDictTypeList() }, methods: { @@ -212,20 +237,15 @@ export default { return data.label.indexOf(value) !== -1 }, handleDictTypeClick(obj, node, vue) { - this.listQuery.page = 1 this.listQuery.type = obj.id this.getList() }, getList() { this.listLoading = true - getDictList(this.listQuery).then(response => { - if (response.code >= 200) { - if (response.data.results) { - this.dictList = response.data - } - this.listLoading = false - } - }) + getDictList(this.listQuery).then(response =>{ + this.dictList = genTree(response.data) + this.listLoading = false + }).catch(error=>{this.listLoading = false}) }, getDictTypeList() { this.treeLoding = true @@ -259,8 +279,8 @@ export default { this.$refs['Form2'].clearValidate() }) }, - handleEditDictType(val) { - this.dicttype = val // copy obj + handleEditDictType(data) { + this.dicttype = Object.assign({}, data) // copy obj this.dgT1 = 'edit' this.dgV1 = true this.$nextTick(() => { @@ -277,7 +297,7 @@ export default { .then(async() => { const { code } = await deleteDict(scope.row.id) if (code>=200){ - this.dictList.results.splice(scope.row.index, 1) + this.dictList.splice(scope.row.index, 1) this.$message({ type: 'success', message: '成功删除!' @@ -294,30 +314,22 @@ export default { const isEdit = this.dgT1 === 'edit' if (isEdit) { updateDictType(this.dicttype.id, this.dicttype).then(res => { - if (res.code >= 200) { this.getDictTypeList() this.dgV1 = false - this.$notify({ - title: '成功', + this.$message({ message: '编辑成功', type: 'success', - duration: 2000 }) - } - }) + }).catch(error=>{}) } else { createDictType(this.dicttype).then(res => { - if (res.code >= 200) { this.getDictTypeList() this.dgV1 = false - this.$notify({ - title: '成功', + this.$message({ message: '新增成功', type: 'success', - duration: 2000 }) - } - }) + }).catch(error=>{}) } } else { return false @@ -330,30 +342,22 @@ export default { const isEdit = this.dgT2 === 'edit' if (isEdit) { updateDict(this.dict.id, this.dict).then(res => { - if (res.code >= 200) { this.getList() this.dgV2 = false - this.$notify({ - title: '成功', + this.$message({ message: '编辑成功', type: 'success', - duration: 2000 }) - } - }) + }).catch(error=>{}) } else { createDict(this.dict).then(res => { - if (res.code >= 200) { this.getList() this.dgV2 = false - this.$notify({ - title: '成功', + this.$message({ message: '新增成功', type: 'success', - duration: 2000 }) - } - }) + }).catch(error=>{}) } } else { return false diff --git a/server/apps/supervision/__init__.py b/server/apps/supervision/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/apps/supervision/admin.py b/server/apps/supervision/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/server/apps/supervision/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/server/apps/supervision/apps.py b/server/apps/supervision/apps.py new file mode 100644 index 0000000..7da9691 --- /dev/null +++ b/server/apps/supervision/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class SupervisionConfig(AppConfig): + name = 'supervision' diff --git a/server/apps/supervision/migrations/0001_initial.py b/server/apps/supervision/migrations/0001_initial.py new file mode 100644 index 0000000..5ab6657 --- /dev/null +++ b/server/apps/supervision/migrations/0001_initial.py @@ -0,0 +1,56 @@ +# Generated by Django 3.0.5 on 2021-03-11 00:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('system', '0007_auto_20210311_0833'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Content', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('name', models.CharField(max_length=100, verbose_name='名称')), + ('desc', models.CharField(max_length=1000, verbose_name='详情')), + ('can_doself', models.BooleanField(default=False, verbose_name='可随时主动报送')), + ('belong_to', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='content_belong_to', to='system.Organization', verbose_name='所属部门')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='content_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='system.Dict', verbose_name='材料类型')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='content_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '报送清单', + 'verbose_name_plural': '报送清单', + }, + ), + migrations.CreateModel( + name='Record', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('is_lock', models.BooleanField(default=False, verbose_name='是否锁住')), + ('is_yes', models.BooleanField(default=True, verbose_name='是否适用')), + ('note', models.TextField(verbose_name='说明')), + ('content', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='supervision.Content', verbose_name='材料内容')), + ], + options={ + 'verbose_name': '上报记录', + 'verbose_name_plural': '上报记录', + }, + ), + ] diff --git a/server/apps/supervision/migrations/0002_remove_content_belong_to.py b/server/apps/supervision/migrations/0002_remove_content_belong_to.py new file mode 100644 index 0000000..fe54334 --- /dev/null +++ b/server/apps/supervision/migrations/0002_remove_content_belong_to.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.5 on 2021-03-11 00:39 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('supervision', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='content', + name='belong_to', + ), + ] diff --git a/server/apps/supervision/migrations/__init__.py b/server/apps/supervision/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/apps/supervision/models.py b/server/apps/supervision/models.py new file mode 100644 index 0000000..f7006c2 --- /dev/null +++ b/server/apps/supervision/models.py @@ -0,0 +1,37 @@ +from django.db import models +from utils.model import BaseModel +from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict +# Create your models here. + +class Content(CommonAModel): + """ + 资料清单 + """ + name = models.CharField('名称', max_length=100) + desc = models.CharField('详情', max_length=1000) + type = models.ForeignKey(Dict, verbose_name='材料类型', on_delete= models.DO_NOTHING) + can_doself = models.BooleanField('可随时主动报送', default=False) + + class Meta: + verbose_name = '报送清单' + verbose_name_plural = verbose_name + + +# class Task(CommonBModel): +# name = models.CharField('名称', max_length=100) +# pass + + +class Record(BaseModel): + """ + 上报记录 + """ + content = models.ForeignKey(Content, verbose_name='材料内容', on_delete=models.DO_NOTHING) + # task = models.ForeignKey(Task, verbose_name='关联任务', null=True, blank=True, on_delete=models.SET_NULL) + is_lock = models.BooleanField('是否锁住', default=False) + is_yes = models.BooleanField('是否适用', default=True) + note = models.TextField('说明') + class Meta: + verbose_name = '上报记录' + verbose_name_plural = verbose_name + \ No newline at end of file diff --git a/server/apps/supervision/serializers.py b/server/apps/supervision/serializers.py new file mode 100644 index 0000000..40ed624 --- /dev/null +++ b/server/apps/supervision/serializers.py @@ -0,0 +1,21 @@ +from rest_framework import serializers +from .models import * +from apps.system.serializers import OrganizationSerializer + +class ContentSerializer(serializers.ModelSerializer): + type_ = serializers.SerializerMethodField() + class Meta: + model = Content + fields = '__all__' + + @staticmethod + def setup_eager_loading(queryset): + """ Perform necessary eager loading of data. """ + queryset = queryset.select_related('type') + return queryset + + def get_type_ (self, obj): + data = obj.type.name + if obj.type.pid: + data = obj.type.pid.name + '/' + data + return data diff --git a/server/apps/supervision/tests.py b/server/apps/supervision/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/server/apps/supervision/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/server/apps/supervision/urls.py b/server/apps/supervision/urls.py new file mode 100644 index 0000000..390942a --- /dev/null +++ b/server/apps/supervision/urls.py @@ -0,0 +1,9 @@ +from django.urls import path, include +from rest_framework import routers +from .views import ContentViewSet + +router = routers.DefaultRouter() +router.register('content', ContentViewSet, basename="content") +urlpatterns = [ + path('', include(router.urls)) +] \ No newline at end of file diff --git a/server/apps/supervision/views.py b/server/apps/supervision/views.py new file mode 100644 index 0000000..c354aa8 --- /dev/null +++ b/server/apps/supervision/views.py @@ -0,0 +1,28 @@ +from django.shortcuts import render +from rest_framework.mixins import ListModelMixin +from rest_framework.viewsets import GenericViewSet, ModelViewSet +from .models import * +from .serializers import * +from rest_framework.decorators import action +from django.conf import settings +from rest_framework import status +from rest_framework.response import Response +from apps.system.models import Organization +from openpyxl import Workbook, load_workbook +from django.db.models import Count +from utils.pagination import PageOrNot +from apps.system.mixins import CreateModelAMixin + +# Create your views here. + +class ContentViewSet(CreateModelAMixin, ModelViewSet): + """ + 资料清单:增删改查 + """ + perms_map = {'get': '*', 'post': 'content_create', + 'put': 'content_update', 'delete': 'content_delete'} + queryset = Content.objects.all() + serializer_class = ContentSerializer + search_fields = ['name', 'desc'] + filterset_fields = ['type'] + ordering = ['type__sort', 'create_time'] \ No newline at end of file diff --git a/server/apps/system/migrations/0007_auto_20210311_0833.py b/server/apps/system/migrations/0007_auto_20210311_0833.py new file mode 100644 index 0000000..05b74a5 --- /dev/null +++ b/server/apps/system/migrations/0007_auto_20210311_0833.py @@ -0,0 +1,25 @@ +# Generated by Django 3.0.5 on 2021-03-11 00:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('system', '0006_auto_20201230_1730'), + ] + + operations = [ + migrations.AlterField( + model_name='file', + name='create_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='file_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'), + ), + migrations.AlterField( + model_name='file', + name='update_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='file_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'), + ), + ] diff --git a/server/apps/system/migrations/0008_auto_20210311_0919.py b/server/apps/system/migrations/0008_auto_20210311_0919.py new file mode 100644 index 0000000..8f7761f --- /dev/null +++ b/server/apps/system/migrations/0008_auto_20210311_0919.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.5 on 2021-03-11 01:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('system', '0007_auto_20210311_0833'), + ] + + operations = [ + migrations.AddField( + model_name='dict', + name='is_used', + field=models.BooleanField(default=True, verbose_name='是否有效'), + ), + migrations.AddField( + model_name='historicaldict', + name='is_used', + field=models.BooleanField(default=True, verbose_name='是否有效'), + ), + ] diff --git a/server/apps/system/models.py b/server/apps/system/models.py index 1e63d48..ab9547f 100644 --- a/server/apps/system/models.py +++ b/server/apps/system/models.py @@ -155,6 +155,7 @@ class Dict(SoftModel): sort = models.IntegerField('排序', default=1) pid = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父') + is_used = models.BooleanField('是否有效', default=True) history = HistoricalRecords() class Meta: @@ -170,9 +171,9 @@ class CommonAModel(SoftModel): 业务用基本表A,包含create_by, update_by字段 """ create_by = models.ForeignKey( - User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name='create_by') + User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name='%(class)s_create_by') update_by = models.ForeignKey( - User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name='update_by') + User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name='%(class)s_update_by') class Meta: abstract = True @@ -182,11 +183,11 @@ class CommonBModel(SoftModel): 业务用基本表B,包含create_by, update_by, belong_to字段 """ create_by = models.ForeignKey( - User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name='create_by') + User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name='%(class)s_create_by') update_by = models.ForeignKey( - User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name='update_by') + User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name='%(class)s_update_by') belong_to = models.ForeignKey( - Organization, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='所属部门', related_name='belong_to') + Organization, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='所属部门', related_name='%(class)s_belong_to') class Meta: abstract = True diff --git a/server/apps/system/views.py b/server/apps/system/views.py index 5f43b33..6274a24 100644 --- a/server/apps/system/views.py +++ b/server/apps/system/views.py @@ -64,6 +64,9 @@ import datetime class Login2View(APIView): + """ + 邮箱验证码登录 + """ authentication_classes = [] permission_classes = [] def post(self, request): @@ -139,6 +142,16 @@ class DictViewSet(ModelViewSet): search_fields = ['^name'] ordering_fields = ['id'] ordering = 'id' + def paginate_queryset(self, queryset): + """ + 如果查询参数里没有page但有type或type__code时则不分页,否则请求分页 + 也可用utils.pageornot方法 + """ + if self.paginator is None: + return None + elif (not self.request.query_params.get('page', None)) and ((self.request.query_params.get('type__code', None)) or (self.request.query_params.get('type', None))): + return None + return self.paginator.paginate_queryset(queryset, self.request, view=self) class PositionViewSet(ModelViewSet): diff --git a/server/requirements.txt b/server/requirements.txt index 5e1431fb92b026b44fc126b93163a113cbce50d8..f38aec5336ccfa0938ea42024223026fb3955096 100644 GIT binary patch delta 35 tcmV+;0Nnqe5{v@^|NfJd0WOpH0brB*0&tU%11^)w1tgO$1|X9L2^tCn4F3QC literal 2336 zcmb7`OK;mi421Vwpg%=M>@;b5=&h#!1p>4{&weP55?OX6I}iW(w)5?1wQ`#t3SnWx zB!|Nxm-4Tl^RNkzVHZB@nT1KX(3yqz;a!-ACcK9G(1oqOVLy}YJRaM-untvdLm6(P z9UB^Z8db z^me1jqavD!08e!B)RFt|tnR~JQ{jG=;W=h}7*z0d{7+;d-no){A-WeZ7_(^Px6`!l zRcpFiXfutIoieuKR>*5E?{#ElpO4WK#hKG0yr}v*PB;3|7wepQScWJ4-pCib8KLED zbko*Sp^RRqKJJ?*k6YaIb5BQnYg{kA0>9D>7O@+9d9HN$Oq{s4uC5Z&ZRE3*M>VJb zFK(Tuk2x?h2ynqR8?1Y&!}jouS)G*OUfGw*T@Tq^3%Xq^V-xSuELuHZj>rC>tQ%Ew zh*siY?s{us9+kI{&q5fbve1Q{6xga4-a%lQFL+-S(+c${6pMM>+Uysy%witrxDhV=ueK+(ihNBc8utnLCoHs*ixNhDm^=%_0$LZAA6+qCb7b7 z5^gP#t~<~2=|1H5JdfBOmD8$un#nrTlQe5(=e@&Tn}{>t&5sUwb4+`E-}aqI3*S&w zAS$Dy=1Z)}^9VQhsuQz%&^%A3XN#^gk*8ep%%mH-(hXscxu@xNxB~}iR>{Kqkaqw( zBdh1?$b+B%4J@<=r~w>rG2hK6;qV4Xw#@NavAmUY{%Ne<433K1=^@S?OV$4d2TN0z diff --git a/server/server/settings.py b/server/server/settings.py index 9d0a244..3f28a85 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -43,7 +43,8 @@ INSTALLED_APPS = [ "django_filters", 'apps.system', 'apps.crm', - 'apps.ability' + 'apps.ability', + 'apps.supervision' ] MIDDLEWARE = [ diff --git a/server/server/urls.py b/server/server/urls.py index aff0004..7c0a0b3 100644 --- a/server/server/urls.py +++ b/server/server/urls.py @@ -58,16 +58,14 @@ class MyTokenObtainPairView(TokenViewBase): urlpatterns = [ path('', TemplateView.as_view(template_name="index.html")), path('api/admin/', admin.site.urls), - path('api/login/', MyTokenObtainPairView.as_view(), name='my_login'), path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token2/', Login2View.as_view(), name='token_obtain_2'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('api/token/black/', LogoutView.as_view(), name='token_black'), path('api/system/', include('apps.system.urls')), path('api/ability/', include('apps.ability.urls')), - path('api/docs/', include_docs_urls(title="接口文档", - authentication_classes=[], permission_classes=[])), + path('api/supervision/', include('apps.supervision.urls')), + path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])), path('api/', include(router.urls)), - url(r'^static/(?P.*)$', serve, - {'document_root': settings.STATIC_ROOT}, name='static'), + url(r'^static/(?P.*)$', serve,{'document_root': settings.STATIC_ROOT}, name='static'), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)