This commit is contained in:
shijing 2022-05-30 08:45:21 +08:00
commit b94acf0f73
31 changed files with 1148 additions and 189 deletions

0
server/apps/__init__.py Normal file
View File

View File

@ -0,0 +1,138 @@
# Generated by Django 3.0.5 on 2022-05-16 02:44
from django.conf import settings
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('system', '0020_auto_20220513_0926'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('ability', '0024_auto_20220316_0858'),
]
operations = [
migrations.CreateModel(
name='QualiLib',
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=20, verbose_name='名称')),
('levels', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=list, null=True, verbose_name='等级')),
('scopes', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=list, null=True, verbose_name='范围')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Quali',
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=20, verbose_name='资质名称')),
('type', models.PositiveSmallIntegerField(choices=[('CMA', 'CMA'), ('CNAS', 'CNAS'), ('OTHER', 'OTHER')], verbose_name='资质类型')),
('grade', models.PositiveSmallIntegerField(verbose_name='等级')),
('scope', models.TextField(blank=True, null=True, verbose_name='范围')),
('level', models.CharField(max_length=10, verbose_name='等级')),
('description', models.TextField(blank=True, null=True, verbose_name='描述')),
('end_date', models.DateField(blank=True, null=True, verbose_name='截至日期')),
('city', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quali_city', to='system.City')),
('citys', models.ManyToManyField(related_name='quali_citys', to='system.City', verbose_name='备案城市')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quali_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.Organization', verbose_name='所属单位')),
('province', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.Province')),
('qualilib', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ability.QualiLib', verbose_name='关联资质库')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quali_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='QTask',
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='名称')),
('end_date', models.DateField(blank=True, null=True, verbose_name='截止时间')),
('state', models.CharField(choices=[('待发布', '待发布'), ('进行中', '进行中'), ('已关闭', '已关闭')], default='待发布', max_length=50, verbose_name='任务状态')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qtask_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qtask_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qtask_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '资质报送任务',
'verbose_name_plural': '资质报送任务',
},
),
migrations.CreateModel(
name='QOrg',
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='删除标记')),
('count', models.PositiveIntegerField(default=0)),
('count_confirmed', models.PositiveIntegerField(default=0)),
('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='qorg_org', to='system.Organization', verbose_name='关联公司')),
('qtask', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='qorg_qtask', to='ability.QTask', verbose_name='关联任务')),
],
options={
'verbose_name': '资质报送任务部门',
'verbose_name_plural': '资质报送任务部门',
},
),
migrations.CreateModel(
name='QActionItem',
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='删除标记')),
('action', models.PositiveSmallIntegerField(blank=True, choices=[('update', '更新'), ('citys:add', '新增备案城市'), ('citys:remove', '移除备案城市')], null=True, verbose_name='操作类型')),
('field', models.CharField(max_length=20, verbose_name='变动字段')),
('value1', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, null=True, verbose_name='原值')),
('value2', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, null=True, verbose_name='新值')),
('city', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.City')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='QAction',
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='删除标记')),
('action', models.CharField(choices=[('service:update', '更新服务'), ('quali:create', '新增资质'), ('quali:update', '更新资质'), ('ablity:create', '新增能力')], max_length=20, verbose_name='操作类型')),
('num', models.PositiveIntegerField(blank=True, null=True, verbose_name='新增能力数量')),
('value1', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, null=True, verbose_name='值1')),
('value2', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict, null=True, verbose_name='值2')),
('confirmed', models.BooleanField(default=False, verbose_name='是否确认')),
('afield', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quali_afield', to='system.Dict', verbose_name='所属领域')),
('atype', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quali_atype', to='system.Dict', verbose_name='能力类型')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qaction_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qaction_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='system.File', verbose_name='能力文件')),
('qtask', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ability.QOrg')),
('quali', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ability.Quali', verbose_name='操作资质')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qaction_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2022-05-16 03:35
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('ability', '0025_qaction_qactionitem_qorg_qtask_quali_qualilib'),
]
operations = [
migrations.AddField(
model_name='qactionitem',
name='qaction',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='items_qaction', to='ability.QAction', verbose_name='关联操作'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2022-05-19 00:11
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('ability', '0026_qactionitem_qaction'),
]
operations = [
migrations.AlterField(
model_name='qaction',
name='qtask',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ability.QTask'),
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 3.0.5 on 2022-05-19 00:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ability', '0027_auto_20220519_0811'),
]
operations = [
migrations.AlterField(
model_name='quali',
name='grade',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='等级'),
),
migrations.AlterField(
model_name='quali',
name='level',
field=models.CharField(blank=True, max_length=10, null=True, verbose_name='等级'),
),
migrations.AlterField(
model_name='quali',
name='name',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='资质名称'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2022-05-19 00:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0020_auto_20220513_0926'),
('ability', '0028_auto_20220519_0832'),
]
operations = [
migrations.AlterField(
model_name='quali',
name='citys',
field=models.ManyToManyField(blank=True, null=True, related_name='quali_citys', to='system.City', verbose_name='备案城市'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2022-05-19 00:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0020_auto_20220513_0926'),
('ability', '0029_auto_20220519_0833'),
]
operations = [
migrations.AlterField(
model_name='quali',
name='citys',
field=models.ManyToManyField(blank=True, related_name='quali_citys', to='system.City', verbose_name='备案城市'),
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 3.0.5 on 2022-05-19 01:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ability', '0030_auto_20220519_0834'),
]
operations = [
migrations.AlterField(
model_name='quali',
name='grade',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='等级1'),
),
migrations.AlterField(
model_name='quali',
name='level',
field=models.CharField(blank=True, max_length=10, null=True, verbose_name='等级2'),
),
migrations.AlterField(
model_name='quali',
name='type',
field=models.CharField(choices=[('CMA', 'CMA'), ('CNAS', 'CNAS'), ('OTHER', 'OTHER')], max_length=10, verbose_name='资质类型'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.5 on 2022-05-19 01:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ability', '0031_auto_20220519_0903'),
]
operations = [
migrations.AlterField(
model_name='qactionitem',
name='action',
field=models.CharField(choices=[('update', '更新'), ('citys:add', '新增备案城市'), ('citys:remove', '移除备案城市')], default='update', max_length=20, verbose_name='操作类型'),
preserve_default=False,
),
]

View File

@ -1,8 +1,8 @@
from datetime import MAXYEAR
from apps.system.models import City, Dict, Province
from django.db import models from django.db import models
from django.db.models.fields import related
from utils.model import BaseModel from utils.model import BaseModel
from apps.system.models import Organization, User from apps.system.models import CommonAModel, CommonBModel, File, Organization, User
# Create your models here. # Create your models here.
from django.contrib.postgres.fields import JSONField from django.contrib.postgres.fields import JSONField
@ -121,3 +121,108 @@ class Qualificationother(BaseModel):
qualification = models.ForeignKey(Qualification, on_delete=models.CASCADE, related_name='other_qualification') qualification = models.ForeignKey(Qualification, on_delete=models.CASCADE, related_name='other_qualification')
name = models.TextField('其他资质', null=True, blank=True) name = models.TextField('其他资质', null=True, blank=True)
description = models.TextField('资质范围', null=True, blank=True) description = models.TextField('资质范围', null=True, blank=True)
class QualiLib(BaseModel):
"""
资质库
"""
name = models.CharField('名称', max_length=20)
levels = JSONField('等级', default=list, null=True, blank=True)
scopes = JSONField('范围', default=list, null=True, blank=True)
class Quali(CommonAModel):
"""
资质
"""
QUALI_TYPE_CHOICES=(
('CMA', 'CMA'),
('CNAS', 'CNAS'),
('OTHER', 'OTHER')
)
QUALI_GRADE_CHOICES = (
(10, '国家级'),
(20, '省级'),
(30, '市级')
)
org = models.ForeignKey(Organization, on_delete=models.CASCADE, verbose_name='所属单位')
name = models.CharField('资质名称', max_length=20, null=True, blank=True)
type = models.CharField('资质类型', choices=QUALI_TYPE_CHOICES, max_length=10)
grade = models.PositiveSmallIntegerField('等级1', null=True, blank=True)
scope = models.TextField('范围', null=True, blank=True)
level = models.CharField('等级2', max_length=10, null=True, blank=True)
province = models.ForeignKey(Province, on_delete=models.SET_NULL, null=True, blank=True)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True, blank=True, related_name='quali_city')
citys = models.ManyToManyField(City, verbose_name='备案城市', related_name='quali_citys', blank=True)
description = models.TextField('描述', null=True, blank=True)
qualilib = models.ForeignKey(QualiLib, verbose_name='关联资质库',
null=True, blank=True, on_delete=models.SET_NULL)
end_date = models.DateField('截至日期', null=True, blank=True)
class QTask(CommonBModel):
"""
资质报送任务
"""
state_choices = (
('待发布', '待发布'),
('进行中', '进行中'),
('已关闭', '已关闭'),
)
name = models.CharField('名称', max_length=100)
end_date = models.DateField('截止时间', null=True, blank=True)
state = models.CharField('任务状态', max_length=50, choices=state_choices, default='待发布')
class Meta:
verbose_name = '资质报送任务'
verbose_name_plural = verbose_name
class QOrg(BaseModel):
qtask = models.ForeignKey(QTask, verbose_name='关联任务', on_delete=models.CASCADE, related_name='qorg_qtask')
org = models.ForeignKey(Organization, verbose_name='关联公司', on_delete=models.CASCADE, related_name='qorg_org')
count = models.PositiveIntegerField(default=0)
count_confirmed = models.PositiveIntegerField(default=0)
class Meta:
verbose_name = '资质报送任务部门'
verbose_name_plural = verbose_name
class QAction(CommonBModel):
"""
任务操作
"""
QACTION_CHOICE = (
('service:update', '更新服务'),
('quali:create', '新增资质'),
('quali:update', '更新资质'),
('ablity:create', '新增能力'),
)
action = models.CharField('操作类型', max_length=20, choices=QACTION_CHOICE)
quali = models.ForeignKey(Quali, null=True, blank=True, verbose_name='操作资质', on_delete=models.CASCADE)
file = models.ForeignKey(File, null=True, blank=True, verbose_name='能力文件', on_delete=models.CASCADE)
atype = models.ForeignKey(Dict, null=True, blank=True, verbose_name='能力类型',
on_delete=models.CASCADE, related_name='quali_atype')
afield = models.ForeignKey(Dict, null=True, blank=True, verbose_name='所属领域',
on_delete=models.CASCADE, related_name='quali_afield')
num = models.PositiveIntegerField('新增能力数量', null=True, blank=True)
qtask = models.ForeignKey(QTask, on_delete=models.CASCADE)
value1 = JSONField('值1', null=True, blank=True, default=dict)
value2 = JSONField('值2', null=True, blank=True, default=dict)
confirmed = models.BooleanField('是否确认',default=False)
class QActionItem(BaseModel):
QACTIONITEM_CHOICE = (
('update', '更新'),
('citys:add', '新增备案城市'),
('citys:remove', '移除备案城市'),
)
action = models.CharField('操作类型', max_length=20, choices=QACTIONITEM_CHOICE)
field = models.CharField('变动字段', max_length=20)
value1 = JSONField('原值', null=True, blank=True, default=dict)
value2 = JSONField('新值', null=True, blank=True, default=dict)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True, blank=True)
qaction = models.ForeignKey(QAction, verbose_name='关联操作',
on_delete=models.CASCADE, related_name='items_qaction', null=True, blank=True)

View File

@ -81,3 +81,4 @@ class CorrectSerializer(serializers.ModelSerializer):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
queryset = queryset.select_related('ssbm') queryset = queryset.select_related('ssbm')
return queryset return queryset

View File

@ -0,0 +1,157 @@
from rest_framework import serializers
from apps.system.models import City, Organization
from .models import QAction, QActionItem, QOrg, QTask, Quali, QualiLib
from django.db import transaction
from apps.system.serializers import OrganizationSimpleSerializer, DictSerializer
from rest_framework.exceptions import ParseError
class QualiLibListSerializer(serializers.ModelSerializer):
class Meta:
model = QualiLib
fields = '__all__'
class QualiListSerializer(serializers.ModelSerializer):
province_name = serializers.CharField(source='province.name', read_only=True)
city_name = serializers.CharField(source='city.name', read_only=True)
service = serializers.CharField(source='org.service', read_only=True)
class Meta:
model = Quali
fields = '__all__'
class QTaskCreateUpdateSerializer(serializers.ModelSerializer):
orgs = serializers.PrimaryKeyRelatedField(label='上报公司ID列表',
queryset = Organization.objects.all(), many=True, write_only=True)
class Meta:
model = QTask
fields = ['name', 'end_date', 'orgs']
def create(self, validated_data):
with transaction.atomic():
orgs = validated_data.pop('orgs')
validated_data['state'] = '待发布'
instance = super().create(validated_data)
for i in orgs:
QOrg.objects.get_or_create(qtask=instance, org=i,
defaults={'qtask': instance, 'org': i})
return instance
def update(self, instance, validated_data):
with transaction.atomic():
if instance.state == '已关闭':
raise ParseError('任务已关闭,不可更改')
orgs = validated_data.pop('orgs')
instance = super().update(instance, validated_data)
for i in orgs:
QOrg.objects.get_or_create(qtask=instance, org=i,
defaults={'qtask': instance, 'org': i})
return instance
class QTaskListSerializer(serializers.ModelSerializer):
orgs_count = serializers.SerializerMethodField()
class Meta:
model = QTask
fields = '__all__'
def get_orgs_count(self, obj):
count = QOrg.objects.filter(qtask=obj).count()
return count
class QTaskSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = QTask
fields = '__all__'
class QOrgListSerializer(serializers.ModelSerializer):
org_ = OrganizationSimpleSerializer(source='org', read_only=True)
qtask_ = QTaskSimpleSerializer(source='qtask', read_only=True)
class Meta:
model = QOrg
fields = '__all__'
class QActionListSerializer(serializers.ModelSerializer):
quali_name = serializers.CharField(source='quali.name', read_only=True)
atype_name = serializers.CharField(source='atype.name', read_only=True)
afield_name = serializers.CharField(source='afield.name', read_only=True)
class Meta:
model = QAction
fields = '__all__'
class QActionServiceSerializer(serializers.ModelSerializer):
class Meta:
model = QAction
fields = ['qtask', 'value2']
def create(self, validated_data):
validated_data['action'] = 'service:update'
return super().create(validated_data)
class QualiCreateSerializer(serializers.ModelSerializer):
citys = serializers.ListField(child=serializers.IntegerField(), label='城市ID列表')
class Meta:
model = Quali
fields = ['name', 'type', 'grade', 'scope', 'level', 'province', 'city', 'description', 'citys']
class QualiUpdateSerializer(serializers.ModelSerializer):
citys = serializers.ListField(child=serializers.IntegerField(), label='城市ID列表')
id = serializers.IntegerField(label='修改资质的ID')
class Meta:
model = Quali
fields = ['scope', 'level', 'description', 'id', 'citys']
class QualiSerializer(serializers.ModelSerializer):
class Meta:
model = Quali
fields = '__all__'
class QActionQualiCreateSerializer(serializers.ModelSerializer):
value2 = QualiCreateSerializer()
class Meta:
model = QAction
fields = ['qtask', 'value2']
def create(self, validated_data):
validated_data['action'] = 'quali:create'
if validated_data['value2']['type'] in ['CMA', 'CNAS']:
validated_data['value2']['name'] = validated_data['value2']['type']
return super().create(validated_data)
class QActionQualiUpdateSerializer(serializers.ModelSerializer):
value2 = QualiUpdateSerializer()
class Meta:
model = QAction
fields = ['qtask', 'value2']
def create(self, validated_data):
validated_data['action'] = 'quali:update'
return super().create(validated_data)
class QActionACreateSerializer(serializers.ModelSerializer):
class Meta:
model = QAction
fields = ['atype', 'afield', 'file', 'num', 'qtask']
extra_kwargs = {'atype': {'required': True}, 'afield': {'required': True}, 'file': {'required': True}}
def create(self, validated_data):
validated_data['action'] = 'ablity:create'
return super().create(validated_data)
class QActionItemSerializer(serializers.ModelSerializer):
class Meta:
model = QActionItem
fields = ['action', 'field', 'value1', 'value2', 'city']
class QActionDetailSerializer(serializers.ModelSerializer):
update_detail = QActionItemSerializer(source='items_qaction', many=True, read_only=True)
class Meta:
model = QAction
fields ='__all__'

View File

@ -1,6 +1,8 @@
from django.db.models import base from django.db.models import base
from django.urls import path, include from django.urls import path, include
from rest_framework import routers from rest_framework import routers
from apps.ability.views_qtask import QActionViewSet, QOrgViewSet, QTaskViewSet, QualiLibViewSet, QualiViewSet
from .views import AbilityContentViewSet, AbilityRecordViewSet, CMAViewSet, CNASViewSet, CorrectViewSet, QualificationViewSet,InspectionViewSet,QualificationotherViewSet, QueryRecordListViewSet, correct_ability, correct_cma, merge_cma, merge_cnas from .views import AbilityContentViewSet, AbilityRecordViewSet, CMAViewSet, CNASViewSet, CorrectViewSet, QualificationViewSet,InspectionViewSet,QualificationotherViewSet, QueryRecordListViewSet, correct_ability, correct_cma, merge_cma, merge_cnas
router = routers.DefaultRouter() router = routers.DefaultRouter()
@ -13,6 +15,11 @@ router.register('queryrecord', QueryRecordListViewSet, basename="queryrecord")
router.register('correct', CorrectViewSet, basename="correct") router.register('correct', CorrectViewSet, basename="correct")
router.register('content', AbilityContentViewSet, basename="abilitycontent") router.register('content', AbilityContentViewSet, basename="abilitycontent")
router.register('record', AbilityRecordViewSet, basename="abilityrecord") router.register('record', AbilityRecordViewSet, basename="abilityrecord")
router.register('qualilib', QualiLibViewSet),
router.register('quali', QualiViewSet),
router.register('qorg', QOrgViewSet),
router.register('qtask', QTaskViewSet),
router.register('qaction', QActionViewSet)
urlpatterns = [ urlpatterns = [
path('merge/cma/', merge_cma), path('merge/cma/', merge_cma),
path('merge/cnas/', merge_cnas), path('merge/cnas/', merge_cnas),

View File

@ -21,6 +21,8 @@ from apps.system.mixins import CreateUpdateCustomMixin
from utils.queryset import get_child_queryset2 from utils.queryset import get_child_queryset2
from django.utils import timezone from django.utils import timezone
from apps.supervision.permission import RecordPermission from apps.supervision.permission import RecordPermission
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
# Create your views here. # Create your views here.
import json import json
@ -343,6 +345,11 @@ class QualificationotherViewSet(RecordMixin, PageOrNot,ModelViewSet):
filterset_fields = ['qualification__ssbm__name'] filterset_fields = ['qualification__ssbm__name']
ordering_fields = ['qualification__ssbm__name'] ordering_fields = ['qualification__ssbm__name']
ordering = ['create_time'] ordering = ['create_time']
@method_decorator(cache_page(60*60*2))
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
@action(methods=['post'], detail=False, url_path='deletes', url_name='qualificationother_deletes', perms_map = {'post':'qualificationother_deletes'}) @action(methods=['post'], detail=False, url_path='deletes', url_name='qualificationother_deletes', perms_map = {'post':'qualificationother_deletes'})
def deletes(self, request): def deletes(self, request):

View File

@ -0,0 +1,253 @@
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin
from rest_framework.decorators import action
from apps.ability.models import QAction, QActionItem, QOrg, QTask, Quali, QualiLib
from apps.ability.serializers_qtask import QActionACreateSerializer, QActionDetailSerializer, QActionListSerializer, QActionQualiCreateSerializer, QActionQualiUpdateSerializer, QActionServiceSerializer, QOrgListSerializer, QTaskCreateUpdateSerializer, QTaskListSerializer, QualiCreateSerializer, QualiLibListSerializer, QualiListSerializer, QualiSerializer, QualiUpdateSerializer
from django.db import transaction
from rest_framework.response import Response
from rest_framework import status
from apps.system.mixins import CreateUpdateCustomMixin
from apps.system.models import City
from utils.pagination import PageOrNot
from rest_framework.exceptions import ParseError
from rest_framework import serializers
from rest_framework.exceptions import ParseError
class QualiLibViewSet(PageOrNot, ListModelMixin, GenericViewSet):
perms_map = {'get': '*'}
queryset = QualiLib.objects.all()
serializer_class = QualiLibListSerializer
search_fields = ['name']
ordering = ['-create_time']
class QualiViewSet(ListModelMixin, GenericViewSet):
perms_map = {'get': '*'}
queryset = Quali.objects.all()
serializer_class = QualiListSerializer
search_fields = ['name', 'type', 'grade']
ordering = ['org__sort']
@action(methods=['get'], detail=False, perms_map = {'get':'*'})
def my(self, request, *args, **kwargs):
"""
我的资质
"""
user = self.request.user
queryset = self.filter_queryset(self.get_queryset().filter(org=user.dept))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
class QTaskViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
perms_map = {'get': 'qtask_view', 'post': 'qtask_create', 'put': 'qtask_update'}
queryset = QTask.objects.all()
serializer_class = QTaskListSerializer
ordering = ['-create_time']
def get_serializer_class(self):
if self.action in ['create', 'update']:
return QTaskCreateUpdateSerializer
return super().get_serializer_class()
@action(methods=['put'], detail=True, perms_map = {'put':'qtask_start'}, serializer_class=serializers.Serializer)
@transaction.atomic
def start(self, request, *args, **kwargs):
"""
发布任务
"""
obj = self.get_object()
if obj.state == '待发布':
obj.state = '进行中'
obj.save()
return Response()
return Response('任务状态错误', status=status.HTTP_400_BAD_REQUEST)
class QOrgViewSet(ListModelMixin, GenericViewSet):
perms_map = {'get': 'qtask_view'}
queryset = QOrg.objects.select_related('qtask', 'org')
filterset_fields = ['qtask', 'org', 'qtask__state']
serializer_class = QOrgListSerializer
ordering = ['-create_time']
@action(methods=['get'], detail=False, perms_map = {'get':'qtask_my'})
def my(self, request, *args, **kwargs):
"""
我的报送任务
"""
user = self.request.user
queryset = self.filter_queryset(self.get_queryset().filter(org=user.dept).exclude(qtask__state='待发布'))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
def cal_count(qtask, org):
qs = QAction.objects.filter(qtask=qtask, belong_dept=org)
qorg = QOrg.objects.get(qtask=qtask, org=org)
qorg.count = qs.count()
qorg.count_confirmed = qs.filter(confirmed=True).count()
qorg.save()
class QActionViewSet(PageOrNot, ListModelMixin, DestroyModelMixin, RetrieveModelMixin,GenericViewSet):
perms_map = {'get': 'qtask_view'}
queryset = QAction.objects.select_related('file', 'atype', 'afield', 'qtask', 'belong_dept')
filterset_fields = ['qtask', 'belong_dept', 'atype', 'afield']
serializer_class = QActionListSerializer
def get_serializer_class(self):
if self.action == 'list':
return QActionListSerializer
elif self.action == 'retrieve':
return QActionDetailSerializer
return super().get_serializer_class()
@action(methods=['get'], detail=False, perms_map = {'get':'qaction_my'})
def my(self, request, *args, **kwargs):
"""
我的报送操作
"""
user = self.request.user
queryset = self.filter_queryset(self.get_queryset().filter(belong_dept=user.dept))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
def perform_destroy(self, instance):
if not instance.confirmed:
instance.delete(soft=False)
raise ParseError('报送已确认, 不可删除')
@action(methods=['post'], detail=False,
perms_map = {'post':'qaction_create'}, serializer_class=QActionServiceSerializer)
@transaction.atomic
def service_update(self, request, *args, **kwargs):
"""
更新提供服务
"""
user = request.user
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(create_by=user, belong_dept=user.dept)
vdata = serializer.validated_data
cal_count(vdata['qtask'], user.dept)
return Response()
@action(methods=['post'], detail=False,
perms_map = {'post':'qaction_create'}, serializer_class=QActionQualiCreateSerializer)
@transaction.atomic
def quali_create(self, request, *args, **kwargs):
"""
新增资质
"""
user = request.user
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(create_by=user, belong_dept=user.dept)
vdata = serializer.validated_data
cal_count(vdata['qtask'], user.dept)
return Response()
@action(methods=['post'], detail=False,
perms_map = {'post':'qaction_update'}, serializer_class=QActionQualiUpdateSerializer)
@transaction.atomic
def quali_update(self, request, *args, **kwargs):
"""
修改资质
"""
user = request.user
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
obj = serializer.save(create_by=user, belong_dept=user.dept)
vdata = serializer.validated_data
# 比较差别
quali = Quali.objects.get(id=obj.value2.get('id'))
old_data = QualiSerializer(instance=quali).data
obj.value1 = old_data
for k, v in obj.value2.items():
if v != old_data[k]:
QActionItem.objects.create(action='update', field=k, value1=old_data[k], value2=v, qaction=obj)
if k == 'citys':
old_citys = set(old_data['citys'])
new_citys = set(v)
removes = old_citys.difference(new_citys)
adds = new_citys.difference(old_citys)
for i in removes:
QActionItem.objects.create(action='city:remove', field='citys', city=City.objects.get(id=i), qaction=obj)
for i in adds:
QActionItem.objects.create(action='city:add', field='citys', city=City.objects.get(id=i), qaction=obj)
cal_count(vdata['qtask'], user.dept)
return Response()
@action(methods=['post'], detail=False,
perms_map = {'post':'ability_create'}, serializer_class=QActionACreateSerializer)
@transaction.atomic
def ability_create(self, request, *args, **kwargs):
"""
新增能力
"""
user = request.user
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(create_by=user, belong_dept=user.dept)
vdata = serializer.validated_data
cal_count(vdata['qtask'], user.dept)
return Response()
@action(methods=['put'], detail=True, perms_map = {'put':'qaction_confirm'},
serializer_class=serializers.Serializer)
@transaction.atomic
def confirm(self, request, *args, **kwargs):
"""
确认
"""
obj = self.get_object()
if obj.confirmed:
raise ParseError('该动作已确认')
if obj.action == 'service:update':
org = obj.belong_dept
org.service = obj.value2
org.save()
elif obj.action == 'quali:create':
serializer = QualiCreateSerializer(data=obj.value2)
serializer.is_valid(raise_exception=True)
instance = serializer.save(org=obj.belong_dept, create_by=obj.create_by)
if instance.type == 'OTHER':
qualiLib, _ = QualiLib.objects.get_or_create(name=instance.name)
levels = qualiLib.levels
levels.append(instance.level)
le = list(set(levels))
qualiLib.levels = le
qualiLib.save()
instance.qualilib = qualiLib
instance.save()
elif obj.action == 'quali:update':
quali = Quali.objects.get(id=obj.value2.get('id'))
s = QualiUpdateSerializer(instance=quali, data=obj.value2)
s.is_valid(raise_exception=True)
s.save(update_by=obj.create_by)
elif obj.action == 'ability:create':
pass
obj.confirmed = True
obj.save()
cal_count(obj.qtask, obj.belong_dept)
return Response(status=status.HTTP_200_OK)

View File

@ -0,0 +1,34 @@
# Generated by Django 3.0.5 on 2022-05-13 01:05
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0018_auto_20210430_1156'),
]
operations = [
migrations.CreateModel(
name='Province',
fields=[
('id', models.PositiveSmallIntegerField(primary_key=True, serialize=False, verbose_name='id')),
('name', models.CharField(max_length=20)),
],
),
migrations.AddField(
model_name='organization',
name='service',
field=models.TextField(blank=True, null=True, verbose_name='提供服务'),
),
migrations.CreateModel(
name='City',
fields=[
('id', models.PositiveSmallIntegerField(primary_key=True, serialize=False, verbose_name='id')),
('name', models.CharField(max_length=20)),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.Province')),
],
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.0.5 on 2022-05-13 01:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0019_auto_20220513_0905'),
]
operations = [
migrations.AlterField(
model_name='city',
name='id',
field=models.PositiveIntegerField(primary_key=True, serialize=False, verbose_name='id'),
),
migrations.AlterField(
model_name='province',
name='id',
field=models.PositiveIntegerField(primary_key=True, serialize=False, verbose_name='id'),
),
]

View File

@ -6,7 +6,14 @@ from django.db.models.query import QuerySet
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
class Province(models.Model):
id = models.PositiveIntegerField('id', primary_key=True)
name = models.CharField(max_length=20)
class City(models.Model):
id = models.PositiveIntegerField('id', primary_key=True)
name = models.CharField(max_length=20)
parent = models.ForeignKey(Province, on_delete=models.CASCADE)
class Position(BaseModel): class Position(BaseModel):
""" """
@ -61,6 +68,7 @@ class Organization(SoftModel):
on_delete=models.SET_NULL, verbose_name='') on_delete=models.SET_NULL, verbose_name='')
sort = models.CharField('排序', null=True, blank=True, max_length=100) sort = models.CharField('排序', null=True, blank=True, max_length=100)
can_supervision = models.BooleanField('是否可监督', default=False) can_supervision = models.BooleanField('是否可监督', default=False)
service = models.TextField('提供服务', null=True, blank=True)
class Meta: class Meta:
verbose_name = '组织架构' verbose_name = '组织架构'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -2,7 +2,7 @@ import re
from rest_framework import serializers from rest_framework import serializers
from .models import Organization, Permission, Role, User, Position, DictType, Dict, File from .models import City, Organization, Permission, Province, Role, User, Position, DictType, Dict, File
class FileSerializer(serializers.ModelSerializer): class FileSerializer(serializers.ModelSerializer):
@ -153,3 +153,15 @@ class FileSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = File model = File
fields = ['id', 'name', 'path', 'file'] fields = ['id', 'name', 'path', 'file']
class ProvinceSerializer(serializers.ModelSerializer):
class Meta:
model = Province
fields = '__all__'
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City
fields = '__all__'

View File

@ -1,5 +1,6 @@
from django.urls import path, include from django.urls import path, include
from .views import UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet, sendMsg
from .views import CityViewSet, ProviceViewSet, UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet, sendMsg
from rest_framework import routers from rest_framework import routers
@ -11,6 +12,8 @@ router.register('role', RoleViewSet, basename="role")
router.register('position', PositionViewSet, basename="position") router.register('position', PositionViewSet, basename="position")
router.register('dicttype', DictTypeViewSet, basename="dicttype") router.register('dicttype', DictTypeViewSet, basename="dicttype")
router.register('dict', DictViewSet, basename="dict") router.register('dict', DictViewSet, basename="dict")
router.register('province', ProviceViewSet, basename="province")
router.register('city', CityViewSet, basename="city")
urlpatterns = [ urlpatterns = [
path('', include(router.urls)), path('', include(router.urls)),
path('sendmsg/', sendMsg.as_view()), path('sendmsg/', sendMsg.as_view()),

View File

@ -27,13 +27,13 @@ from utils.pagination import PageOrNot
from utils.queryset import get_child_queryset2 from utils.queryset import get_child_queryset2
from .filters import UserFilter from .filters import UserFilter
from .models import (Dict, DictType, File, Message, Organization, Permission, from .models import (City, Dict, DictType, File, Message, Organization, Permission,
Position, Role, User, UserThird) Position, Province, Role, User, UserThird)
from .permission import RbacPermission, get_permission_list from .permission import RbacPermission, get_permission_list
from .permission_data import RbacFilterSet from .permission_data import RbacFilterSet
from .serializers import (DictSerializer, DictTypeSerializer, FileSerializer, from .serializers import (CitySerializer, DictSerializer, DictTypeSerializer, FileSerializer,
OrganizationSerializer, PermissionSerializer, OrganizationSerializer, PermissionSerializer,
PositionSerializer, RoleSerializer, PositionSerializer, ProvinceSerializer, RoleSerializer,
UserCreateSerializer, UserListSerializer, UserCreateSerializer, UserListSerializer,
UserModifySerializer) UserModifySerializer)
import requests import requests
@ -385,9 +385,19 @@ class WXMPlogin(APIView):
class ProviceViewSet(PageOrNot, ListModelMixin, GenericViewSet):
queryset = Province.objects.all()
serializer_class = ProvinceSerializer
ordering = 'id'
class CityViewSet(PageOrNot, ListModelMixin, GenericViewSet):
queryset = City.objects.all()
serializer_class = CitySerializer
ordeing = 'id'
class FileViewSet(ModelViewSet): class FileViewSet(ModelViewSet):
""" """
文件增删改查 文件增删改查

View File

@ -116,9 +116,9 @@ class MyViewRecordAPIView(APIView):
return Response('视频不存在', status=HTTP_400_BAD_REQUEST) return Response('视频不存在', status=HTTP_400_BAD_REQUEST)
record = ViewRecord.objects.filter(video=video, user=request.user).first() record = ViewRecord.objects.filter(video=video, user=request.user).first()
fcreated = False
if record:
fcreated = True fcreated = True
if record:
fcreated = False
else: else:
record = ViewRecord.objects.create(video=video, user=request.user) record = ViewRecord.objects.create(video=video, user=request.user)

View File

@ -38,6 +38,7 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'drf_yasg',
'rest_framework', 'rest_framework',
'corsheaders', 'corsheaders',
"django_filters", "django_filters",
@ -67,7 +68,7 @@ ROOT_URLCONF = 'server.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['dist'], 'DIRS': ['vuedist'],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@ -129,10 +130,19 @@ CORS_ORIGIN_ALLOW_ALL = True
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'vuedist/static'),
)
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# swagger配置
SWAGGER_SETTINGS = {
'LOGIN_URL':'/api/admin/login/',
'LOGOUT_URL':'/api/admin/logout/'
}
# restframework配置 # restframework配置
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [ 'DEFAULT_AUTHENTICATION_CLASSES': [

View File

@ -1,20 +1,21 @@
from .settings import * from .settings import *
DEBUG = True DEBUG = True
DATABASES = { DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.postgresql',
# 'NAME': 'cma',
# 'USER': 'postgres',
# 'PASSWORD': 'zctest1234',
# 'HOST': '47.95.0.242',
# 'PORT': '5432',
# }
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql', 'ENGINE': 'django.db.backends.postgresql',
'NAME': 'cma', 'NAME': 'cma',
'USER': 'cma', 'USER': 'postgres',
'PASSWORD': 'cma123', 'PASSWORD': 'zctest1234',
'HOST': '172.16.80.102', 'HOST': '47.95.0.242',
'PORT': '5432', 'PORT': '5432',
} }
# 'default': {
# 'ENGINE': 'django.db.backends.postgresql',
# 'NAME': 'cma',
# 'USER': 'cma',
# 'PASSWORD': 'cma123',
# # 'HOST': '172.16.80.102',
# 'HOST': '1.203.161.102',
# 'PORT': '5432',
# }
} }

View File

@ -31,11 +31,26 @@ from django.conf.urls import url
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenViewBase from rest_framework_simplejwt.views import TokenViewBase
from apps.system.views import WXMPlogin,mediaauth from apps.system.views import WXMPlogin,mediaauth
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
import os
schema_dict = dict(
info=openapi.Info(
title="CMA API",
default_version='v1',
contact=openapi.Contact(email="caoqianming@foxmail.com"),
license=openapi.License(name="MIT License"),
),
public=True,
permission_classes=[],)
if os.getenv('DJANGO_SETTINGS_MODULE') != 'server.settings_dev':
schema_dict['url'] = "https://testsearch.ctc.ac.cn/"
schema_view = get_schema_view(**schema_dict)
urlpatterns = [ urlpatterns = [
path('', TemplateView.as_view(template_name="index.html")),
path('api/admin/', admin.site.urls), path('api/admin/', admin.site.urls),
path('api/mediaauth/',mediaauth), path('api/mediaauth/',mediaauth),
path('api/wxmplogin/',WXMPlogin.as_view()), path('api/wxmplogin/',WXMPlogin.as_view()),
@ -51,5 +66,9 @@ urlpatterns = [
path('api/consulting/', include('apps.consulting.urls')), path('api/consulting/', include('apps.consulting.urls')),
path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])), path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])),
url(r'^api/swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('api/swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('api/redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
path('api/', include(router.urls)), path('api/', include(router.urls)),
path('', TemplateView.as_view(template_name="index.html")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

View File

@ -10,8 +10,8 @@ class PageOrNot:
def paginate_queryset(self, queryset): def paginate_queryset(self, queryset):
if (self.paginator is None): if (self.paginator is None):
return None return None
elif self.request.query_params.get('pageoff', None) and queryset.count()<500: elif (self.request.query_params.get('pageoff', None)) and queryset.count()<500:
return None return None
elif self.request.query_params.get('pageoff', None) and queryset.count()>=500: elif (self.request.query_params.get('pageoff', None)) and queryset.count()>=500:
raise ParseError('单次请求数据量大,请求中止') raise ParseError('单次请求数据量大,请求中止')
return self.paginator.paginate_queryset(queryset, self.request, view=self) return self.paginator.paginate_queryset(queryset, self.request, view=self)

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICpjCCAY4CAQAwYTEdMBsGA1UEAwwUdGVzdHNlYXJjaC5jdGMuYWMuY24xDzAN
BgNVBAoMBnFjbG91ZDEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECAwHQmVpamlu
ZzELMAkGA1UEBhMCQ04wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7
ntPf0oN5RpbUorSglOLiAZal1SI3BoEh6Fmk1NzLUvT0DDTmKaFz4waxTwAglk3Y
pI0TGl+9G5UrmwLia9O17sm0KfHqLe3rEE4EsUD3Uk2CBPVnTMgPS79dAPv04Y3H
H1395h5XSSpzKPzyeQZf3FsyQiAyA9ij77t7jLdPPcHrsgI0adBW8bejF4KQQfRe
25g3nO498GEi76OAaPC2fb48j3ZJ7s8xRcQSt78Ut8rGqaB4Kw8MdxH7yBUooHkx
E7xtv/a86x9c8+cYeYhlLoKhn7n3vxehRM8xv5SI2eZuTfLqTjgvdKbYLztqvxFq
1O+/SksqGrRq2IIV9kcnAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAmRAftF9Y
O3l/XX2UBzVEy4KKdddRQxlIEmuSTOAq2JaUwgCSGFSl5ue3ZpjW3rOMwAYjHPl3
N3DVFMqBJnI8vbLCJK43idTm1pE6Ikv2urPoFJyL2+CyyyeJpv+NiEzQOVHnomlY
xqYjePtp9V/H2W1U+JRz4P3ZD/jOLDEsGutE545UZA9cUo3JfJz/uYkzd1kRfoP/
wqsfreMoMzxLhfWxf/4woQf2e2neixR/JKnTg4duSt86FCHxGuMlJ7x8qLB+N6cK
eW4i+/m6FeFeCI4FvIABYq9bk5/QGNfXd2BluU+s6BfAfhMVPeuwzIVcPdQmplC9
i9qPUhGJ3IDELQ==
-----END CERTIFICATE REQUEST-----

View File

@ -1,28 +1,27 @@
-----BEGIN PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
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
MjzYAERmsYQA2CkkSLCFhQU2 -----END RSA PRIVATE KEY-----
-----END PRIVATE KEY-----

View File

@ -1,128 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGTDCCBTSgAwIBAgIQPS0W9BEZigBFmUThrWpjwTANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTIxMDQyNTAwMDAwMFoXDTIyMDQyNTIzNTk1OVowHzEdMBsGA1UEAxMUdGVz
dHNlYXJjaC5jdGMuYWMuY24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCqBDfLPIyYIee9M7LjCzdRRP5PHezjaks360V5AnK+oJO7HMgdH7z4QQG8AjKN
bLOSFmVaH0R5YTJ3XmOGgrdnmb+mCUx3G5wdO9/UXpP4ZA0Gx0S7nqmNPWR03wEN
oQQjcfMpkBFxMlwCopS/EeBmQXaKIcg6B4hw3JLObdlr3f1eHccPZchH8Bwho4Uj
FO7rYVX8jfshV5iC99KV650jv9uQ3OKno3moDPk9JRnozBpyUwRJ9SFFCZ1lOO62
5M+dPG13hZcGxMSyT9wXzcij2luRHXxTSky952ciN3nTomKY00WcOCj0ZCGdHQV/
6CzPALdL64TtN5uqFLG0IoLxAgMBAAGjggMRMIIDDTAfBgNVHSMEGDAWgBSNjF7E
VK2K4Xfpm/mbBeG4AY1h4TAdBgNVHQ4EFgQUr4UA+Awov3oaqRuAMgP3UbKkxF0w
DgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUH
AwEGCCsGAQUFBwMCMEkGA1UdIARCMEAwNAYLKwYBBAGyMQECAgcwJTAjBggrBgEF
BQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQIBMIGEBggrBgEF
BQcBAQR4MHYwTwYIKwYBBQUHMAKGQ2h0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2Vj
dGlnb1JTQURvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcnQwIwYIKwYB
BQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMDkGA1UdEQQyMDCCFHRlc3Rz
ZWFyY2guY3RjLmFjLmNughh3d3cudGVzdHNlYXJjaC5jdGMuYWMuY24wggF/Bgor
BgEEAdZ5AgQCBIIBbwSCAWsBaQB3AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr
8vxw/m1HAAABeQalozkAAAQDAEgwRgIhAISF+Qpq5bQHPbWpjW8XGdvm6sxf4HKu
vOrk4NTSX1zBAiEAzzOX6eWf6b8eyBWUPQpaEcEr/wYWLjj+84/FMhO1UnEAdQDf
pV6raIJPH2yt7rhfTj5a6s2iEqRqXo47EsAgRFwqcwAAAXkGpaLUAAAEAwBGMEQC
IE+Nd7R7KnkKQwESXlUM8CMoU2ubZRKleyGodJpVK8O8AiAqPBhS1AXPZ/ZIrCg4
Fg8pqoLMcxxRmsfAewI3OpbUWAB3AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+j
qh0HE9MMAAABeQalos0AAAQDAEgwRgIhAOkGSJnkhA9GxnVL7h85Q59b84cJOjtj
r3ThnHypBamEAiEA096UyGiIKNIVChALqjv8lQh1rywKba0UiI0lLrh7DHwwDQYJ
KoZIhvcNAQELBQADggEBAH8N8GxC+04Pt3XJZD/UoUWIcIJ2uHOhtVVe/pebctMk
8VjD1BF4uKJOGpGRQ80cYB/DWScJL6x0TyTvLyTfeR26tndWDZvNk+L3GokwptRp
XCgNmSUHOhS7wnKCXKqRZZ0QkR32HpNknv36qn9fhe/6wcnUyQeYYCc9AUKyGoKY
EwnS0sL0HLLIDGiewXtR/mSeLt7lbx7+kffxIvRvQvjBV/m+4bHYJHLC/RvwTrWW
+fZcAg595PypE6mZrV9Hb9Vuh5mHRUioPYRT+pEBiih4qzZTHn7c4rQC1c8URuWm
8Ima8Y+4fi3Iwly+JHNv2LaYQlNdtM8iWoIWfwlTzFo=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx
MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBjzELMAkGA1UEBhMCR0IxGzAZBgNV
BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE
ChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFJTQSBEb21haW4g
VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA1nMz1tc8INAA0hdFuNY+B6I/x0HuMjDJsGz99J/LEpgPLT+N
TQEMgg8Xf2Iu6bhIefsWg06t1zIlk7cHv7lQP6lMw0Aq6Tn/2YHKHxYyQdqAJrkj
eocgHuP/IJo8lURvh3UGkEC0MpMWCRAIIz7S3YcPb11RFGoKacVPAXJpz9OTTG0E
oKMbgn6xmrntxZ7FN3ifmgg0+1YuWMQJDgZkW7w33PGfKGioVrCSo1yfu4iYCBsk
Haswha6vsC6eep3BwEIc4gLw6uBK0u+QDrTBQBbwb4VCSmT3pDCg/r8uoydajotY
uK3DGReEY+1vVv2Dy2A0xHS+5p3b4eTlygxfFQIDAQABo4IBbjCCAWowHwYDVR0j
BBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFI2MXsRUrYrhd+mb
+ZsF4bgBjWHhMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYGBFUdIAAw
CAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0
LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2Bggr
BgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNv
bS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDov
L29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAMr9hvQ5Iw0/H
ukdN+Jx4GQHcEx2Ab/zDcLRSmjEzmldS+zGea6TvVKqJjUAXaPgREHzSyrHxVYbH
7rM2kYb2OVG/Rr8PoLq0935JxCo2F57kaDl6r5ROVm+yezu/Coa9zcV3HAO4OLGi
H19+24rcRki2aArPsrW04jTkZ6k4Zgle0rj8nSg6F0AnwnJOKf0hPHzPE/uWLMUx
RP0T7dWbqWlod3zu4f+k+TY4CFM5ooQ0nBnzvg6s1SQ36yOoeNDT5++SR2RiOSLv
xvcRviKFxmZEJCaOEDKNyJOuB56DPi/Z+fVGjmO+wea03KbNIaiGCpXZLoUmGv38
sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL
l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq
6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY
LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5
yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K
00u/I5sUKUErmgQfky3xxzlIPK1aEn8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7
MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD
VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE
AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4
MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5
MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO
ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI
s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG
vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ
Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb
IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0
tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E
xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV
icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5
D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ
WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ
5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG
KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg
EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID
ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG
BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t
L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr
BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA
A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+
rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+
/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA
CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F
zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA
vGp4z7h/jnZymQyd/teRCBaho1+V
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----

View File

@ -0,0 +1,66 @@
-----BEGIN CERTIFICATE-----
MIIGczCCBNugAwIBAgIRAOYohHXv8FLXo4baCaGGuZswDQYJKoZIhvcNAQEMBQAw
WTELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xIzAhBgNVBAMTGlRydXN0QXNpYSBSU0EgRFYgVExTIENBIEcyMB4XDTIy
MDQyNjAwMDAwMFoXDTIzMDQyNjIzNTk1OVowHzEdMBsGA1UEAxMUdGVzdHNlYXJj
aC5jdGMuYWMuY24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7ntPf
0oN5RpbUorSglOLiAZal1SI3BoEh6Fmk1NzLUvT0DDTmKaFz4waxTwAglk3YpI0T
Gl+9G5UrmwLia9O17sm0KfHqLe3rEE4EsUD3Uk2CBPVnTMgPS79dAPv04Y3HH139
5h5XSSpzKPzyeQZf3FsyQiAyA9ij77t7jLdPPcHrsgI0adBW8bejF4KQQfRe25g3
nO498GEi76OAaPC2fb48j3ZJ7s8xRcQSt78Ut8rGqaB4Kw8MdxH7yBUooHkxE7xt
v/a86x9c8+cYeYhlLoKhn7n3vxehRM8xv5SI2eZuTfLqTjgvdKbYLztqvxFq1O+/
SksqGrRq2IIV9kcnAgMBAAGjggLuMIIC6jAfBgNVHSMEGDAWgBRfOnwREH4MZ3Fh
3IujtQADZ/VXHDAdBgNVHQ4EFgQUprxC4BrX8XvDT1n1xTS7U31JYW4wDgYDVR0P
AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
AQUFBwMCMEkGA1UdIARCMEAwNAYLKwYBBAGyMQECAjEwJTAjBggrBgEFBQcCARYX
aHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQIBMH0GCCsGAQUFBwEBBHEw
bzBCBggrBgEFBQcwAoY2aHR0cDovL2NydC50cnVzdC1wcm92aWRlci5jbi9UcnVz
dEFzaWFSU0FEVlRMU0NBRzIuY3J0MCkGCCsGAQUFBzABhh1odHRwOi8vb2NzcC50
cnVzdC1wcm92aWRlci5jbjAfBgNVHREEGDAWghR0ZXN0c2VhcmNoLmN0Yy5hYy5j
bjCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYArfe++nz/EMiLnT2cHj4YarRn
KV3PsQwkyoWGNOvcgooAAAGAY3BYXgAABAMARzBFAiAeB3GNy4ySrz7YlvJUQVRe
6rWMWOIHLcfSkLIWo/VzYgIhAPvcJV/9eRM83a6iEf11p36MJ3jPvwGtWr2LrlCK
+InIAHYAejKMVNi3LbYg6jjgUh7phBZwMhOFTTvSK8E6V6NS61IAAAGAY3BYEwAA
BAMARzBFAiAQkq1NFojQbL/SyeClv7UkFXyB6UCZlWHjFvhUS/ODOgIhAJHNkEpo
g7NodBVkS6t3pO9pGRFNXn63PEdcob6RUCoXAHYA6D7Q2j71BjUy51covIlryQPT
y9ERa+zraeF3fW0GvW4AAAGAY3BX9QAABAMARzBFAiAJr+d2ycuSAreIgSPM+Qe+
I4ajUeAftxWte8gaf2SaOwIhAPWx4260Egud1QrPULoLtNy7hWFNNnfkeiTK3Nmd
EqttMA0GCSqGSIb3DQEBDAUAA4IBgQBRgUlvliFI/KpbWyjUnR5YPpDEylYhXm/3
GM/XVlXtJDNcpyLyK6SAMri8wxv245Ts7wU+YI2FYlkLzArPiJD85YE+SSu4v0Ea
ZSdj1hPuxFRgidQON7pRS0y5ORgZ2ZDQZMufbEK6l4BmchdGDYtuSTA8iZVFDTIP
H3TlQCza7piHljOY7vRJQcn4l3krIOq6G3uruy+XdywQlfXB1hhRrve340ZFGAiK
4xK9v/gkOt4k4PJD+OzJoJKiezaVIWrYkx86me4O6rU8f/FAYYhONUVh8iIcYMeQ
tJ4gmxUxEc0EUW9kZbuVi7nAzChuhfZebPMI8KQyi7fLsuuzjxzEwqHcSDu7H1AP
GyqJos8AbILID2o2u91aLIBDuMCzSWzq0xu/JqczcmnpEbNHqRRUeTVHiMFgejXQ
lN2wDMOoMQFPTnIs+EvlnguidkC8OjNONQSveG4OAwgiquYbD6WRl/VT9wFeyTmS
gAhJb/H+IjuKr3JHDXtZophtqUu1ZKc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFBzCCA++gAwIBAgIRALIM7VUuMaC/NDp1KHQ76aswDQYJKoZIhvcNAQELBQAw
ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yMjAxMTAwMDAwMDBaFw0y
ODEyMzEyMzU5NTlaMFkxCzAJBgNVBAYTAkNOMSUwIwYDVQQKExxUcnVzdEFzaWEg
VGVjaG5vbG9naWVzLCBJbmMuMSMwIQYDVQQDExpUcnVzdEFzaWEgUlNBIERWIFRM
UyBDQSBHMjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKjGDe0GSaBs
Yl/VhMaTM6GhfR1TAt4mrhN8zfAMwEfLZth+N2ie5ULbW8YvSGzhqkDhGgSBlafm
qq05oeESrIJQyz24j7icGeGyIZ/jIChOOvjt4M8EVi3O0Se7E6RAgVYcX+QWVp5c
Sy+l7XrrtL/pDDL9Bngnq/DVfjCzm5ZYUb1PpyvYTP7trsV+yYOCNmmwQvB4yVjf
IIpHC1OcsPBntMUGeH1Eja4D+qJYhGOxX9kpa+2wTCW06L8T6OhkpJWYn5JYiht5
8exjAR7b8Zi3DeG9oZO5o6Qvhl3f8uGU8lK1j9jCUN/18mI/5vZJ76i+hsgdlfZB
Rh5lmAQjD80M9TY+oD4MYUqB5XrigPfFAUwXFGehhlwCVw7y6+5kpbq/NpvM5Ba8
SeQYUUuMA8RXpTtGlrrTPqJryfa55hTuX/ThhX4gcCVkbyujo0CYr+Uuc14IOyNY
1fD0/qORbllbgV41wiy/2ZUWZQUodqHWkjT1CwIMbQOY5jmrSYGBwwIDAQABo4IB
JjCCASIwHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYE
FF86fBEQfgxncWHci6O1AANn9VccMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8E
CDAGAQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAE
GzAZMA0GCysGAQQBsjEBAgIxMAgGBmeBDAECATBDBgNVHR8EPDA6MDigNqA0hjJo
dHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNy
bDA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9k
b2NhLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHMUom5cxIje2IiFU7mOCsBr2F6CY
eU5cyfQ/Aep9kAXYUDuWsaT85721JxeXFYkf4D/cgNd9+hxT8ZeDOJrn+ysqR7NO
2K9AdqTdIY2uZPKmvgHOkvH2gQD6jc05eSPOwdY/10IPvmpgUKaGOa/tyygL8Og4
3tYyoHipMMnS4OiYKakDJny0XVuchIP7ZMKiP07Q3FIuSS4omzR77kmc75/6Q9dP
v4wa90UCOn1j6r7WhMmX3eT3Gsdj3WMe9bYD0AFuqa6MDyjIeXq08mVGraXiw73s
Zale8OMckn/BU3O/3aFNLHLfET2H2hT6Wb3nwxjpLIfXmSVcVd8A58XH0g==
-----END CERTIFICATE-----

View File

@ -0,0 +1,66 @@
-----BEGIN CERTIFICATE-----
MIIGczCCBNugAwIBAgIRAOYohHXv8FLXo4baCaGGuZswDQYJKoZIhvcNAQEMBQAw
WTELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xIzAhBgNVBAMTGlRydXN0QXNpYSBSU0EgRFYgVExTIENBIEcyMB4XDTIy
MDQyNjAwMDAwMFoXDTIzMDQyNjIzNTk1OVowHzEdMBsGA1UEAxMUdGVzdHNlYXJj
aC5jdGMuYWMuY24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7ntPf
0oN5RpbUorSglOLiAZal1SI3BoEh6Fmk1NzLUvT0DDTmKaFz4waxTwAglk3YpI0T
Gl+9G5UrmwLia9O17sm0KfHqLe3rEE4EsUD3Uk2CBPVnTMgPS79dAPv04Y3HH139
5h5XSSpzKPzyeQZf3FsyQiAyA9ij77t7jLdPPcHrsgI0adBW8bejF4KQQfRe25g3
nO498GEi76OAaPC2fb48j3ZJ7s8xRcQSt78Ut8rGqaB4Kw8MdxH7yBUooHkxE7xt
v/a86x9c8+cYeYhlLoKhn7n3vxehRM8xv5SI2eZuTfLqTjgvdKbYLztqvxFq1O+/
SksqGrRq2IIV9kcnAgMBAAGjggLuMIIC6jAfBgNVHSMEGDAWgBRfOnwREH4MZ3Fh
3IujtQADZ/VXHDAdBgNVHQ4EFgQUprxC4BrX8XvDT1n1xTS7U31JYW4wDgYDVR0P
AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
AQUFBwMCMEkGA1UdIARCMEAwNAYLKwYBBAGyMQECAjEwJTAjBggrBgEFBQcCARYX
aHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQIBMH0GCCsGAQUFBwEBBHEw
bzBCBggrBgEFBQcwAoY2aHR0cDovL2NydC50cnVzdC1wcm92aWRlci5jbi9UcnVz
dEFzaWFSU0FEVlRMU0NBRzIuY3J0MCkGCCsGAQUFBzABhh1odHRwOi8vb2NzcC50
cnVzdC1wcm92aWRlci5jbjAfBgNVHREEGDAWghR0ZXN0c2VhcmNoLmN0Yy5hYy5j
bjCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYArfe++nz/EMiLnT2cHj4YarRn
KV3PsQwkyoWGNOvcgooAAAGAY3BYXgAABAMARzBFAiAeB3GNy4ySrz7YlvJUQVRe
6rWMWOIHLcfSkLIWo/VzYgIhAPvcJV/9eRM83a6iEf11p36MJ3jPvwGtWr2LrlCK
+InIAHYAejKMVNi3LbYg6jjgUh7phBZwMhOFTTvSK8E6V6NS61IAAAGAY3BYEwAA
BAMARzBFAiAQkq1NFojQbL/SyeClv7UkFXyB6UCZlWHjFvhUS/ODOgIhAJHNkEpo
g7NodBVkS6t3pO9pGRFNXn63PEdcob6RUCoXAHYA6D7Q2j71BjUy51covIlryQPT
y9ERa+zraeF3fW0GvW4AAAGAY3BX9QAABAMARzBFAiAJr+d2ycuSAreIgSPM+Qe+
I4ajUeAftxWte8gaf2SaOwIhAPWx4260Egud1QrPULoLtNy7hWFNNnfkeiTK3Nmd
EqttMA0GCSqGSIb3DQEBDAUAA4IBgQBRgUlvliFI/KpbWyjUnR5YPpDEylYhXm/3
GM/XVlXtJDNcpyLyK6SAMri8wxv245Ts7wU+YI2FYlkLzArPiJD85YE+SSu4v0Ea
ZSdj1hPuxFRgidQON7pRS0y5ORgZ2ZDQZMufbEK6l4BmchdGDYtuSTA8iZVFDTIP
H3TlQCza7piHljOY7vRJQcn4l3krIOq6G3uruy+XdywQlfXB1hhRrve340ZFGAiK
4xK9v/gkOt4k4PJD+OzJoJKiezaVIWrYkx86me4O6rU8f/FAYYhONUVh8iIcYMeQ
tJ4gmxUxEc0EUW9kZbuVi7nAzChuhfZebPMI8KQyi7fLsuuzjxzEwqHcSDu7H1AP
GyqJos8AbILID2o2u91aLIBDuMCzSWzq0xu/JqczcmnpEbNHqRRUeTVHiMFgejXQ
lN2wDMOoMQFPTnIs+EvlnguidkC8OjNONQSveG4OAwgiquYbD6WRl/VT9wFeyTmS
gAhJb/H+IjuKr3JHDXtZophtqUu1ZKc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFBzCCA++gAwIBAgIRALIM7VUuMaC/NDp1KHQ76aswDQYJKoZIhvcNAQELBQAw
ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yMjAxMTAwMDAwMDBaFw0y
ODEyMzEyMzU5NTlaMFkxCzAJBgNVBAYTAkNOMSUwIwYDVQQKExxUcnVzdEFzaWEg
VGVjaG5vbG9naWVzLCBJbmMuMSMwIQYDVQQDExpUcnVzdEFzaWEgUlNBIERWIFRM
UyBDQSBHMjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKjGDe0GSaBs
Yl/VhMaTM6GhfR1TAt4mrhN8zfAMwEfLZth+N2ie5ULbW8YvSGzhqkDhGgSBlafm
qq05oeESrIJQyz24j7icGeGyIZ/jIChOOvjt4M8EVi3O0Se7E6RAgVYcX+QWVp5c
Sy+l7XrrtL/pDDL9Bngnq/DVfjCzm5ZYUb1PpyvYTP7trsV+yYOCNmmwQvB4yVjf
IIpHC1OcsPBntMUGeH1Eja4D+qJYhGOxX9kpa+2wTCW06L8T6OhkpJWYn5JYiht5
8exjAR7b8Zi3DeG9oZO5o6Qvhl3f8uGU8lK1j9jCUN/18mI/5vZJ76i+hsgdlfZB
Rh5lmAQjD80M9TY+oD4MYUqB5XrigPfFAUwXFGehhlwCVw7y6+5kpbq/NpvM5Ba8
SeQYUUuMA8RXpTtGlrrTPqJryfa55hTuX/ThhX4gcCVkbyujo0CYr+Uuc14IOyNY
1fD0/qORbllbgV41wiy/2ZUWZQUodqHWkjT1CwIMbQOY5jmrSYGBwwIDAQABo4IB
JjCCASIwHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYE
FF86fBEQfgxncWHci6O1AANn9VccMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8E
CDAGAQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAE
GzAZMA0GCysGAQQBsjEBAgIxMAgGBmeBDAECATBDBgNVHR8EPDA6MDigNqA0hjJo
dHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNy
bDA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9k
b2NhLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHMUom5cxIje2IiFU7mOCsBr2F6CY
eU5cyfQ/Aep9kAXYUDuWsaT85721JxeXFYkf4D/cgNd9+hxT8ZeDOJrn+ysqR7NO
2K9AdqTdIY2uZPKmvgHOkvH2gQD6jc05eSPOwdY/10IPvmpgUKaGOa/tyygL8Og4
3tYyoHipMMnS4OiYKakDJny0XVuchIP7ZMKiP07Q3FIuSS4omzR77kmc75/6Q9dP
v4wa90UCOn1j6r7WhMmX3eT3Gsdj3WMe9bYD0AFuqa6MDyjIeXq08mVGraXiw73s
Zale8OMckn/BU3O/3aFNLHLfET2H2hT6Wb3nwxjpLIfXmSVcVd8A58XH0g==
-----END CERTIFICATE-----