访客接口v1

This commit is contained in:
曹前明 2022-06-29 09:48:27 +08:00
parent b5415917a5
commit fe52b60bad
11 changed files with 179 additions and 8 deletions

View File

@ -1,3 +1,4 @@
from atexit import register
from django.urls import path from django.urls import path
from rest_framework_simplejwt.views import (TokenObtainPairView, from rest_framework_simplejwt.views import (TokenObtainPairView,
TokenRefreshView) TokenRefreshView)
@ -10,5 +11,5 @@ urlpatterns = [
path(API_BASE_URL + 'token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path(API_BASE_URL + 'token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path(API_BASE_URL + 'token/black/', TokenBlackView.as_view(), name='token_black'), path(API_BASE_URL + 'token/black/', TokenBlackView.as_view(), name='token_black'),
path(API_BASE_URL + 'login/', LoginView.as_view(), name='session_login'), path(API_BASE_URL + 'login/', LoginView.as_view(), name='session_login'),
path(API_BASE_URL + 'logout/', LogoutView.as_view(), name='session_logout') path(API_BASE_URL + 'logout/', LogoutView.as_view(), name='session_logout'),
] ]

View File

@ -7,9 +7,12 @@ from django.contrib.auth import authenticate, login, logout
from rest_framework.generics import CreateAPIView from rest_framework.generics import CreateAPIView
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from apps.auth1.errors import USERNAME_OR_PASSWORD_WRONG from apps.auth1.errors import USERNAME_OR_PASSWORD_WRONG
from rest_framework.exceptions import ParseError
from apps.auth1.serializers import LoginSerializer from apps.auth1.serializers import LoginSerializer
from apps.system.models import User
# Create your views here. # Create your views here.
@ -46,7 +49,7 @@ class LoginView(CreateAPIView):
password=vdata.get('password')) password=vdata.get('password'))
if user is not None: if user is not None:
login(request, user) login(request, user)
return Response() return Response(status=201)
raise ParseError(**USERNAME_OR_PASSWORD_WRONG) raise ParseError(**USERNAME_OR_PASSWORD_WRONG)

View File

@ -39,8 +39,11 @@ class NotifySetting(CommonAModel):
(40, '属地部门以上') (40, '属地部门以上')
) )
event_cate = models.ForeignKey(EventCate, verbose_name='关联事件种类', on_delete=models.CASCADE) event_cate = models.ForeignKey(EventCate, verbose_name='关联事件种类', on_delete=models.CASCADE)
obj_cate = models.CharField('提醒对象', max_length=20, help_text='post岗位/user用户/var变量')
post = models.ForeignKey(Post, verbose_name='提醒岗位', post = models.ForeignKey(Post, verbose_name='提醒岗位',
on_delete=models.CASCADE, null=True, blank=True) on_delete=models.CASCADE, null=True, blank=True)
user = models.ForeignKey(User, verbose_name='提醒用户',
on_delete=models.CASCADE, null=True, blank=True)
filter_recipient = models.PositiveSmallIntegerField('提醒人员过滤', null=True, blank=True) filter_recipient = models.PositiveSmallIntegerField('提醒人员过滤', null=True, blank=True)
filter_area_level = models.PositiveSmallIntegerField('区域级别过滤', null=True, blank=True) filter_area_level = models.PositiveSmallIntegerField('区域级别过滤', null=True, blank=True)
sms_enable = models.BooleanField('短信通知', default=False) sms_enable = models.BooleanField('短信通知', default=False)

View File

