源文件

This commit is contained in:
gyq
2024-05-23 14:39:33 +08:00
commit a1128dd791
2997 changed files with 500069 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
<!--
环境变量切换组件
@author terrfly
@site https://www.jeequan.com
@date 2022/04/12 10:14
-->
<template>
<view>
<!-- 当包含环境变量 && 不是生产环境时 -->
<view
class="login-test"
v-if="
vdata.currentEnvEnum &&
vdata.currentEnvEnum != appConfig.ENV_ENUM.PRODUCTION
"
><text>{{ vdata.currentEnvEnum }}</text></view
>
<!-- 切换环境提示 -->
<uni-popup ref="uniPopupRef" :mask-click="false" :open="false">
<view class="uni-popup-dialog">
<image
@tap="uniClose"
class="uni-dialog-close"
src="/static/img/account-delete.svg"
mode="scaleToFill"
/>
<view class="uni-dialog-button-box">
<view
class="uni-dialog-button"
style="border-bottom: 2rpx solid #e1e1e1"
@click="changeEnvFunc(appConfig.ENV_ENUM.DEVELOPMENT)"
><text>开发环境</text></view
>
<view
class="uni-dialog-button"
style="border-bottom: 2rpx solid #e1e1e1"
@click="changeEnvFunc(appConfig.ENV_ENUM.TEST)"
><text>测试环境</text></view
>
<view
class="uni-dialog-button"
style="border-bottom: 2rpx solid #e1e1e1"
@click="changeEnvFunc(appConfig.ENV_ENUM.DEMO)"
><text>演示环境</text></view
>
<view
class="uni-dialog-button"
@click="changeEnvFunc(appConfig.ENV_ENUM.PRODUCTION)"
><text>生产环境</text></view
>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue'
import appConfig from '@/config/appConfig.js'
import envConfig from '@/env/config.js'
import storageManage from '@/util/storageManage.js'
const uniPopupRef = ref()
const vdata = reactive({
currentEnvEnum: '', // 当前环境变量
count: 0, // 当前点击次数
})
onMounted(() => {
vdata.currentEnvEnum = storageManage.env()
})
// 父组件的点击事件
function tapFunc() {
vdata.count++
if (vdata.count >= 10) {
vdata.count = 0
uniPopupRef.value.open()
}
}
// 改变环境函数
function changeEnvFunc(envMode) {
vdata.currentEnvEnum = envMode //显示信息
envConfig.changeEnv(envMode) //更改请求包
storageManage.env(envMode)
uniPopupRef.value.close() //弹层关闭
}
// 关闭弹窗
function uniClose() {
uniPopupRef.value.close()
}
defineExpose({ tapFunc })
</script>
<style lang="scss" scoped>
.uni-popup-dialog {
position: relative;
box-sizing: border-box;
width: 500rpx;
height: 750rpx;
overflow: hidden;
border-radius: 30rpx;
background-color: #ffffff;
display: flex;
flex-direction: column;
justify-content: space-around;
.uni-dialog-close {
position: absolute;
top: 30rpx;
right: 30rpx;
width: 50rpx;
height: 50rpx;
}
.uni-dialog-button-box {
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-around;
flex-direction: column;
text-align: center;
padding: 0 40rpx;
.uni-dialog-button {
width: 100%;
height: 150rpx;
line-height: 150rpx;
text {
font-size: 40rpx;
}
}
}
}
.login-test {
position: absolute;
bottom: 70rpx;
width: 100%;
text-align: center;
text {
color: #666f80;
}
}
</style>

View File

