c5_labsci/fapp/ciyon_ap/components/ciy-auth/ciy-auth.vue
2026-01-26 17:45:00 +08:00

530 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view :animation="anidataauth" class="auth">
<view class="swiper" :style="{transform: 'translateX(' + pg + 'vw)',height:height}">
<!-- 注册页面 -->
<view class="content">
<view class="title">
<ciy-gesture @toleft="gopg(1)" class="mid" style="letter-spacing: 1em;">{{lang('login.tabreg')}}</ciy-gesture>
<view class="itm" @tap="gopg(1)">{{lang('login.tablogin')}}</view>
<view class="itm" @tap="gopg(2)">{{lang('login.tabforget')}}</view>
</view>
<form @submit="submitreg">
<view style="width:600rpx;margin:0.5em auto;">
<view class="ciy-form">
<label>{{lang('login.form_mobile')}}</label>
<view>
<ciy-input type="number" name="user" placeholder="请输入手机号"></ciy-input>
</view>
</view>
<view class="ciy-form">
<label>{{lang('login.form_setpass')}}</label>
<view>
<ciy-input name="pass" type="password" placeholder="请输入登录密码"></ciy-input>
</view>
</view>
<view class="ciy-form">
<label>{{lang('login.form_repass')}}</label>
<view>
<ciy-input name="pass2" type="password" placeholder="再次输入登录密码"></ciy-input>
</view>
</view>
<view style="margin:1em 0;">
<ciy-checkitem sq v-model="xieyi">
已阅读并同意《
<text @tap="gourl" :data-url="lang('login.xieyi')" style="color:#0000FF;">
用户协议
</text>》。
</ciy-checkitem>
</view>
<view style="text-align: center;padding-top:1em;">
<button class="btn lg cc" form-type="submit">{{lang('login.btn_reg')}}</button>
</view>
</view>
</form>
</view>
<!-- 登录页面 -->
<view class="content">
<view class="title">
<view @tap="gopg(0)" style="padding-right:2em;">{{lang('login.tabreg')}}</view>
<ciy-gesture @todown="close" class="mid" style="letter-spacing: 1em;padding-left: 0.5em;" @toright="gopg(0)" @toleft="gopg(2)">{{lang('login.tablogin')}}</ciy-gesture>
<view @tap="gopg(2)">{{lang('login.tabforget')}}</view>
</view>
<form @submit="submitlogin">
<view style="width:600rpx;margin:0.5em auto;">
<view class="ciy-form">
<label @tap="showver">{{lang('login.form_mobile')}}</label>
<view>
<ciy-input :value="user" type="number" name="user" placeholder="请输入手机号"></ciy-input>
</view>
</view>
<view class="ciy-form">
<label>{{lang('login.form_pass')}}</label>
<view>
<ciy-input :value="pass" name="pass" type="password" placeholder="请输入密码"></ciy-input>
</view>
</view>
<view style="margin:1em 0;">
<ciy-checkitem sq v-model="xieyi">
已阅读并同意《
<text @tap="gourl" :data-url="lang('login.xieyi')" style="color:#0000FF;">
用户协议
</text>》。
</ciy-checkitem>
</view>
<view style="text-align: center;padding-top:1em;">
<button class="btn lg cc" style="width: 100%;" form-type="submit">{{lang('login.btn_login')}}</button>
</view>
<view style="display:inline-block;min-width:2em;min-height:2em;">
<view v-if="tusers.length > 0" class="cuser">
<view class="itm code" @tap="setdbg(index)" v-for="(item,index) in tusers" :key="index">
{{item.name}}
</view>
</view>
</view>
<view v-if="ver<-6" style="text-align: center;color:var(--txt1)">众产(杭州)科技有限公司</view>
</view>
</form>
</view>
<!-- 忘记密码页面 -->
<view class="content">
<view class="title">
<view @tap="gopg(0)">{{lang('login.tabreg')}}</view>
<view @tap="gopg(1)">{{lang('login.tablogin')}}</view>
<ciy-gesture @toright="gopg(1)" class="mid">{{lang('login.tabforget')}}</ciy-gesture>
</view>
<form @submit="submitforget">
<view style="width:600rpx;margin:0.5em auto;">
<view class="ciy-form">
<label>{{lang('login.form_mobile')}}</label>
<view>
<ciy-input v-model="forgetmobile" name="user" type="number" placeholder="请输入手机号"></ciy-input>
</view>
</view>
<view class="ciy-form">
<label>验证码</label>
<view>
<ciy-capcode hasmore name="captcha" btntxt="发送短信" :account="forgetmobile" :func="smsfunc" placeholder="请输入验证码"></ciy-capcode>
</view>
</view>
<view class="ciy-form">
<label>新密码</label>
<view>
<ciy-input name="pass" type="password" placeholder="请输入新密码"></ciy-input>
</view>
</view>
<view class="ciy-form">
<label>再次输入</label>
<view>
<ciy-input name="pass2" type="password" placeholder="再次输入新密码"></ciy-input>
</view>
</view>
<view style="text-align: center;padding-top:1em;">
<button class="btn lg cc" form-type="submit">{{lang('login.btn_forget')}}</button>
</view>
</view>
</form>
</view>
</view>
</view>
<view :animation="anidatabg" class="authbg" @tap="close"></view>
</template>
<style scoped>
.cuser {
display: flex;
flex-wrap: wrap;
padding-bottom: 2em;
}
.cuser>.itm {
margin: 0.5em;
}
.title {
display: flex;
text-align: center;
font-size: 1em;
margin: 1em;
align-items: flex-end;
}
.title>.itm {
text-decoration: underline;
padding: 0 1em;
min-width: 4em;
}
.title .mid {
text-decoration: none;
font-weight: bolder;
font-size: 1.6em;
padding: 0;
flex: 1;
background: linear-gradient(30deg, var(--man5), var(--man7));
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.auth {
position: fixed;
z-index: 50002;
bottom: -2em;
left: 0;
right: 0;
transform: translateY(28em)
}
.authbg {
position: fixed;
z-index: 50001;
top: 0;
bottom: 0;
left: -0.5em;
right: -0.5em;
touch-action: none;
background: linear-gradient(0deg, var(--bg2), transparent);
transform: translateY(100vh);
}
.auth .swiper {
display: flex;
width: 300vw;
flex-wrap: nowrap;
transition: all 0.3s;
}
.auth .content {
width: 100vw;
margin: 0 0.5em;
border-radius: 1em 1em 0 0;
background: radial-gradient(at center 5em, var(--bg1), var(--bg3));
overflow: auto;
box-shadow: 2px 2px 20px -10px var(--bg9);
}
</style>
<script>
import md5 from '@/util/md5.js';
export default {
props: {},
data() {
return {
forgetmobile: '',
smsfunc: '',
user: '',
pass: '',
xieyi: false,
pg: -100,
ver: 6,
height: '28em',
tusers: [],
anidataauth: {},
anidatabg: {},
};
},
options: {
virtualHost: true
},
mounted() {},
methods: {
// 打开登录弹窗
async Open(authcb, must) {
this.authcb = authcb;
if (!must) {
var me = this.getme();
if (me.id > 0) {
authcb({
me: me
});
this.authcb = null;
return;
}
//#ifdef MP-WEIXIN
var upid = this.toint(this.getstorage('upid'));
var res = await uni.login({
provider: 'weixin',
scopes: 'auth_base',
onlyAuthorize: true
});
var retjson = await this.callfunc({
func: 'login.json_wx_autouser',
loadhide: true,
data: {
code: res.code,
upid: upid
}
});
if (retjson.code != 1)
return;
this.tologin(retjson);
return;
//#endif
}
// 动画显示
var animation = uni.createAnimation({
timingFunction: 'ease'
});
animation.translateY(0);
animation.step({
duration: 700
});
this.anidataauth = animation.export();
var animation = uni.createAnimation({
timingFunction: 'ease'
});
animation.translateY(0);
animation.step({
duration: 400
});
this.anidatabg = animation.export();
this.user = this.getstorage('login_mb');
this.smsfunc = 'login.json_sendsms';
},
// 登录提交
async submitlogin(e) {
var app = getApp();
var post = e.detail.value;
if (post.user.length > 0)
this.setstorage('login_mb', post.user);
if (post.user == '')
return this.toast('请填写手机号');
if (post.pass == '')
return this.toast('请填写密码');
if (!this.xieyi && await this.askmsg('是否阅读并同意协议?', '同意') != 'ok')
return;
// 时间戳(毫秒级)
post.auth = (new Date()).getTime();
post.appcid = app.globalData._appcid;
// 密码加密md5(用户输入密码MD5 + auth时间戳)
var userPassMd5 = md5.md5(post.pass);
post.pass = md5.md5(userPassMd5 + post.auth);
// 调用登录接口
var retjson = await this.callfunc({
func: 'login.json_login_mobile',
data: post
});
if (retjson.code != 1)
return this.toast(retjson.errmsg);
this.setstorage('_dbgs', retjson.dbgs);
this.tologin(retjson);
},
// 注册提交
async submitreg(e) {
var app = getApp();
var post = e.detail.value;
if (post.user == '')
return this.toast('请填写手机号');
if (post.pass == '')
return this.toast('请填写密码');
if (post.pass != post.pass2)
return this.toast('两次密码输入不同');
if (!this.xieyi && await this.askmsg('是否阅读并同意协议?', '同意') != 'ok')
return;
post.upid = app.getstorage('upid');
post.appcid = app.globalData._appcid;
// 密码加密MD5(用户输入密码)
post.pass = md5.md5(post.pass);
post.pass2 = '';
// 调用注册接口
var retjson = await this.callfunc({
func: 'login.json_reg_mobile',
data: post
});
if (retjson.code != 1)
return this.toast(retjson.errmsg);
this.setstorage('login_mb', post.user);
this.tologin(retjson);
this.toast('注册成功,已自动登录');
},
// 忘记密码提交
async submitforget(e) {
var app = getApp();
var post = e.detail.value;
if (post.user == '')
return this.toast('请填写手机号');
if (post.captcha == '')
return this.toast('请填写验证码');
if (post.pass == '')
return this.toast('请填写密码');
if (post.pass != post.pass2)
return this.toast('两次密码输入不同');
// 密码加密MD5(用户输入密码)
post.pass = md5.md5(post.pass);
// 调用忘记密码接口
var retjson = await this.callfunc({
func: 'login.json_forgetpass',
data: post
});
if (retjson.code != 1)
return this.toast(retjson.errmsg);
this.tologin(retjson);
this.toast('密码找回成功,已自动登录');
},
// 登录成功处理
tologin(json) {
var app = getApp();
var auth = app.setuserstorage(json);
if (this.authcb != null)
this.authcb(auth);
this.authcb = null;
this.close();
},
// 切换页面
gopg(idx) {
this.pg = idx * -100;
},
// 关闭登录弹窗
close() {
if (this.authcb != null)
this.authcb({
me: {
id: 0
}
});
this.authcb = null;
var animation = uni.createAnimation({
timingFunction: 'ease'
});
animation.translateY(this.height);
animation.step({
duration: 1000
});
this.anidataauth = animation.export();
var animation = uni.createAnimation({
timingFunction: 'ease'
});
animation.translateY('100vh');
animation.step({
duration: 1000
});
this.anidatabg = animation.export();
},
// 显示调试用户
async showver(e) {
this.ver--;
if (this.ver !== 0)
return;
var app = getApp();
if (app.globalData._wxenv == 'release')
return;
var retjson = await this.callfunc({
func: 'login.json_debug_list',
data: {}
});
this.tusers = retjson.list;
},
// 设置调试用户
setdbg(idx) {
this.xieyi = true;
this.user = this.tusers[idx].user;
this.pass = this.tusers[idx].pass;
},
// 获取用户信息
getme() {
return uni.getStorageSync('me') || {id: 0};
},
// 获取本地存储
getstorage(key) {
return uni.getStorageSync(key) || '';
},
// 设置本地存储
setstorage(key, value) {
uni.setStorageSync(key, value);
},
// 转整数
toint(val) {
return parseInt(val) || 0;
},
// 提示框
toast(msg) {
uni.showToast({
title: msg,
icon: 'none',
duration: 2000
});
},
// 确认弹窗
askmsg(content, confirmText = '确定') {
return new Promise((resolve) => {
uni.showModal({
title: '提示',
content: content,
confirmText: confirmText,
success: (res) => {
resolve(res.confirm ? 'ok' : 'cancel');
}
});
});
},
// 接口调用封装
async callfunc(options) {
return new Promise((resolve) => {
uni.request({
url: 'http://localhost:5173/ambap/login.php', // 根据实际接口地址调整
method: 'POST',
data: {
act: options.func,
...options.data
},
success: (res) => {
resolve(res.data || {code: 0, errmsg: '接口返回异常'});
},
fail: (err) => {
this.toast('网络请求失败');
resolve({code: 0, errmsg: '网络错误'});
}
});
});
},
// 跳转链接(用户协议)
gourl(e) {
var url = e.currentTarget.dataset.url;
if (url) {
uni.navigateTo({
url: url
});
}
}
}
}
</script>