diff --git a/client/src/api/employee.js b/client/src/api/employee.js new file mode 100644 index 0000000..32a3920 --- /dev/null +++ b/client/src/api/employee.js @@ -0,0 +1,32 @@ +import request from '@/utils/request' + +export function getEmployeeList(query) { + return request({ + url: '/employee/employee/', + method: 'get', + params: query + }) +} + +export function createEmployee(data) { + return request({ + url: '/employee/employee/', + method: 'post', + data + }) +} + +export function updateEmployee(id, data) { + return request({ + url: `/employee/employee/${id}/`, + method: 'put', + data + }) +} + +export function deleteEmployee(id) { + return request({ + url: `/employee/employee/${id}/`, + method: 'delete' + }) +} \ No newline at end of file diff --git a/client/src/api/userdetail.js b/client/src/api/userdetail.js deleted file mode 100644 index 13becc6..0000000 --- a/client/src/api/userdetail.js +++ /dev/null @@ -1,32 +0,0 @@ -import request from '@/utils/request' - -export function getUserDetailList(query) { - return request({ - url: '/employee/userdetail/', - method: 'get', - params: query - }) -} - -export function createUserDetail(data) { - return request({ - url: '/employee/userdetail/', - method: 'post', - data - }) -} - -export function updateUserDetail(id, data) { - return request({ - url: `/employee/userdetail/${id}/`, - method: 'put', - data - }) -} - -export function deleteUserDetail(id) { - return request({ - url: `/employee/userdetail/${id}/`, - method: 'delete' - }) -} \ No newline at end of file diff --git a/client/src/router/index.js b/client/src/router/index.js index 1842f63..f10f0fc 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.js @@ -61,6 +61,34 @@ export const constantRoutes = [ * the routes that need to be dynamically loaded based on user perms */ export const asyncRoutes = [ + { + path: '/employee', + component: Layout, + redirect: '/employee/', + name: 'EmployeeManage', + meta: { title: '人员管理', icon: 'example'}, + children: [ + { + path: 'employee', + name: 'Employee', + component: () => import('@/views/employee/employee'), + meta: { title: '人员信息', icon: 'example', perms: ['employee_manage'] } + }, + { + path: 'employee/update', + name: 'EmployeeUpdate', + component: () => import('@/views/employee/employeeupdate'), + meta: { title: '人员信息变更', icon: 'example', perms: ['employee_update'] }, + hidden: true + }, + { + path: 'qualification', + name: 'Qualification', + component: () => import('@/views/employee/qualification'), + meta: { title: '注册资格', icon: 'example', perms: ['qualification_manage'] } + }, + ] + }, { path: '/certset', component: Layout, @@ -96,27 +124,6 @@ export const asyncRoutes = [ } ] }, - { - path: '/employee', - component: Layout, - redirect: '/employee/userdetail', - name: 'Employee', - meta: { title: '人员管理', icon: 'example'}, - children: [ - { - path: 'userdetail', - name: 'UserDetail', - component: () => import('@/views/employee/userdetail'), - meta: { title: '人员信息', icon: 'example', perms: ['userdetail_manage'] } - }, - { - path: 'qualification', - name: 'Qualification', - component: () => import('@/views/employee/qualification'), - meta: { title: '注册资格', icon: 'example', perms: ['qualification_manage'] } - }, - ] - }, { path: '/system', component: Layout, @@ -193,7 +200,7 @@ export const asyncRoutes = [ component: Layout, children: [ { - path: 'https://jakhuang.github.io/form-generator/', + path: 'http://121.36.23.77:8037/', meta: { title: '表单设计器', icon: 'link', perms: ['dev_form_gen'] } } ] diff --git a/client/src/views/employee/userdetail.vue b/client/src/views/employee/employee.vue similarity index 79% rename from client/src/views/employee/userdetail.vue rename to client/src/views/employee/employee.vue index 95b1821..fb176f6 100644 --- a/client/src/views/employee/userdetail.vue +++ b/client/src/views/employee/employee.vue @@ -55,19 +55,19 @@ + + + - + - - + + - - + + - - - - + @@ -77,13 +77,13 @@ 编辑 删除 @@ -100,7 +100,7 @@ \ No newline at end of file diff --git a/server/apps/employee/migrations/0002_userdetail_photo.py b/server/apps/employee/migrations/0002_userdetail_photo.py new file mode 100644 index 0000000..ea86779 --- /dev/null +++ b/server/apps/employee/migrations/0002_userdetail_photo.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-07-10 02:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('employee', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='userdetail', + name='photo', + field=models.CharField(blank=True, default='', max_length=1000, null=True, verbose_name='证件照'), + ), + ] diff --git a/server/apps/employee/migrations/0003_auto_20200710_1139.py b/server/apps/employee/migrations/0003_auto_20200710_1139.py new file mode 100644 index 0000000..55ba2b2 --- /dev/null +++ b/server/apps/employee/migrations/0003_auto_20200710_1139.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-07-10 03:39 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('employee', '0002_userdetail_photo'), + ] + + operations = [ + migrations.RenameField( + model_name='userdetail', + old_name='gengder', + new_name='gender', + ), + ] diff --git a/server/apps/employee/migrations/0004_auto_20200710_1535.py b/server/apps/employee/migrations/0004_auto_20200710_1535.py new file mode 100644 index 0000000..6dded88 --- /dev/null +++ b/server/apps/employee/migrations/0004_auto_20200710_1535.py @@ -0,0 +1,84 @@ +# Generated by Django 3.0.7 on 2020-07-10 07:35 + +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 = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('system', '0022_auto_20200710_1535'), + ('employee', '0003_auto_20200710_1139'), + ] + + operations = [ + migrations.CreateModel( + name='Employee', + 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='删除标记')), + ('code', models.CharField(blank=True, max_length=30, null=True, verbose_name='编号')), + ('photo', models.CharField(blank=True, default='', max_length=1000, null=True, verbose_name='证件照')), + ('remember_code', models.CharField(blank=True, max_length=30, null=True, verbose_name='易记码')), + ('gender', models.CharField(choices=[('男', '男'), ('女', '女')], default='男', max_length=50, verbose_name='性别')), + ('landline', models.CharField(blank=True, max_length=100, null=True, verbose_name='座机')), + ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='邮箱')), + ('birth', models.DateField(blank=True, null=True, verbose_name='出生日期')), + ('ID_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='身份证号')), + ('is_onjob', models.BooleanField(default=True, verbose_name='是否在职')), + ('is_fulltime', models.BooleanField(default=True, verbose_name='是否专职')), + ('is_payinsurance', models.BooleanField(default=True, verbose_name='是否缴纳保险')), + ('finance_number', models.CharField(blank=True, max_length=30, null=True, verbose_name='财务编号')), + ('address', models.TextField(blank=True, null=True, verbose_name='详细地址')), + ('signature', models.CharField(blank=True, max_length=200, null=True, verbose_name='签名图片')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('fee_level', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='userdetail_fee_level', to='system.Dict', verbose_name='劳务费级别')), + ('pro_title', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='userdetail_pro_title', to='system.Dict', verbose_name='职称')), + ('region', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='userdetail_region', to='system.Dict', verbose_name='省市区')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': '人员详细信息', + 'verbose_name_plural': '人员详细信息', + }, + ), + migrations.DeleteModel( + name='UserDetail', + ), + migrations.AlterField( + model_name='ability', + name='employee', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ability_employee', to='employee.Employee'), + ), + migrations.AlterField( + model_name='education', + name='employee', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='education_employee', to='employee.Employee'), + ), + migrations.AlterField( + model_name='historicalability', + name='employee', + field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.Employee'), + ), + migrations.AlterField( + model_name='historicalqualification', + name='employee', + field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='employee.Employee'), + ), + migrations.AlterField( + model_name='qualification', + name='employee', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='qualification_employee', to='employee.Employee'), + ), + migrations.AlterField( + model_name='train', + name='employees', + field=models.ManyToManyField(related_name='train_employees', to='employee.Employee', verbose_name='参加人员'), + ), + ] diff --git a/server/apps/employee/models.py b/server/apps/employee/models.py index c3fdfe7..e5b64a7 100644 --- a/server/apps/employee/models.py +++ b/server/apps/employee/models.py @@ -6,7 +6,7 @@ from simple_history.models import HistoricalRecords # Create your models here. -class UserDetail(CommonAModel): +class Employee(CommonAModel): """ 详细信息表 """ @@ -14,11 +14,13 @@ class UserDetail(CommonAModel): ('男', '男'), ('女', '女'), ) - employee = models.OneToOneField(User, on_delete=models.CASCADE) + user = models.OneToOneField(User, on_delete=models.CASCADE) code = models.CharField('编号', max_length=30, null=True, blank=True) + photo = models.CharField( + '证件照', default='', max_length=1000, null=True, blank=True) remember_code = models.CharField( '易记码', max_length=30, null=True, blank=True) - gengder = models.CharField('性别', max_length=50, + gender = models.CharField('性别', max_length=50, choices=gender_choices, default='男') landline = models.CharField('座机', max_length=100, null=True, blank=True) email = models.EmailField('邮箱', null=True, blank=True) @@ -50,7 +52,7 @@ class Qualification(CommonAModel): """ 注册资格表 """ - employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='qualification_employee') + employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='qualification_employee') cert_field = models.ForeignKey( Dict, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='认证领域', related_name='qualification_cert_field') cert_number = models.CharField('证书号', max_length=200, unique=True) @@ -79,7 +81,7 @@ class Ability(CommonAModel): """ 能力表 """ - employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='ability_employee') + employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='ability_employee') qualification = models.ForeignKey( Qualification, on_delete=models.SET_NULL, null=True, blank=True, related_name='ability_qualification') cert_field = models.ForeignKey( @@ -114,7 +116,7 @@ class Education(CommonAModel): """ 教育经历表 """ - employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='education_employee') + employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='education_employee') admission_date = models.DateField('入学时间') graduation_date = models.DateField('毕业时间') school = models.CharField('毕业院校', max_length=200) @@ -143,7 +145,7 @@ class Train(CommonAModel): teacher = models.CharField('主讲人', max_length=200) content = models.TextField('培训内容') remark = models.TextField('备注') - employees = models.ManyToManyField(User, verbose_name='参加人员', related_name='train_employees') + employees = models.ManyToManyField(Employee, verbose_name='参加人员', related_name='train_employees') class Meta: verbose_name = '培训记录' diff --git a/server/apps/employee/serializers.py b/server/apps/employee/serializers.py index cc0c0fe..2cb872a 100644 --- a/server/apps/employee/serializers.py +++ b/server/apps/employee/serializers.py @@ -2,17 +2,24 @@ from rest_framework import serializers from .models import * -from apps.system.serializers import DictSerializer +from apps.system.serializers import DictSerializer, UserListSerializer -class UserDetailSerializer(serializers.ModelSerializer): +class EmployeeSerializer(serializers.ModelSerializer): """ 普通序列化 """ + user = UserListSerializer() class Meta: - model = UserDetail + model = Employee fields = '__all__' + @staticmethod + def setup_eager_loading(queryset): + """ Perform necessary eager loading of data. """ + queryset = queryset.select_related('user') + return queryset + class QualificationSerializer(serializers.ModelSerializer): """ 普通序列化 diff --git a/server/apps/employee/urls.py b/server/apps/employee/urls.py index 085f728..b34b8ae 100644 --- a/server/apps/employee/urls.py +++ b/server/apps/employee/urls.py @@ -3,7 +3,7 @@ from .views import * from rest_framework import routers router = routers.DefaultRouter() -router.register('userdetail', UserDetailViewSet, basename="userdetail") +router.register('employee', EmployeeViewSet, basename="employee") router.register('qualification', QualificationViewSet, basename="qualification") router.register('ability', AbilityViewSet, basename="ability") router.register('education', EducationViewSet, basename="education") diff --git a/server/apps/employee/views.py b/server/apps/employee/views.py index 204a6f5..625942a 100644 --- a/server/apps/employee/views.py +++ b/server/apps/employee/views.py @@ -5,14 +5,14 @@ from .serializers import * from apps.system.permission_data import RbacFilterSet from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin # Create your views here. -class UserDetailViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet): +class EmployeeViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelViewSet): """ 详细信息-增删改查 """ - perms_map = {'get': '*', 'post': 'userdetail_create', - 'put': 'userdetail_update', 'delete': 'userdetail_delete'} - queryset = UserDetail.objects.all() - serializer_class = UserDetailSerializer + perms_map = {'get': '*', + 'put': 'employee_update', 'delete': 'employee_delete'} + queryset = Employee.objects.all() + serializer_class = EmployeeSerializer search_fields = ['code', 'remember_code', 'user__name'] filterset_fields = ['is_onjob', 'is_fulltime'] ordering = ['-create_time'] diff --git a/server/apps/system/migrations/0022_auto_20200710_1535.py b/server/apps/system/migrations/0022_auto_20200710_1535.py new file mode 100644 index 0000000..00f1e20 --- /dev/null +++ b/server/apps/system/migrations/0022_auto_20200710_1535.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-07-10 07:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('system', '0021_auto_20200616_1722'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='phone', + field=models.CharField(blank=True, max_length=11, null=True, unique=True, verbose_name='手机号'), + ), + ] diff --git a/server/apps/system/models.py b/server/apps/system/models.py index 00c286e..f400616 100644 --- a/server/apps/system/models.py +++ b/server/apps/system/models.py @@ -107,7 +107,7 @@ class User(AbstractUser): 用户 """ name = models.CharField('姓名', max_length=20, null=True, blank=True) - phone = models.CharField('手机号码', max_length=11, + phone = models.CharField('手机号', max_length=11, null=True, blank=True, unique=True) avatar = models.CharField( '头像', default='/media/default/avatar.png', max_length=1000, null=True, blank=True) diff --git a/server/apps/system/views.py b/server/apps/system/views.py index 767f928..88812b4 100644 --- a/server/apps/system/views.py +++ b/server/apps/system/views.py @@ -36,7 +36,7 @@ from .serializers import (DictSerializer, DictTypeSerializer, FileSerializer, logger = logging.getLogger('log') # logger.info('请求成功! response_code:{};response_headers:{};response_body:{}'.format(response_code, response_headers, response_body[:251])) -# logger.error('请求出错:{}'.format(error)) +# logger.error('请求出错-{}'.format(error)) class LogoutView(APIView): @@ -56,7 +56,7 @@ class TaskViewSet(ModelViewSet): class DictTypeViewSet(ModelViewSet): """ - 数据字典类型:增删改查 + 数据字典类型-增删改查 """ perms_map = {'get': '*', 'post': 'dicttype_create', 'put': 'dicttype_update', 'delete': 'dicttype_delete'} @@ -70,7 +70,7 @@ class DictTypeViewSet(ModelViewSet): class DictViewSet(ModelViewSet): """ - 数据字典:增删改查 + 数据字典-增删改查 """ perms_map = {'get': '*', 'post': 'dict_create', 'put': 'dict_update', 'delete': 'dict_delete'} @@ -95,7 +95,7 @@ class DictViewSet(ModelViewSet): class PositionViewSet(ModelViewSet): """ - 岗位:增删改查 + 岗位-增删改查 """ perms_map = {'get': '*', 'post': 'position_create', 'put': 'position_update', 'delete': 'position_delete'} @@ -114,7 +114,7 @@ class TestView(APIView): class PermissionViewSet(ModelViewSet): """ - 权限:增删改查 + 权限-增删改查 """ perms_map = {'get': '*', 'post': 'perm_create', 'put': 'perm_update', 'delete': 'perm_delete'} @@ -128,7 +128,7 @@ class PermissionViewSet(ModelViewSet): class OrganizationViewSet(ModelViewSet): """ - 组织机构:增删改查 + 组织机构-增删改查 """ perms_map = {'get': '*', 'post': 'org_create', 'put': 'org_update', 'delete': 'org_delete'} @@ -142,7 +142,7 @@ class OrganizationViewSet(ModelViewSet): class RoleViewSet(ModelViewSet): """ - 角色:增删改查 + 角色-增删改查 """ perms_map = {'get': '*', 'post': 'role_create', 'put': 'role_update', 'delete': 'role_delete'} @@ -156,7 +156,7 @@ class RoleViewSet(ModelViewSet): class UserViewSet(ModelViewSet): """ - 用户管理:增删改查 + 用户管理-增删改查 """ perms_map = {'get': '*', 'post': 'user_create', 'put': 'user_update', 'delete': 'user_delete'} @@ -193,7 +193,9 @@ class UserViewSet(ModelViewSet): password = make_password('0000') serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) - serializer.save(password=password) + instance = serializer.save(password=password) + from apps.employee.models import Employee + Employee.objects.create(user=instance,create_by=request.user) return Response(serializer.data) @action(methods=['put'], detail=False, permission_classes=[IsAuthenticated], # perms_map={'put':'change_password'} @@ -237,7 +239,7 @@ class UserViewSet(ModelViewSet): class FileViewSet(CreateUpdateModelAMixin, ModelViewSet): """ - 文件:增删改查 + 文件-增删改查 """ perms_map = None parser_classes = [MultiPartParser, JSONParser]