diff --git a/ce_server/apps/expert/admin.py b/ce_server/apps/expert/admin.py index d185d18..4e7504d 100644 --- a/ce_server/apps/expert/admin.py +++ b/ce_server/apps/expert/admin.py @@ -1,24 +1,41 @@ from django.contrib import admin from django.contrib.admin.decorators import register -from .models import BaseInfo, WorkExperience, Paper, Project, Award +from .models import Expert, WorkExperience, Paper, Project, Award +from simple_history.admin import SimpleHistoryAdmin # Register your models here. +class WorkExperienceInline(admin.StackedInline): + model = WorkExperience + extra = 0 + fields = ('expert', 'name','start_date', 'post') -@admin.register(BaseInfo) -class BaseInfoAdmin(admin.ModelAdmin): - pass +@admin.register(Expert) +class ExpertAdmin(SimpleHistoryAdmin): + date_hierarchy = 'create_time' + list_display = ('name', 'gender','idnumber', 'create_time') + search_fields = ("name", "workexperience_expert__name", "paper_expert__name", "project_expert__name", "award_expert__name") + inlines = [ + WorkExperienceInline, + ] @admin.register(WorkExperience) class WorkExperienceAdmin(admin.ModelAdmin): - pass + date_hierarchy = 'start_date' + list_display = ('expert', 'name','start_date', 'post') @admin.register(Paper) class PaperAdmin(admin.ModelAdmin): - pass + date_hierarchy = 'publish_date' + list_display = ('expert', 'name','is_leader', 'publish_date') + list_filter = ('is_leader',) @admin.register(Project) class ProjectAdmin(admin.ModelAdmin): - pass + date_hierarchy = 'start_date' + list_display = ('expert', 'name','number', 'content', 'start_date') + @admin.register(Award) class AwardAdmin(admin.ModelAdmin): - pass \ No newline at end of file + date_hierarchy = 'issue_date' + list_display = ('expert', 'name','level', 'issue_date') + list_filter = ('level',) \ No newline at end of file diff --git a/ce_server/apps/expert/migrations/0002_auto_20210603_1322.py b/ce_server/apps/expert/migrations/0002_auto_20210603_1322.py new file mode 100644 index 0000000..f22ecb3 --- /dev/null +++ b/ce_server/apps/expert/migrations/0002_auto_20210603_1322.py @@ -0,0 +1,128 @@ +# Generated by Django 3.1.8 on 2021-06-03 05:22 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('system', '0002_auto_20210602_1459'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('expert', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Award', + 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='名称')), + ('level', models.CharField(choices=[('省部级', '省部级')], max_length=60, verbose_name='级别')), + ('issue_date', models.DateField(verbose_name='颁发日期')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='award_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '专家获奖/荣誉', + 'verbose_name_plural': '专家获奖/荣誉', + }, + ), + migrations.CreateModel( + name='Expert', + 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='姓名')), + ('gender', models.CharField(choices=[('男', '男'), ('女', '女')], default='男', max_length=10, verbose_name='性别')), + ('idnumber', models.CharField(max_length=40, verbose_name='身份证号')), + ('paddress', models.TextField(verbose_name='通讯地址')), + ('photo', models.CharField(blank=True, max_length=100, null=True, verbose_name='证件照')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expert_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='expert_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='expert_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='expert_user', to=settings.AUTH_USER_MODEL, verbose_name='关联账户')), + ], + options={ + 'verbose_name': '专家基本信息', + 'verbose_name_plural': '专家基本信息', + }, + ), + migrations.CreateModel( + name='Paper', + 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='名称')), + ('is_leader', models.BooleanField(default=True, verbose_name='是否第一作者')), + ('publish_date', models.DateField(verbose_name='发表日期')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='paper_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('expert', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='paper_expert', to='expert.expert', verbose_name='所属专家')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='paper_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '专家论文/著作', + 'verbose_name_plural': '专家论文/著作', + }, + ), + migrations.CreateModel( + name='Project', + 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='名称')), + ('number', models.CharField(max_length=100, verbose_name='项目编号')), + ('start_date', models.DateField(verbose_name='开始日期')), + ('content', models.TextField(verbose_name='主要工作内容')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='project_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('expert', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_expert', to='expert.expert', verbose_name='所属专家')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='project_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '专家项目', + 'verbose_name_plural': '专家项目', + }, + ), + migrations.CreateModel( + name='WorkExperience', + 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='单位名')), + ('start_date', models.DateField(verbose_name='开始日期')), + ('post', models.CharField(max_length=100, verbose_name='职务/岗位')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workexperience_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('expert', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workexperience_expert', to='expert.expert', verbose_name='所属专家')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workexperience_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '专家工作经历', + 'verbose_name_plural': '专家工作经历', + }, + ), + migrations.DeleteModel( + name='BaseInfo', + ), + migrations.AddField( + model_name='award', + name='expert', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='award_expert', to='expert.expert', verbose_name='所属专家'), + ), + migrations.AddField( + model_name='award', + name='update_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='award_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'), + ), + ] diff --git a/ce_server/apps/expert/migrations/0003_historicalexpert.py b/ce_server/apps/expert/migrations/0003_historicalexpert.py new file mode 100644 index 0000000..b3ce18c --- /dev/null +++ b/ce_server/apps/expert/migrations/0003_historicalexpert.py @@ -0,0 +1,48 @@ +# Generated by Django 3.1.8 on 2021-06-03 07:09 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('system', '0002_auto_20210602_1459'), + ('expert', '0002_auto_20210603_1322'), + ] + + operations = [ + migrations.CreateModel( + name='HistoricalExpert', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(blank=True, editable=False, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('name', models.CharField(max_length=100, verbose_name='姓名')), + ('gender', models.CharField(choices=[('男', '男'), ('女', '女')], default='男', max_length=10, verbose_name='性别')), + ('idnumber', models.CharField(max_length=40, verbose_name='身份证号')), + ('paddress', models.TextField(verbose_name='通讯地址')), + ('photo', models.CharField(blank=True, max_length=100, null=True, verbose_name='证件照')), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField()), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('belong_dept', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='system.organization', verbose_name='所属部门')), + ('create_by', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('update_by', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ('user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='关联账户')), + ], + options={ + 'verbose_name': 'historical 专家基本信息', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': 'history_date', + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/ce_server/apps/expert/models.py b/ce_server/apps/expert/models.py index a3b10f3..172368e 100644 --- a/ce_server/apps/expert/models.py +++ b/ce_server/apps/expert/models.py @@ -1,21 +1,23 @@ from django.db import models from utils.model import SoftModel, BaseModel from apps.system.models import CommonAModel, CommonBModel, User +from simple_history.models import HistoricalRecords # Create your models here. -class BaseInfo(CommonBModel): +class Expert(CommonBModel): gender_choices = ( ('男', '男'), ('女', '女'), ) - user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联账户") + user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联账户", related_name="expert_user") name = models.CharField(verbose_name="姓名", max_length=100) gender = models.CharField(verbose_name="性别",choices=gender_choices, default='男', max_length=10) idnumber = models.CharField(verbose_name="身份证号", max_length=40) paddress = models.TextField(verbose_name="通讯地址") photo = models.CharField(verbose_name="证件照", max_length=100, null=True, blank=True) + history = HistoricalRecords() class Meta: verbose_name = '专家基本信息' @@ -27,6 +29,9 @@ class BaseInfo(CommonBModel): class WorkExperience(CommonAModel): name = models.CharField(verbose_name="单位名", max_length=100) + start_date = models.DateField(verbose_name="开始日期") + post = models.CharField(verbose_name="职务/岗位", max_length=100) + expert = models.ForeignKey(Expert, on_delete=models.CASCADE, verbose_name="所属专家", related_name="workexperience_expert") class Meta: verbose_name = '专家工作经历' verbose_name_plural = verbose_name @@ -37,6 +42,10 @@ class WorkExperience(CommonAModel): class Project(CommonAModel): name = models.CharField(verbose_name="名称", max_length=100) + number = models.CharField(verbose_name="项目编号", max_length=100) + start_date = models.DateField(verbose_name="开始日期") + content = models.TextField(verbose_name="主要工作内容") + expert = models.ForeignKey(Expert, on_delete=models.CASCADE, verbose_name="所属专家", related_name="project_expert") class Meta: verbose_name = '专家项目' verbose_name_plural = verbose_name @@ -47,6 +56,9 @@ class Project(CommonAModel): class Paper(CommonAModel): name = models.CharField(verbose_name="名称", max_length=100) + is_leader = models.BooleanField(verbose_name="是否第一作者", default=True) + publish_date = models.DateField(verbose_name="发表日期") + expert = models.ForeignKey(Expert, on_delete=models.CASCADE, verbose_name="所属专家", related_name="paper_expert") class Meta: verbose_name = '专家论文/著作' verbose_name_plural = verbose_name @@ -57,7 +69,14 @@ class Paper(CommonAModel): class Award(CommonAModel): + level_choices = ( + ('省部级', '省部级'), + ) + name = models.CharField(verbose_name="名称", max_length=100) + level = models.CharField(verbose_name="级别", choices=level_choices, max_length=60) + issue_date = models.DateField(verbose_name="颁发日期") + expert = models.ForeignKey(Expert, on_delete=models.CASCADE, verbose_name="所属专家", related_name="award_expert") class Meta: verbose_name = '专家获奖/荣誉' verbose_name_plural = verbose_name diff --git a/ce_server/apps/system/admin.py b/ce_server/apps/system/admin.py index 9616a03..c518cae 100644 --- a/ce_server/apps/system/admin.py +++ b/ce_server/apps/system/admin.py @@ -3,7 +3,7 @@ from simple_history.admin import SimpleHistoryAdmin from .models import User, Organization, Role, Permission, DictType, Dict, File # Register your models here. -admin.site.site_header = '专家库管理系统' +admin.site.site_header = '专家库开发系统' admin.site.site_title = '专家库' admin.site.index_title = '后台管理' diff --git a/ce_server/requirements.txt b/ce_server/requirements.txt index e85e4ce..72c956d 100644 Binary files a/ce_server/requirements.txt and b/ce_server/requirements.txt differ diff --git a/ce_server/server/settings.py b/ce_server/server/settings.py index d4b0b80..e53ab9b 100644 --- a/ce_server/server/settings.py +++ b/ce_server/server/settings.py @@ -32,6 +32,7 @@ ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [ + 'simpleui', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -189,7 +190,8 @@ CELERYD_MAX_TASKS_PER_CHILD = 100 # 每个worker最多执行300个任务就会 CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区 CELERY_ENABLE_UTC = True # 启动时区设置 - +SIMPLEUI_HOME_INFO = False +SIMPLEUI_ANALYSIS = False # 日志配置 # 创建日志的路径 LOG_PATH = os.path.join(BASE_DIR, 'log') diff --git a/ce_server/server/urls.py b/ce_server/server/urls.py index 5900ebb..afdfd9a 100644 --- a/ce_server/server/urls.py +++ b/ce_server/server/urls.py @@ -42,13 +42,15 @@ schema_view = get_schema_view( urlpatterns = [ path('admin/doc/', include('django.contrib.admindocs.urls')), path('admin/', admin.site.urls), + + # api path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('token/black/', LogoutView.as_view(), name='token_black'), - path('system/', include('apps.system.urls')), path('monitor/', include('apps.monitor.urls')), + # api文档 path('docs/', include_docs_urls(title="接口文档", authentication_classes=[], permission_classes=[])), path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),