解绑微信

This commit is contained in:
caoqianming 2021-06-25 09:43:15 +08:00
parent ae345f232d
commit 5b5e7a5dd3
19 changed files with 398 additions and 237 deletions

View File

@ -16,35 +16,41 @@
//var that=this //var that=this
// 小程序自动登录 // 小程序自动登录
uni.showLoading({ uni.showLoading({
title:'微信自动登录中...', title: '微信自动登录中...',
mask: true mask: true
}) })
uni.login({ uni.login({
provider: 'weixin', provider: 'weixin',
success: (loginRes)=>{ success: (loginRes) => {
this.$u.api.wxmplogin({code:loginRes.code}).then(res=>{ this.$u.api.wxmplogin({
this.$u.vuex('vuex_token', res.data.access) code: loginRes.code
this.$u.api.getUserInfo().then(res=>{ }).then(res => {
uni.hideLoading() this.$u.vuex('vuex_token', res.data.access)
uni.showToast({ this.$u.api.getUserInfo().then(res => {
title:"登录成功", uni.hideLoading()
icon:"none" uni.showToast({
}) title: "登录成功",
uni.reLaunch({ icon: "none"
url:"/pages/home/home" })
}) uni.reLaunch({
this.$u.vuex('vuex_user', res.data) url: "/pages/home/home"
}) })
}).catch(e=>{ this.$u.vuex('vuex_user', res.data)
uni.hideLoading() // 修改资源请求地址
uni.showToast({ this.$u.vuex('vuex_user.avatar', this.vuex_user.avatar +
title:"暂未绑定微信!", '?token=' + this.vuex_token)
icon:"none" })
}) }).catch(e => {
uni.reLaunch({ uni.hideLoading()
url:'/pages/login/login' // uni.showToast({
})}) // title: "暂未绑定微信!",
} // icon: "none"
// })
uni.reLaunch({
url: '/pages/login/login'
})
})
}
}); });
}, },

View File

@ -23,6 +23,8 @@ const install = (Vue, vm) => {
let bindmp = (params = {}) => vm.$u.post('/system/user/bindwxmp/', params); //微信绑定 let bindmp = (params = {}) => vm.$u.post('/system/user/bindwxmp/', params); //微信绑定
let unbindmp = (params = {}) => vm.$u.post('/system/user/unbindwxmp/', 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);
@ -49,6 +51,7 @@ const install = (Vue, vm) => {
login, login,
wxmplogin, wxmplogin,
bindmp, bindmp,
unbindmp,
getMyInspectTaskList, getMyInspectTaskList,
getSubinspectTask, getSubinspectTask,
getSubtaskDepts, getSubtaskDepts,

View File

@ -45,24 +45,22 @@ const install = (Vue, vm) => {
return res; return res;
} }
else if(res.code === 401){ else if(res.code === 401){
vm.$u.toast('验证失败,请重新登录'); uni.showToast({
title: "验证失败,请重新登录!",
icon: "none"
})
uni.reLaunch({ uni.reLaunch({
url:'/pages/login/login' url:'/pages/login/login'
}) })
return false; return false;
} }
else{ else{
if(typeof(res.msg)=='string'){ uni.showToast({
vm.$u.toast(res.msg) title: res.msg,
}else{ icon: "none"
let msg = JSON.stringify(res.msg) })
vm.$u.toast(res.msg)
}
return false; return false;
} }
} }
} }

View File

@ -77,10 +77,11 @@
for (var i = 0; i < res.data.imgs_.length; i++) { for (var i = 0; i < res.data.imgs_.length; i++) {
fileList.push({ fileList.push({
id: res.data.imgs_[i].id, id: res.data.imgs_[i].id,
url: res.data.imgs_[i].file url: res.data.imgs_[i].file + '?token='+ this.vuex_token
}) })
} }
this.fileList = fileList this.fileList = fileList
console.log(this.fileList)
}) })
}, },
submit() { submit() {

View File

@ -14,9 +14,9 @@
</u-form-item> </u-form-item>
</u-form> </u-form>
<!-- <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="warning" >登录</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="navigate">密码登录</navigator> <navigator url="login_password" class="password" open-type="navigate">密码登录</navigator>
@ -24,7 +24,9 @@
</view> </view>
<u-verification-code seconds="30" ref="uCode" @change="codeChange"></u-verification-code> <u-verification-code seconds="30" ref="uCode" @change="codeChange"></u-verification-code>
<view style="text-align: center;"> <view style="text-align: center;">
<view class="icon"><u-icon size="70" name="weixin-fill" color="rgb(83,194,64)" @click="mpLogin"></u-icon></view> <view class="icon">
<u-icon size="70" name="weixin-fill" color="rgb(83,194,64)" @click="mpLogin"></u-icon>
</view>
微信登录 微信登录
</view> </view>
<!-- <view class="buttom"> <!-- <view class="buttom">
@ -43,215 +45,225 @@
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
imageURL: '/static/banner3.jpg', imageURL: '/static/banner3.jpg',
loginForm:{ loginForm: {
mail:"", mail: "",
msg:"" msg: ""
}, },
codeTips:"获取验证码", codeTips: "获取验证码",
rules:{ rules: {
mail:[ mail: [{
{ required: true,
required: true, message: '请输入邮箱号',
message: '请输入邮箱号', trigger: ['change', 'blur'],
trigger: ['change','blur'], },
}, {
{ // 正则不能含有两边的引号
// 正则不能含有两边的引号 pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/, message: '格式有误',
message: '格式有误', trigger: ['change', 'blur'],
trigger: ['change','blur'], }
} // {
// { // // 此为同步验证可以直接返回true或者false如果是异步验证稍微不同见下方说明
// // 此为同步验证可以直接返回true或者false如果是异步验证稍微不同见下方说明 // validator: (rule, value, callback) => {
// validator: (rule, value, callback) => { // // 调用uView自带的js验证规则详见https://www.uviewui.com/js/test.html
// // 调用uView自带的js验证规则详见https://www.uviewui.com/js/test.html // return this.$u.test.idCard(value);
// return this.$u.test.idCard(value); // },
// }, // message: '格式有误',
// message: '格式有误', // // 触发器可以同时用blur和change二者之间用英文逗号隔开
// // 触发器可以同时用blur和change二者之间用英文逗号隔开 // trigger: ['change','blur'],
// trigger: ['change','blur'], // }
// } ],
], msg: [{
msg:[
{
required: true, required: true,
message: '请输入验证码', message: '请输入验证码',
trigger: ['change','blur'], trigger: ['change', 'blur'],
}, }, ]
] },
}, errorType: ['message'],
errorType: ['message'],
}
},
onReady() {
this.$refs.uForm.setRules(this.rules);
uni.hideHomeButton()
},
computed: {
inputStyle() {
let style = {};
if(this.loginForm.mail && this.loginForm.msg) {
style.color = "#fff";
style.backgroundColor = this.$u.color['warning'];
} }
return style;
}, },
submitEnable(){ onReady() {
if(this.loginForm.mail && this.loginForm.msg) { this.$refs.uForm.setRules(this.rules);
return false; uni.hideHomeButton()
},
computed: {
inputStyle() {
let style = {};
if (this.loginForm.mail && this.loginForm.msg) {
style.color = "#fff";
style.backgroundColor = this.$u.color['warning'];
}
return style;
},
submitEnable() {
if (this.loginForm.mail && this.loginForm.msg) {
return false;
}
return true;
} }
return true; },
} methods: {
}, submit() {
methods: { this.$refs.uForm.validate(valid => {
submit() { if (valid) {
this.$refs.uForm.validate(valid => { uni.showLoading({})
if (valid) { this.$u.api.codeLogin(this.loginForm).then(res => {
uni.showLoading({ this.$u.vuex('vuex_token', res.data.access)
}) this.$u.api.getUserInfo().then(res => {
this.$u.api.codeLogin(this.loginForm).then(res=>{ this.$u.vuex('vuex_user', res.data)
this.$u.vuex('vuex_token', res.data.access) // 修改资源请求地址
this.$u.api.getUserInfo().then(res=>{ this.$u.vuex('vuex_user.avatar', this.vuex_user.avatar +
this.$u.vuex('vuex_user', res.data) '?token=' + this.vuex_token)
uni.hideLoading()
})
uni.reLaunch({
url: '/pages/home/home'
})
}).catch(e => {
uni.hideLoading() uni.hideLoading()
}) })
uni.reLaunch({ }
url:'/pages/home/home' });
}) },
}).catch(e=>{uni.hideLoading()}) codeChange(text) {
this.codeTips = text;
},
// 获取验证码
getCode() {
if (this.$refs.uCode.canGetCode && this.loginForm.mail) {
uni.showLoading({
title: '正在获取验证码',
mask: true
})
this.$u.api.getCode(this.loginForm).then(res => {
setTimeout(() => {
uni.hideLoading();
// 这里此提示会被this.start()方法中的提示覆盖
this.$u.toast('验证码已发送');
// 通知验证码组件内部开始倒计时
this.$refs.uCode.start();
}, 2000);
})
} else {
this.$u.toast('倒计时结束后再发送');
} }
}); },
}, mpLogin() {
codeChange(text) {
this.codeTips = text;
},
// 获取验证码
getCode() {
if(this.$refs.uCode.canGetCode && this.loginForm.mail) {
uni.showLoading({ uni.showLoading({
title: '正在获取验证码', title: '微信登录中...',
mask: true mask: true
}) })
this.$u.api.getCode(this.loginForm).then(res=>{ uni.login({
setTimeout(() => { provider: 'weixin',
uni.hideLoading(); success: (loginRes) => {
// 这里此提示会被this.start()方法中的提示覆盖 this.$u.api.wxmplogin({
this.$u.toast('验证码已发送'); code: loginRes.code
// 通知验证码组件内部开始倒计时 }).then(res => {
this.$refs.uCode.start(); this.$u.vuex('vuex_token', res.data.access)
}, 2000); this.$u.api.getUserInfo().then(res => {
}) uni.hideLoading()
} else { uni.showToast({
this.$u.toast('倒计时结束后再发送'); title: "登录成功",
icon: "none"
})
uni.reLaunch({
url: "/pages/home/home"
})
this.$u.vuex('vuex_user', res.data)
// 修改资源请求地址
this.$u.vuex('vuex_user.avatar', this.vuex_user.avatar +
'?token=' + this.vuex_token)
})
}).catch(e => {
uni.hideLoading()
uni.showToast({
title: "暂未绑定微信!",
icon: "none"
})
})
}
});
} }
},
mpLogin(){
uni.showLoading({
title:'微信登录中...',
mask: true
})
uni.login({
provider: 'weixin',
success: (loginRes)=>{
this.$u.api.wxmplogin({code:loginRes.code}).then(res=>{
this.$u.vuex('vuex_token', res.data.access)
this.$u.api.getUserInfo().then(res=>{
uni.hideLoading()
uni.showToast({
title:"登录成功",
icon:"none"
})
uni.reLaunch({
url:"/pages/home/home"
})
this.$u.vuex('vuex_user', res.data)
})
}).catch(e=>{
uni.hideLoading()
uni.showToast({
title:"暂未绑定微信!",
icon:"none"
})
uni.reLaunch({
url:'/pages/login/login'
})})
}
});
} }
} };
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.wrap { .wrap {
font-size: 28rpx; font-size: 28rpx;
.content {
width: 90%;
margin: 40rpx auto 0;
.title { .content {
text-align: center; width: 90%;
font-size: 40rpx; margin: 40rpx auto 0;
font-weight: 500;
margin-bottom: 100rpx;
}
input {
text-align: left;
margin-bottom: 10rpx;
padding-bottom: 6rpx;
}
.tips {
color: $u-type-info;
margin-bottom: 60rpx;
margin-top: 8rpx;
}
.getCaptcha {
background-color: rgb(253, 243, 208);
color: $u-tips-color;
border: none;
font-size: 30rpx;
padding: 12rpx 0;
margin-top:6rpx;
&::after { .title {
text-align: center;
font-size: 40rpx;
font-weight: 500;
margin-bottom: 100rpx;
}
input {
text-align: left;
margin-bottom: 10rpx;
padding-bottom: 6rpx;
}
.tips {
color: $u-type-info;
margin-bottom: 60rpx;
margin-top: 8rpx;
}
.getCaptcha {
background-color: rgb(253, 243, 208);
color: $u-tips-color;
border: none; border: none;
} font-size: 30rpx;
} padding: 12rpx 0;
.alternative { margin-top: 6rpx;
color: $u-tips-color;
display: flex;
justify-content: space-between;
margin-top: 30rpx;
}
}
.buttom {
.loginType {
display: flex;
padding: 350rpx 150rpx 150rpx 150rpx;
justify-content:space-between;
.item { &::after {
border: none;
}
}
.alternative {
color: $u-tips-color;
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
align-items: center; margin-top: 30rpx;
color: $u-content-color;
font-size: 28rpx;
} }
} }
.hint { .buttom {
padding: 20rpx 40rpx; .loginType {
font-size: 20rpx; display: flex;
color: $u-tips-color; padding: 350rpx 150rpx 150rpx 150rpx;
justify-content: space-between;
.link { .item {
color: $u-type-warning; display: flex;
flex-direction: column;
align-items: center;
color: $u-content-color;
font-size: 28rpx;
}
}
.hint {
padding: 20rpx 40rpx;
font-size: 20rpx;
color: $u-tips-color;
.link {
color: $u-type-warning;
}
} }
} }
} }
}
</style> </style>

View File

@ -81,6 +81,10 @@ export default {
this.$u.vuex('vuex_token', res.data.access) this.$u.vuex('vuex_token', res.data.access)
this.$u.api.getUserInfo().then(res=>{ this.$u.api.getUserInfo().then(res=>{
this.$u.vuex('vuex_user', res.data) this.$u.vuex('vuex_user', res.data)
// 修改资源请求地址
this.$u.vuex('vuex_user.avatar', this.vuex_user.avatar +
'?token=' + this.vuex_token)
console.log(this.vuex_user)
}) })
uni.reLaunch({ uni.reLaunch({
url:'/pages/home/home' url:'/pages/home/home'

View File

@ -61,10 +61,14 @@
}, },
methods: { methods: {
Logout(){ Logout(){
this.$u.vuex('vuex_token', '') this.$u.api.unbindmp().then(res=>{
uni.redirectTo({ this.$u.vuex('vuex_token', '')
url: '/pages/login/login' uni.redirectTo({
}); url: '/pages/login/login'
});
}
)
}, },
bindMP(){ bindMP(){
uni.login({ uni.login({

View File

@ -352,6 +352,13 @@ class UserViewSet(PageOrNot, ModelViewSet):
UserThird.objects.get_or_create(openid=openid, type='wx_mp', user=request.user, defaults={'openid':openid, 'user':request.user, 'type':'wx_mp'}) 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) return Response({'wxmp_openid':openid},status=status.HTTP_200_OK)
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated])
def unbindwxmp(self, request, pk=None):
"""
解除微信绑定
"""
UserThird.objects.filter(user=request.user, type='wx_mp').delete()
return Response()
class WXMPlogin(APIView): class WXMPlogin(APIView):
authentication_classes=[] authentication_classes=[]

View File

3
server/apps/vod/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
server/apps/vod/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class VodConfig(AppConfig):
name = 'vod'

View File

24
server/apps/vod/models.py Normal file
View File

@ -0,0 +1,24 @@
from django.db import models
from utils.model import BaseModel
from apps.system.models import User, CommonAModel
# Create your models here.
class Video(CommonAModel):
pass
class WatchRecord(BaseModel):
# 观看记录
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='观看人')
num = models.IntegerField(verbose_name='观看次数', default=0)
total = models.IntegerField(verbose_name='观看总时长', default=0)
current = models.IntegerField(verbose_name='当前观看进度', default=0)
vod_id = models.CharField(verbose_name='视频id', max_length=100)
vod_title = models.CharField(verbose_name='视频标题', max_length=100)
vod_cover = models.CharField(verbose_name='视频封面地址', max_length=200)
class Meta:
verbose_name = '点播观看记录'
verbose_name_plural = verbose_name

3
server/apps/vod/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

9
server/apps/vod/urls.py Normal file
View File

@ -0,0 +1,9 @@
from django.urls import path, include
from .views import ClassView, VideoView
from rest_framework import routers
urlpatterns = [
path('class/', ClassView.as_view()),
path('video/', VideoView.as_view())
]

32
server/apps/vod/views.py Normal file
View File

@ -0,0 +1,32 @@
from django.shortcuts import render
from .vodclient import getAllClass, searchMedia
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
# Create your views here.
class ClassView(APIView):
perms_map={'get':'*'}
def get(self, request, format=None):
"""
查询分类
"""
return getAllClass()
class VideoView(APIView):
perms_map={'get':'video_view'}
def get(self, request, format=None):
"""
查询视频
"""
params={'Filters':['basicInfo', 'metaData']}
params['Offset'] = request.query_params.get('Offset', 0)
params['Limit'] = request.query_params.get('Limit', 20)
params['Names'] = request.query_params.getlist('name') if request.query_params.get('name') else []
params['ClassIds']= request.query_params.getlist('classid') if request.query_params.get('classid') else []
return searchMedia(params)
class RecordViewSet(ModelViewSet):
pass

View File

@ -0,0 +1,48 @@
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.vod.v20180717 import vod_client, models
from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST
SecretId = 'AKIDhDTaV9WeXAXcQxEH4buwg9LGvJQHr9Au'
SecretKey = 'VjfKjrhGYrte8MIxMUMxHL9h39zYqrc6'
# 初始化点播client
def initClient():
cred = credential.Credential(SecretId, SecretKey)
httpProfile = HttpProfile()
httpProfile.endpoint = "vod.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = vod_client.VodClient(cred, "", clientProfile)
return client
def doResponse(res):
# 处理返回结果
# 转变为常用返回Response
if hasattr(res, 'Error'):
return Response(res._serialize(allow_none=True), status=HTTP_400_BAD_REQUEST)
return Response(res._serialize(allow_none=True))
def getAllClass(params={}):
# 获取所有分类
try:
client = initClient()
req = models.DescribeAllClassRequest()
req.from_json_string(json.dumps(params))
resp = client.DescribeAllClass(req)
return doResponse(resp)
except TencentCloudSDKException as err:
print(err)
def searchMedia(params={}):
try:
client = initClient()
req = models.SearchMediaRequest()
req.from_json_string(json.dumps(params))
resp = client.SearchMedia(req)
return doResponse(resp)
except TencentCloudSDKException as err:
print(err)

View File

@ -45,7 +45,8 @@ INSTALLED_APPS = [
'apps.crm', 'apps.crm',
'apps.ability', 'apps.ability',
'apps.supervision', 'apps.supervision',
'apps.quality' 'apps.quality',
'apps.vod'
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -47,6 +47,7 @@ urlpatterns = [
path('api/ability/', include('apps.ability.urls')), path('api/ability/', include('apps.ability.urls')),
path('api/supervision/', include('apps.supervision.urls')), path('api/supervision/', include('apps.supervision.urls')),
path('api/quality/', include('apps.quality.urls')), path('api/quality/', include('apps.quality.urls')),
path('api/vod/', include('apps.vod.urls')),
path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])), path('api/docs/', include_docs_urls(title="接口文档",authentication_classes=[], permission_classes=[])),
path('api/', include(router.urls)), path('api/', include(router.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)