546 lines
14 KiB
Vue
546 lines
14 KiB
Vue
<template>
|
||
<view class="login-wrapper">
|
||
|
||
<!-- 切换环境提示 -->
|
||
<EnvChangeTips ref="envChangeTipsRef" @change="vdata.siteInfos = storageManage.siteInfos()" />
|
||
|
||
<view class="login-top">
|
||
<text>欢迎回来,请登录</text>
|
||
<image @tap="envChangeTipsRef.tapFunc()" style="width: 320rpx; height: 76rpx"
|
||
:src="vdata.siteInfos.appTopImgUrl" />
|
||
</view>
|
||
<view class="login-bottom jeepay-form">
|
||
|
||
<!-- 不需要label, 需要修改: label-width="0" -->
|
||
<uni-forms ref="loginFormRef" label-width="0" :model="vdata.formData" :rules="rules">
|
||
<view class="u-p-b-30">
|
||
<my-tabs size="large" @change="accountTypeChange" v-model="accountType.sel" :list="accountType.list"
|
||
textKey="label"></my-tabs>
|
||
</view>
|
||
<view v-if="vdata.loginType == 'pwd' ">
|
||
<template v-if="accountType.sel==1">
|
||
<uni-forms-item name="merchantName">
|
||
<uni-easyinput class='jeepay-easyinput' placeholder="请输入商户号"
|
||
v-model="vdata.formData.merchantName" :clearable="false">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-user.svg" class="input-icon" />
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
</template>
|
||
|
||
<uni-forms-item name="username">
|
||
<uni-easyinput class='jeepay-easyinput' placeholder="请输入登录名/手机号"
|
||
v-model="vdata.formData.username" :clearable="false">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-user.svg" class="input-icon" />
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
|
||
<uni-forms-item name="pwd">
|
||
<uni-easyinput class='jeepay-easyinput' :type="vdata.isShowPwd ? 'text' : 'password'"
|
||
v-model="vdata.formData.pwd" :clearable="false" placeholder="请输入登录密码">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-pw.svg" class="input-icon" />
|
||
</template>
|
||
<template #suffixIcon>
|
||
<view class='show-tips' @tap="vdata.isShowPwd = !vdata.isShowPwd ">
|
||
{{ vdata.isShowPwd ? '隐藏' : '显示' }}
|
||
</view>
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
|
||
<uni-forms-item name="code">
|
||
<!-- 手机验证码, 不限制数字还是本文, 如果发送为文本则无需app升级。 -->
|
||
<view style="display: flex;" class="u-flex u-flex-y-center">
|
||
<uni-easyinput class='jeepay-easyinput' :maxlength="6" placeholder="请输入验证码"
|
||
v-model="vdata.formData.code" :clearable="false">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-sms-code.svg" class="input-icon" />
|
||
</template>
|
||
</uni-easyinput>
|
||
<image :src="vdata.formData.img" class=" u-m-b-50"
|
||
style="width: 200rpx; height: 80rpx;margin-left: 10rpx;" @click="getCode" mode="">
|
||
</image>
|
||
</view>
|
||
</uni-forms-item>
|
||
|
||
</view>
|
||
|
||
<view v-if="vdata.loginType == 'sms' ">
|
||
<uni-forms-item name="loginPhone">
|
||
<uni-easyinput class='jeepay-easyinput' v-model="vdata.formData.loginPhone" type="number"
|
||
:maxlength="11" :disabled="!vdata.allowSendMsgFlag" placeholder="请输入手机号" :clearable="false">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-phone.svg" class="input-icon" />
|
||
</template>
|
||
<template #suffixIcon>
|
||
<view class='show-tips' @tap="sendSmscodeFunc">{{ vdata.sendMsgText }}</view>
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
<uni-forms-item>
|
||
<!-- 手机验证码, 不限制数字还是本文, 如果发送为文本则无需app升级。 -->
|
||
<view style="display: flex;">
|
||
<uni-easyinput class='jeepay-easyinput' :maxlength="6" placeholder="请输入验证码"
|
||
v-model="vdata.formData.vercode" :clearable="false">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-sms-code.svg" class="input-icon" />
|
||
</template>
|
||
</uni-easyinput>
|
||
<image :src="vdata.formData.imgCodeUrl"
|
||
style="width: 200rpx; height: 110rpx;margin-left: 10rpx;" @click="getCode" mode="">
|
||
</image>
|
||
</view>
|
||
</uni-forms-item>
|
||
|
||
<uni-forms-item name="smsCode">
|
||
<!-- 手机验证码, 不限制数字还是本文, 如果发送为文本则无需app升级。 -->
|
||
<uni-easyinput class='jeepay-easyinput' :maxlength="6" placeholder="请输入手机验证码"
|
||
v-model="vdata.formData.smsCode" :clearable="false">
|
||
<template #prefixIcon>
|
||
<image src="@/static/login/icon-sms-code.svg" class="input-icon" />
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
|
||
</view>
|
||
|
||
</uni-forms>
|
||
|
||
<view class="agreement-policy">
|
||
<JeepayCheckbox v-model:checked="vdata.isSelectedAgreement" />
|
||
同意
|
||
<text class="agreement" @click="toPrivacy">《用户服务协议》</text>
|
||
<text>与</text>
|
||
<text class="policy" @click="toPrivacy">《隐私政策》</text>
|
||
</view>
|
||
|
||
|
||
<!-- <view class="agreement-policy">
|
||
<JeepayCheckbox v-model:checked="vdata.isSelectedAgreement" />
|
||
同意
|
||
<text class="agreement" @click="go.to('PAGES_STATIC_AGREEMENT')">《用户服务协议》</text>
|
||
<text>与</text>
|
||
<text class="policy" @click="toPrivacy">《隐私政策》</text>
|
||
<text class="policy" @click="go.to('PAGES_STATIC_POLICY')">《隐私政策》</text>
|
||
</view> -->
|
||
|
||
|
||
<Button @tap="loginFunc">登录</Button>
|
||
|
||
<!-- <view class="register-box">
|
||
<view class="register">
|
||
<text>还没有账号?</text> <text @tap="go.to('PAGES_REGISTER')">去注册></text>
|
||
</view>
|
||
<view class="forget" @tap="go.to('PAGES_FORGET_PASSWORD')">忘记密码</view>
|
||
</view>
|
||
<view class="swidth-login" @click="changeLoginType">
|
||
{{ vdata.loginType == 'pwd' ? '短信验证码登录' : '账号密码登录' }}
|
||
<image src="@/static/login/icon-arrow-left.svg"></image>
|
||
</view> -->
|
||
|
||
</view>
|
||
</view>
|
||
<JAgree service="PAGES_STATIC_AGREEMENT" privacy="PAGES_FORGET_PASSWORD" ref="refAgr"
|
||
@agree="vdata.isSelectedAgreement = true" />
|
||
</template>
|
||
<script setup>
|
||
import {
|
||
encrypt
|
||
} from '@/commons/utils/rsaEncrypt.js'
|
||
|
||
import {
|
||
ref,
|
||
reactive,
|
||
onMounted,
|
||
watch
|
||
} from 'vue';
|
||
import {
|
||
$loginByPwd,
|
||
$phoneCodeLogin,
|
||
$userInfo,
|
||
$sendSms,
|
||
$getSiteInfos,
|
||
$getUploadImgSize,
|
||
$isCode
|
||
} from '@/http/apiManager.js';
|
||
import storageManage from '@/commons/utils/storageManage.js'
|
||
import infoBox from '@/commons/utils/infoBox.js';
|
||
import go from '@/commons/utils/go.js'
|
||
import timer from '@/commons/utils/timer.js'
|
||
import formUtil from '@/commons/utils/formUtil.js'
|
||
import EnvChangeTips from './components/EnvChangeTips.vue'
|
||
import dayjs from 'dayjs' //时间格式库
|
||
import {
|
||
getExtStoreId
|
||
} from "@/commons/utils/versionManage.js"
|
||
import {
|
||
$login
|
||
} from '@/http/newApi/login.js';
|
||
import {
|
||
login,
|
||
getCodeImg
|
||
} from '@/http/yskApi/login.js';
|
||
|
||
const accountType = reactive({
|
||
list: [{
|
||
label: '商户',
|
||
value: 'merchant'
|
||
},
|
||
{
|
||
label: '员工',
|
||
value: 'staff'
|
||
},
|
||
],
|
||
sel: 0
|
||
})
|
||
|
||
const loginFormRef = ref()
|
||
const envChangeTipsRef = ref()
|
||
const refAgr = ref()
|
||
const rules = {
|
||
merchantName: {
|
||
rules: [formUtil.rules.requiredInputShowToast('商户号')],
|
||
},
|
||
username: {
|
||
rules: [formUtil.rules.requiredInputShowToast('用户名')],
|
||
},
|
||
pwd: {
|
||
rules: [formUtil.rules.requiredInputShowToast('密码')],
|
||
},
|
||
safetyCode: {
|
||
rules: [formUtil.rules.requiredInputShowToast('安全码')],
|
||
},
|
||
code: {
|
||
rules: [formUtil.rules.requiredInputShowToast('验证码')],
|
||
},
|
||
loginPhone: {
|
||
rules: [formUtil.rules.requiredInputShowToast('手机号')],
|
||
},
|
||
|
||
smsCode: {
|
||
rules: [formUtil.rules.requiredInputShowToast('短信验证码')],
|
||
},
|
||
}
|
||
|
||
const vdata = reactive({
|
||
|
||
isShowPwd: false, // 是否显示密码
|
||
loginType: 'pwd', // 类型切换: pwd or sms
|
||
isShowSafetyCode: false, // 是否显示安全码输入框
|
||
allowSendMsgFlag: true, // 是否可发送短信验证码
|
||
sendMsgText: '发送验证码',
|
||
isSelectedAgreement: false, // 勾选隐私协议
|
||
|
||
siteInfos: storageManage.siteInfos() || {},
|
||
|
||
formData: {
|
||
username: '', // 账密登录: 用户名
|
||
pwd: '', // 账密登录: 密码
|
||
rememberMe: false,
|
||
code: '',
|
||
uuid: '',
|
||
merchantName: '',
|
||
loginType: 'merchant'
|
||
},
|
||
|
||
})
|
||
// #ifdef H5
|
||
vdata.formData.username = '17792050546'
|
||
vdata.formData.pwd = 'qwer1234'
|
||
// #endif
|
||
// #ifdef MP-WEIXIN
|
||
// vdata.formData.username = '15699991111'
|
||
// vdata.formData.pwd = 'qwer1234'
|
||
// #endif
|
||
|
||
function accountTypeChange(e) {
|
||
// #ifdef H5
|
||
if (e == 1) {
|
||
vdata.formData.merchantName = '18049104914'
|
||
vdata.formData.username = '13666666666'
|
||
vdata.formData.pwd = '123456'
|
||
} else {
|
||
vdata.formData.pwd = 'qwer1234'
|
||
}
|
||
// #endif
|
||
}
|
||
|
||
const getCode = () => {
|
||
getCodeImg().then(res => {
|
||
vdata.formData.img = res.img
|
||
vdata.formData.uuid = res.uuid
|
||
})
|
||
}
|
||
|
||
getCode()
|
||
|
||
onMounted(() => {
|
||
// getExtStoreId()
|
||
|
||
// 查询是否包含网站信息, 否则更新
|
||
|
||
// if(!vdata.siteInfos || Object.keys(vdata.siteInfos) <= 0){
|
||
// $getSiteInfos().then( ( { bizData } ) => {
|
||
// vdata.siteInfos = storageManage.siteInfos(bizData)
|
||
// })
|
||
// }
|
||
// 获取商户信息,有就回显
|
||
let info = uni.getStorageSync('MerchantId')
|
||
if (info.merchantName) {
|
||
vdata.formData.merchantName = info.merchantName
|
||
vdata.formData.username = info.username
|
||
}
|
||
})
|
||
|
||
// 切换登录方式
|
||
function changeLoginType() {
|
||
vdata.loginType = vdata.loginType == 'pwd' ? 'sms' : 'pwd';
|
||
}
|
||
|
||
function loginFunc() {
|
||
|
||
// 表单验证
|
||
formUtil.validate(loginFormRef.value).then(() => {
|
||
if (!vdata.isSelectedAgreement) {
|
||
infoBox.showToast('请勾选同意用户服务协议与隐私政策')
|
||
return false
|
||
}
|
||
let loginPromise = null;
|
||
if (vdata.loginType == 'pwd') { // 用户名密码登录
|
||
// loginPromise = $loginByPwd(vdata.formData.username, vdata.formData.pwd, vdata.formData.safetyCode)
|
||
loginPromise = login({
|
||
username: vdata.formData.username,
|
||
password: encrypt(vdata.formData.pwd),
|
||
rememberMe: false,
|
||
code: vdata.formData.code,
|
||
uuid: vdata.formData.uuid,
|
||
merchantName: vdata.formData.merchantName,
|
||
loginType: accountType.list[accountType.sel].value
|
||
})
|
||
|
||
} else if (vdata.loginType == 'sms') { // 短信验证码登录
|
||
loginPromise = $phoneCodeLogin(vdata.formData.loginPhone, vdata.formData.smsCode)
|
||
}
|
||
|
||
if (loginPromise == null) {
|
||
return false;
|
||
}
|
||
|
||
|
||
// 请求后的操作
|
||
loginPromise.then(res => {
|
||
// 登录成功
|
||
loginFinishFunc(res)
|
||
// 保存商户号
|
||
uni.setStorageSync('MerchantId', {
|
||
merchantName: vdata.formData.merchantName,
|
||
username: vdata.formData.username,
|
||
})
|
||
}).catch(e => {
|
||
getCode()
|
||
})
|
||
})
|
||
|
||
}
|
||
const toPrivacy = () => {
|
||
// #ifdef APP-PLUS
|
||
go.to('PAGES_STATIC_POLICY')
|
||
// #endif
|
||
// 打开小程序隐私政策
|
||
// #ifdef MP-WEIXIN
|
||
wx.openPrivacyContract({
|
||
fail: () => {
|
||
uni.showToast({
|
||
title: '打开失败请稍后重试', // 打开失败
|
||
icon: 'none'
|
||
})
|
||
},
|
||
})
|
||
// #endif
|
||
}
|
||
watch(() => accountType.sel, (newval) => {
|
||
if (newval == 1) {
|
||
vdata.formData.merchantName = uni.getStorageSync('merchantName') || ''
|
||
} else {
|
||
vdata.formData.username = ''
|
||
}
|
||
})
|
||
// 封装登录成功后的操作
|
||
async function loginFinishFunc(loginBizData) {
|
||
// 保存 token
|
||
storageManage.setLogin(loginBizData)
|
||
storageManage.token(loginBizData.token)
|
||
storageManage.shopId(loginBizData.shopId)
|
||
storageManage.shopUserId(loginBizData.user.user.id)
|
||
storageManage.userInfo(loginBizData)
|
||
var time1 = new Date();
|
||
var time2 = new Date(loginBizData.expireDate);
|
||
let les = (time1.getTime() - time2.getTime()) / 86400000;
|
||
uni.showToast({
|
||
title: '店铺账号有限期至' + loginBizData.expireDate + ',店铺账号到期剩余' + Math.abs(les.toFixed(0)) + '天!',
|
||
icon: 'none'
|
||
});
|
||
|
||
setTimeout(() => {
|
||
// 跳转到首页
|
||
go.to("PAGES_INDEX", {
|
||
isGetCid: true
|
||
}, go.GO_TYPE_RELAUNCH)
|
||
}, 1000)
|
||
|
||
}
|
||
|
||
// 点击发送验证码的函数
|
||
function sendSmscodeFunc() {
|
||
// 按钮禁用
|
||
if (!vdata.allowSendMsgFlag) {
|
||
return false;
|
||
}
|
||
|
||
// 验证失败
|
||
if (!formUtil.regexp.mobile.test(vdata.formData.loginPhone)) {
|
||
return infoBox.showToast("请输入正确的手机号")
|
||
}
|
||
|
||
if (!vdata.formData.vercode) {
|
||
return infoBox.showToast("请输入图像验证码");
|
||
}
|
||
|
||
vdata.allowSendMsgFlag = false; // 按钮禁用
|
||
|
||
|
||
let data = {
|
||
phone: vdata.formData.loginPhone,
|
||
vercode: vdata.formData.vercode,
|
||
vercodeToken: vdata.formData.vercodeToken,
|
||
}
|
||
|
||
// 发送短信验证码
|
||
$sendSms(data, 'auth').then(({
|
||
bizData
|
||
}) => {
|
||
infoBox.showSuccessToast('验证码发送成功')
|
||
timer.startTimeoutTask(1, 60, (subTime) => {
|
||
|
||
if (subTime <= 0) { // 任务结束
|
||
vdata.sendMsgText = '发送验证码'
|
||
vdata.allowSendMsgFlag = true;
|
||
return false;
|
||
}
|
||
|
||
vdata.sendMsgText = `${subTime}s后可重新发送`
|
||
})
|
||
}).catch(() => {
|
||
vdata.allowSendMsgFlag = true;
|
||
})
|
||
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.login-wrapper {
|
||
min-height: 100vh;
|
||
background-color: $v-color-bgrey;
|
||
|
||
.login-top {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 376rpx;
|
||
padding: 176rpx 70rpx 0;
|
||
box-sizing: border-box;
|
||
background: url("/static/indexImg/user-bg.svg") center center no-repeat;
|
||
background-size: cover;
|
||
|
||
text:first-child {
|
||
margin-bottom: 30rpx;
|
||
font-size: 38rpx;
|
||
font-weight: 500;
|
||
color: rgba(0, 0, 0, 0.8);
|
||
}
|
||
|
||
text:last-child {
|
||
font-size: 50rpx;
|
||
font-weight: 600;
|
||
color: #48C0FF;
|
||
}
|
||
}
|
||
|
||
.login-bottom {
|
||
height: calc(100vh - 376rpx);
|
||
padding: 50rpx;
|
||
box-sizing: border-box;
|
||
border-radius: 60rpx 60rpx 0 0;
|
||
background-color: #fff;
|
||
|
||
.show-tips {
|
||
color: rgba(88, 132, 204, 1);
|
||
font-weight: 400;
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.agreement-policy {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 0 30rpx;
|
||
margin-top: 10rpx;
|
||
margin-bottom: 50rpx;
|
||
font-size: 26rpx;
|
||
color: #8C8C8C;
|
||
|
||
.select-box {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.select-img {
|
||
width: 46rpx;
|
||
height: 46rpx;
|
||
}
|
||
}
|
||
|
||
.agreement,
|
||
.policy {
|
||
color: #1D79FD;
|
||
}
|
||
}
|
||
|
||
.register-box {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 0 30rpx;
|
||
margin-top: 50rpx;
|
||
font-size: 26rpx;
|
||
font-weight: 400;
|
||
|
||
.register {
|
||
text:last-child {
|
||
color: #1D79FD;
|
||
}
|
||
}
|
||
|
||
.forget {
|
||
color: #1D79FD;
|
||
}
|
||
}
|
||
|
||
.swidth-login {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-top: 212rpx;
|
||
font-size: 30rpx;
|
||
font-weight: 400;
|
||
color: rgba(77, 77, 77, 1);
|
||
|
||
image {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |