You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

568 lines
14 KiB

<template>
<view class="container">
<image class="bkg" mode="aspectFill" src="../static/login-bg.png"></image>
<view class="login">
<view class="login-title">
<view>Hello</view>
<view>欢迎登录护工端</view>
</view>
<view class="login-form">
<view>
<u-input v-model="form.username" border-color="#f5f5f5" placeholder="请输入用户名"></u-input>
</view>
<view>
<u-input v-model="form.password" border-color="#f5f5f5" type="password"
placeholder="请输入密码"></u-input>
</view>
</view>
<view class="role-select">
<view class="role-title">请选择登录角色:</view>
<view class="role-options">
<view class="role-item" v-for="(item, index) in roleList" :key="index"
@click="form.role = item.value">
<view class="radio-box" :class="{'active': form.role === item.value}">
<view class="radio-inner" v-if="form.role === item.value"></view>
</view>
<text class="role-label">{{item.label}}</text>
</view>
<view class="role-item role-item-check"
@click="isRemeber = !isRemeber">
<view class="radio-box" :class="{'active': isRemeber}">
<view class="radio-inner" v-if="isRemeber"></view>
</view>
<text class="role-label">记住当前登录状态</text>
</view>
</view>
</view>
<view class="login-btn">
<view @click="login">立即登录</view>
</view>
<!-- 隐私政策提示 -->
<view class="privacy-tip" v-if="showPrivacyTip">
<view class="privacy-content">
<view class="privacy-title">用户隐私保护指引</view>
<view class="privacy-text">
为了向您提供更好的服务,我们需要获取您的个人信息。我们将严格遵守相关法律法规,保护您的隐私安全。
</view>
<view class="privacy-link" @click="openPrivacyContract">
查看《用户隐私保护指引》
</view>
<view class="privacy-buttons">
<view class="privacy-btn cancel" @click="handlePrivacyCancel">暂不使用</view>
<view class="privacy-btn confirm" @click="handlePrivacyConfirm"></view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
form: {
username: '',
password: '',
role:''
// role: uni.getStorageSync('login_role') || 'nurse' // 从缓存获取角色,默认护工
},
roleList: [{
value: 'nurse',
label: '护工'
},
{
value: 'staff',
label: '工作人员'
},
{
value: 'operator',
label: '运营人员'
}
],
site_name: '',
isRemeber: true,
showPrivacyTip: false, // 是否显示隐私授权提示
privacyAuthorized: false, // 是否已授权隐私
needPrivacyAuth: false // 是否需要隐私授权
};
},
onReady() {},
onShareAppMessage() {
return {
title: '医康养服务', // 分享标题
path: '/pages/index/index', // 分享路径,通常指向首页
}
},
onLoad() {
// 进入页面立即显示隐私弹窗,并加载微信隐私配置
// #ifdef MP-WEIXIN
this.showPrivacyTip = true
this.needPrivacyAuth = true
this.privacyAuthorized = false
this.checkPrivacySetting()
// #endif
},
mounted() {
this.form = this.vuex_saved_username_psd || {
username: "",
password: "",
role:'nurse'
};
console.log("form",this.form)
},
methods: {
// 检查隐私设置
checkPrivacySetting() {
// #ifdef MP-WEIXIN
if (wx.getPrivacySetting) {
wx.getPrivacySetting({
success: (res) => {
console.log('隐私设置:', res)
// needAuthorization: true 表示需要弹出隐私授权
if (res.needAuthorization) {
this.needPrivacyAuth = true
// 进入页面就显示弹窗,这里只负责标记,不再关闭弹窗
this.showPrivacyTip = true
}
},
fail: (err) => {
console.error('获取隐私设置失败:', err)
}
})
}
// #endif
},
// 处理隐私授权确认
handlePrivacyConfirm() {
// #ifdef MP-WEIXIN
if (wx.requirePrivacyAuthorize) {
wx.requirePrivacyAuthorize({
success: () => {
console.log('隐私授权成功')
this.privacyAuthorized = true
this.showPrivacyTip = false
this.needPrivacyAuth = false
},
fail: (err) => {
console.error('隐私授权失败:', err)
uni.showToast({
title: '需要授权才能使用',
icon: 'none'
})
}
})
} else {
// 兼容旧版本
this.showPrivacyTip = false
this.privacyAuthorized = true
}
// #endif
// #ifndef MP-WEIXIN
this.showPrivacyTip = false
this.privacyAuthorized = true
// #endif
},
// 处理隐私授权取消
handlePrivacyCancel() {
this.showPrivacyTip = false
uni.showToast({
title: '需要授权才能使用',
icon: 'none'
})
},
// 打开微信官方隐私协议页面
openPrivacyContract() {
// #ifdef MP-WEIXIN
if (wx.openPrivacyContract) {
wx.openPrivacyContract({
success: (res) => {
console.log('打开隐私协议成功', res)
},
fail: (err) => {
console.error('打开隐私协议失败:', err)
uni.showToast({
title: '无法打开隐私协议',
icon: 'none'
})
}
})
} else {
uni.showToast({
title: '当前微信版本不支持查看隐私协议',
icon: 'none'
})
}
// #endif
},
login() {
// 检查隐私授权
if (this.needPrivacyAuth && !this.privacyAuthorized) {
this.showPrivacyTip = true
return
}
if (!this.form.username || !this.form.password) {
uni.showToast({
title: '请输入用户名和密码',
icon: 'none'
})
return
}
if (!this.form.role) {
uni.showToast({
title: '请选择登录角色',
icon: 'none'
})
return
}
let that = this
// 根据角色选择不同的登录接口
let loginApi = null
switch (this.form.role) {
case 'nurse':
loginApi = this.$u.api.login // 护工登录
break
case 'staff':
loginApi = this.$u.api.staffLogin // 工作人员登录
break
case 'operator':
loginApi = this.$u.api.operatorLogin // 运营人员登录
break
default:
uni.showToast({
title: '无效的角色选择',
icon: 'none'
})
return
}
loginApi({
username: this.form.username,
password: this.form.password,
}).then(res => {
console.log("res1", res)
if (res.errcode === 40002) {
that.base.toast("账号密码不正确")
return
}
// 缓存登录角色
uni.setStorageSync('login_role', this.form.role)
const loginRole = uni.getStorageSync('login_role');
if (loginRole === 'staff') {
that.$u.vuex('vuex_token', res.token)
} else if (loginRole === 'operator') {
that.$u.vuex('vuex_token', res.access_token)
} else {
that.$u.vuex('vuex_token', res.token)
}
if (this.isRemeber) {
this.$u.vuex("vuex_saved_username_psd", this.form);
} else {
this.$u.vuex("vuex_saved_username_psd", {
username: "",
password: "",
role:'nurse'
});
}
that.base.toast("登录成功", 1500, function() {
// #ifdef MP-WEIXIN
// 在调用 uni.login 之前,确保已授权隐私
if (that.needPrivacyAuth && !that.privacyAuthorized) {
// 如果需要授权但未授权,先请求授权
if (wx.requirePrivacyAuthorize) {
wx.requirePrivacyAuthorize({
success: () => {
that.privacyAuthorized = true
that.doWeixinLogin(that)
},
fail: () => {
uni.showToast({
title: '需要授权才能使用',
icon: 'none'
})
}
})
} else {
that.doWeixinLogin(that)
}
} else {
that.doWeixinLogin(that)
}
// #endif
// #ifndef MP-WEIXIN
that.doWeixinLogin(that)
// #endif
})
}).catch(err => {
console.error("登录失败", err)
that.base.toast("登录失败,请稍后重试")
})
},
// 执行微信登录
doWeixinLogin(that) {
uni.login({
provider: 'weixin',
success: (loginRes) => {
const code = loginRes.code;
// 调用静默登录接口
setTimeout(function() {
const loginRole = uni.getStorageSync('login_role');
if (loginRole === 'staff') {
// that.$u.vuex('vuex_token', res.token)
that.$u.api.appletLogin({
code
}).then(silentRes => {
uni.reLaunch({
url: '/pages/index/staffIndex'
});
}).catch(err => {
console.error('静默登录失败', err);
// 可以给用户提示
});
} else if (loginRole === 'operator') {
// that.$u.vuex('vuex_token', res.access_token)
uni.reLaunch({
url: '/pages/index/operatorIndex'
});
} else {
// that.$u.vuex('vuex_token', res.token)
that.$u.api.nurseAppletLogin({
code
}).then(silentRes => {
uni.switchTab({
url: '/pages/index/index'
});
}).catch(err => {
console.error('静默登录失败', err);
// 可以给用户提示
});
}
}, 1500)
},
fail: (err) => {
console.error('获取微信code失败', err);
// 可以给用户提示
}
});
}
}
}
</script>
<style lang="scss" scoped>
.container {
width: 100vw;
height: 100vh;
background-color: #fff;
font-size: 32rpx;
.bkg {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.login {
position: absolute;
top: 0;
left: 0;
padding-top: 150rpx;
// text-align: center;
width: 100%;
&-title {
font-size: 50rpx;
color: #fff;
text-align: left;
&>view {
width: 50%;
margin: 0 auto;
}
}
&-form {
padding: 400rpx 65rpx 100rpx 65rpx;
margin-bottom: 10rpx;
&>view {
background-color: #f5f5f5;
border-radius: 60rpx;
padding: 10rpx 30rpx;
margin-bottom: 35rpx;
}
}
&-btn {
padding: 0 65rpx;
&>view {
font-size: 33rpx;
border-radius: 60rpx;
margin-bottom: 35rpx;
height: 90rpx;
line-height: 90rpx;
text-align: center;
color: #fff;
background: linear-gradient(-90deg, #e26165 0%, #c10d12 94%, #c10d12 100%);
box-shadow: 1rpx 1rpx 10rpx #c10d12;
}
}
}
.role-select {
padding: 0 30rpx;
margin-bottom: 50rpx;
margin-top: -60rpx;
.role-title {
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
text-align: center;
}
.role-options {
display: flex;
// justify-content: center;
flex-wrap: wrap;
.role-item {
display: flex;
align-items: center;
margin: 0 20rpx;
margin-bottom: 10rpx;
.radio-box {
width: 36rpx;
height: 36rpx;
border-radius: 50%;
border: 2rpx solid #dcdfe6;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12rpx;
&.active {
border-color: #1479ff;
.radio-inner {
width: 24rpx;
height: 24rpx;
border-radius: 50%;
background-color: #1479ff;
}
}
}
.role-label {
font-size: 28rpx;
color: #333;
}
}
.role-item-check{
margin-top:20rpx;
.radio-box{
border-radius: 0;
.radio-inner{
border-radius: 0;
}
&.active {
border-color: #1479ff;
.radio-inner {
border-radius: 0%;
}
}
}
}
}
}
.privacy-tip {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
.privacy-content {
width: 600rpx;
background: #fff;
border-radius: 20rpx;
padding: 40rpx;
.privacy-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 30rpx;
}
.privacy-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
margin-bottom: 20rpx;
}
.privacy-link {
font-size: 26rpx;
color: #1479ff;
text-align: center;
text-decoration: underline;
margin-bottom: 40rpx;
}
.privacy-buttons {
display: flex;
justify-content: space-between;
gap: 20rpx;
.privacy-btn {
flex: 1;
height: 80rpx;
line-height: 80rpx;
text-align: center;
border-radius: 40rpx;
font-size: 30rpx;
&.cancel {
background: #f5f5f5;
color: #666;
}
&.confirm {
background: linear-gradient(-90deg, #e26165 0%, #c10d12 94%, #c10d12 100%);
color: #fff;
}
}
}
}
}
}
</style>