Files
property-manager-side/wuye-manager-uniapp/pageSubPack/loginSub/pwd-login.vue
zhouyanli 1b2dd8d2f2 修改bug
2026-06-22 17:27:37 +08:00

369 lines
9.2 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 class="login-page">
<view class="status_bar"></view>
<!-- 标题 -->
<view class="login-title">账号密码登录</view>
<!-- 手机号输入框 -->
<view class="input-item">
<view class="input-icon">
<!-- <uni-icons type="phone" size="24" color="#999"></uni-icons> -->
<image src="https://wuyeadmin.bugtc.com/images/login/phone.png" mode=""
style="height: 100%;width: 100%;"></image>
</view>
<uni-easyinput class="input-content" type="text" v-model="phoneNumber" placeholder="请输入帐号"
:inputBorder="false" :placeholderStyle="placeholderStyle">
</uni-easyinput>
</view>
<!-- 密码输入框 -->
<view class="input-item">
<view class="input-icon">
<!-- <uni-icons type="locked" size="24" color="#999"></uni-icons> -->
<image src="https://wuyeadmin.bugtc.com/images/login/password.png" mode=""
style="height: 100%;width: 100%;"></image>
</view>
<uni-easyinput class="input-content" type="password" v-model="password" placeholder="请输入6-16位密码"
:inputBorder="false" :placeholderStyle="placeholderStyle">
</uni-easyinput>
</view>
<!-- 记住密码 -->
<view class="remember-wrap" style="display: none;">
<view class="remember-item" @click="toggleRemember">
<uni-icons type="checkbox-filled" size="18" color="#4D5DFA" v-if="rememberPwd"></uni-icons>
<uni-icons type="checkbox" size="18" color="#999" v-else></uni-icons>
<text class="remember-text">记住密码</text>
</view>
</view>
<!-- 协议勾选 + 忘记密码 -->
<view class="agreement-wrap">
<view class="agreement-item">
<view @click="toggleAgreement">
<uni-icons type="checkbox-filled" size="24" color="#4D5DFA" v-if="agreeAgreement"></uni-icons>
<uni-icons type="checkbox" size="24" color="#999" v-else></uni-icons>
</view>
<text class="agreement-text" >我已阅读并同意
<text class="agreePrivacy" @click.stop="">《用户协议》</text>和
<text class="agreePrivacy" @click.stop="goToPrivacy">《隐私政策》</text>
</text>
</view>
<navigator class="forget-pwd" url="/pageSubPack/loginSub/forget-pwd">忘记密码?</navigator>
</view>
<!-- 登录按钮 -->
<button class="login-btn" @click="handleLogin">
登录
</button>
<!-- 底部链接 -->
<view class="bottom-link">
<navigator class="link-item" url="/pageSubPack/loginSub/login">验证码登录</navigator>
<!-- <navigator class="link-item" url="/pageSubPack/loginSub/register-new-user">注册新用户</navigator> -->
</view>
</view>
<!-- 隐私协议弹窗 -->
<privacy-popup v-model:show="showPrivacyPopup" @agree="agreePrivacy" @disagree="disagreePrivacy" @close="showPrivacyPopup = false" />
</template>
<script setup>
import {
ref,
computed
} from 'vue';
import {
onLoad
} from "@dcloudio/uni-app"
import {
getLoginPassword
} from '../../api/api.js'
import PrivacyPopup from '@/components/privacy-popup/privacy-popup.vue'
// 响应式数据
const phoneNumber = ref('');
const password = ref('');
const agreeAgreement = ref(false); // 默认勾选
const rememberPwd = ref(false);
const placeholderStyle = ref('font-size:24rpx')
const showPrivacyPopup = ref(false)
// 计算属性:是否可登录(帐号+密码+协议都满足)
const canLogin = computed(() => {
const phoneReg = /^[a-zA-Z0-9_-]{4,16}$/; // 4-16位
const pwdReg = /^.{6,16}$/; // 密码6-16位
return phoneReg.test(phoneNumber.value) && pwdReg.test(password.value) && agreeAgreement.value;
});
// 切换协议勾选
const toggleAgreement = () => {
agreeAgreement.value = !agreeAgreement.value;
};
// 切换记住密码
const toggleRemember = () => {
rememberPwd.value = !rememberPwd.value;
};
// 打开隐私协议弹窗
const goToPrivacy = () => {
showPrivacyPopup.value = true
}
// 不同意隐私协议
const disagreePrivacy = () => {
agreeAgreement.value = false
showPrivacyPopup.value = false
}
// 检查表单
const checkForm = () => {};
onLoad(() => {
const savedPhone = uni.getStorageSync('rememberPhone');
const savedPwd = uni.getStorageSync('rememberPassword');
const savedRemember = uni.getStorageSync('rememberPwd');
if (savedPhone) phoneNumber.value = savedPhone;
if (savedPwd) password.value = savedPwd;
if (savedRemember) rememberPwd.value = savedRemember;
});
// 登录逻辑
const handleLogin = () => {
if (!phoneNumber.value) {
uni.showToast({ title: '请输入账号', icon: 'none' });
return;
}
if (phoneNumber.value.length < 4 || phoneNumber.value.length > 16) {
uni.showToast({ title: '账号长度需为 4-16 位', icon: 'none' });
return;
}
if (!password.value) {
uni.showToast({ title: '请输入密码', icon: 'none' });
return;
}
if (password.value.length < 6) {
uni.showToast({ title: '密码至少输入 6 位', icon: 'none' });
return;
}
if (password.value.length > 16) {
uni.showToast({ title: '密码不能超过 16 位', icon: 'none' });
return;
}
if(!agreeAgreement.value){
showPrivacyPopup.value = true;
return;
}
uni.showLoading({ title: '登录中...', mask: true });
const push_cid = uni.getStorageSync('push_cid')
// console.log('cid',push_cid)
let params = {
username:phoneNumber.value,
password:password.value,
cid:push_cid
}
getLoginPassword(params).then(res =>{
// console.log('33333',res)
if(res.code === 200){
uni.setStorageSync('token', res.data.token);
// 清掉上次账号的小区缓存,防止新账号显示旧小区
uni.removeStorageSync('currentVillage');
// 存用户ID
// if(res.data) {
// // 存当前绑定的小区ID,0 表示未绑定
// // const currentVillageId = res.data.currentVillageId || 0;
// // uni.setStorageSync('currentVillageId', currentVillageId);
// }
uni.hideLoading();
if (rememberPwd.value) {
uni.setStorageSync('rememberPhone', phoneNumber.value);
uni.setStorageSync('rememberPassword', password.value);
uni.setStorageSync('rememberPwd', true);
} else {
uni.removeStorageSync('rememberPhone');
uni.removeStorageSync('rememberPassword');
uni.removeStorageSync('rememberPwd');
}
uni.showToast({ title: '登录成功', icon: 'success' });
setTimeout(() =>{
uni.switchTab({
url: '/pages/index/index'
},1000);
})
}else{
uni.showToast({ title: res.msg, icon: 'error' });
}
}).catch(err => {
uni.showToast({
title: err.msg,
icon: 'error'
});
})
};
// 同意隐私协议(弹窗中点击同意 → 直接登录)
const agreePrivacy = () => {
agreeAgreement.value = true
showPrivacyPopup.value = false
handleLogin()
}
</script>
<style scoped>
.login-page {
padding: 80rpx 40rpx 40rpx;
/* background-color: #f8f9fa; */
min-height: 100vh;
background: repeating-linear-gradient(180deg, #E2F0FF, #F6FAFF);
}
.status_bar {
height: 160px;
width: 100%;
}
.login-title {
font-size: 52rpx;
font-weight: 600;
color: #333;
text-align: center;
margin-bottom: 142rpx;
}
.input-item {
display: flex;
align-items: center;
background-color: #fff;
border-radius: 40rpx;
padding: 0 30rpx;
height: 88rpx;
margin-bottom: 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.input-icon {
margin-right: 20rpx;
width: 50rpx;
height: 50rpx;
}
.input-content {
flex: 1;
font-size: 28rpx;
color: #333;
display: flex;
align-items: center;
}
/* 清除 uni-easyinput 内部默认边距 */
:deep(.uni-easyinput__content) {
margin: 0 !important;
padding: 0 !important;
min-height: auto !important;
background-color: transparent !important;
}
:deep(.uni-easyinput__content-input) {
height: 60rpx !important;
min-height: 60rpx !important;
line-height: 60rpx !important;
padding: 0 !important;
margin: 0 !important;
font-size: 28rpx;
}
.remember-wrap {
display: flex;
align-items: center;
margin: 20rpx 0 0 0;
padding: 0 10rpx;
}
.remember-item {
display: flex;
align-items: center;
}
.remember-text {
font-size: 24rpx;
color: #666;
margin-left: 10rpx;
}
.agreement-wrap {
display: flex;
justify-content: space-between;
align-items: center;
margin: 40rpx 0 28rpx 0;
padding: 0 10rpx;
}
.agreement-item {
display: flex;
align-items: center;
flex: 1;
min-width: 0;
}
.agreement-text {
font-size: 24rpx;
color: #666;
margin-left: 10rpx;
line-height: 1.5;
}
.agreePrivacy{
color: #4D5DFA;
}
/* .agreePrivacy.active{
color: #4D5DFA;
} */
.forget-pwd {
font-size: 24rpx;
color: #666;
text-decoration: none;
flex-shrink: 0;
margin-left: 16rpx;
line-height: 1.5;
}
.login-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background-color: #4D5DFA;
color: #fff;
border-radius: 8rpx;
font-size: 28rpx;
margin-bottom: 40rpx;
}
.login-btn:disabled {
background-color: #99c8ff;
color: #fff;
/* border-radius: 50px; */
}
/* 禁用按钮边框 */
button:after {
border-radius: 8px;
}
.bottom-link {
display: flex;
justify-content: center;
padding: 0 20rpx;
}
.link-item {
font-size: 28rpx;
color: #4D5DFA;
text-decoration: none;
}
</style>