增加实人认证界面

pull/16/head
youngS 4 years ago
parent fbb4d41934
commit c45aeed34e
  1. 2
      fir_client/src/components/FirAppInfosbaseinfo.vue
  2. 2
      fir_client/src/components/FirUserProfileBase.vue
  3. 434
      fir_client/src/components/FirUserProfileCertification.vue
  4. 15
      fir_client/src/restful/index.js
  5. 3
      fir_ser/api/migrations/0025_order_price.py
  6. 17
      fir_ser/api/migrations/0034_usercertificationinfo_msg.py
  7. 18
      fir_ser/api/migrations/0035_usercertificationinfo_reviewed_time.py
  8. 2
      fir_ser/api/models.py
  9. 3
      fir_ser/api/urls.py
  10. 39
      fir_ser/api/utils/serializer.py
  11. 97
      fir_ser/api/views/login.py
  12. 22
      fir_ser/api/views/uploads.py

@ -210,11 +210,11 @@
return this.beforeAvatarUpload(file, 'screen') return this.beforeAvatarUpload(file, 'screen')
}, },
beforeAvatarUpload(file, act) { beforeAvatarUpload(file, act) {
// eslint-disable-next-line no-unused-vars
return AvatarUploadUtils(this, file, { return AvatarUploadUtils(this, file, {
'app_id': this.currentapp.app_id, 'app_id': this.currentapp.app_id,
'upload_key': file.name, 'upload_key': file.name,
'ftype': act 'ftype': act
// eslint-disable-next-line no-unused-vars
}, res => { }, res => {
this.getappinfo(); this.getappinfo();
}); });

@ -95,11 +95,11 @@
this.updateUserInfo({"methods": 'PUT', 'data': {"first_name": this.userinfo.first_name}}); this.updateUserInfo({"methods": 'PUT', 'data': {"first_name": this.userinfo.first_name}});
}, },
beforeAvatarUpload(file) { beforeAvatarUpload(file) {
// eslint-disable-next-line no-unused-vars
return AvatarUploadUtils(this, file, { return AvatarUploadUtils(this, file, {
'app_id': this.userinfo.uid, 'app_id': this.userinfo.uid,
'upload_key': file.name, 'upload_key': file.name,
'ftype': 'head' 'ftype': 'head'
// eslint-disable-next-line no-unused-vars
}, res => { }, res => {
this.updateUserInfo({"methods": 'GET'}); this.updateUserInfo({"methods": 'GET'});
}); });

@ -1,94 +1,204 @@
<template> <template>
<div> <div v-if="certification && certification.code === 0">
<el-form style="max-width: 400px">
<el-form ref="form" :model="form">
<el-form-item> <el-form-item>
<el-row> <el-row :gutter="36">
<el-col :span="22"> <el-col :span="18">
<el-input v-model="form.oldpassword" autofocus="true" prefix-icon="el-icon-user" <el-link :underline="false" type="success" style="font-size: x-large"
placeholder="真实姓名" clearable></el-input> v-if="certification.status === 1">已经认证
</el-link>
<el-link :underline="false" type="primary" style="font-size: x-large"
v-else-if="certification.status === 0">审核中
</el-link>
<el-link v-else-if="certification.status === 2" :underline="false" type="danger"
style="font-size: x-large"
>审核失败
</el-link>
<el-link :underline="false" type="info" style="font-size: x-large" v-else>待认证</el-link>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item>
<el-row> <el-form-item label="真实姓名">
<el-col :span="22"> <el-row :gutter="36">
<el-input v-model="form.newpassword" clearable prefix-icon="el-icon-s-order" <el-col :span="18">
placeholder="身份证号"></el-input> <el-link :underline="false">{{ certification.name }}</el-link>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="身份证号">
<el-form-item> <el-row :gutter="36">
<el-row> <el-col :span="18">
<el-col :span="22"> <el-link :underline="false">{{ certification.card }}</el-link>
<el-input v-model="form.surepassword" clearable prefix-icon="el-icon-house" </el-col>
placeholder="居住地"></el-input> </el-row>
</el-form-item>
<el-form-item label="手机号码">
<el-row :gutter="36">
<el-col :span="18">
<el-link :underline="false">{{ certification.mobile }}</el-link>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="联系地址">
<el-row :gutter="36">
<el-col :span="18">
<el-link :underline="false">{{ certification.addr }}</el-link>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="身份证" style="width: 100%"> <el-form-item v-if="certification.status === 2" label="审核信息" style="width: 700px">
<el-row :gutter="36">
<el-col :span="18">
<el-link :underline="false" type="danger">{{ certification.msg }}</el-link>
</el-col>
</el-row>
</el-form-item>
<div class="appdownload"> <el-form-item v-if="certification.status === 2">
<el-image <el-row :gutter="36">
style="width: 155px;height: 188px;margin-right: 20px;background-color: #d1eef9;float: left" <el-col :span="18">
fit="scale-down" <el-button type="danger" @click="recommit">重新提交审核</el-button>
@click="delscreen(screen.id)" </el-col>
v-for="(screen) in user_certification" :key="screen.id" :src="screen.url" alt=""/> </el-row>
<div style="width: 155px;height: 188px;background-color: #d1eef9;float: left" </el-form-item>
v-if="user_certification && user_certification.length < 2">
<el-upload
drag
action="#"
accept=".png , .jpg , .jpeg"
:before-upload="beforeAvatarUpload">
<i class="el-icon-upload"></i>
</el-upload>
</div>
</div> </el-form>
</div>
<div v-else>
<el-form ref="form" :model="form">
<el-form-item label="真实姓名">
<el-row :gutter="36">
<el-col :span="18">
<el-input v-model="form.name" autofocus="true" prefix-icon="el-icon-user"
placeholder="请输入真实姓名" clearable></el-input>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="身份证号">
<el-row :gutter="36">
<el-col :span="18">
<el-input v-model="form.card" clearable prefix-icon="el-icon-s-order"
placeholder="请输入身份证号"></el-input>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="居住地址">
<el-row :gutter="36">
<el-col :span="18">
<el-input v-model="form.addr" clearable prefix-icon="el-icon-house"
placeholder="请输入现居住地址"></el-input>
</el-col>
</el-row>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item label="手机号码">
<el-row> <el-row :gutter="36">
<el-col :span="22"> <el-col :span="18">
<el-input v-model="form.mobile" ref="phone" clearable <el-input v-model="form.mobile" ref="phone" clearable
prefix-icon="el-icon-mobile" placeholder="请输入手机号码" maxlength="11"></el-input> prefix-icon="el-icon-mobile" placeholder="请输入手机号码" maxlength="11"></el-input>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item style="height: 40px" v-if="cptch.cptch_image">
<el-row style="height: 40px" :gutter="10"> <el-form-item label="手机验证码">
<el-col :span="11"> <el-row :gutter="11">
<el-input placeholder="请输入图片验证码" v-model="userinfo.authcode" maxlength="6"></el-input> <el-col :span="12">
<el-input v-model="form.auth_key" prefix-icon="el-icon-mobile" placeholder="请输入您收到的验证码"
maxlength="6"></el-input>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="6">
<el-button type="info" @click="getsmsemailcode('sms',form.mobile)" plain
style="border-radius:4px;cursor:pointer;height: 40px;background-color: #ecf5ff;color: #dd6161">
获取验证码
</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="图片验证码" v-if="cptch.cptch_image">
<el-row :gutter="11">
<el-col :span="12">
<el-input placeholder="请输入图片验证码" v-model="form.authcode" maxlength="6"></el-input>
</el-col>
<el-col :span="6">
<el-image <el-image
style="margin:0px 4px;border-radius:4px;cursor:pointer;height: 40px" style="border-radius:4px;cursor:pointer;height: 40px"
:src="cptch.cptch_image" :src="cptch.cptch_image"
fit="contain" @click="get_auth_code"> fit="contain" @click="get_auth_code">
</el-image> </el-image>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-row :gutter="10"> <el-row style="margin-left: 88px">
<el-col :span="16"> <el-col :span="8">
<el-input v-model="userinfo.auth_key" prefix-icon="el-icon-mobile" placeholder="请输入您收到的验证码" <div id="captcha" ref="captcha"></div>
maxlength="6"></el-input>
</el-col>
<el-col :span="6">
<el-button type="info" @click="getsmsemailcode('sms',userinfo.mobile)" plain
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 40px;background-color: #ecf5ff;color: #dd6161">
获取验证码
</el-button>
</el-col> </el-col>
</el-row>
</el-form-item>
<el-form-item label="身份证号">
<el-row style="height: 40px" :gutter="36">
<el-col :span="19">
<div class="appdownload">
<el-upload
drag
action="#"
accept=".png , .jpg , .jpeg"
:before-upload="upload_one">
<el-tooltip v-if="user_certification.one" placement="top">
<div slot="content">上传身份证<i style="color: #2abb9d!important;">国徽面</i>照片</div>
<img :src="user_certification.one"
class="avatar">
</el-tooltip>
<i v-else class="avatar-uploader-icon" style="text-align: center">
上传身份证<i style="color: #2abb9d!important;">国徽面</i>照片
</i>
</el-upload>
</div>
<div class="appdownload">
<el-upload
drag
action="#"
accept=".png , .jpg , .jpeg"
:before-upload="upload_two">
<el-tooltip v-if="user_certification.two" placement="top">
<div slot="content">上传身份证<i style="color: #2abb9d!important;">人像面</i>照片</div>
<img :src="user_certification.two"
class="avatar">
</el-tooltip>
<i v-else class="avatar-uploader-icon" style="text-align: center">
上传身份证<i style="color: #2abb9d!important;">人像面</i>照片
</i>
</el-upload>
</div>
<div class="appdownload">
<el-upload
drag
action="#"
accept=".png , .jpg , .jpeg"
:before-upload="upload_three">
<el-tooltip v-if="user_certification.three" placement="top">
<div slot="content">上传<i style="color: #2abb9d!important;">手持身份证</i>照片</div>
<img :src="user_certification.three"
class="avatar">
</el-tooltip>
<i v-else class="avatar-uploader-icon" style="text-align: center">
上传<i style="color: #2abb9d!important;">手持身份证</i>照片
</i>
</el-upload>
</div>
</el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
@ -96,75 +206,199 @@
<el-form-item> <el-form-item>
<el-row> <el-row>
<el-col :span="22"> <el-col :span="22">
<el-button type="danger" @click="updatepasswd">提交</el-button> <el-button type="danger" @click="commit">提交</el-button>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<script> <script>
import {userinfos} from "../restful"; import {getAuthcTokenFun, registerFun, user_certification} from "../restful";
import {AvatarUploadUtils} from "../utils"; import {AvatarUploadUtils, checkphone, geetest} from "../utils";
export default { export default {
name: "FirUserProfileCertification", name: "FirUserProfileCertification",
data() { data() {
return { return {
form: { form: {
oldpassword: '', name: '',
newpassword: '', card: '',
surepassword: '' addr: '',
mobile: '15738962953',
authcode: '',
cptch_key: '',
auth_token: '',
}, },
cptch: {}, cptch: {"cptch_image": '', "cptch_key": '', "length": 8},
userinfo: {}, user_certification: {'one': '', 'two': '', 'three': ''},
user_certification: [], certification: {'code': 0},
} }
}, methods: { }, methods: {
beforeAvatarUpload(file) { recommit() {
// eslint-disable-next-line no-unused-vars this.certification.code = -1;
this.get_user_certification({methods: 'GET', data: {act: 'certpiccertinfo'}});
this.get_auth_code();
},
commit() {
for (let v of Object.keys(this.form)) {
if (this.form[v].length < 4) {
this.$message.error("填写错误,请检查");
return false
}
}
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
if (reg.test(this.form.card) === false) {
this.$message.error("身份证输入不合法");
return false;
}
let checkp = checkphone(this.form.mobile);
if (!checkp) {
this.$message.error("手机号输入不合法");
return false;
}
this.get_user_certification({methods: 'POST', data: this.form})
},
get_user_certification(parmas) {
user_certification(res => {
if (res.code === 1000) {
if (parmas.methods === 'POST') {
this.$message.success("信息提交成功,正在审核中")
}
const ft = ['one', 'two', 'three'];
if (res.data.certification && res.data.certification.length > 0) {
for (let v of res.data.certification) {
this.user_certification[ft[v.type - 1]] = v.certification_url;
}
}
if (res.data.user_certification) {
this.form = res.data.user_certification;
}
} else {
this.$message.error(res.msg)
}
}, parmas)
},
getsmsemailcode(act, target) {
let picode = {
"authcode": this.form.authcode,
"cptch_key": this.cptch.cptch_key,
};
let cptch_flag = this.form.authcode.length === this.cptch.length;
if (this.cptch.cptch_key === '' || !this.cptch.cptch_key) {
cptch_flag = true
}
if (cptch_flag) {
let checkp = checkphone(this.form.mobile);
if (!checkp) {
this.$message({
message: '手机号输入有误',
type: 'error'
});
return
}
} else {
this.$message({
message: '图片验证码有误',
type: 'error'
});
return
}
let params = {'act': act, 'target': target, 'ext': picode, 'user_id': target, 'ftype': 'certification'};
this.form.email = this.form.mobile;
if (this.cptch.geetest) {
geetest(this, params, (n_params) => {
this.get_phone_code(n_params);
})
} else {
this.get_phone_code(params)
}
},
get_phone_code(params) {
getAuthcTokenFun(data => {
if (data.code === 1000) {
let msg = '您正在进行身份认证,验证码已经发送您手机';
this.$notify({
title: '验证码',
message: msg,
type: 'success'
});
this.form.auth_token = data.data.auth_token;
} else {
this.$message.error(data.msg)
}
}, {"methods": 'POST', 'data': params})
},
get_auth_code() {
registerFun(data => {
if (data.code === 1000) {
this.cptch = data.data;
this.form.cptch_key = this.cptch.cptch_key;
} else {
this.$message({
message: data.msg,
type: 'error'
});
}
}, {
"methods": "GET",
"data": {}
});
},
upload_one(file) {
return this.beforeAvatarUpload(file, 1)
},
upload_two(file) {
return this.beforeAvatarUpload(file, 2)
},
upload_three(file) {
return this.beforeAvatarUpload(file, 3)
},
beforeAvatarUpload(file, ptype) {
return AvatarUploadUtils(this, file, { return AvatarUploadUtils(this, file, {
'app_id': this.$store.state.userinfo.uid, 'app_id': this.$store.state.userinfo.uid,
'upload_key': file.name, 'upload_key': file.name,
'ftype': 'certification', 'ftype': 'certification',
'ext': {'type': 1} 'ext': {'ptype': ptype}
// eslint-disable-next-line no-unused-vars
}, res => { }, res => {
this.get_user_certification({methods: 'GET'});
}); });
}, },
updatepasswd() { init() {
if (this.form.newpassword === this.form.surepassword) { if (this.$store.state.userinfo.certification) {
this.certification = this.$store.state.userinfo.certification;
userinfos(data => {
if (data.code === 1000) {
this.userinfo = data.data;
this.$message.success('密码修改成功');
} else {
this.$message.error('密码修改失败,' + data.msg);
}
}, {
"methods": 'PUT', 'data': {
"oldpassword": this.form.oldpassword,
"surepassword": this.form.surepassword
}
});
} else {
this.$message.error('密码不一致');
} }
} if (this.certification.code === -1) {
this.get_user_certification({methods: 'GET', data: {act: 'certpiccertinfo'}});
this.get_auth_code();
}
},
}, mounted() { }, mounted() {
this.$store.dispatch('douserInfoIndex', 2); this.$store.dispatch('douserInfoIndex', 2);
this.init();
}, watch: {
'$store.state.userinfo': function () {
this.init();
}
} }
} }
</script> </script>
<style scoped> <style scoped>
.el-form { .el-form {
max-width: 360px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
} }
@ -176,14 +410,22 @@
.appdownload /deep/ .el-upload-dragger { .appdownload /deep/ .el-upload-dragger {
background: #d1eef9; background: #d1eef9;
width: 155px; width: 200px;
height: 188px; height: 166px;
} }
.appdownload /deep/ .el-icon-upload { .appdownload /deep/ .el-icon-upload {
margin-top: 45%; margin-top: 45%;
} }
.appdownload {
float: left;
width: 200px;
height: 166px;
background-color: #d1eef9;
}
.avatar-uploader .el-upload { .avatar-uploader .el-upload {
border: 1px dashed #d9d9d9; border: 1px dashed #d9d9d9;
border-radius: 6px; border-radius: 6px;
@ -197,11 +439,11 @@
} }
.avatar-uploader-icon { .avatar-uploader-icon {
font-size: 28px; /*font-size: 28px;*/
color: #8c939d; color: #8c939d;
width: 178px; width: 158px;
height: 178px; height: 158px;
line-height: 178px; line-height: 158px;
text-align: center; text-align: center;
} }

@ -513,3 +513,18 @@ export function my_order(callBack, params, load = true) {
true true
); );
} }
/**实名认证 */
export function user_certification(callBack, params, load = true) {
getData(
params.methods,
USERSEVER + '/certification',
params.data,
data => {
callBack(data);
},
load,
true,
true
);
}

