diff --git a/test_mini/app.json b/test_mini/app.json index 8bc0cf8..cc7cb9c 100644 --- a/test_mini/app.json +++ b/test_mini/app.json @@ -31,7 +31,11 @@ "pages/qtest/form", "pages/main/start", "pages/exam/index", - "pages/exam/note" + "pages/exam/note", + "pages/admin/index", + "pages/admin/login", + "pages/admin/exam/add", + "pages/admin/exam/add2" ], "window": { "backgroundTextStyle": "light", @@ -88,7 +92,7 @@ }, "plugins": { "tencentvideo": { - "version": "1.3.15", + "version": "1.3.31", "provider": "wxa75efa648b60994b" } }, diff --git a/test_mini/components/dynamicForm/components/timePicker/timePicker.js b/test_mini/components/dynamicForm/components/timePicker/timePicker.js new file mode 100644 index 0000000..0eb7587 --- /dev/null +++ b/test_mini/components/dynamicForm/components/timePicker/timePicker.js @@ -0,0 +1,566 @@ + +Component({ + /** + * 组件的属性列表 + */ + properties: { + pickerShow: { + type: Boolean, + observer:function(val){ //弹出动画 + // console.log(this.data); + if(val){ + let animation = wx.createAnimation({ + duration: 500, + timingFunction: "ease" + }); + let animationOpacity = wx.createAnimation({ + duration: 500, + timingFunction: "ease" + }); + setTimeout(() => { + animation.bottom(0).step(); + animationOpacity.opacity(0.7).step(); + this.setData({ + animationOpacity: animationOpacity.export(), + animationData: animation.export() + }) + }, 0); + }else{ + let animation = wx.createAnimation({ + duration: 100, + timingFunction: "ease" + }); + let animationOpacity = wx.createAnimation({ + duration: 500, + timingFunction: "ease" + }); + animation.bottom(-320).step(); + animationOpacity.opacity(0).step(); + this.setData({ + animationOpacity: animationOpacity.export(), + animationData: animation.export() + }); + } + + // 在picker滚动未停止前点确定,会使startValue数组各项归零,发生错误,这里判断并重新初始化 + // 微信新增了picker滚动的回调函数,已进行兼容 + if(this.data.startValue&&this.data.endValue){ + let s = 0, e = 0; + let conf = this.data.config; + + this.data.startValue.map(val => { + if (val == 0) { + s++ + } + }) + this.data.endValue.map(val => { + if (val == 0) { + e++; + } + }); + let tmp={ + hour:4, + minute:5, + second:6 + } + let n = tmp[conf.column]; + if (s>=n || e>=n) { + this.initPick(this.data.config); + this.setData({ + startValue: this.data.startValue, + endValue: this.data.endValue, + }); + } + } + + + } + }, + config: Object + }, + + /** + * 组件的初始数据 + */ + data: { + // pickerShow:true + // limitStartTime: new Date().getTime()-1000*60*60*24*30, + // limitEndTime: new Date().getTime(), + // yearStart:2000, + // yearEnd:2100 + }, + detached: function() { + console.log("dele"); + }, + attached: function() {}, + ready: function() { + this.readConfig(); + this.initPick(this.data.config || null); + this.setData({ + startValue: this.data.startValue, + endValue: this.data.endValue, + }); + + + + + }, + /** + * 组件的方法列表 + */ + methods: { + //阻止滑动事件 + onCatchTouchMove(e) { + + }, + //读取配置项 + readConfig() { + let limitEndTime = new Date().getTime(); + let limitStartTime = new Date().getTime() - 1000 * 60 * 60 * 24 * 30; + if (this.data.config) { + let conf = this.data.config; + + if (typeof conf.dateLimit == "number") { + limitStartTime = + new Date().getTime() - 1000 * 60 * 60 * 24 * conf.dateLimit; + } + if(conf.limitStartTime){ + + limitStartTime = new Date(conf.limitStartTime.replace(/-/g,'/')).getTime(); + } + + if (conf.limitEndTime) { + limitEndTime = new Date(conf.limitEndTime.replace(/-/g, '/')).getTime(); + } + + this.setData({ + yearStart: conf.yearStart || 2000, + yearEnd: conf.yearEnd || 2100, + endDate: conf.endDate || false, + dateLimit: conf.dateLimit || false, + hourColumn: + conf.column == "hour" || + conf.column == "minute" || + conf.column == "second", + minColumn: conf.column == "minute" || conf.column == "second", + secColumn: conf.column == "second" + }); + } + + let limitStartTimeArr = formatTime(limitStartTime); + let limitEndTimeArr = formatTime(limitEndTime); + + this.setData({ + limitStartTime, + limitStartTimeArr, + limitEndTime, + limitEndTimeArr + }); + }, + //滚动开始 + handlePickStart:function(e){ + this.setData({ + isPicking:true + }) + }, + //滚动结束 + handlePickEnd:function(e){ + this.setData({ + isPicking:false + }) + }, + onConfirm: function() { + //滚动未结束时不能确认 + if(this.data.isPicking){return} + let startTime = new Date(this.data.startPickTime.replace(/-/g, "/")); + let endTime = new Date(this.data.endPickTime.replace(/-/g, "/")); + if (startTime <= endTime || !this.data.endDate) { + this.setData({ + startTime, + endTime + }); + let startArr = formatTime(startTime).arr; + let endArr = formatTime(endTime).arr; + let format0 = function(num){ + return num<10?'0'+num:num + } + + let startTimeBack = + startArr[0] + + "-" + + format0(startArr[1]) + + "-" + + format0(startArr[2]) + + " " + + (this.data.hourColumn ? format0(startArr[3]) : "00") + + ":" + + (this.data.minColumn ? format0(startArr[4]) : "00") + + ":" + + (this.data.secColumn ? format0(startArr[5]) : "00"); + + let endTimeBack = + endArr[0] + + "-" + + format0(endArr[1]) + + "-" + + format0(endArr[2]) + + " " + + (this.data.hourColumn ? format0(endArr[3]) : "00") + + ":" + + (this.data.minColumn ? format0(endArr[4]) : "00") + + ":" + + (this.data.secColumn ? format0(endArr[5]) : "00"); + + let time = { + startTime: startTimeBack, + endTime: endTimeBack + }; + + //触发自定义事件 + this.triggerEvent("setPickerTime", time); + this.triggerEvent("hidePicker", {}); + } else { + wx.showToast({ + icon: "none", + title: "时间不合理" + }); + } + }, + hideModal: function() { + + this.triggerEvent("hidePicker", {}); + }, + changeStartDateTime: function(e) { + let val = e.detail.value; + + this.compareTime(val, "start"); + }, + + changeEndDateTime: function(e) { + let val = e.detail.value; + this.compareTime(val, "end"); + }, + //比较时间是否在范围内 + compareTime(val, type) { + let h = val[3] ? this.data.HourList[val[3]] : "00"; + let m = val[4] ? this.data.MinuteList[val[4]] : "00"; + let s = val[5] ? this.data.SecondList[val[5]] : "00"; + let time = + this.data.YearList[val[0]] + + "-" + + this.data.MonthList[val[1]] + + "-" + + this.data.DayList[val[2]] + + " " + + h + + ":" + + m + + ":" + + s; + + let start = this.data.limitStartTime; + let end = this.data.limitEndTime; + let timeNum = new Date(time.replace(/-/g, '/')).getTime(); + let year, month, day, hour, min, sec, limitDate; + let tempArr = [] + + if (!this.data.dateLimit){ + limitDate = [ + this.data.YearList[val[0]], + this.data.MonthList[val[1]], + this.data.DayList[val[2]], + this.data.HourList[val[3]], + this.data.MinuteList[val[4]], + this.data.SecondList[val[5]]] + } else if (type == "start" && timeNum > new Date(this.data.endPickTime.replace(/-/g, '/')) && this.data.config.endDate) { + limitDate = formatTime(this.data.endPickTime).arr; + + } else if (type == "end" && timeNum < new Date(this.data.startPickTime.replace(/-/g, '/'))) { + limitDate = formatTime(this.data.startPickTime).arr; + + } else if (timeNum < start) { + limitDate = this.data.limitStartTimeArr.arr; + + } else if (timeNum > end) { + limitDate = this.data.limitEndTimeArr.arr; + + } else { + limitDate = [ + this.data.YearList[val[0]], + this.data.MonthList[val[1]], + this.data.DayList[val[2]], + this.data.HourList[val[3]], + this.data.MinuteList[val[4]], + this.data.SecondList[val[5]] + ] + + } + + year = limitDate[0]; + month = limitDate[1]; + day = limitDate[2]; + hour = limitDate[3]; + min = limitDate[4]; + sec = limitDate[5]; + + if (type == "start") { + this.setStartDate(year, month, day, hour, min, sec); + } else if (type == "end") { + this.setEndDate(year, month, day, hour, min, sec); + } + }, + getDays: function(year, month) { + let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + if (month === 2) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 + ? 29 + : 28; + } else { + return daysInMonth[month - 1]; + } + }, + initPick: function(initData) { + const date = initData.initStartTime ? new Date(initData.initStartTime.replace(/-/g, '/')): new Date(); + const endDate = initData.initEndTime ? new Date(initData.initEndTime.replace(/-/g, '/')) : new Date(); + // const startDate = new Date(date.getTime() - 1000 * 60 * 60 * 24); + const startDate = date; + const startYear = date.getFullYear(); + const startMonth = date.getMonth() + 1; + const startDay = date.getDate(); + const startHour = date.getHours(); + const startMinute = date.getMinutes(); + const startSecond = date.getSeconds(); + + const endYear = endDate.getFullYear(); + const endMonth = endDate.getMonth() + 1; + const endDay = endDate.getDate(); + const endHour = endDate.getHours(); + const endMinute = endDate.getMinutes(); + const endSecond = endDate.getSeconds(); + + let YearList = []; + let MonthList = []; + let DayList = []; + let HourList = []; + let MinuteList = []; + let SecondList = []; + + //设置年份列表 + for (let i = this.data.yearStart; i <= this.data.yearEnd; i++) { + YearList.push(i); + } + + // 设置月份列表 + for (let i = 1; i <= 12; i++) { + MonthList.push(i); + } + // 设置日期列表 + for (let i = 1; i <= 31; i++) { + DayList.push(i); + } + // 设置时列表 + for (let i = 0; i <= 23; i++) { + if (0 <= i && i < 10) { + i = "0" + i; + } + HourList.push(i); + } + // 分|秒 + for (let i = 0; i <= 59; i++) { + if (0 <= i && i < 10) { + i = "0" + i; + } + MinuteList.push(i); + SecondList.push(i); + } + + this.setData({ + YearList, + MonthList, + DayList, + HourList, + MinuteList, + SecondList + }); + + this.setStartDate(startYear, startMonth, startDay, startHour, startMinute, startSecond); + this.setEndDate(endYear, endMonth, endDay, endHour, endMinute, endSecond); + + //!!! + // setTimeout(() => { + // this.setStartDate(nowYear, nowMonth, nowDay, nowHour, nowMinute) + // this.setEndDate(nowYear, nowMonth, nowDay, nowHour, nowMinute) + // }, 0); + }, + setPickerDateArr(type, year, month, day, hour, minute, second) { + let yearIdx = 0; + let monthIdx = 0; + let dayIdx = 0; + let hourIdx = 0; + let minuteIdx = 0; + let secondIdx = 0; + + this.data.YearList.map((v, idx) => { + if (parseInt(v) === year) { + yearIdx = idx; + } + }); + + this.data.MonthList.map((v, idx) => { + if (parseInt(v) === month) { + monthIdx = idx; + } + }); + + // 重新设置日期列表 + let DayList = []; + for (let i = 1; i <= this.getDays(year, month); i++) { + DayList.push(i); + } + + DayList.map((v, idx) => { + if (parseInt(v) === day) { + dayIdx = idx; + } + }); + if (type == "start") { + this.setData({ startDayList: DayList }); + } else if (type == "end") { + this.setData({ endDayList: DayList }); + } + + this.data.HourList.map((v, idx) => { + if (parseInt(v) === parseInt(hour)) { + hourIdx = idx; + } + }); + + this.data.MinuteList.map((v, idx) => { + if (parseInt(v) === parseInt(minute)) { + minuteIdx = idx; + } + }); + this.data.SecondList.map((v, idx) => { + if (parseInt(v) === parseInt(second)) { + secondIdx = idx; + } + }); + + return { + yearIdx, + monthIdx, + dayIdx, + hourIdx, + minuteIdx, + secondIdx + }; + }, + setStartDate: function(year, month, day, hour, minute, second) { + let pickerDateArr = this.setPickerDateArr( + "start", + year, + month, + day, + hour, + minute, + second + ); + this.setData({ + startYearList: this.data.YearList, + startMonthList: this.data.MonthList, + // startDayList: this.data.DayList, + startHourList: this.data.HourList, + startMinuteList: this.data.MinuteList, + startSecondList: this.data.SecondList, + startValue: [ + pickerDateArr.yearIdx, + pickerDateArr.monthIdx, + pickerDateArr.dayIdx, + pickerDateArr.hourIdx, + pickerDateArr.minuteIdx, + pickerDateArr.secondIdx + ], + startPickTime: + this.data.YearList[pickerDateArr.yearIdx] + + "-" + + this.data.MonthList[pickerDateArr.monthIdx] + + "-" + + this.data.DayList[pickerDateArr.dayIdx] + + " " + + this.data.HourList[pickerDateArr.hourIdx] + + ":" + + this.data.MinuteList[pickerDateArr.minuteIdx] + + ":" + + this.data.SecondList[pickerDateArr.secondIdx] + }); + }, + setEndDate: function(year, month, day, hour, minute, second) { + let pickerDateArr = this.setPickerDateArr( + "end", + year, + month, + day, + hour, + minute, + second + ); + + this.setData({ + endYearList: this.data.YearList, + endMonthList: this.data.MonthList, + // endDayList: this.data.DayList, + endHourList: this.data.HourList, + endMinuteList: this.data.MinuteList, + endSecondList: this.data.SecondList, + endValue: [ + pickerDateArr.yearIdx, + pickerDateArr.monthIdx, + pickerDateArr.dayIdx, + pickerDateArr.hourIdx, + pickerDateArr.minuteIdx, + pickerDateArr.secondIdx + ], + endPickTime: + this.data.YearList[pickerDateArr.yearIdx] + + "-" + + this.data.MonthList[pickerDateArr.monthIdx] + + "-" + + this.data.DayList[pickerDateArr.dayIdx] + + " " + + this.data.HourList[pickerDateArr.hourIdx] + + ":" + + this.data.MinuteList[pickerDateArr.minuteIdx] + + ":" + + this.data.SecondList[pickerDateArr.secondIdx] + }); + }, + } +}); + + +function formatTime(date) { + + if (typeof date == 'string' || 'number') { + try { + date = date.replace(/-/g, '/')//兼容ios + } catch (error) { + } + date = new Date(date) + } + + const year = date.getFullYear() + const month = date.getMonth() + 1 + const day = date.getDate() + const hour = date.getHours() + const minute = date.getMinutes() + const second = date.getSeconds() + + return { + str: [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':'), + arr: [year, month, day, hour, minute, second] + } +} +function formatNumber(n) { + n = n.toString() + return n[1] ? n : '0' + n +} diff --git a/test_mini/components/dynamicForm/components/timePicker/timePicker.json b/test_mini/components/dynamicForm/components/timePicker/timePicker.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/test_mini/components/dynamicForm/components/timePicker/timePicker.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/test_mini/components/dynamicForm/components/timePicker/timePicker.wxml b/test_mini/components/dynamicForm/components/timePicker/timePicker.wxml new file mode 100644 index 0000000..963e0dd --- /dev/null +++ b/test_mini/components/dynamicForm/components/timePicker/timePicker.wxml @@ -0,0 +1,68 @@ + + + - Copyright © 2018-2020 国检集团 + 管理员入口 + Copyright © 2018-2021 国检集团 中存大数据提供技术支持 \ No newline at end of file diff --git a/test_mini/pages/my/index.wxml b/test_mini/pages/my/index.wxml index 4d9e547..7659c07 100644 --- a/test_mini/pages/my/index.wxml +++ b/test_mini/pages/my/index.wxml @@ -72,6 +72,13 @@ + 管理员操作台 + + + 管理员入口 + + + 更多服务请联系课程顾问 diff --git a/test_mini/project.config.json b/test_mini/project.config.json index be350c3..028731e 100644 --- a/test_mini/project.config.json +++ b/test_mini/project.config.json @@ -21,13 +21,15 @@ "checkSiteMap": true, "uploadWithSourceMap": true, "compileHotReLoad": false, - "useMultiFrameRuntime": false, + "useMultiFrameRuntime": true, "useApiHook": true, + "useApiHostProcess": false, "babelSetting": { "ignore": [], "disablePlugins": [], "outputPath": "" }, + "enableEngineNative": false, "bundle": false, "useIsolateContext": true, "useCompilerModule": true, @@ -38,7 +40,7 @@ "minifyWXSS": true }, "compileType": "miniprogram", - "libVersion": "2.14.1", + "libVersion": "2.16.1", "appid": "wxf1e9471c93f05ad6", "projectname": "test_mini", "debugOptions": { diff --git a/test_mini/utils/request.js b/test_mini/utils/request.js index 3248084..8c498f2 100644 --- a/test_mini/utils/request.js +++ b/test_mini/utils/request.js @@ -51,6 +51,57 @@ function request(url, method, data) { return promise; } +function requesta(url, method, data) { + let promise = new Promise((resolve, reject) => { + wx.showNavigationBarLoading(); + wx.request({ + url: getApp().globalData.host + url, + method: method, + data: data, + header:{ + 'Authorization': 'JWT ' + getApp().globalData.admintoken + }, + success: (res => { + if (res.data.code >= 200 && res.data.code < 400) { + resolve(res.data); + }else if(res.data.code == 401){ + + } + else { + var msg = '请求错误' + if(res.data.msg){ + msg = res.data.msg + } + if (msg.indexOf('该操作的权限')!=-1){ + msg = '权限不足或账户过期,请联系课程顾问' + } + wx.showToast({ + title: msg, + icon: 'none', + duration: 1000 + }) + } + + }), + fail: (res => { + wx.showToast({ + title: '请求出错', + icon: 'none', + duration: 1500 + }) + console.log(res) + reject('网络出错'); + }), + complete: function () { + wx.hideNavigationBarLoading(); + } + + }) + }) + return promise; +} + module.exports = { - request: request + request: request, + requesta: requesta } \ No newline at end of file diff --git a/test_server/crm/views.py b/test_server/crm/views.py index d75ab2f..7699b0a 100644 --- a/test_server/crm/views.py +++ b/test_server/crm/views.py @@ -16,8 +16,7 @@ from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet from rest_framework_jwt.authentication import JSONWebTokenAuthentication -from rest_framework_jwt.serializers import (jwt_encode_handler, - jwt_payload_handler) +from rest_framework_jwt.serializers import jwt_encode_handler from rest_framework_jwt.settings import api_settings from crm.zhenzismsclient import ZhenziSmsClient @@ -35,16 +34,12 @@ from rbac.models import UserProfile from django.http import Http404 from .spider import getZs import time -appid = 'wxf1e9471c93f05ad6' -secret = '4bf7f9bd6c52634586bbe792a1f0a834' -sms_appid = '100172' -sms_appsecret = '00b8681c-0ce6-41c8-a867-904c1891c78a' -sms_url = 'https://sms.zhenzikj.com' +from server.config import * -def jwt_payload_handler(user): +def my_payload_handler(user, dtype="admin"): payload = { 'user_id': user.pk, - 'type':'consumer', + 'type':dtype, 'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA } if api_settings.JWT_ALLOW_REFRESH: @@ -571,7 +566,7 @@ class ConsumerMPLoginView(APIView): session_key = info['session_key'] consumer = Consumer.objects.get_or_create(openid = openid)[0] serializer = ConsumerDetailSerializer(instance=consumer) - payload = jwt_payload_handler(consumer) + payload = my_payload_handler(consumer, 'consumer') token = jwt_encode_handler(payload) return Response({"token":token,"session_key":session_key, "openid":openid, "userinfo":serializer.data}) diff --git a/test_server/rbac/migrations/0006_userprofile_mpopenid.py b/test_server/rbac/migrations/0006_userprofile_mpopenid.py new file mode 100644 index 0000000..6f6cff2 --- /dev/null +++ b/test_server/rbac/migrations/0006_userprofile_mpopenid.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2021-05-25 02:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0005_userprofile_bcompany'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='mpopenid', + field=models.CharField(blank=True, max_length=100, null=True, unique=True, verbose_name='小程序openid'), + ), + ] diff --git a/test_server/rbac/models.py b/test_server/rbac/models.py index 3a439e0..f797707 100644 --- a/test_server/rbac/models.py +++ b/test_server/rbac/models.py @@ -152,6 +152,7 @@ class UserProfile(AbstractUser): pname = models.CharField('所属省份', max_length=100, null=True, blank=True) bcompany = models.ForeignKey('crm.company', verbose_name='所属公司', null=True, blank=True, on_delete=models.SET_NULL) + mpopenid = models.CharField(max_length=100, verbose_name='小程序openid', unique=True, null=True, blank=True) class Meta: verbose_name = "用户信息" diff --git a/test_server/rbac/views/user.py b/test_server/rbac/views/user.py index 9ac1280..b481c0e 100644 --- a/test_server/rbac/views/user.py +++ b/test_server/rbac/views/user.py @@ -1,28 +1,35 @@ # -*- coding: utf-8 -*- +import json from operator import itemgetter +import requests # import jwt from django.conf import settings -from django.contrib.auth import authenticate,login,logout -from django.contrib.auth.hashers import check_password +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.hashers import check_password, make_password from django_filters.rest_framework import DjangoFilterBackend -from django.contrib.auth.hashers import make_password -from rest_framework.decorators import action -from rest_framework.filters import SearchFilter, OrderingFilter +from rest_framework import status +from rest_framework.decorators import action, authentication_classes +from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet -from rest_framework import status - -from utils.custom import CommonPagination from utils.child import get_child_queryset -from ..models import UserProfile, Menu, Organization +from utils.custom import CommonPagination + +from ..models import Menu, Organization, UserProfile +from ..permission import (RbacPermission, get_all_menu_queryset, + get_permission_list) from ..serializers.menu_serializer import MenuSerializer -from ..serializers.user_serializer import UserListSerializer, UserCreateSerializer, UserModifySerializer, \ - UserInfoListSerializer -from ..permission import get_all_menu_queryset,get_permission_list,RbacPermission +from ..serializers.user_serializer import (UserCreateSerializer, + UserInfoListSerializer, + UserListSerializer, + UserModifySerializer) +from server.config import * +from rest_framework_jwt.serializers import jwt_encode_handler +from crm.views import my_payload_handler class UserLogoutView(APIView): authentication_classes = () @@ -47,6 +54,8 @@ class UserInfoView(APIView): # 'avatar': request._request._current_scheme_host + '/media/' + str(user.image), 'avatar': user.avatar, 'perms': perms, + 'roles':user.roles.values_list('name', flat=True), + 'mpopenid': user.mpopenid } return Response(data) @@ -59,6 +68,7 @@ class UserInfoView(APIView): from utils.pagination import PageOrNot + class UserViewSet(PageOrNot, ModelViewSet): """ 用户管理:增删改查 @@ -135,4 +145,39 @@ class UserViewSet(PageOrNot, ModelViewSet): return Response({'error': '新密码两次输入不一致!'}) else: return Response({'error':'旧密码错误!'}) + + @action(methods=['post'], detail=False, permission_classes=[], authentication_classes=[]) + def mplogin(self, request, pk=None): + """ + 小程序登录 + """ + code = request.data['code'] + info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+appid+'&secret='+secret+'&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 = UserProfile.objects.get(mpopenid = openid) + payload = my_payload_handler(user) + token = jwt_encode_handler(payload) + return Response({"token":token,"session_key":session_key, "openid":openid}) + except: + return Response({'error':'自动登录失败!'}) + + @action(methods=['post'], detail=False, permission_classes=[IsAuthenticated]) + def bindmp(self, request, pk=None): + """ + 绑定微信 + """ + user = request.user + code = request.data['code'] + info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+appid+'&secret='+secret+'&js_code=' + + code+'&grant_type=authorization_code').content.decode('utf-8') + info = json.loads(info) + openid = info['openid'] + user.mpopenid = openid + user.save() + return Response({'mpopenid':openid}) + diff --git a/test_server/server/config.py b/test_server/server/config.py new file mode 100644 index 0000000..eeeabd4 --- /dev/null +++ b/test_server/server/config.py @@ -0,0 +1,5 @@ +appid = 'wxf1e9471c93f05ad6' +secret = '4bf7f9bd6c52634586bbe792a1f0a834' +sms_appid = '100172' +sms_appsecret = '00b8681c-0ce6-41c8-a867-904c1891c78a' +sms_url = 'https://sms.zhenzikj.com' \ No newline at end of file diff --git a/test_server/utils/response.py b/test_server/utils/response.py index 13f8553..e97d94a 100644 --- a/test_server/utils/response.py +++ b/test_server/utils/response.py @@ -45,7 +45,11 @@ class FitJSONRenderer(JSONRenderer): response = renderer_context.get("response") response_body.code = response.status_code if response_body.code >= 400: # drf异常 - response_body.msg = data['detail'] if 'detail' in data else data + if isinstance(data, dict): + data = data[list(data.keys())[0]] + if isinstance(data, list): + data = data[0] + response_body.msg = data elif data and 'error' in data and data['error']:# 自传异常,key为error response_body.code = data.get("code",400) response_body.msg = data.get("error", "")