@@ -0,0 +1,73 @@
<template>
<view class="login-wrapper">
<LoginInput pd="0 50rpx" v-model:value="loginInfo.userName"></LoginInput>
<LoginInput title="密码" place="请输入账号密码" :password="!isOpenEyes" v-model:value="loginInfo.passwordType">
<view class="right-eyes" @tap="isOpenEyes = !isOpenEyes">
<image :src="eyeImg[isOpenEyes ? 1 : 0]" mode="scaleToFill" />
</view>
</LoginInput>
<LoginButton @login="login" :forgotPassword="true" :isRegister="true"></LoginButton>
</view>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue"
import LoginInput from "@/components/newComponents/LoginInput/LoginInput"
import LoginButton from "./LoginButton"
import { $login, $getPasswordRules } from "@/http/apiManager.js"
import reg from "@/hooks/validate"
import { Base64 } from "js-base64"
onMounted(() => {
getRules()
})
const eyeImg = reactive(["/static/loginImg/login-eye-close.svg", "/static/loginImg/login-eye-open.svg"])
const emits = defineEmits(["successLogin"])
const selected = ref(false)
const isOpenEyes = ref(false)
const loginInfo = reactive({}) //密码信息
const rules = ref({})
const getRules = () => {
$getPasswordRules().then((res) => {
rules.value.rule = new RegExp(res.bizData.regexpRules)
rules.value.ruleText = res.bizData.errTips
})
}
const login = () => {
if (!loginInfo.userName && !loginInfo.passwordType) {
uni.showToast({
title: "请输入账号和密码",
icon: "none",
})
} else {
$login({
ia: Base64.encode(loginInfo.userName),
ip: Base64.encode(loginInfo.passwordType),
// #ifdef APP-PLUS
lt: Base64.encode("APP"),
// #endif
// #ifdef H5 || MP-WEIXIN
lt: Base64.encode("LITE"),
// #endif
}).then((res) => {
const { bizData } = res
emits("successLogin", bizData.iToken)
})
}
}
</script>
<style lang="scss" scoped>
image {
display: block;
width: 36rpx;
height: 36rpx;
}
.right-eyes {
display: flex;
justify-content: center;
align-items: center;
width: 110rpx;
height: 110rpx;
background-color: transparent;
}
</style>

View File