@ -47,7 +47,8 @@ class Migration(migrations.Migration):
('pay_time', models.DateTimeField(blank=True, null=True, verbose_name='付款时间')), ('pay_time', models.DateTimeField(blank=True, null=True, verbose_name='付款时间')),
('cancel_time', models.DateTimeField(blank=True, null=True, verbose_name='订单取消时间')), ('cancel_time', models.DateTimeField(blank=True, null=True, verbose_name='订单取消时间')),
( (
'account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 'account',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
), ),
] ]

@ -0,0 +1,17 @@
# Generated by Django 3.0.3 on 2021-04-08 18:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0033_auto_20210407_2045'),
]
operations = [
migrations.AddField(
model_name='usercertificationinfo',
name='msg',
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='备注'),
),
]

@ -0,0 +1,18 @@
# Generated by Django 3.0.3 on 2021-04-08 18:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0034_usercertificationinfo_msg'),
]
operations = [
migrations.AddField(
model_name='usercertificationinfo',
name='reviewed_time',
field=models.DateTimeField(default='2021-04-08 16:28:28.142887', verbose_name='审核时间'),
preserve_default=False,
),
]

@ -404,7 +404,9 @@ class UserCertificationInfo(models.Model):
mobile = models.BigIntegerField(verbose_name="手机号码", unique=True, null=False) mobile = models.BigIntegerField(verbose_name="手机号码", unique=True, null=False)
status_choices = ((0, '审核中'), (1, '审核成功'), (2, '审核失败')) status_choices = ((0, '审核中'), (1, '审核成功'), (2, '审核失败'))
status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="审核状态") status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="审核状态")
msg = models.CharField(max_length=512, null=True, blank=True, verbose_name="备注")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
reviewed_time = models.DateTimeField(auto_now_add=False, verbose_name="审核时间")
class Meta: class Meta:
verbose_name = '用户认证信息' verbose_name = '用户认证信息'

