diff --git a/client/src/layout/components/Navbar.vue b/client/src/layout/components/Navbar.vue index a277ecb..62ac3ea 100644 --- a/client/src/layout/components/Navbar.vue +++ b/client/src/layout/components/Navbar.vue @@ -5,6 +5,9 @@
+
+ {{name}} +
@@ -40,7 +43,6 @@ import { mapGetters } from 'vuex' import Breadcrumb from '@/components/Breadcrumb' import Hamburger from '@/components/Hamburger' - export default { components: { Breadcrumb, @@ -49,7 +51,8 @@ export default { computed: { ...mapGetters([ 'sidebar', - 'avatar' + 'avatar', + 'name' ]) }, methods: { diff --git a/client/src/router/index.js b/client/src/router/index.js index e82c31b..6fd2674 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.js @@ -112,13 +112,13 @@ export const asyncRoutes = [ component: Layout, redirect: '/supervision/task', name:'Supervision', - meta: { title: '日常监督', icon: 'table', perms: ['supervision_manage'] }, + meta: { title: '日常监督', icon: 'table', perms: ['supervision'] }, children: [ { path: 'content', name: 'Content', component: () => import('@/views/supervision/content.vue'), - meta: { title: '材料清单', icon: 'documentation', perms: ['content_manage'] } + meta: { title: '材料清单', icon: 'documentation', perms: ['content'] } }, { path: 'task', diff --git a/client/src/views/supervision/record.vue b/client/src/views/supervision/record.vue index b4c6a13..48408e7 100644 --- a/client/src/views/supervision/record.vue +++ b/client/src/views/supervision/record.vue @@ -100,7 +100,7 @@ - + diff --git a/client/src/views/supervision/recorddo.vue b/client/src/views/supervision/recorddo.vue index 5572daa..10a87ba 100644 --- a/client/src/views/supervision/recorddo.vue +++ b/client/src/views/supervision/recorddo.vue @@ -23,7 +23,7 @@ v-model="record.note" placeholder="" type="textarea" - :readonly="record.state != '待上报'" + :readonly="data.action!= 'update'" >
@@ -41,13 +41,13 @@ v-model="record.noteb" placeholder="" type="textarea" - :readonly="record.state == '已上报' && record.state == '已确认'" + :readonly="data.action!='up'" >
是否适用 - +
- 上传文件 + 上传文件 diff --git a/client/src/views/supervision/taskdo.vue b/client/src/views/supervision/taskdo.vue index b83af38..fe0462c 100644 --- a/client/src/views/supervision/taskdo.vue +++ b/client/src/views/supervision/taskdo.vue @@ -118,7 +118,7 @@ @@ -147,6 +147,12 @@ @click="handleReject(scope)" >驳回 + 查看 @@ -180,7 +186,7 @@ 当前选择的是 {{ now.name }}
- - + + + + + + + + + + + + + + @@ -346,7 +402,18 @@ export default { this.drawer = true; }, handleConfirm(scope) { - + this.data = { + action: "reject", + record: scope.row, + }; + this.drawer = true; + }, + handleView(scope) { + this.data = { + action: "view", + record: scope.row, + }; + this.drawer = true; }, handleDo(data){ this.drawer = false diff --git a/server/apps/ability/views.py b/server/apps/ability/views.py index 987fb70..3af95cb 100644 --- a/server/apps/ability/views.py +++ b/server/apps/ability/views.py @@ -1,5 +1,6 @@ from django.shortcuts import render from rest_framework.mixins import ListModelMixin +from rest_framework.permissions import IsAuthenticated from rest_framework.viewsets import GenericViewSet, ModelViewSet from .models import * from .serializers import * diff --git a/server/apps/supervision/migrations/0009_auto_20210317_0922.py b/server/apps/supervision/migrations/0009_auto_20210317_0922.py new file mode 100644 index 0000000..f0ef3a7 --- /dev/null +++ b/server/apps/supervision/migrations/0009_auto_20210317_0922.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.5 on 2021-03-17 01:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('supervision', '0008_auto_20210316_0827'), + ] + + operations = [ + migrations.RemoveField( + model_name='task', + name='complete_rate', + ), + migrations.AddField( + model_name='task', + name='confirm_rate', + field=models.IntegerField(default=0, verbose_name='确认率'), + ), + migrations.AddField( + model_name='task', + name='up_rate', + field=models.IntegerField(default=0, verbose_name='上报率'), + ), + ] diff --git a/server/apps/supervision/models.py b/server/apps/supervision/models.py index b831fcd..23db718 100644 --- a/server/apps/supervision/models.py +++ b/server/apps/supervision/models.py @@ -29,7 +29,8 @@ class Task(CommonBModel): name = models.CharField('名称', max_length=100) end_date = models.DateField('截止时间', null=True, blank=True) note = models.TextField('任务备注', null=True, blank=True) - complete_rate = models.IntegerField('完成度', default=0) + up_rate = models.IntegerField('上报率', default=0) + confirm_rate = models.IntegerField('确认率', default=0) contents = models.ManyToManyField('supervision.content', through='supervision.record') depts = models.ManyToManyField('system.organization', through='supervision.record') state = models.CharField('任务状态', max_length=50, choices=state_choices, default='创建中') diff --git a/server/apps/supervision/serializers.py b/server/apps/supervision/serializers.py index ba505bb..caca285 100644 --- a/server/apps/supervision/serializers.py +++ b/server/apps/supervision/serializers.py @@ -35,7 +35,7 @@ class TaskCreateUpdateSerializer(serializers.ModelSerializer): class TaskListSerializer(serializers.ModelSerializer): class Meta: model = Task - fields = ['name', 'end_date', 'note', 'complete_rate', 'state', 'id'] + fields = ['name', 'end_date', 'note', 'up_rate', 'state', 'id', 'confirm_rate'] class RecordSerializer(serializers.ModelSerializer): task_ = TaskListSerializer(source='task') diff --git a/server/apps/supervision/views.py b/server/apps/supervision/views.py index a12ab38..f45906d 100644 --- a/server/apps/supervision/views.py +++ b/server/apps/supervision/views.py @@ -10,11 +10,13 @@ from rest_framework.response import Response from apps.system.models import Organization from django.db.models import Count from utils.pagination import PageOrNot -from apps.system.mixins import OptimizationMixin from apps.system.mixins import CreateUpdateCustomMixin +from apps.system.permission_data import RbacFilterSet from django.utils import timezone from .filters import RecordFilter - +from django.db.models.query import QuerySet +from django.core.cache import cache +from apps.system.permission import get_permission_list # Create your views here. class ContentViewSet(CreateUpdateCustomMixin, ModelViewSet): @@ -97,7 +99,20 @@ class TaskViewSet(CreateUpdateCustomMixin, ModelViewSet): serializer = OrganizationSimpleSerializer(obj.depts.distinct(), many=True) return Response(serializer.data) -class RecordViewSet(OptimizationMixin,PageOrNot, CreateUpdateCustomMixin, ModelViewSet): +def cal_task_rate(task): + """ + 计算任务上报率, 确认率 + """ + objs = Record.objects.filter(task=task) + if objs.exists(): + count = objs.count() + up_rate = objs.filter(state__in=['已确认','已上报']).count()/count + confirm_rate = objs.filter(state='已确认').count()/count + task.up_rate = int(up_rate) + task.confirm_rate = int(confirm_rate) + task.save() + +class RecordViewSet(RbacFilterSet, PageOrNot, CreateUpdateCustomMixin, ModelViewSet): perms_map = {'get': '*', 'post': 'record_create', 'put': 'record_update', 'delete': 'record_delete'} queryset = Record.objects.all() diff --git a/server/apps/system/permission.py b/server/apps/system/permission.py index 62b4231..6e82ca0 100644 --- a/server/apps/system/permission.py +++ b/server/apps/system/permission.py @@ -18,8 +18,7 @@ def get_permission_list(user): perms = perms | i.perms.all() perms_list = perms.values_list('method', flat=True) perms_list = list(set(perms_list)) - cache.set(user.username, perms_list) - # cache.persist(user.username) + cache.set(user.username + '__perms', perms_list) return perms_list @@ -35,7 +34,10 @@ class RbacPermission(BasePermission): :param view: :return: """ - perms = cache.get(request.user) + if not request.user: + perms = ['visitor'] # 如果没有经过认证,视为游客 + else: + perms = cache.get(request.user.username + '__perms') if not perms: perms = get_permission_list(request.user) if perms: @@ -59,7 +61,10 @@ class RbacPermission(BasePermission): """ Return `True` if permission is granted, `False` otherwise. """ - has_obj_perm(request.user, obj) + # if not request.user: + # return False + # if hasattr(obj, 'belong_dept'): + # has_obj_perm(request.user, obj) return True def has_obj_perm(user, obj): @@ -78,8 +83,8 @@ def has_obj_perm(user, obj): if obj.belong_dept not in roles.depts: return False elif '同级及以下' in data_range: - if user.dept.pid: - belong_depts = get_child_queryset2(user.dept.pid) + if user.dept.parent: + belong_depts = get_child_queryset2(user.dept.parent) if obj.belong_dept not in belong_depts: return False elif '本级及以下' in data_range: diff --git a/server/apps/system/permission_data.py b/server/apps/system/permission_data.py index e195c44..65bf5c9 100644 --- a/server/apps/system/permission_data.py +++ b/server/apps/system/permission_data.py @@ -1,15 +1,18 @@ from django.db.models import Q from django.db.models.query import QuerySet from rest_framework.generics import GenericAPIView - +from apps.system.mixins import CreateUpdateModelBMixin from utils.queryset import get_child_queryset2 -class RbacFilterSet(GenericAPIView): +class RbacFilterSet(object): """ 数据权限控权返回的queryset 在必须的View下继承 需要控数据权限的表需有belong_dept, create_by, update_by字段(部门, 创建人, 编辑人) + 带性能优化 + + 此处对性能有较大影响,根据业务需求进行修改或取舍 """ def get_queryset(self): assert self.queryset is not None, ( @@ -22,6 +25,13 @@ class RbacFilterSet(GenericAPIView): if isinstance(queryset, QuerySet): # Ensure queryset is re-evaluated on each request. queryset = queryset.all() + + if hasattr(self.get_serializer_class(), 'setup_eager_loading'): + queryset = self.get_serializer_class().setup_eager_loading(queryset) # 性能优化 + + if self.request.user.is_superuser: + return queryset + if hasattr(queryset.model, 'belong_dept'): user = self.request.user roles = user.roles @@ -33,8 +43,8 @@ class RbacFilterSet(GenericAPIView): queryset = queryset.filter(belong_dept__in = roles.depts) return queryset elif '同级及以下' in data_range: - if user.dept.pid: - belong_depts = get_child_queryset2(user.dept.pid) + if user.dept.parent: + belong_depts = get_child_queryset2(user.dept.parent) queryset = queryset.filter(belong_dept__in = belong_depts) return queryset elif '本级及以下' in data_range: @@ -47,7 +57,6 @@ class RbacFilterSet(GenericAPIView): elif '仅本人' in data_range: queryset = queryset.filter(Q(create_by=user)|Q(update_by=user)) return queryset - return queryset @@ -57,28 +66,32 @@ def rbac_filter_queryset(user, queryset): 需要控数据权限的表需有belong_dept, create_by, update_by字段(部门, 创建人, 编辑人) 传入user实例,queryset """ + if user.is_superuser: + return queryset + roles = user.roles data_range = roles.values_list('datas', flat=True) - if '全部' in data_range: - return queryset - elif '自定义' in data_range: - if roles.depts.exists(): - queryset = queryset.filter(belong_dept__in = roles.depts) + if hasattr(queryset.model, 'belong_dept'): + if '全部' in data_range: return queryset - elif '同级及以下' in data_range: - if user.dept.pid: - belong_depts = get_child_queryset2(user.dept.pid) + elif '自定义' in data_range: + if roles.depts.exists(): + queryset = queryset.filter(belong_dept__in = roles.depts) + return queryset + elif '同级及以下' in data_range: + if user.dept.parent: + belong_depts = get_child_queryset2(user.dept.parent) + queryset = queryset.filter(belong_dept__in = belong_depts) + return queryset + elif '本级及以下' in data_range: + belong_depts = get_child_queryset2(user.dept) queryset = queryset.filter(belong_dept__in = belong_depts) return queryset - elif '本级及以下' in data_range: - belong_depts = get_child_queryset2(user.dept) - queryset = queryset.filter(belong_dept__in = belong_depts) - return queryset - elif '本级' in data_range: - queryset = queryset.filter(belong_dept = user.dept) - return queryset - elif '仅本人' in data_range: - queryset = queryset.filter(Q(create_by=user)|Q(update_by=user)) - return queryset + elif '本级' in data_range: + queryset = queryset.filter(belong_dept = user.dept) + return queryset + elif '仅本人' in data_range: + queryset = queryset.filter(Q(create_by=user)|Q(update_by=user)) + return queryset return queryset