增加相关中间表的操作
This commit is contained in:
parent
27591e5fd3
commit
fc1199bb31
|
@ -13,13 +13,25 @@
|
||||||
/**
|
/**
|
||||||
* h5,app-plus(nvue下也为app-plus),mp-weixin,mp-alipay......
|
* h5,app-plus(nvue下也为app-plus),mp-weixin,mp-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>
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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({
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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=>{})
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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='关联账户')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -262,3 +262,6 @@ LOGGING = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WX_APPID = 'wx0605643660b9b2ec'
|
||||||
|
WX_APPSECRET = '94527cb8cb8d696f1af3b2b99b7fb01d'
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
Loading…
Reference in New Issue