增加相关中间表的操作

This commit is contained in:
caoqianming 2021-04-30 09:46:03 +08:00
parent 27591e5fd3
commit fc1199bb31
16 changed files with 228 additions and 80 deletions

View File

@ -13,13 +13,25 @@
/** /**
* h5app-plus(nvue下也为app-plus)mp-weixinmp-alipay...... * h5app-plus(nvue下也为app-plus)mp-weixinmp-alipay......
*/ */
this.$u.api.getUserInfo().then(res=>{ var that=this
this.$u.vuex('vuex_user', res.data) // 小程序自动登录
}).catch(e=>{ uni.login({
uni.reLaunch({ provider: 'weixin',
success: function (loginRes) {
that.$u.api.wxmplogin({code:loginRes.code}).then(res=>{
that.$u.vuex('vuex_token', res.data.access)
}).catch(e=>{uni.reLaunch({
url:'/pages/login/login' url:'/pages/login/login'
}) })})
}) }
});
// this.$u.api.getUserInfo().then(res=>{
// this.$u.vuex('vuex_user', res.data)
// }).catch(e=>{
// uni.reLaunch({
// url:'/pages/login/login'
// })
// })
}, },
} }
</script> </script>

View File

@ -19,6 +19,10 @@ const install = (Vue, vm) => {
let login = (params = {}) => vm.$u.post('/token/', params); //账户密码登录 let login = (params = {}) => vm.$u.post('/token/', params); //账户密码登录
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下 // 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
let wxmplogin = (params = {}) => vm.$u.post('/wxmplogin/', params); //微信登录
let bindmp = (params = {}) => vm.$u.post('/system/user/bindwxmp/', params); //微信绑定
let getMyInspectTaskList = (params = {}) => vm.$u.get('/quality/subinspecttask/self/', params); let getMyInspectTaskList = (params = {}) => vm.$u.get('/quality/subinspecttask/self/', params);
let getSubinspectTask = (id, params)=> vm.$u.get(`/quality/subinspecttask/${id}/`, params); let getSubinspectTask = (id, params)=> vm.$u.get(`/quality/subinspecttask/${id}/`, params);
@ -43,6 +47,8 @@ const install = (Vue, vm) => {
getCode, getCode,
codeLogin, codeLogin,
login, login,
wxmplogin,
bindmp,
getMyInspectTaskList, getMyInspectTaskList,
getSubinspectTask, getSubinspectTask,
getSubtaskDepts, getSubtaskDepts,

View File

@ -13,7 +13,7 @@
<view style="margin-bottom: 12rpx;"> <view style="margin-bottom: 12rpx;">
<u-grid :col="3" :border="false"> <u-grid :col="3" :border="false">
<u-grid-item v-for="(item, index) in grids" v-bind:key="index" @click="clickGrid(item)"> <u-grid-item v-for="(item, index) in grids" v-bind:key="index" @click="clickGrid(item)">
<u-icon :name="item.icon" :size="60" color="#2b85e4" size="72"></u-icon> <u-icon :name="item.icon" color="#2b85e4" size="80"></u-icon>
<view class="grid-text">{{item.name}}</view> <view class="grid-text">{{item.name}}</view>
</u-grid-item> </u-grid-item>
</u-grid> </u-grid>
@ -116,9 +116,9 @@
}).then(res => { }).then(res => {
this.myinspecttaskList = res.data this.myinspecttaskList = res.data
}).catch(e => { }).catch(e => {
uni.reLaunch({ // uni.reLaunch({
url:'/pages/login/login' // url:'/pages/login/login'
}) // })
}) })
}, },
openPage(path) { openPage(path) {

View File

@ -48,7 +48,7 @@
</u-card> --> </u-card> -->
<view v-show="currentIndex==0" style="text-align: right;"> <view v-show="currentIndex==0" style="text-align: right;">
<u-checkbox v-model="mutiSelect" @change="mutiSelectChange">多选</u-checkbox> <u-checkbox v-model="mutiSelect" @change="mutiSelectChange" v-if="initData.leader==vuex_user.id">多选</u-checkbox>
<u-button type="primary" size="mini" style="margin-left:6rpx" @click="membersShow" <u-button type="primary" size="mini" style="margin-left:6rpx" @click="membersShow"
v-if="initData.leader==vuex_user.id && mutiSelect">指派给</u-button> v-if="initData.leader==vuex_user.id && mutiSelect">指派给</u-button>
</view> </view>

View File

@ -111,7 +111,7 @@
// console.log(sData.imgs) // console.log(sData.imgs)
this.$u.api.checkInspectRecord(sData.id, sData).then(res => { this.$u.api.checkInspectRecord(sData.id, sData).then(res => {
this.$u.toast('提交成功');
uni.navigateBack({ uni.navigateBack({
}) })

View File

@ -1,9 +1,8 @@
<template> <template>
<view class="wrap"> <view class="wrap">
<view class="top"></view> <view class="top"></view>
<u-image :src="imageURL" mode="widthFix"></u-image>
<view class="content"> <view class="content">
<view style="text-align: center;font-weight: 500;font-size: 40rpx;">国检集团</view>
<view class="title">能力共享和质量监督平台</view>
<u-form :model="loginForm" :rules="rules" ref="uForm" :errorType="errorType"> <u-form :model="loginForm" :rules="rules" ref="uForm" :errorType="errorType">
<u-form-item label="邮箱号" prop="mail" label-width="150"> <u-form-item label="邮箱号" prop="mail" label-width="150">
<u-input placeholder="请输入邮箱号" v-model="loginForm.mail" type="text"> <u-input placeholder="请输入邮箱号" v-model="loginForm.mail" type="text">
@ -17,7 +16,7 @@
<!-- <button :style="[inputStyle]" class="getCaptcha">登录</button> --> <!-- <button :style="[inputStyle]" class="getCaptcha">登录</button> -->
<!-- <u-gap height="0.5" bg-color="#bbb"></u-gap> --> <!-- <u-gap height="0.5" bg-color="#bbb"></u-gap> -->
<view style="margin-top: 16rpx;"> <view style="margin-top: 16rpx;">
<u-button @click="submit" type="primary" >登录</u-button> <u-button @click="submit" type="warning" >登录</u-button>
</view> </view>
<view class="alternative"> <view class="alternative">
<navigator url="login_password" class="password" open-type="redirect">密码登录</navigator> <navigator url="login_password" class="password" open-type="redirect">密码登录</navigator>
@ -43,6 +42,7 @@
export default { export default {
data() { data() {
return { return {
imageURL: 'http://testsearch.ctc.ac.cn:8000/media/default/banner3.jpg',
loginForm:{ loginForm:{
mail:"", mail:"",
msg:"" msg:""
@ -85,6 +85,7 @@ export default {
}, },
onReady() { onReady() {
this.$refs.uForm.setRules(this.rules); this.$refs.uForm.setRules(this.rules);
uni.hideHomeButton()
}, },
computed: { computed: {
inputStyle() { inputStyle() {

View File

@ -1,9 +1,10 @@
<template> <template>
<view class="wrap"> <view class="wrap">
<view class="top"></view> <view class="top"></view>
<u-image :src="imageURL" mode="widthFix"></u-image>
<view class="content"> <view class="content">
<view style="text-align: center;font-weight: 500;font-size: 40rpx;">国检集团</view> <!-- <view style="text-align: center;font-weight: 500;font-size: 40rpx;">国检集团</view>
<view class="title">能力共享和质量监督平台</view> <view class="title">能力共享和质量监督平台</view> -->
<u-form :model="loginForm" :rules="rules" ref="uForm" :errorType="errorType"> <u-form :model="loginForm" :rules="rules" ref="uForm" :errorType="errorType">
<u-form-item label="账户" prop="username" label-width="150"> <u-form-item label="账户" prop="username" label-width="150">
<u-input placeholder="请输入账户" v-model="loginForm.username" type="text"></u-input> <u-input placeholder="请输入账户" v-model="loginForm.username" type="text"></u-input>
@ -13,7 +14,7 @@
</u-form-item> </u-form-item>
</u-form> </u-form>
<view style="margin-top: 16rpx;"> <view style="margin-top: 16rpx;">
<u-button @click="submit" type="primary" >登录</u-button> <u-button @click="submit" type="warning" >登录</u-button>
</view> </view>
</view> </view>
</view> </view>
@ -23,6 +24,7 @@
export default { export default {
data() { data() {
return { return {
imageURL: 'http://testsearch.ctc.ac.cn:8000/media/default/banner3.jpg',
loginForm:{ loginForm:{
username:"", username:"",
password:"" password:""
@ -58,6 +60,7 @@ export default {
}, },
onReady() { onReady() {
this.$refs.uForm.setRules(this.rules); this.$refs.uForm.setRules(this.rules);
uni.hideHomeButton()
}, },
computed: { computed: {
inputStyle() { inputStyle() {

View File

@ -13,7 +13,8 @@
</view> </view>
<view class="u-flex-1"> <view class="u-flex-1">
<view class="u-font-18 u-p-b-20">{{vuex_user.name}}</view> <view class="u-font-18 u-p-b-20">{{vuex_user.name}}</view>
<view class="u-font-14 u-tips-color">{{vuex_user.username}}-{{vuex_user.dept_name}}</view> <view class="u-font-14 u-type-info">{{vuex_user.username}}-{{vuex_user.dept_name}}</view>
<view class="u-font-14 u-tips-color" v-if="vuex_user.wxmp_openid">已绑定微信</view>
</view> </view>
<!-- <view class="u-m-l-10 u-p-10"> <!-- <view class="u-m-l-10 u-p-10">
<u-icon name="scan" color="#969799" size="28"></u-icon> <u-icon name="scan" color="#969799" size="28"></u-icon>
@ -40,6 +41,7 @@
<view class="u-m-t-20"> <view class="u-m-t-20">
<u-cell-group> <u-cell-group>
<u-cell-item icon="weixin-fill" title="绑定微信" :arrow="false" @click="bindMP" v-if="!vuex_user.wxmp_openid"></u-cell-item>
<u-cell-item icon="close" title="退出" @click="Logout"></u-cell-item> <u-cell-item icon="close" title="退出" @click="Logout"></u-cell-item>
</u-cell-group> </u-cell-group>
</view> </view>
@ -63,6 +65,20 @@
uni.redirectTo({ uni.redirectTo({
url: '/pages/login/login' url: '/pages/login/login'
}); });
},
bindMP(){
uni.login({
provider: 'weixin',
success: (loginRes)=>{
this.$u.api.bindmp({code:loginRes.code}).then(res=>{
this.$u.toast('绑定成功');
this.$u.vuex('vuex_user.wxmp_openid', res.data.wxmp_openid)
uni.reLaunch({
url:'/pages/my/my'
})
}).catch(e=>{})
}
});
} }
} }
} }

View File

@ -34,12 +34,12 @@ const store = new Vuex.Store({
vuex_user: lifeData.vuex_user ? lifeData.vuex_user : {}, vuex_user: lifeData.vuex_user ? lifeData.vuex_user : {},
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '', vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',
// vuex_host: 'http://127.0.0.1:8000', // vuex_host: 'http://127.0.0.1:8000',
// vuex_api: 'http://127.0.0.1:8000/api', vuex_api: 'http://127.0.0.1:8000/api',
// vuex_apifile: 'http://127.0.0.1:8000/api/file/', vuex_apifile: 'http://127.0.0.1:8000/api/file/',
vuex_host: 'https://testsearch.ctc.ac.cn', vuex_host: 'https://testsearch.ctc.ac.cn',
vuex_api: 'https://testsearch.ctc.ac.cn/api', // vuex_api: 'https://testsearch.ctc.ac.cn/api',
vuex_apifile: 'https://testsearch.ctc.ac.cn/api/file/', // vuex_apifile: 'https://testsearch.ctc.ac.cn/api/file/',
// 如果vuex_version无需保存到本地永久存储无需lifeData.vuex_version方式 // 如果vuex_version无需保存到本地永久存储无需lifeData.vuex_version方式
// vuex_version: '1.0.1', // vuex_version: '1.0.1',

View File

@ -101,6 +101,17 @@ class InspectRecordDetailSerializer(serializers.ModelSerializer):
queryset = queryset.prefetch_related('imgs',) queryset = queryset.prefetch_related('imgs',)
return queryset return queryset
class InspectTeamSerializer(serializers.ModelSerializer):
member_ = UserSimpleSerializer(source='member', read_only=True)
class Meta:
model = InspectTeam
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('member')
return queryset
class InspectDeptSerializer(serializers.ModelSerializer): class InspectDeptSerializer(serializers.ModelSerializer):
dept__name = serializers.CharField(source='dept.name', read_only=True) dept__name = serializers.CharField(source='dept.name', read_only=True)
leader = serializers.SerializerMethodField() leader = serializers.SerializerMethodField()

View File

@ -7,7 +7,7 @@ from django.shortcuts import render
from django.utils import timezone from django.utils import timezone
from rest_framework import status from rest_framework import status
from rest_framework.decorators import action, permission_classes from rest_framework.decorators import action, permission_classes
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
@ -46,7 +46,7 @@ class InspectItemViewSet(PageOrNot, CreateUpdateCustomMixin, ModelViewSet):
ordering = ['sortnum', 'cate__sort', 'create_time'] ordering = ['sortnum', 'cate__sort', 'create_time']
class InspectTaskViewSet(CreateUpdateCustomMixin, ModelViewSet): class InspectTaskViewSet(OptimizationMixin, CreateUpdateCustomMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'inspecttask_create', perms_map = {'get': '*', 'post': 'inspecttask_create',
'put': 'inspecttask_update', 'delete': 'inspecttask_delete'} 'put': 'inspecttask_update', 'delete': 'inspecttask_delete'}
queryset = InspectTask.objects.all() queryset = InspectTask.objects.all()
@ -84,6 +84,8 @@ class SubtaskViewSet(PageOrNot, CreateUpdateCustomMixin, OptimizationMixin, Mode
def get_queryset(self): def get_queryset(self):
queryset = self.queryset queryset = self.queryset
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset)
if has_permission('inspecttask_create', self.request.user): if has_permission('inspecttask_create', self.request.user):
return queryset return queryset
else: else:
@ -111,6 +113,7 @@ class SubtaskViewSet(PageOrNot, CreateUpdateCustomMixin, OptimizationMixin, Mode
instance = self.get_object() instance = self.get_object()
if request.data.get('name', None): if request.data.get('name', None):
instance.name = request.data.get('name') instance.name = request.data.get('name')
instance.update_by = request.user
instance.save() instance.save()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@ -164,11 +167,10 @@ class SubtaskViewSet(PageOrNot, CreateUpdateCustomMixin, OptimizationMixin, Mode
records.append(InspectRecord(**r)) records.append(InspectRecord(**r))
for member in request.data['members']: for member in request.data['members']:
mmember = User.objects.get(pk=member) mmember = User.objects.get(pk=member)
if not InspectTeam.objects.filter(member=mmember, subtask=obj).exists(): data = {}
data = {} data['member'] = mmember
data['member'] = mmember data['subtask'] = obj
data['subtask'] = obj members.append(InspectTeam(**data))
members.append(InspectTeam(**data))
InspectTeam.objects.bulk_create(members) InspectTeam.objects.bulk_create(members)
InspectDept.objects.bulk_create(depts) InspectDept.objects.bulk_create(depts)
InspectRecord.objects.bulk_create(records) InspectRecord.objects.bulk_create(records)
@ -176,13 +178,31 @@ class SubtaskViewSet(PageOrNot, CreateUpdateCustomMixin, OptimizationMixin, Mode
return Response('组织和成员不能为空', status=status.HTTP_400_BAD_REQUEST) return Response('组织和成员不能为空', status=status.HTTP_400_BAD_REQUEST)
class InspectDeptViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
class InspectDeptViewSet(OptimizationMixin, ListModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet):
""" """
子任务对检查组织的提交 子任务涉及组织表
""" """
perms_map = {'get':'*'} perms_map = {'get':'*', 'put':'inspecttask_update', 'post':'inspecttask_update', 'delete':'inspecttask_update'}
queryset = InspectDept.objects.all() queryset = InspectDept.objects.all()
serializer_class = InspectDeptSerializer serializer_class = InspectDeptSerializer
filterset_fields = ['subtask']
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
obj = serializer.save(create_time=timezone.now())
records = []
if not InspectRecord.objects.filter(dept=obj.dept, subtask=obj.subtask).exists():
for i in InspectItem.objects.filter(is_deleted=False, template=obj.subtask.inspecttask.template):
r = {}
r['dept'] = obj.dpet
r['item'] = i
r['subtask'] = obj.subtask
r['create_by'] = request.user
records.append(InspectRecord(**r))
InspectRecord.objects.bulk_create(records)
return Response(status=status.HTTP_201_CREATED)
@action(methods=['put'], detail=True, perms_map = {'put':'inspectrecord_update'}, @action(methods=['put'], detail=True, perms_map = {'put':'inspectrecord_update'},
permission_classes=[IsAdminUser|IsSubInspectTaskLeader]) permission_classes=[IsAdminUser|IsSubInspectTaskLeader])
@ -205,24 +225,36 @@ class InspectDeptViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
组长对该组织检查结果提交 组长对该组织检查结果提交
""" """
obj = self.get_object() obj = self.get_object()
if InspectRecord.objects.filter(checked=False, subtask=obj.subtask, dept=obj.dept).exists(): if obj.state == '检查中':
return Response('存在未完成检查记录', status=status.HTTP_400_BAD_REQUEST) if InspectRecord.objects.filter(checked=False, subtask=obj.subtask, dept=obj.dept).exists():
return Response('存在未完成检查记录', status=status.HTTP_400_BAD_REQUEST)
else:
if 'note' in request.data and request.data['note']:
obj.note = request.data['note']
obj.state = '已提交'
obj.save()
# 更新主任务和子任务状态
if not InspectDept.objects.filter(subtask=obj.subtask).exclude(state='已提交').exists():
obj.subtask.state = '已完成'
obj.subtask.save()
if not SubInspectTask.objects.filter(inspecttask=obj.subtask.inspecttask).exclude(state='已完成').exists():
obj.subtask.inspecttask.state = '已完成'
obj.subtask.inspecttask.save()
return Response(InspectDeptSerializer(instance=obj).data, status=status.HTTP_200_OK)
else: else:
if 'note' in request.data and request.data['note']: return Response('检查状态错误', status=status.HTTP_400_BAD_REQUEST)
obj.note = request.data['note']
obj.state = '已提交'
obj.save()
# 更新主任务和子任务状态
if not InspectDept.objects.filter(subtask=obj.subtask).exclude(state='已提交').exists():
obj.subtask.state = '已完成'
obj.subtask.save()
if not SubInspectTask.objects.filter(inspecttask=obj.subtask.inspecttask).exclude(state='已完成').exists():
obj.subtask.inspecttask.state = '已完成'
obj.subtask.inspecttask.save()
return Response(InspectDeptSerializer(instance=obj).data, status=status.HTTP_200_OK)
class InspectRecordViewSet(PageOrNot, ModelViewSet): class InspectTeamViewSet(OptimizationMixin, ListModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet):
"""
子任务涉及组员表
"""
perms_map = {'get':'*', 'put':'inspecttask_update', 'post':'inspecttask_update', 'delete':'inspecttask_update'}
queryset = InspectTeam.objects.all()
serializer_class = InspectTeamSerializer
filterset_fields = ['subtask']
class InspectRecordViewSet(OptimizationMixin, PageOrNot, ModelViewSet):
perms_map = {'get': '*', 'post': 'inspectrecord_create', perms_map = {'get': '*', 'post': 'inspectrecord_create',
'put': 'inspectrecord_update', 'delete': 'inspectrecord_delete'} 'put': 'inspectrecord_update', 'delete': 'inspectrecord_delete'}
queryset = InspectRecord.objects.all() queryset = InspectRecord.objects.all()

View File

@ -0,0 +1,24 @@
# Generated by Django 3.0.5 on 2021-04-29 07:49
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0016_auto_20210331_1040'),
]
operations = [
migrations.CreateModel(
name='UserThird',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('type', models.CharField(choices=[('wx_mp', '微信小程序')], default='wx_mp', max_length=50, verbose_name='类型')),
('openid', models.CharField(blank=True, max_length=200, null=True, verbose_name='第三方账号')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='third_user', to=settings.AUTH_USER_MODEL, verbose_name='关联账户')),
],
),
]

View File

@ -217,3 +217,16 @@ class File(CommonAModel):
class Message(BaseModel): class Message(BaseModel):
mail = models.CharField('发送邮箱', max_length=200) mail = models.CharField('发送邮箱', max_length=200)
msg = models.CharField('验证码', max_length=200) msg = models.CharField('验证码', max_length=200)
class UserThird(models.Model):
"""
第三方账户
"""
type_choices = (
('wx_mp', '微信小程序'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='关联账户', related_name='third_user')
type = models.CharField('类型', max_length=50, choices=type_choices, default='wx_mp')
openid = models.CharField('第三方账号', null=True, blank=True, max_length=200)

View File

@ -1,9 +1,12 @@
import logging import logging
from django.conf import settings
from django.contrib.auth.hashers import check_password, make_password from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import UserManager from django.contrib.auth.models import UserManager
from django.core.cache import cache from django.core.cache import cache
from django.db.models import Count
from django.http import request from django.http import request
from django.http.response import JsonResponse
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status from rest_framework import status
from rest_framework.decorators import (action, authentication_classes, from rest_framework.decorators import (action, authentication_classes,
@ -13,18 +16,19 @@ from rest_framework.mixins import (CreateModelMixin, DestroyModelMixin,
ListModelMixin, RetrieveModelMixin, ListModelMixin, RetrieveModelMixin,
UpdateModelMixin) UpdateModelMixin)
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from rest_framework.parsers import (FileUploadParser, JSONParser,
MultiPartParser)
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
from utils.queryset import get_child_queryset2
from django.db.models import Count
from utils.pagination import PageOrNot from utils.pagination import PageOrNot
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 (Dict, DictType, File, Message, Organization, Permission,
Position, Role, User) Position, 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 (DictSerializer, DictTypeSerializer, FileSerializer,
@ -32,7 +36,9 @@ from .serializers import (DictSerializer, DictTypeSerializer, FileSerializer,
PositionSerializer, RoleSerializer, PositionSerializer, RoleSerializer,
UserCreateSerializer, UserListSerializer, UserCreateSerializer, UserListSerializer,
UserModifySerializer) UserModifySerializer)
import requests
import json
from rest_framework.exceptions import AuthenticationFailed
logger = logging.getLogger('log') logger = logging.getLogger('log')
# logger.info('请求成功! response_code:{}response_headers:{}response_body:{}'.format(response_code, response_headers, response_body[:251])) # logger.info('请求成功! response_code:{}response_headers:{}response_body:{}'.format(response_code, response_headers, response_body[:251]))
# logger.error('请求出错:{}'.format(error)) # logger.error('请求出错:{}'.format(error))
@ -308,9 +314,14 @@ class UserViewSet(PageOrNot, ModelViewSet):
'avatar': request._request._current_scheme_host + user.avatar, 'avatar': request._request._current_scheme_host + user.avatar,
'perms': perms, 'perms': perms,
} }
try:
user = UserThird.objects.get(user=user,type='wx_mp').user
data['wxmp_openid'] = user.openid
except:
pass
return Response(data) return Response(data)
@action(methods=['put'], detail=True, url_name='userpw_reset', perms_map={'put':'userpw_reset'}) @action(methods=['put'], detail=True, url_name='userpw_reset', permission_classes=[IsAuthenticated])
def resetpw(self, request, pk=None): def resetpw(self, request, pk=None):
""" """
重置密码 重置密码
@ -322,9 +333,43 @@ class UserViewSet(PageOrNot, ModelViewSet):
return Response('密码已重置为0000', status=status.HTTP_200_OK) return Response('密码已重置为0000', status=status.HTTP_200_OK)
return Response('权限不足', status=status.HTTP_400_BAD_REQUEST) return Response('权限不足', status=status.HTTP_400_BAD_REQUEST)
from django.conf import settings @action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
from rest_framework.parsers import (FileUploadParser, JSONParser, def bindwxmp(self, request, pk=None):
MultiPartParser) """
绑定微信
"""
code = request.data['code']
info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+settings.WX_APPID+'&secret='+settings.WX_APPSECRET+'&js_code=' +
code+'&grant_type=authorization_code').content.decode('utf-8')
info = json.loads(info)
openid = info['openid']
UserThird.objects.get_or_create(openid=openid, type='wx_mp', user=request.user, defaults={'openid':openid, 'user':request.user, 'type':'wx_mp'})
return Response({'wxmp_openid':openid},status=status.HTTP_200_OK)
class WXMPlogin(APIView):
authentication_classes=[]
permission_classes=[]
def post(self,request):
"""
微信登录
"""
code = request.data['code']
info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+settings.WX_APPID+'&secret='+settings.WX_APPSECRET+'&js_code=' +
code+'&grant_type=authorization_code').content.decode('utf-8')
info = json.loads(info)
openid = info['openid']
session_key = info['session_key']
try:
user = UserThird.objects.get(openid=openid,type='wx_mp').user
return Response(get_tokens_for_user(user), status=status.HTTP_200_OK)
except:
raise AuthenticationFailed
class FileViewSet(ModelViewSet): class FileViewSet(ModelViewSet):
@ -358,3 +403,5 @@ class FileViewSet(ModelViewSet):
instance.path = settings.MEDIA_URL + instance.file.name instance.path = settings.MEDIA_URL + instance.file.name
instance.save() instance.save()

View File

@ -262,3 +262,6 @@ LOGGING = {
}, },
} }
} }
WX_APPID = 'wx0605643660b9b2ec'
WX_APPSECRET = '94527cb8cb8d696f1af3b2b99b7fb01d'

View File

@ -30,34 +30,14 @@ 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.permission import get_permission_list from apps.system.views import WXMPlogin
class MyloginSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
user = self.user
perms = get_permission_list(user)
data['user'] = {
'id': user.id,
'username': user.username,
'name': user.name,
'roles': user.roles.all().values_list('name', flat=True),
# 'avatar': request._request._current_scheme_host + '/media/' + str(user.image),
'avatar': user.avatar,
'perms': perms,
}
return data
class MyTokenObtainPairView(TokenViewBase):
serializer_class = MyloginSerializer
urlpatterns = [ urlpatterns = [
path('', TemplateView.as_view(template_name="index.html")), path('', TemplateView.as_view(template_name="index.html")),
path('api/admin/', admin.site.urls), path('api/admin/', admin.site.urls),
path('api/wxmplogin/',WXMPlogin.as_view()),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token2/', Login2View.as_view(), name='token_obtain_2'), path('api/token2/', Login2View.as_view(), name='token_obtain_2'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),