@@ -0,0 +1,362 @@
<template>
<JPopup ref="popup" @onClose="reset" @onOpen="isFlag">
<view class="register-main bgF" v-if="flag">
<LoginInput
title="手机号"
v-model:value="registerInfo.phone"
place="请输入注册手机号"
type="number"
:rules="{ name: 'phone', rule: 'REG_Phone' }"
pd="50rpx 50rpx 35rpx 50rpx"
>
<view class="sms-tips" v-if="registerInfo.phone.length == 11" @tap="createInterval">
<text v-if="smsNumber != 60">{{ smsNumber }}s</text>
{{ smsNumber !== 60 ? '后可重新发送' : '发送验证码' }}
</view>
</LoginInput>
<LoginInput
title="图形验证码"
v-model:value="registerInfo.vercode"
place="请输入图形验证码"
pd="0rpx 50rpx 35rpx 50rpx"
>
<view style="padding-top: 5px;">
<image :src="registerInfo.imgCodeUrl" style="width: 200rpx; height: 110rpx;margin-left: 10rpx;" @click="getCode" mode=""></image>
</view>
</LoginInput>
<LoginInput
title="验证码"
v-model:value="registerInfo.code"
place="请输入短信验证码"
type="number"
:rules="{ name: 'code', rule: 'REG_NotNUll' }"
pd="0 50rpx 35rpx 50rpx"
></LoginInput>
<LoginInput
title="代理商名称"
v-model:value="registerInfo.agentName"
place="请输入代理商名称"
:rules="{ name: 'agentName', rule: 'REG_NotNUll' }"
pd="0 50rpx 35rpx 50rpx"
></LoginInput>
<LoginInput
title="密码"
v-model:value="registerInfo.password"
place="请输入密码"
:rules="{ name: 'password', rule: 'REG_NotNUll' }"
:password="!isPassword"
pd="0 50rpx 35rpx 50rpx"
>
<view class="right-eyes" @tap="isPassword = !isPassword">
<image :src="eyeImg[isPassword ? 1 : 0]" mode="scaleToFill" />
</view>
</LoginInput>
<LoginInput
title="确认密码"
v-model:value="registerInfo.confirmPwd"
:rules="{ name: 'confirmPwd', rule: 'REG_NotNUll' }"
place="请再次输入密码"
:password="!isOpenEyes"
pd="0 50rpx 35rpx 50rpx"
>
<view class="right-eyes" @tap="isOpenEyes = !isOpenEyes">
<image :src="eyeImg[isOpenEyes ? 1 : 0]" mode="scaleToFill" />
</view>
</LoginInput>
<LoginInput title="邀请码" v-model:value="registerInfo.inviteCode" place="请输入邀请码(选填)" pd="0 50rpx 70rpx 50rpx"></LoginInput>
<view class="agreement-wrapper">
<button class="agree-item" id="agree-btn" open-type="agreePrivacyAuthorization"
@agreeprivacyauthorization="handAgree">
<view class="agreement-garden" :class="[selected ? 'selected' : '']" @tap="selected = !selected"></view>
</button>
同意
<view @tap="toPage('/pages/login/serviceAgreement')"> 用户服务协议 </view>
<view @tap="toPrivacy"> 隐私政策 </view>
</view>
<view class="register-button">
<view @tap="close">取消</view>
<view class="confirm" @tap="confirm">确认注册</view>
</view>
</view>
</JPopup>
<JAgree service="/pages/login/serviceAgreement" privacy="/pages/login/privacyPolicy" ref="refAgr" @agree="selected = true"/>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { $sendMessage, $register, $getPasswordRules,$isCode } from '@/http/apiManager.js'
import { Base64 } from 'js-base64'
import { validateArray } from '@/hooks/rules'
import LoginInput from '@/components/newComponents/LoginInput/LoginInput'
import JPopup from '@/components/newComponents/JPopup/JPopup'
onMounted(() => {
getRules()
})
const vdata = reactive({})
const popup = ref(null)
const refAgr = ref(null)
const flag = ref(false)
const rules = ref({}) //密码规则
const registerInfo = ref({
phone: '',
inviteCode: '',
imgCodeUrl:'',
vercodeToken:'',
vercode:'',
})
const eyeImg = reactive(['/static/loginImg/login-eye-close.svg', '/static/loginImg/login-eye-open.svg'])
const selected = ref(false)
const isOpenEyes = ref(false)
const isPassword = ref(false)
const emits = defineEmits(['registerClose'])
const smsNumber = ref(60)
let interval = null
// 创建定时器
let createInterval = () => {
if (interval) return
sendMsg()
interval = setInterval(() => {
openInterval()
}, 1000)
}
const getCode=()=>{
$isCode().then(res=>
{
console.log(res);
registerInfo.value.imgCodeUrl=res.bizData.imageBase64Data
registerInfo.value.vercodeToken=res.bizData.vercodeToken
})
}
const getRules = () => {
$getPasswordRules().then((res) => {
rules.value.rule = new RegExp(res.bizData.regexpRules)
rules.value.ruleText = res.bizData.errTips
})
}
// smsNumber -1 倒计时
const openInterval = () => {
smsNumber.value--
if (smsNumber.value <= 0) {
smsNumber.value = 60
clearInterval(interval)
interval = null
}
}
// 发送短信验证码"
const sendMsg = () => {
if (interval) return
$sendMessage({
phone: registerInfo.value.phone,
smsType: 'register',
vercodeToken:registerInfo.value.vercodeToken,
vercode:registerInfo.value.vercode
})
.then((res) => {
const { bizData } = res
uni.showToast({
title: '发送成功',
icon: 'success',
mask: true,
})
})
.catch((err) => {
clearInterval(interval)
interval = null
})
}
const isFlag = () => {
flag.value = true
}
const open = () => {
popup.value.open()
getCode()
}
const close = () => {
reset()
popup.value.close()
}
const reset = () => {
flag.value = false
registerInfo.value = { phone: '' }
}
// 确认注册
const confirm = () => {
if (validateArray(registerInfo.value)) {
if (registerInfo.value.password !== registerInfo.value.confirmPwd)
return uni.showToast({
title: '两次密码输入不一致',
icon: 'none',
mask: true,
})
if (!rules.value.rule.test(registerInfo.value.confirmPwd))
return uni.showToast({
title: rules.value.ruleText,
icon: 'none',
})
if (!selected.value)
return refAgr.value.open()
uni.showLoading({
title: '正在注册中',
mask: true,
})
$register({
agentName: registerInfo.value.agentName,
phone: Base64.encode(registerInfo.value.phone),
code: Base64.encode(registerInfo.value.code),
confirmPwd: Base64.encode(registerInfo.value.confirmPwd),
inviteCode: registerInfo.value.inviteCode,
}).then((res) => {
uni.hideLoading()
uni.showToast({
title: '注册成功请登录',
icon: 'none',
mask: true,
})
close()
})
}
}
// 隐私政策页面
const toPrivacy = () => {
// #ifdef APP-PLUS
uni.navigateTo({
url: '/pages/login/privacyPolicy',
})
// #endif
// #ifdef MP-WEIXIN
wx.openPrivacyContract(
{
fail: () => {
uni.showToast({
title: '打开失败请稍后重试', // 打开失败
icon: 'none'
})
},
}
)
// #endif
}
// #ifdef MP-WEIXIN
const getPrivacy = () => {
wx.getPrivacySetting({
success: (r) => {
Object.assign(vdata, r)
if (vdata.needAuthorization) {
wx.onNeedPrivacyAuthorization(res => {
vdata.resolve = res
})
}
}
})
}
getPrivacy()
// #endif
const handAgree = () => {
// #ifdef MP-WEIXIN
if (vdata.needAuthorization) {
vdata.resolve({ buttonId: 'agree-btn', event: 'agree' })
}
// #endif
}
const toPage = (url) => {
uni.navigateTo({ url })
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
.register-main {
width: 100%;
height: 70vh;
overflow-y: scroll;
border-radius: 32rpx 32rpx 0px 0px;
.register-button {
display: flex;
justify-content: space-between;
padding: 0 30rpx 70rpx 30rpx;
view {
flex: 1;
padding: 32rpx;
margin: 0 20rpx;
border-radius: 20rpx;
background-color: #f2f2f2;
text-align: center;
}
.confirm {
background-color: $primaryColor;
color: #fff;
}
}
}
.agreement-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
font-size: 24rpx;
white-space: nowrap;
transform: translateY(-40rpx);
color: #8c8c8c;
view {
margin: 0 10rpx;
color: $primaryColor;
}
.agreement-garden {
position: relative;
width: 30rpx;
height: 30rpx;
border-radius: 50%;
border: 2rpx solid $primaryColor;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
width: 80%;
height: 80%;
border-radius: 50%;
}
}
}
.selected::after {
background-color: $primaryColor;
}
.sms-tips {
font-size: 28rpx;
color: $primaryColor;
margin-right: 30rpx;
}
.right-eyes {
display: flex;
justify-content: center;
align-items: center;
width: 110rpx;
height: 110rpx;
background-color: transparent;
}
image {
width: 36rpx;
height: 36rpx;
}
.agree-item {
padding: 0;
margin: 0;
line-height: 0;
border-radius: 0;
background-color: transparent;
&::after{
display: none;
}
}
</style>

View File

@@ -0,0 +1,121 @@
<template>
<view class="sms-wrapper">
<LoginInput pd="0 50rpx" v-model:value="loginInfo.phone" title="手机号" type="number" place="请输入登录名/手机号">
<view class="sms-tips" v-if="loginInfo.phone.length == 11" @tap="createInterval">
<text v-if="smsNumber != 60">{{ smsNumber }}s</text>
{{ smsNumber !== 60 ? '后可重新发送' : '发送验证码' }}
</view>
</LoginInput>
<LoginInput
title="图形验证码"
v-model:value="loginInfo.vercode"
place="请输入图形验证码"
pd="50rpx 50rpx 0rpx 50rpx"
>
<view style="padding-top: 5px;">
<image :src="loginInfo.imgCodeUrl" style="width: 200rpx; height: 110rpx;margin-left: 10rpx;" @click="getCode" mode=""></image>
</view>
</LoginInput>
<LoginInput v-model:value="loginInfo.verificationCode" title="短信验证码" type="number" place="请输入短信验证码"></LoginInput>
<LoginButton @login="phoneCodeLogin" :isRegister="true"></LoginButton>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { $sendMessage, $login, $userInfo, $phoneCodeLogin, $getCompanyInfo,$isCode } from '@/http/apiManager.js'
import { Base64 } from 'js-base64'
import LoginInput from '@/components/newComponents/LoginInput/LoginInput'
import LoginButton from './LoginButton'
const emits = defineEmits(['successLogin'])
const loginInfo = reactive({
phone: '',
imgCodeUrl:'',
vercode:'',
vercodeToken:'',
})
const smsNumber = ref(60)
let interval = null
// 创建定时器
let createInterval = () => {
if (interval) return
sendMsg()
interval = setInterval(() => {
openInterval()
}, 1000)
}
const getCode=()=>{
$isCode().then(res=>
{
console.log(res);
loginInfo.imgCodeUrl=res.bizData.imageBase64Data
loginInfo.vercodeToken=res.bizData.vercodeToken
})
}
getCode()
// smsNumber -1 倒计时
const openInterval = () => {
smsNumber.value--
if (smsNumber.value <= 0) {
smsNumber.value = 60
clearInterval(interval)
interval = null
}
}
// 发送短信验证码"
const sendMsg = () => {
if (interval) return
$sendMessage({
phone: loginInfo.phone,
smsType: 'auth',
vercodeToken:loginInfo.vercodeToken,
vercode:loginInfo.vercode
})
.then((res) => {
const { bizData } = res
uni.showToast({
title: '发送成功',
icon: 'success',
mask: true,
})
})
.catch((err) => {
smsNumber.value = 60
clearInterval(interval)
})
}
// 验证码登录
const phoneCodeLogin = () => {
if (!loginInfo.phone.length != 11 && !loginInfo.verificationCode) {
uni.showToast({
title: '请输入手机号和验证码',
icon: 'none',
})
} else {
$phoneCodeLogin({
phone: Base64.encode(loginInfo.phone),
code: Base64.encode(loginInfo.verificationCode),
// #ifdef APP-PLUS
lt: Base64.encode('APP'),
// #endif
// #ifdef H5 || MP-WEIXIN
lt: Base64.encode('LITE'),
// #endif
}).then((res) => {
const { bizData } = res
emits('successLogin', bizData.iToken)
})
}
}
</script>
<style lang="scss" scoped>
.sms-wrapper {
.sms-tips {
font-size: 28rpx;
color: $primaryColor;
margin-right: 30rpx;
}
}
</style>