@ -427,6 +427,7 @@ class UserViewSet(CustomModelViewSet):
data = { data = {
'id': user.id, 'id': user.id,
'username': user.username, 'username': user.username,
'type': user.type,
'name': user.name, 'name': user.name,
'posts': user.posts.values_list('name', flat=True), 'posts': user.posts.values_list('name', flat=True),
'avatar': user.avatar, 'avatar': user.avatar,

View File

@ -0,0 +1,80 @@
# Generated by Django 3.2.12 on 2022-06-29 01:46
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('hrm', '0002_auto_20220617_1124'),
('system', '0005_auto_20220627_0836'),
]
operations = [
migrations.CreateModel(
name='Visit',
fields=[
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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='删除标记')),
('purpose', models.PositiveSmallIntegerField(choices=[(10, '参观'), (20, '拜访'), (30, '面试'), (40, '开会')], verbose_name='来访事由')),
('level', models.PositiveSmallIntegerField(choices=[(10, '一般'), (20, '重要')], verbose_name='访问级别')),
('company', models.CharField(blank=True, max_length=100, null=True, verbose_name='来访单位')),
('state', models.PositiveSmallIntegerField(choices=[(10, '创建中'), (20, '审批中'), (30, '待入厂'), (40, '进行中'), (50, '已完成')], default=10)),
('name', models.CharField(max_length=50, verbose_name='来访概述')),
('description', models.TextField(blank=True, null=True, verbose_name='来访详述')),
('visit_time', models.DateTimeField(verbose_name='来访时间')),
('leave_time', models.DateTimeField(verbose_name='离开时间')),
('count_people', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='来访人数')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='visit_belong_dept', to='system.dept', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='visit_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('receptionist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, 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='visit_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Visitor',
fields=[
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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='姓名')),
('phone', models.CharField(max_length=11, verbose_name='手机号')),
('photo', models.CharField(max_length=1000, verbose_name='证件照')),
('id_number', 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='visitor_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('employee', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='hrm.employee', verbose_name='成员信息')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='visitor_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
('visit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='vm.visit', verbose_name='最近所属访问项目')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Vpeople',
fields=[
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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='删除标记')),
('is_main', models.BooleanField(default=False, verbose_name='是否主访人')),
('visit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vm.visit', verbose_name='关联访问项目')),
('visitor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vm.visitor', verbose_name='访客')),
],
options={
'abstract': False,
},
),
]

View File

View File

@ -9,7 +9,7 @@ class Visit(CommonBModel):
""" """
访问项目 访问项目
""" """
VISIT_PURPOSE_CHOICES = ( V_PURPOSE_CHOICES = (
(10, '参观'), (10, '参观'),
(20, '拜访'), (20, '拜访'),
(30, '面试'), (30, '面试'),
@ -27,13 +27,21 @@ class Visit(CommonBModel):
(40, '进行中'), (40, '进行中'),
(50, '已完成') (50, '已完成')
) )
purpose = models.PositiveSmallIntegerField('来访事由') V_LEVEL_CHOICES = (
(10, '一般'),
(20, '重要')
)
purpose = models.PositiveSmallIntegerField('来访事由', choices=V_PURPOSE_CHOICES)
level = models.PositiveSmallIntegerField('访问级别', choices=V_LEVEL_CHOICES)
company = models.CharField('来访单位', max_length=100, null=True, blank=True)
state = models.PositiveSmallIntegerField(choices=V_STATE_CHOICES, default=10) state = models.PositiveSmallIntegerField(choices=V_STATE_CHOICES, default=10)
name = models.CharField('来访概述', max_length=50) name = models.CharField('来访概述', max_length=50)
description = models.TextField('来访详述', null=True, blank=True) description = models.TextField('来访详述', null=True, blank=True)
visit_time = models.DateTimeField('来访时间') visit_time = models.DateTimeField('来访时间')
leave_time = models.DateTimeField('离开时间') leave_time = models.DateTimeField('离开时间')
count_people = models.PositiveSmallIntegerField('来访人数', null=True, blank=True)
receptionist = models.ForeignKey(User, verbose_name='接待人', on_delete=models.CASCADE) receptionist = models.ForeignKey(User, verbose_name='接待人', on_delete=models.CASCADE)
# create_by 创建人
class Visitor(CommonAModel): class Visitor(CommonAModel):

View File

@ -9,7 +9,7 @@ from rest_framework import serializers
class VisitCreateUpdateSerializer(CustomModelSerializer): class VisitCreateUpdateSerializer(CustomModelSerializer):
class Meta: class Meta:
model = Visit model = Visit
fields = ['purpose', 'name', 'description', 'visit_time', 'leave_time', 'receptionist'] fields = ['purpose', 'name', 'description', 'visit_time', 'leave_time', 'receptionist', 'company']
class VisitSerializer(CustomModelSerializer): class VisitSerializer(CustomModelSerializer):
@ -23,7 +23,7 @@ class VisitorCreateSerializer(CustomModelSerializer):
class Meta: class Meta:
model = Visitor model = Visitor
exclude = ['name', 'phone', 'photo', 'id_number'] fields = ['name', 'phone', 'photo', 'id_number']
class VisitorSerializer(CustomModelSerializer): class VisitorSerializer(CustomModelSerializer):
@ -48,3 +48,8 @@ class VpeopleSerializer(CustomModelSerializer):
class Meta: class Meta:
model = Vpeople model = Vpeople
fields = '__all__' fields = '__all__'
class VisitorRegisterSerializer(serializers.Serializer):
name = serializers.CharField(label="姓名")
username = serializers.CharField(label='用户名', min_length=6)

15
apps/vm/urls.py Normal file
View File

@ -0,0 +1,15 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.vm.views import VisitViewSet, VisitorViewSet, VpeopleViewSet
API_BASE_URL = 'api/vm/'
HTML_BASE_URL = 'vm/'
router = DefaultRouter()
router.register('visit', VisitViewSet, basename='visit')
router.register('visitor', VisitorViewSet, basename='visitor')
router.register('vpeople', VpeopleViewSet, basename='vpeople')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
]

View File

@ -1,12 +1,17 @@
from django.shortcuts import render from django.shortcuts import render
from apps.hrm.models import Employee
from apps.system.models import User
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet, GenericViewSet from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet, GenericViewSet
from apps.vm.models import Visit, Visitor, Vpeople from apps.vm.models import Visit, Visitor, Vpeople
from apps.vm.serializers import VisitCreateUpdateSerializer, VisitSerializer, VisitorCreateSerializer, VisitorSerializer, VpeopleCreateSerializer, VpeopleSerializer from apps.vm.serializers import VisitCreateUpdateSerializer, VisitSerializer, VisitorCreateSerializer, VisitorRegisterSerializer, VisitorSerializer, VpeopleCreateSerializer, VpeopleSerializer
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin
from apps.utils.mixins import CustomDestoryModelMixin from apps.utils.mixins import CustomDestoryModelMixin
from django.contrib.auth.hashers import make_password
from rest_framework.permissions import IsAuthenticated
from django.db import transaction
# Create your views here. # Create your views here.
@ -23,6 +28,12 @@ class VisitViewSet(CustomModelViewSet):
queryset = queryset.filter(create_by=user) queryset = queryset.filter(create_by=user)
return queryset return queryset
def create(self, request, *args, **kwargs):
user = self.request.user
if user.type == 'visitor' and not user.employee:
raise ParseError('请先完善个人信息')
return super().create(request, *args, **kwargs)
def update(self, request, *args, **kwargs): def update(self, request, *args, **kwargs):
obj = self.get_object() obj = self.get_object()
if obj.state != Visit.V_CREATE: if obj.state != Visit.V_CREATE:
@ -42,8 +53,51 @@ class VisitorViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Custo
create_serializer_class = VisitorCreateSerializer create_serializer_class = VisitorCreateSerializer
serializer_class = VisitorSerializer serializer_class = VisitorSerializer
@action(methods=['post'], detail=False,
authentication_classes=[], permission_classes=[],
serializer_class=VisitorRegisterSerializer)
def register(self, request, *args, **kwargs):
"""访客账户注册
class VpeopleView(ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet): 访客账户注册
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
user = User.objects.get_queryset(all=True).filter(username=vdata['username']).first()
if user:
raise ParseError('账号已存在或禁用不可注册')
else:
password = make_password('0000')
user = User.objects.create(name=vdata['name'],
username=vdata['username'],
type='visitor',
password=password)
return Response({'user': user.id}, status=201)
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated],
serializer_class=VisitorCreateSerializer)
@transaction.atomic
def improve_info(self, request, *args, **kwargs):
"""完善个人信息
完善个人信息
"""
user = self.request.user
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
epdata = vdata
epdata['type'] = 'visitor'
epdata['user'] = user
ep = Employee(**epdata)
ep.save()
vdata['employee'] = ep
Visitor(**vdata).save()
return Response()
class VpeopleViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet):
perms_map = {'get': '*', 'post': 'visit:update', 'put': 'visit:update', 'delete': 'visit:update'} perms_map = {'get': '*', 'post': 'visit:update', 'put': 'visit:update', 'delete': 'visit:update'}
queryset = Vpeople.objects.all() queryset = Vpeople.objects.all()
create_serializer_class = VpeopleCreateSerializer create_serializer_class = VpeopleCreateSerializer

View File

@ -54,6 +54,7 @@ urlpatterns = [
path('', include('apps.ecm.urls')), path('', include('apps.ecm.urls')),
path('', include('apps.rpm.urls')), path('', include('apps.rpm.urls')),
path('', include('apps.opm.urls')), path('', include('apps.opm.urls')),
path('', include('apps.vm.urls')),