@ -16,7 +16,7 @@ Including another URLconf
from django.urls import path, re_path, include from django.urls import path, re_path, include
from api.views.login import LoginView, UserInfoView, RegistView, AuthorizationView, ChangeAuthorizationView, \ from api.views.login import LoginView, UserInfoView, RegistView, AuthorizationView, ChangeAuthorizationView, \
UserApiTokenView UserApiTokenView, CertificationView
from api.views.logout import LogoutView from api.views.logout import LogoutView
from api.views.apps import AppsView, AppInfoView, AppReleaseinfoView from api.views.apps import AppsView, AppInfoView, AppReleaseinfoView
from api.views.download import ShortDownloadView from api.views.download import ShortDownloadView
@ -51,5 +51,6 @@ urlpatterns = [
re_path("^supersign/udid$", AppUDIDUsedView.as_view()), re_path("^supersign/udid$", AppUDIDUsedView.as_view()),
re_path("^package_prices$", PriceView.as_view()), re_path("^package_prices$", PriceView.as_view()),
re_path("^orders$", OrderView.as_view()), re_path("^orders$", OrderView.as_view()),
re_path("^certification$", CertificationView.as_view()),
] ]

@ -45,7 +45,8 @@ class UserInfoSerializer(serializers.ModelSerializer):
model = models.UserInfo model = models.UserInfo
# fields="__all__" # fields="__all__"
fields = ["username", "uid", "mobile", "job", "email", "domain_name", "role", "first_name", fields = ["username", "uid", "mobile", "job", "email", "domain_name", "role", "first_name",
'head_img', 'storage_active', 'supersign_active', 'free_download_times', 'download_times'] 'head_img', 'storage_active', 'supersign_active', 'free_download_times', 'download_times',
'certification']
head_img = serializers.SerializerMethodField() head_img = serializers.SerializerMethodField()
@ -58,6 +59,25 @@ class UserInfoSerializer(serializers.ModelSerializer):
def get_free_download_times(self, obj): def get_free_download_times(self, obj):
return get_user_free_download_times(obj.id) return get_user_free_download_times(obj.id)
certification = serializers.SerializerMethodField()
def get_certification(self, obj):
result = {'code': -1}
certification_obj = models.UserCertificationInfo.objects.filter(user_id=obj).first()
if certification_obj:
result['code'] = 0
card = certification_obj.card
data = {
'name': certification_obj.name,
'addr': certification_obj.addr,
'card': "%s%s%s" % (card[:4], '*' * (len(card) - 8), card[-4:]),
'mobile': certification_obj.mobile,
'status': certification_obj.status,
'msg': certification_obj.msg,
}
result.update(data)
return result
class AppsSerializer(serializers.ModelSerializer): class AppsSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -332,3 +352,20 @@ class OrdersSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.Order model = models.Order
exclude = ["id"] exclude = ["id"]
class CertificationSerializer(serializers.ModelSerializer):
class Meta:
model = models.CertificationInfo
fields = ["certification_url", "type"]
certification_url = serializers.SerializerMethodField()
def get_certification_url(self, obj):
return get_download_url_from_context(self, '', obj.certification_url)
class UserCertificationSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserCertificationInfo
exclude = ["id", "user_id", "created_time"]

@ -1,7 +1,7 @@
from django.contrib import auth from django.contrib import auth
from api.models import Token, UserInfo from api.models import Token, UserInfo, UserCertificationInfo, CertificationInfo
from rest_framework.response import Response from rest_framework.response import Response
from api.utils.serializer import UserInfoSerializer from api.utils.serializer import UserInfoSerializer, CertificationSerializer, UserCertificationSerializer
from django.core.cache import cache from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
import binascii import binascii
@ -16,6 +16,7 @@ from api.utils.storage.caches import login_auth_failed, set_default_app_wx_easy
import logging import logging
from api.utils.geetest.geetest_utils import first_register, second_validate from api.utils.geetest.geetest_utils import first_register, second_validate
from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle, GetAuthC1Throttle, GetAuthC2Throttle from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle, GetAuthC1Throttle, GetAuthC2Throttle
from api.utils.storage.storage import Storage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -68,7 +69,7 @@ def CheckRegisterUerinfo(target, act, key):
res.data["auth_token"] = token res.data["auth_token"] = token
else: else:
res.code = 1009 res.code = 1009
res.msg = "该手机号今日注册次数已经达到上限" res.msg = "该手机号今日使用次数已经达到上限"
else: else:
res.code = 1005 res.code = 1005
res.msg = "手机号校验失败" res.msg = "手机号校验失败"
@ -108,7 +109,7 @@ def CheckRegisterUerinfo(target, act, key):
return res return res
def CheckChangeUerinfo(target, act, key, user): def CheckChangeUerinfo(target, act, key, user, ftype=None):
res = BaseResponse() res = BaseResponse()
res.data = {} res.data = {}
@ -122,7 +123,7 @@ def CheckChangeUerinfo(target, act, key, user):
if is_valid_phone(target) and str(user.mobile) != str(target): if is_valid_phone(target) and str(user.mobile) != str(target):
if login_auth_failed("get", times_key): if login_auth_failed("get", times_key):
login_auth_failed("set", times_key) login_auth_failed("set", times_key)
if UserInfo.objects.filter(mobile=target): if UserInfo.objects.filter(mobile=target) and ftype is None:
res.code = 1005 res.code = 1005
res.msg = "手机号已经存在" res.msg = "手机号已经存在"
else: else:
@ -255,8 +256,12 @@ class LoginView(APIView):
import hashlib import hashlib
response = BaseResponse() response = BaseResponse()
user_id = request.data.get('user_id', None) user_id = request.data.get('user_id', None)
sha = hashlib.sha1(user_id.encode("utf-8")) if user_id:
response.data = first_register(sha.hexdigest(), request.META.get('REMOTE_ADDR')) sha = hashlib.sha1(user_id.encode("utf-8"))
response.data = first_register(sha.hexdigest(), request.META.get('REMOTE_ADDR'))
else:
response.code = 1002
response.msg = '参数错误'
return Response(response.dict) return Response(response.dict)
@ -533,6 +538,7 @@ class ChangeAuthorizationView(APIView):
act = request.data.get("act", None) act = request.data.get("act", None)
target = request.data.get("target", None) target = request.data.get("target", None)
ext = request.data.get("ext", None) ext = request.data.get("ext", None)
ftype = request.data.get("ftype", None)
if REGISTER.get("captcha"): if REGISTER.get("captcha"):
if ext and valid_captcha(ext.get("cptch_key", None), ext.get("authcode", None), target): if ext and valid_captcha(ext.get("cptch_key", None), ext.get("authcode", None), target):
pass pass
@ -541,7 +547,16 @@ class ChangeAuthorizationView(APIView):
res.msg = "图片验证码有误" res.msg = "图片验证码有误"
return Response(res.dict) return Response(res.dict)
res = CheckChangeUerinfo(target, act, 'change', request.user) if REGISTER.get("geetest"):
geetest = request.data.get("geetest", None)
if geetest and second_validate(geetest).get("result", "") == "success":
pass
else:
res.code = 1018
res.msg = "geetest验证有误"
return Response(res.dict)
res = CheckChangeUerinfo(target, act, 'change', request.user, ftype)
return Response(res.dict) return Response(res.dict)
@ -567,3 +582,69 @@ class UserApiTokenView(APIView):
except Exception as e: except Exception as e:
logger.error("User %s api_token save failed. Excepiton:%s" % (request.user, e)) logger.error("User %s api_token save failed. Excepiton:%s" % (request.user, e))
return self.get(request) return self.get(request)
class CertificationView(APIView):
authentication_classes = [ExpiringTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
res.data = {}
act = request.query_params.get("act", "")
user_certification_obj = UserCertificationInfo.objects.filter(user_id=request.user).first()
if user_certification_obj and user_certification_obj.status == 1:
return Response(res.dict)
if 'certinfo' in act:
if user_certification_obj:
user_certification_serializer = UserCertificationSerializer(user_certification_obj)
res.data["user_certification"] = user_certification_serializer.data
if 'certpic' in act:
certification_obj = CertificationInfo.objects.filter(user_id=request.user).all()
if certification_obj:
storage = Storage(request.user)
certification_serializer = CertificationSerializer(certification_obj, many=True,
context={"storage": storage})
res.data["certification"] = certification_serializer.data
return Response(res.dict)
def post(self, request):
res = BaseResponse()
data = request.data
user_certification_obj = UserCertificationInfo.objects.filter(user_id=request.user).first()
if user_certification_obj and user_certification_obj.status == 1:
return Response(res.dict)
try:
if REGISTER.get("captcha"):
if data and valid_captcha(data.get("cptch_key", None), data.get("authcode", None), data.get("mobile")):
pass
else:
res.code = 1009
res.msg = "图片验证码有误"
return Response(res.dict)
is_valid, target = is_valid_sender_code('sms', data.get("auth_token", None), data.get("auth_key", None))
if is_valid and str(target) == str(data.get("mobile")):
if login_auth_failed("get", data.get("mobile")):
del data["cptch_key"]
del data["authcode"]
del data["auth_key"]
del data["auth_token"]
UserCertificationInfo.objects.update_or_create(user_id=request.user, status=0, defaults=data)
return self.get(request)
else:
res.code = 1006
logger.error("username:%s failed too try , locked" % (request.user,))
res.msg = "用户注册失败次数过多,已被锁定,请1小时之后再次尝试"
else:
res.code = 1001
res.msg = "短信验证码有误"
except Exception as e:
logger.error("%s UserCertificationInfo save %s failed Exception: %s" % (request.user, data, e))
res.msg = "数据异常,请检查"
res.code = 1002
return Response(res.dict)

@ -7,7 +7,7 @@
from api.utils.app.apputils import get_random_short, SaveAppInfos from api.utils.app.apputils import get_random_short, SaveAppInfos
from api.utils.storage.storage import Storage from api.utils.storage.storage import Storage
from api.utils.storage.caches import upload_file_tmp_name, del_cache_response_by_short from api.utils.storage.caches import upload_file_tmp_name, del_cache_response_by_short
from api.models import Apps, AppReleaseInfo, UserInfo, AppScreenShot from api.models import Apps, AppReleaseInfo, UserInfo, AppScreenShot, CertificationInfo
from api.utils.app.randomstrings import make_app_uuid from api.utils.app.randomstrings import make_app_uuid
from rest_framework.views import APIView from rest_framework.views import APIView
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
@ -344,13 +344,21 @@ class UploadView(APIView):
elif ftype == 'certification': elif ftype == 'certification':
ext = certinfo.get('ext', None) ext = certinfo.get('ext', None)
if ext: if ext:
ptype = ext.get('type', None) ptype = ext.get('ptype', None)
if ptype is not None: if ptype is not None and ptype in [1, 2, 3]:
pass certification_obj = CertificationInfo.objects.filter(user_id=request.user,
pass type=ptype).first()
else: if certification_obj:
pass old_certification_url = certification_obj.certification_url
certification_obj.certification_url = new_upload_key
certification_obj.save()
storage.delete_file(old_certification_url)
else:
CertificationInfo.objects.create(user_id=request.user, type=ptype,
certification_url=new_upload_key)
storage.rename_file(upload_key, new_upload_key)
return Response(res.dict)
return Response(res.dict) return Response(res.dict)
else: else:
pass pass

Loading…
Cancel
Save