View File

@@ -0,0 +1,167 @@
<template>
<view class="agreement-wrapper">
<button class="agree-item" id="agree-btn" open-type="agreePrivacyAuthorization"
@agreeprivacyauthorization="handAgree">
<view class="agreement-garden" :class="[selected ? 'selected' : '']" @tap="selected = !selected"></view>
</button>
同意
<view @tap="toPage('/pages/login/serviceAgreement')"> 用户服务协议 </view>
<view @tap="toPage('/pages/login/privacyPolicy')"> 隐私政策 </view>
<!-- <view @tap="toPrivacy"> 隐私政策 </view> -->
</view>
<JButton pdTop="0" @HandleTouch="login" bottom="30rpx">登录</JButton>
<view class="register-wrapper">
<view v-if="isRegister">还没有账号?<text @tap="register.open()">去注册</text> </view>
<view v-if="forgotPassword"><text @tap="jumpPage">忘记密码</text></view>
</view>
<JRegister ref="register"></JRegister>
<JAgree service="/pages/login/serviceAgreement" privacy="/pages/login/privacyPolicy" ref="refAgr" @agree="selected = true"/>
</template>
<script setup>
import { ref ,reactive,onMounted} from "vue"
import JButton from "@/components/newComponents/JButton/JButton"
import JRegister from "./JRegister.vue"
import { clearRulesArray } from "@/hooks/rules"
const register = ref(null)
const vdata = reactive({})
const props = defineProps({
forgotPassword: {
type: Boolean,
default: false,
},
isRegister: {
type: Boolean,
default: false,
},
})
const refAgr = ref(null)
const selected = ref(false)
const emits = defineEmits(["login"])
onMounted(()=>{
refAgr.value.open()
console.log(uni.getAccountInfoSync().miniProgram);
})
const login = () => {
if (!selected.value)
return refAgr.value.open()
emits("login")
}
const toPage = (url) => {
uni.navigateTo({ url })
}
const jumpPage = () => {
clearRulesArray()
uni.navigateTo({ url: "/pages/login/forgetPassword" })
}
// 隐私政策页面
const toPrivacy = () => {
// #ifdef APP-PLUS
uni.navigateTo({
url: '/pages/login/privacyPolicy',
})
// #endif
// #ifdef MP-WEIXIN
wx.openPrivacyContract(
{
fail: () => {
uni.showToast({
title: '打开失败请稍后重试', // 打开失败
icon: 'none'
})
},
}
)
// #endif
}
// #ifdef MP-WEIXIN
const getPrivacy = () => {
wx.getPrivacySetting({
success: (r) => {
Object.assign(vdata, r)
if (vdata.needAuthorization) {
wx.onNeedPrivacyAuthorization(res => {
vdata.resolve = res
})
}
}
})
}
getPrivacy()
// #endif
const handAgree = () => {
// #ifdef MP-WEIXIN
if (vdata.needAuthorization) {
vdata.resolve({ buttonId: 'agree-btn', event: 'agree' })
}
// #endif
}
</script>
<style lang="scss" scoped>
.agreement-wrapper {
display: flex;
justify-content: center;
align-items: center;
// width: 100%;
font-size: 24rpx;
white-space: nowrap;
color: #8c8c8c;
view {
margin: 0 10rpx;
color: $primaryColor;
}
.agreement-garden {
position: relative;
width: 30rpx;
height: 30rpx;
border-radius: 50%;
border: 2rpx solid $primaryColor;
&::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
width: 80%;
height: 80%;
border-radius: 50%;
}
}
}
.selected::after {
background-color: $primaryColor;
}
.register-wrapper {
width: 100%;
display: flex;
justify-content: space-between;
font-size: 28rpx;
letter-spacing: 0.02em;
view {
margin: 0 50rpx;
color: #8c8c8c;
text {
color: #7737fe;
}
}
}
.agree-item {
padding: 0;
margin: 0;
line-height: 0;
border-radius: 0;
background-color: transparent;
&::after{
display: none;
}
}
</style>