msg
This commit is contained in:
parent
89482b4aed
commit
ea28be2f5f
|
@ -9,3 +9,18 @@ export default {
|
||||||
name: 'App'
|
name: 'App'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style >
|
||||||
|
.el-table--medium td, .el-table--medium th {
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-card__body {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.el-card__header {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,9 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function sendMsg(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/sendmsg/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
|
@ -8,6 +8,15 @@ export function login(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function login2(data) {
|
||||||
|
//验证码登陆
|
||||||
|
return request({
|
||||||
|
url: '/token2/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function logout() {
|
export function logout() {
|
||||||
return request({
|
return request({
|
||||||
url: '/token/black/',
|
url: '/token/black/',
|
||||||
|
|
|
@ -90,10 +90,10 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
.pagination-container {
|
.pagination-container {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 32px 16px;
|
padding: 0px 2px;
|
||||||
}
|
}
|
||||||
.pagination-container.hidden {
|
.pagination-container.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { login, logout, getInfo } from '@/api/user'
|
import { login, logout, getInfo, login2 } from '@/api/user'
|
||||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||||
import { resetRouter } from '@/router'
|
import { resetRouter } from '@/router'
|
||||||
|
|
||||||
|
@ -47,7 +47,21 @@ const actions = {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// user code login
|
||||||
|
login2({ commit }, msginfo) {
|
||||||
|
const { mail, msg } = msginfo
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
login2({ mail: mail.trim(), msg: msg }).then(response => {
|
||||||
|
const { data } = response
|
||||||
|
commit('SET_TOKEN', data.access)
|
||||||
|
setToken(data.access)
|
||||||
|
resolve()
|
||||||
|
|
||||||
|
}).catch(error => {
|
||||||
|
reject(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
// get user info
|
// get user info
|
||||||
getInfo({ commit, state }) {
|
getInfo({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -61,5 +61,43 @@ div:focus {
|
||||||
|
|
||||||
// main-container global css
|
// main-container global css
|
||||||
.app-container {
|
.app-container {
|
||||||
padding: 20px;
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table--medium td, .el-table--medium th {
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.el-card, .el-message {
|
||||||
|
border-radius: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.el-card__body {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.el-card__header {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.el-tabs--border-card>.el-tabs__content {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.el-dialog__header {
|
||||||
|
padding: 10px 10px 6px;
|
||||||
|
}
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 8px 12px;
|
||||||
|
}
|
||||||
|
// .el-form-item--medium .el-form-item__label {
|
||||||
|
// line-height: 16px;
|
||||||
|
// }
|
||||||
|
.el-form--label-top .el-form-item__label {
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
.el-button+.el-button {
|
||||||
|
margin-left: 1px;
|
||||||
|
}
|
||||||
|
.el-button {
|
||||||
|
border-radius: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,22 +45,30 @@ service.interceptors.response.use(
|
||||||
const res = response.data
|
const res = response.data
|
||||||
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
|
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
|
||||||
if (res.code === 401) {
|
if (res.code === 401) {
|
||||||
MessageBox.confirm('您已退出,您可以停留在本页或者重新登陆.', '确认退出', {
|
if(res.msg.indexOf('No active account')!=-1){
|
||||||
confirmButtonText: '重新登陆',
|
Message({
|
||||||
cancelButtonText: '取消',
|
message: '用户名或密码错误',
|
||||||
type: 'warning'
|
type: 'error',
|
||||||
}).then(() => {
|
duration: 3 * 1000
|
||||||
store.dispatch('user/resetToken').then(() => {
|
|
||||||
location.reload()
|
|
||||||
})
|
})
|
||||||
})
|
}else{
|
||||||
|
MessageBox.confirm('认证失败,请重新登陆.', '确认退出', {
|
||||||
|
confirmButtonText: '重新登陆',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
store.dispatch('user/resetToken').then(() => {
|
||||||
|
location.reload()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
} else if (res.code >= 400) {
|
} else if (res.code >= 400) {
|
||||||
Message({
|
Message({
|
||||||
message: res.msg || '请求出错',
|
message: res.msg || '请求出错',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
duration: 5 * 1000
|
duration: 3 * 1000
|
||||||
})
|
})
|
||||||
|
|
||||||
return Promise.reject(new Error(res.msg || '请求出错'))
|
return Promise.reject(new Error(res.msg || '请求出错'))
|
||||||
} else {
|
} else {
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,62 +1,125 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
|
<div class="login-form">
|
||||||
|
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<h3 class="title">CTC能力检索</h3>
|
<h3 class="title">ctc能力检索</h3>
|
||||||
</div>
|
</div>
|
||||||
|
<el-tabs v-model="activeName" :stretch="true">
|
||||||
|
<el-tab-pane label="验证码登陆" name="msg">
|
||||||
|
<el-form
|
||||||
|
ref="loginForm2"
|
||||||
|
:model="loginForm2"
|
||||||
|
:rules="loginRules2"
|
||||||
|
auto-complete="on"
|
||||||
|
label-position="left"
|
||||||
|
>
|
||||||
|
<el-form-item prop="mail">
|
||||||
|
<span class="svg-container">
|
||||||
|
<svg-icon icon-class="email" />
|
||||||
|
</span>
|
||||||
|
<el-input
|
||||||
|
ref="mail"
|
||||||
|
v-model="loginForm2.mail"
|
||||||
|
placeholder="邮箱号"
|
||||||
|
name="mail"
|
||||||
|
type="text"
|
||||||
|
tabindex="1"
|
||||||
|
auto-complete="on"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="msg">
|
||||||
<span class="svg-container">
|
<span class="svg-container">
|
||||||
<svg-icon icon-class="user" />
|
<svg-icon icon-class="message" />
|
||||||
</span>
|
</span>
|
||||||
<el-input
|
<el-input
|
||||||
ref="username"
|
ref="msg"
|
||||||
v-model="loginForm.username"
|
v-model="loginForm2.msg"
|
||||||
placeholder="账号"
|
type="text"
|
||||||
name="username"
|
placeholder="验证码"
|
||||||
type="text"
|
name="msg"
|
||||||
tabindex="1"
|
tabindex="2"
|
||||||
auto-complete="on"
|
auto-complete="on"
|
||||||
/>
|
@keyup.enter.native="handleLogin"
|
||||||
</el-form-item>
|
/>
|
||||||
|
<span class="show-pwd" @click="sendMsg">
|
||||||
|
<el-button :disabled="disabled" plain type="primary">
|
||||||
|
<template>{{buttonmsg}}</template>
|
||||||
|
</el-button>
|
||||||
|
<!-- <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> -->
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-button
|
||||||
|
:loading="loading2"
|
||||||
|
type="primary"
|
||||||
|
style="width:100%;margin-bottom:30px;"
|
||||||
|
@click.native.prevent="handleLogin2"
|
||||||
|
>验证登陆</el-button>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
<el-form-item prop="password">
|
|
||||||
<span class="svg-container">
|
|
||||||
<svg-icon icon-class="password" />
|
|
||||||
</span>
|
|
||||||
<el-input
|
|
||||||
:key="passwordType"
|
|
||||||
ref="password"
|
|
||||||
v-model="loginForm.password"
|
|
||||||
:type="passwordType"
|
|
||||||
placeholder="密码"
|
|
||||||
name="password"
|
|
||||||
tabindex="2"
|
|
||||||
auto-complete="on"
|
|
||||||
@keyup.enter.native="handleLogin"
|
|
||||||
/>
|
|
||||||
<span class="show-pwd" @click="showPwd">
|
|
||||||
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登陆</el-button>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="账户密码登陆" name="pwd">
|
||||||
|
<el-form
|
||||||
|
ref="loginForm"
|
||||||
|
:model="loginForm"
|
||||||
|
:rules="loginRules"
|
||||||
|
auto-complete="on"
|
||||||
|
label-position="left"
|
||||||
|
>
|
||||||
|
<el-form-item prop="username">
|
||||||
|
<span class="svg-container">
|
||||||
|
<svg-icon icon-class="user" />
|
||||||
|
</span>
|
||||||
|
<el-input
|
||||||
|
ref="username"
|
||||||
|
v-model="loginForm.username"
|
||||||
|
placeholder="账号"
|
||||||
|
name="username"
|
||||||
|
type="text"
|
||||||
|
tabindex="1"
|
||||||
|
auto-complete="on"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<!-- <div class="tips">
|
<el-form-item prop="password">
|
||||||
<span style="margin-right:20px;">username: admin</span>
|
<span class="svg-container">
|
||||||
<span> password: any</span>
|
<svg-icon icon-class="password" />
|
||||||
</div> -->
|
</span>
|
||||||
|
<el-input
|
||||||
</el-form>
|
:key="passwordType"
|
||||||
|
ref="password"
|
||||||
|
v-model="loginForm.password"
|
||||||
|
:type="passwordType"
|
||||||
|
placeholder="密码"
|
||||||
|
name="password"
|
||||||
|
tabindex="2"
|
||||||
|
auto-complete="on"
|
||||||
|
@keyup.enter.native="handleLogin"
|
||||||
|
/>
|
||||||
|
<span class="show-pwd" @click="showPwd">
|
||||||
|
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-button
|
||||||
|
:loading="loading"
|
||||||
|
type="primary"
|
||||||
|
style="width:100%;margin-bottom:30px;"
|
||||||
|
@click.native.prevent="handleLogin"
|
||||||
|
>登陆</el-button>
|
||||||
|
</el-form>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import { validUsername } from '@/utils/validate'
|
// import { validUsername } from '@/utils/validate'
|
||||||
|
import { sendMsg } from '@/api/msg'
|
||||||
|
import { login2 } from "@/api/user"
|
||||||
export default {
|
export default {
|
||||||
name: 'Login',
|
name: "Login",
|
||||||
data() {
|
data() {
|
||||||
// const validateUsername = (rule, value, callback) => {
|
// const validateUsername = (rule, value, callback) => {
|
||||||
// if (!validUsername(value)) {
|
// if (!validUsername(value)) {
|
||||||
|
@ -67,70 +130,147 @@ export default {
|
||||||
// }
|
// }
|
||||||
const validatePassword = (rule, value, callback) => {
|
const validatePassword = (rule, value, callback) => {
|
||||||
if (value.length < 4) {
|
if (value.length < 4) {
|
||||||
callback(new Error('密码长度小于4位!'))
|
callback(new Error("密码长度小于4位!"));
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return {
|
return {
|
||||||
|
timer:null,
|
||||||
|
disabled:false,
|
||||||
|
buttonmsg:'发送验证码',
|
||||||
|
count:20,
|
||||||
|
activeName: "pwd",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: '',
|
username: "",
|
||||||
password: ''
|
password: "",
|
||||||
|
},
|
||||||
|
loginForm2: {
|
||||||
|
mail: "",
|
||||||
|
msg: "",
|
||||||
},
|
},
|
||||||
loginRules: {
|
loginRules: {
|
||||||
username: [{ required: true, trigger: 'blur', message: "请输入账户" }],
|
username: [{ required: true, trigger: "blur", message: "请输入账户" }],
|
||||||
password: [{ required: true, trigger: 'blur', validator: validatePassword, message: "请输入密码" }]
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
trigger: "blur",
|
||||||
|
validator: validatePassword,
|
||||||
|
message: "请输入密码",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
loginRules2: {
|
||||||
|
mail: [{ required: true, trigger: "blur", message: "请输入邮箱号" }],
|
||||||
|
msg: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
trigger: "blur",
|
||||||
|
message: "请输入验证码",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
loading2:false,
|
||||||
loading: false,
|
loading: false,
|
||||||
passwordType: 'password',
|
passwordType: "password",
|
||||||
redirect: undefined
|
redirect: undefined,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: {
|
$route: {
|
||||||
handler: function(route) {
|
handler: function (route) {
|
||||||
this.redirect = route.query && route.query.redirect
|
this.redirect = route.query && route.query.redirect;
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showPwd() {
|
showPwd() {
|
||||||
if (this.passwordType === 'password') {
|
if (this.passwordType === "password") {
|
||||||
this.passwordType = ''
|
this.passwordType = "";
|
||||||
} else {
|
} else {
|
||||||
this.passwordType = 'password'
|
this.passwordType = "password";
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.password.focus()
|
this.$refs.password.focus();
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
handleLogin() {
|
sendMsg(){
|
||||||
this.$refs.loginForm.validate(valid => {
|
if(this.loginForm2.mail.length){
|
||||||
if (valid) {
|
this.getTimer()
|
||||||
this.loading = true
|
sendMsg({'mail':this.loginForm2.mail}).then(res=>{
|
||||||
this.$store.dispatch('user/login', this.loginForm).then(() => {
|
this.$message.success('验证码已发送至该邮箱,请注意查收')
|
||||||
this.$router.push({ path: this.redirect || '/' })
|
}).catch(e=>{})
|
||||||
this.loading = false
|
}else{
|
||||||
}).catch(() => {
|
this.$message.warning('请输入邮箱号')
|
||||||
this.loading = false
|
}
|
||||||
})
|
},
|
||||||
|
getTimer(){
|
||||||
|
const TIME_COUNT = 20;
|
||||||
|
if (!this.timer) {
|
||||||
|
this.count = TIME_COUNT;
|
||||||
|
this.disabled = true;
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
if (this.count > 0 && this.count <= TIME_COUNT) {
|
||||||
|
this.count--;
|
||||||
|
this.buttonmsg = this.count
|
||||||
} else {
|
} else {
|
||||||
console.log('error submit!!')
|
this.disabled = false;
|
||||||
return false
|
clearInterval(this.timer);
|
||||||
|
this.timer = null;
|
||||||
|
this.buttonmsg = '发送验证码'
|
||||||
}
|
}
|
||||||
})
|
}, 1000)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
handleLogin() {
|
||||||
|
this.$refs.loginForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.loading = true;
|
||||||
|
this.$store
|
||||||
|
.dispatch("user/login", this.loginForm)
|
||||||
|
.then(() => {
|
||||||
|
this.$router.push({ path: this.redirect || "/" });
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("error submit!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleLogin2() {
|
||||||
|
this.$refs.loginForm2.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.loading2 = true;
|
||||||
|
this.$store
|
||||||
|
.dispatch("user/login2", this.loginForm2)
|
||||||
|
.then(() => {
|
||||||
|
this.$router.push({ path: this.redirect || "/" });
|
||||||
|
this.loading2 = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading2 = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("error submit!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/* 修复input 背景不协调 和光标变色 */
|
/* 修复input 背景不协调 和光标变色 */
|
||||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
||||||
|
|
||||||
$bg:#283443;
|
$bg: #283443;
|
||||||
$light_gray:#fff;
|
$light_gray: #fff;
|
||||||
$cursor: #fff;
|
$cursor: #fff;
|
||||||
|
|
||||||
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
||||||
|
@ -169,13 +309,19 @@ $cursor: #fff;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: #454545;
|
color: #454545;
|
||||||
}
|
}
|
||||||
|
.el-tabs__item {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.el-tabs__item.is-active {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
$bg:#2d3a4b;
|
$bg: #2d3a4b;
|
||||||
$dark_gray:#889aa4;
|
$dark_gray: #889aa4;
|
||||||
$light_gray:#eee;
|
$light_gray: #eee;
|
||||||
|
|
||||||
.login-container {
|
.login-container {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.0.7 on 2020-09-22 08:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('system', '0003_auto_20200528_1716'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Message',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('mail', models.CharField(max_length=200, verbose_name='发送邮箱')),
|
||||||
|
('msg', models.CharField(max_length=200, verbose_name='验证码')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -215,4 +215,8 @@ class File(CommonAModel):
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
class Message(BaseModel):
|
||||||
|
mail = models.CharField('发送邮箱', max_length=200)
|
||||||
|
msg = models.CharField('验证码', max_length=200)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from .models import Organization, Permission, Role, User, Position, DictType, Dict, File
|
from .models import Organization, Permission, Role, User, Position, DictType, Dict, File
|
||||||
|
|
||||||
|
|
||||||
class FileSerializer(serializers.ModelSerializer):
|
class FileSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = File
|
model = File
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from .views import UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet
|
from .views import UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet, sendMsg
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,5 +13,6 @@ router.register('dicttype', DictTypeViewSet, basename="dicttype")
|
||||||
router.register('dict', DictViewSet, basename="dict")
|
router.register('dict', DictViewSet, basename="dict")
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
|
path('sendmsg/', sendMsg.as_view()),
|
||||||
path('test/', TestView.as_view())
|
path('test/', TestView.as_view())
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
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.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
from django.http import request
|
||||||
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
|
from rest_framework.decorators import action, authentication_classes, permission_classes
|
||||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
from rest_framework.mixins import (CreateModelMixin, DestroyModelMixin,
|
from rest_framework.mixins import (CreateModelMixin, DestroyModelMixin,
|
||||||
ListModelMixin, RetrieveModelMixin,
|
ListModelMixin, RetrieveModelMixin,
|
||||||
|
@ -20,7 +22,7 @@ from utils.queryset import get_child_queryset2
|
||||||
|
|
||||||
from .filters import UserFilter
|
from .filters import UserFilter
|
||||||
from .models import (Dict, DictType, Organization, Permission, Position, Role,
|
from .models import (Dict, DictType, Organization, Permission, Position, Role,
|
||||||
User, File)
|
User, File, Message)
|
||||||
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,
|
from .serializers import (DictSerializer, DictTypeSerializer,
|
||||||
|
@ -40,6 +42,69 @@ class LogoutView(APIView):
|
||||||
def get(self, request, *args, **kwargs): # 可将token加入黑名单
|
def get(self, request, *args, **kwargs): # 可将token加入黑名单
|
||||||
return Response(status=status.HTTP_200_OK)
|
return Response(status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
import smtplib
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.utils import formataddr
|
||||||
|
from email.header import Header
|
||||||
|
import random
|
||||||
|
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
|
||||||
|
def get_tokens_for_user(user):
|
||||||
|
refresh = RefreshToken.for_user(user)
|
||||||
|
return {
|
||||||
|
'refresh': str(refresh),
|
||||||
|
'access': str(refresh.access_token),
|
||||||
|
}
|
||||||
|
|
||||||
|
class Login2View(APIView):
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
def post(self, request):
|
||||||
|
mail = request.data['mail']
|
||||||
|
msg = request.data['msg']
|
||||||
|
if not User.objects.filter(username=mail).exists():
|
||||||
|
return Response('账户不存在', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
if Message.objects.filter(mail=mail).last().msg == msg:
|
||||||
|
user = User.objects.get(username=mail)
|
||||||
|
return Response(get_tokens_for_user(user), status=status.HTTP_200_OK)
|
||||||
|
return Response('验证码错误', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class sendMsg(APIView):
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
code = random.randint(1000,9999)
|
||||||
|
my_sender = 'caoqianming@ctc.ac.cn'
|
||||||
|
my_user = request.data['mail']
|
||||||
|
my_pass = '9093QQww'
|
||||||
|
if not User.objects.filter(username=my_user).exists():
|
||||||
|
return Response('该账户不存在', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
try:
|
||||||
|
# 邮件内容
|
||||||
|
msg=MIMEText('ctc能力检索本次验证码为' + str(code),'plain','utf-8')
|
||||||
|
# 括号里的对应发件人邮箱昵称、发件人邮箱账号
|
||||||
|
msg['From']=formataddr(["国检集团能力检索",my_sender])
|
||||||
|
# 括号里的对应收件人邮箱昵称、收件人邮箱账号
|
||||||
|
msg['To']=formataddr(["国检集团",my_user])
|
||||||
|
# 邮件的主题
|
||||||
|
msg['Subject'] = Header(str(code), 'utf-8').encode()
|
||||||
|
|
||||||
|
# SMTP服务器,腾讯企业邮箱端口是465,腾讯邮箱支持SSL(不强制), 不支持TLS
|
||||||
|
# qq邮箱smtp服务器地址:smtp.qq.com,端口号:456
|
||||||
|
# 163邮箱smtp服务器地址:smtp.163.com,端口号:25
|
||||||
|
server=smtplib.SMTP_SSL("smtp.exmail.qq.com", 465)
|
||||||
|
# 登录服务器,括号中对应的是发件人邮箱账号、邮箱密码
|
||||||
|
server.login(my_sender, my_pass)
|
||||||
|
# 发送邮件,括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
|
||||||
|
server.sendmail(my_sender,[my_user,],msg.as_string())
|
||||||
|
# 关闭连接
|
||||||
|
server.quit()
|
||||||
|
Message.objects.create(mail=my_user, msg=code)
|
||||||
|
except:
|
||||||
|
return Response('验证码发送失败', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
return Response(status=status.HTTP_200_OK)
|
||||||
|
|
||||||
class DictTypeViewSet(ModelViewSet):
|
class DictTypeViewSet(ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
Binary file not shown.
|
@ -22,13 +22,14 @@ from rest_framework.documentation import include_docs_urls
|
||||||
from rest_framework_simplejwt.views import (TokenObtainPairView,
|
from rest_framework_simplejwt.views import (TokenObtainPairView,
|
||||||
TokenRefreshView)
|
TokenRefreshView)
|
||||||
|
|
||||||
from apps.system.views import FileViewSet, LogoutView
|
from apps.system.views import FileViewSet, LogoutView, Login2View
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register('file', FileViewSet, basename="file")
|
router.register('file', FileViewSet, basename="file")
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||||
|
path('token2/', Login2View.as_view(), name='token_obtain_2'),
|
||||||
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||||
path('token/black/', LogoutView.as_view(), name='token_black'),
|
path('token/black/', LogoutView.as_view(), name='token_black'),
|
||||||
path('system/', include('apps.system.urls')),
|
path('system/', include('apps.system.urls')),
|
||||||
|
|
Loading…
Reference in New Issue