task rate
This commit is contained in:
parent
ec2499a147
commit
7d53e69be0
|
@ -5,6 +5,9 @@
|
|||
<breadcrumb class="breadcrumb-container" />
|
||||
|
||||
<div class="right-menu">
|
||||
<div class="right-menu-item" >
|
||||
{{name}}
|
||||
</div>
|
||||
<el-dropdown class="avatar-container" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
|
||||
|
@ -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: {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
</el-table-column>
|
||||
|
||||
<el-table-column label="上报单位">
|
||||
<template slot-scope="scope">{{ scope.row.dept_.name }}</template>
|
||||
<template slot-scope="scope">{{ scope.row.belong_dept_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="记录状态">
|
||||
<template slot-scope="scope">{{ scope.row.state }}</template>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
v-model="record.note"
|
||||
placeholder=""
|
||||
type="textarea"
|
||||
:readonly="record.state != '待上报'"
|
||||
:readonly="data.action!= 'update'"
|
||||
>
|
||||
</el-input>
|
||||
</div>
|
||||
|
@ -41,13 +41,13 @@
|
|||
v-model="record.noteb"
|
||||
placeholder=""
|
||||
type="textarea"
|
||||
:readonly="record.state == '已上报' && record.state == '已确认'"
|
||||
:readonly="data.action!='up'"
|
||||
>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="ma">
|
||||
<span class="term">是否适用</span>
|
||||
<el-switch v-model="record.is_yes"></el-switch>
|
||||
<el-switch v-model="record.is_yes" :disabled="data.action=='view'"></el-switch>
|
||||
</div>
|
||||
<div class="ma">
|
||||
<el-upload
|
||||
|
@ -61,7 +61,7 @@
|
|||
:file-list="fileList"
|
||||
accept="image/*,application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/msword,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
>
|
||||
<el-button size="small" type="primary">上传文件</el-button>
|
||||
<el-button size="small" type="primary" :disabled="data.action!='up'">上传文件</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
可上传pdf,word,ppt,excel,图片文件,大小不超过20M
|
||||
|
@ -72,7 +72,7 @@
|
|||
<el-divider></el-divider>
|
||||
<div style="text-align: right">
|
||||
<el-button type="primary" @click="confirm()" v-if="this.data.action =='reject'">驳回</el-button>
|
||||
<el-button type="primary" @click="confirm()" >确认</el-button>
|
||||
<el-button type="primary" @click="confirm()" v-else>确认</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="文件">
|
||||
<template slot-scope="scope">
|
||||
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作">
|
||||
|
@ -147,6 +147,12 @@
|
|||
@click="handleReject(scope)"
|
||||
>驳回</el-button
|
||||
>
|
||||
<el-button
|
||||
:disabled="!checkPermission(['record_view'])"
|
||||
size="small"
|
||||
@click="handleView(scope)"
|
||||
>查看</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -180,7 +186,7 @@
|
|||
当前选择的是
|
||||
<span style="color: red">{{ now.name }}</span>
|
||||
</div>
|
||||
<el-table
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="recordList"
|
||||
border
|
||||
|
@ -189,11 +195,61 @@
|
|||
highlight-current-row
|
||||
max-height="600px"
|
||||
>
|
||||
<el-table-column label="名称">
|
||||
<el-table-column label="序号" type="index" align="center" />
|
||||
<el-table-column label="材料">
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.content_.name
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.state
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上报情况">
|
||||
<template slot-scope="scope"
|
||||
>{{ scope.row.up_user }}/{{ scope.row.up_date }}</template
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column label="文件">
|
||||
<template slot-scope="scope">
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
v-if="scope.row.state == '待上报'"
|
||||
type="primary"
|
||||
:disabled="!checkPermission(['record_update'])"
|
||||
size="small"
|
||||
@click="handleUpdate(scope)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="scope.row.state == '已提交'"
|
||||
type="primary"
|
||||
:disabled="!checkPermission(['record_confirm'])"
|
||||
size="small"
|
||||
@click="handleConfirm(scope)"
|
||||
>确认</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="scope.state == '已提交'"
|
||||
:disabled="!checkPermission(['record_reject'])"
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleReject(scope)"
|
||||
>驳回</el-button
|
||||
>
|
||||
<el-button
|
||||
:disabled="!checkPermission(['record_view'])"
|
||||
size="small"
|
||||
@click="handleView(scope)"
|
||||
>查看</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@ -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
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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='上报率'),
|
||||
),
|
||||
]
|
|
@ -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='创建中')
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue