取消
@@ -134,35 +129,35 @@ import {
getContentList,
createContent,
deleteContent,
- updateContent
+ updateContent,
} from "@/api/content";
import { genTree } from "@/utils";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
-import {getDictList, getDictTypeList} from "@/api/dict";
+import { getDictList, getDictTypeList } from "@/api/dict";
const defaultContent = {
name: "",
desc: "",
- can_doself: false
+ type: null,
+ can_doself: false,
};
export default {
components: { Pagination, Treeselect },
data() {
return {
Content: defaultContent,
+ contentList: [],
typeOptions: [],
listLoading: true,
dialogVisible: false,
dialogType: "new",
rule1: {
- name: [{ required: true, message: "请输入名称", trigger: "blur" }]
+ name: [{ required: true, message: "请输入名称", trigger: "blur" }],
},
filterOrgText: "",
treeLoding: false,
-
-
};
},
computed: {},
@@ -172,18 +167,17 @@ export default {
},
},
created() {
-
this.getList();
this.getTypeAll();
},
methods: {
checkPermission,
-
+
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
-
+
getList() {
this.listLoading = true;
getContentList().then((response) => {
@@ -193,17 +187,15 @@ export default {
this.listLoading = false;
});
},
- getTypeAll() {
- getDictList({type__code:"data_type"}).then(res=>{
- this.typeOptions = genTree(res.data)
- this.defaultContent.type=this.typeOptions[0].id;
- })
+ getTypeAll() {
+ getDictList({ type__code: "data_type" }).then((res) => {
+ this.typeOptions = genTree(res.data);
+ });
},
-
+
handleFilter() {
this.listQuery.page = 1;
this.getList();
-
},
handleAddContent() {
this.Content = Object.assign({}, defaultContent);
@@ -261,7 +253,7 @@ export default {
return false;
}
});
- }
+ },
},
};
diff --git a/client/src/views/supervision/task.vue b/client/src/views/supervision/task.vue
new file mode 100644
index 0000000..d8a4dd6
--- /dev/null
+++ b/client/src/views/supervision/task.vue
@@ -0,0 +1,259 @@
+
+
+
+ 新增
+
+
+
+
+
+ {{ scope.row.name }}
+
+
+ {{ scope.row.desc }}
+
+
+
+ {{ scope.row.type_ }}
+
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确认
+
+
+
+
+
+
diff --git a/server/apps/supervision/migrations/0004_auto_20210312_1125.py b/server/apps/supervision/migrations/0004_auto_20210312_1125.py
new file mode 100644
index 0000000..730d8bc
--- /dev/null
+++ b/server/apps/supervision/migrations/0004_auto_20210312_1125.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.5 on 2021-03-12 03:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('supervision', '0003_auto_20210311_1658'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='content',
+ name='desc',
+ field=models.TextField(verbose_name='详情'),
+ ),
+ ]
diff --git a/server/apps/supervision/migrations/0005_auto_20210312_1126.py b/server/apps/supervision/migrations/0005_auto_20210312_1126.py
new file mode 100644
index 0000000..8c1feb3
--- /dev/null
+++ b/server/apps/supervision/migrations/0005_auto_20210312_1126.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.5 on 2021-03-12 03:26
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('supervision', '0004_auto_20210312_1125'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='content',
+ name='desc',
+ field=models.TextField(blank=True, null=True, verbose_name='详情'),
+ ),
+ ]
diff --git a/server/apps/supervision/migrations/0006_auto_20210312_1440.py b/server/apps/supervision/migrations/0006_auto_20210312_1440.py
new file mode 100644
index 0000000..5988907
--- /dev/null
+++ b/server/apps/supervision/migrations/0006_auto_20210312_1440.py
@@ -0,0 +1,103 @@
+# Generated by Django 3.0.5 on 2021-03-12 06:40
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('system', '0008_auto_20210311_0919'),
+ ('supervision', '0005_auto_20210312_1126'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='task',
+ options={'verbose_name': '上报任务', 'verbose_name_plural': '上报任务'},
+ ),
+ migrations.RenameField(
+ model_name='task',
+ old_name='is_do',
+ new_name='is_self',
+ ),
+ migrations.RemoveField(
+ model_name='record',
+ name='is_lock',
+ ),
+ migrations.RemoveField(
+ model_name='record',
+ name='updepart',
+ ),
+ migrations.RemoveField(
+ model_name='record',
+ name='upuser',
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='belong_to',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='record_belong_to', to='system.Organization', verbose_name='所属部门'),
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='create_by',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='record_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='截止时间'),
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='noteb',
+ field=models.TextField(blank=True, null=True, verbose_name='上报说明'),
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='state',
+ field=models.CharField(choices=[('待上报', '待上报'), ('已上报', '已上报'), ('已确认', '已确认'), ('待整改', '待整改')], default='待上报', max_length=50, verbose_name='记录状态'),
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='up_user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='上报人'),
+ ),
+ migrations.AddField(
+ model_name='record',
+ name='update_by',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='record_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
+ ),
+ migrations.AddField(
+ model_name='task',
+ name='contents',
+ field=models.ManyToManyField(through='supervision.Record', to='supervision.Content'),
+ ),
+ migrations.AddField(
+ model_name='task',
+ name='depts',
+ field=models.ManyToManyField(through='supervision.Record', to='system.Organization'),
+ ),
+ migrations.AddField(
+ model_name='task',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='截止时间'),
+ ),
+ migrations.AddField(
+ model_name='task',
+ name='note',
+ field=models.TextField(blank=True, null=True, verbose_name='任务备注'),
+ ),
+ migrations.AddField(
+ model_name='task',
+ name='state',
+ field=models.CharField(choices=[('创建中', '创建中'), ('执行中', '执行中'), ('已完成', '已完成')], default='创建中', max_length=50, verbose_name='任务状态'),
+ ),
+ migrations.AlterField(
+ model_name='record',
+ name='note',
+ field=models.TextField(blank=True, null=True, verbose_name='上报备注'),
+ ),
+ ]
diff --git a/server/apps/supervision/models.py b/server/apps/supervision/models.py
index 02dc8bb..fae4c5a 100644
--- a/server/apps/supervision/models.py
+++ b/server/apps/supervision/models.py
@@ -8,7 +8,7 @@ class Content(CommonAModel):
资料清单
"""
name = models.CharField('名称', max_length=100)
- desc = models.CharField('详情', max_length=1000)
+ desc = models.TextField('详情', null=True, blank=True)
type = models.ForeignKey(Dict, verbose_name='材料类型', on_delete= models.DO_NOTHING)
can_doself = models.BooleanField('可随时主动报送', default=False)
@@ -18,23 +18,46 @@ class Content(CommonAModel):
class Task(CommonBModel):
+ """
+ 上报任务
+ """
+ state_choices = (
+ ('创建中', '创建中'),
+ ('执行中', '执行中'),
+ ('已完成', '已完成'),
+ )
name = models.CharField('名称', max_length=100)
- is_do = models.BooleanField('是否自创任务', default=False)
+ is_self = models.BooleanField('是否主动报送', default=False)
+ end_date = models.DateField('截止时间', null=True, blank=True)
+ note = models.TextField('任务备注', null=True, blank=True)
complete_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='创建中')
+ class Meta:
+ verbose_name = '上报任务'
+ verbose_name_plural = verbose_name
-class Record(BaseModel):
+class Record(CommonBModel):
"""
上报记录
"""
+ state_choices = (
+ ('待上报', '待上报'),
+ ('已上报', '已上报'),
+ ('已确认', '已确认'),
+ ('待整改', '待整改')
+ )
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)
- updepart = models.ForeignKey(Organization, verbose_name='上传部门', null=True, blank=True,on_delete=models.DO_NOTHING)
- upuser = models.ForeignKey(User,verbose_name='上传人', null=True, blank=True,on_delete=models.DO_NOTHING)
- is_lock = models.BooleanField('是否锁住', default=False)
+ up_date = models.DateField('上报时间', null=True, blank=True)
+ up_user = models.ForeignKey(User, verbose_name='上报人', null=True, blank=True,on_delete=models.SET_NULL)
+ end_date = models.DateField('截止时间', null=True, blank=True)
+ state = models.CharField('记录状态', max_length=50, choices=state_choices, default='待上报')
is_yes = models.BooleanField('是否适用', default=True)
- note = models.TextField('说明')
+ note = models.TextField('上报备注', null=True, blank=True)
+ noteb = models.TextField('上报说明', null=True, blank=True)
files = models.ManyToManyField(File, verbose_name="关联文件")
class Meta:
verbose_name = '上报记录'
diff --git a/server/apps/supervision/serializers.py b/server/apps/supervision/serializers.py
index cf31580..e88b935 100644
--- a/server/apps/supervision/serializers.py
+++ b/server/apps/supervision/serializers.py
@@ -18,4 +18,14 @@ class ContentSerializer(serializers.ModelSerializer):
data = obj.type.name
if obj.type.pid:
data = obj.type.pid.name + '/' + data
- return data
\ No newline at end of file
+ return data
+
+class TaskCreateUpdateSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Task
+ fields = ['name', 'end_date', 'note']
+
+class TaskListSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Task
+ fields = ['name', 'is_self', 'end_date', 'note', 'complete_rate']
\ No newline at end of file
diff --git a/server/apps/supervision/views.py b/server/apps/supervision/views.py
index 431a30e..4215fde 100644
--- a/server/apps/supervision/views.py
+++ b/server/apps/supervision/views.py
@@ -11,11 +11,11 @@ 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
+from apps.system.mixins import CreateUpdateCustomMixin
# Create your views here.
-class ContentViewSet(CreateModelAMixin, ModelViewSet):
+class ContentViewSet(CreateUpdateCustomMixin, ModelViewSet):
"""
资料清单:增删改查
"""
@@ -23,9 +23,19 @@ class ContentViewSet(CreateModelAMixin, ModelViewSet):
'put': 'content_update', 'delete': 'content_delete'}
queryset = Content.objects.all()
serializer_class = ContentSerializer
+ pagination_class = None
search_fields = ['name', 'desc']
filterset_fields = ['type']
ordering = ['type__sort', 'create_time']
- def paginate_queryset(self, queryset):
- return None
+
+class TaskViewSet(CreateUpdateCustomMixin, ModelViewSet):
+ perms_map = {'get': '*', 'post': 'task_create',
+ 'put': 'task_update', 'delete': 'task_delete'}
+ queryset = Task.objects.all()
+ search_fields = ['name']
+ ordering = ['-create_time']
+ def get_serializer_class(self):
+ if self.action in ['create', 'update']:
+ return TaskCreateUpdateSerializer
+ return TaskListSerializer
\ No newline at end of file
diff --git a/server/apps/system/mixins.py b/server/apps/system/mixins.py
index 4770c75..3d25035 100644
--- a/server/apps/system/mixins.py
+++ b/server/apps/system/mixins.py
@@ -2,30 +2,47 @@ from rest_framework import status
from rest_framework.response import Response
from rest_framework.settings import api_settings
-class CreateModelAMixin:
+class CreateUpdateModelAMixin:
"""
业务用基本表A用
"""
def perform_create(self, serializer):
serializer.save(create_by = self.request.user)
-
-class UpdateModelAMixin:
- """
- 业务用基本表A用
- """
+
def perform_update(self, serializer):
serializer.save(update_by = self.request.user)
-class CreateModelBMixin:
+class CreateUpdateModelBMixin:
"""
业务用基本表B用
"""
def perform_create(self, serializer):
- serializer.save(create_by = self.request.user, belong_to=self.request.user.dept)
-
-class UpdateModelBMixin:
- """
- 业务用基本表B用
- """
+ serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
+
def perform_update(self, serializer):
- serializer.save(update_by = self.request.user)
\ No newline at end of file
+ serializer.save(update_by = self.request.user)
+
+class CreateUpdateCustomMixin:
+ """
+ 整合
+ """
+ def perform_create(self, serializer):
+ if hasattr(self.queryset.model, 'belong_dept'):
+ serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
+ else:
+ serializer.save(create_by = self.request.user)
+ def perform_update(self, serializer):
+ serializer.save(update_by = self.request.user)
+
+class OptimizationMixin:
+ """
+ 性能优化,需要在序列化器里定义setup_eager_loading,可在必要的View下继承
+ """
+ def get_queryset(self):
+ queryset = self.queryset
+ 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) # 性能优化
+ return queryset
\ No newline at end of file
diff --git a/server/apps/system/views.py b/server/apps/system/views.py
index 6274a24..7701b31 100644
--- a/server/apps/system/views.py
+++ b/server/apps/system/views.py
@@ -313,14 +313,13 @@ from django.conf import settings
from rest_framework.parsers import (FileUploadParser, JSONParser,
MultiPartParser)
-from .mixins import CreateModelAMixin
-
class FileViewSet(ModelViewSet):
"""
文件:增删改查
"""
perms_map = None
+ permission_classes=[IsAuthenticated]
parser_classes = [MultiPartParser, JSONParser]
queryset = File.objects.all()
serializer_class = FileSerializer