<template>
<view class="login-container">
<!-- 顶部区域 -->
<view class="logo-container">
<image src="../static/Group824.png" mode="aspectFill" class="bgImg"></image>
</view>
<!-- 登录按钮 -->
<!-- #ifdef MP-WEIXIN -->
<button class="login-btn" v-if="!agreed" @click="agreedShow">
<view class="btn-content">
<text class="btn-text">快捷登录</text>
</view>
</button>
<button v-else class="login-btn" :class="{ disabled: loading }" :disabled="loading" open-type="getPhoneNumber"
@getphonenumber="getWxPhoneNumber">
<view v-if="loading" class="loading-spinner"></view>
<view v-else class="btn-content">
<text class="btn-text">快捷登录</text>
</view>
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="login-btn" :class="{ disabled: loading }" @click="handleLogin" :disabled="loading">
<view v-if="loading" class="loading-spinner"></view>
<view v-else class="btn-content">
<text class="btn-text">本机号码一键登录</text>
</view>
</button>
<!-- #endif -->
<!-- 返回按钮 -->
<!-- #ifdef MP-WEIXIN -->
<view class="goBack">
<text class="agreement-link" @click="navigateTo('goBack')">返回首页</text>
</view>
<!-- #endif -->
<!-- 新增:其他登录方式链接 -->
<!-- #ifndef MP-WEIXIN -->
<view class="other-login" @click="goToLogin">
<view class="line"></view>
<text class="other-login-link">其他方式登录</text>
<view class="line"></view>
</view>
<!-- #endif -->
<!-- 页脚 - 增加底部间距 -->
<view class="footer">
<view class="harmony-tip">{{copyright}} </view>
<view class="agreement">
<u-checkbox-group>
<u-checkbox :checked="agreed" shape="circle" @change="agreed=$event"></u-checkbox>
</u-checkbox-group>
<view class="agreement-text2">
<text @click="agreed=!agreed">已阅读并同意</text>
<text class="agreement-link" @click="navigateTo('1000022')">《用户协议》</text>
和
<text class="agreement-link" @click="navigateTo('1000021')">《隐私政策》</text>
</view>
</view>
</view>
</view>
<!-- 绑定微信弹窗 -->
<uni-popup ref="bindWechatPopup" type="center" :mask-click="false">
<view class="bind-wechat-dialog">
<text class="dialog-title">绑定微信</text>
<!-- 第一行提示文本 -->
<view class="dialog-content-text">
<text>{{ noticeTitle }}</text>
</view>
<!-- 第二行:是否允许使用微信头像和昵称 -->
<view class="bindwxcheck">
<checkbox-group @change="onWechatProfileChange">
<label>
<checkbox :checked="useWechatProfile" color="#007AFF" />
<text class="update-profile-text">使用微信头像和昵称</text>
</label>
</checkbox-group>
</view>
<!-- 按钮区域 -->
<view class="dialog-buttons">
<button class="dialog-btn cancel-btn" @click="closeBindWechatDialog">取消</button>
<button class="dialog-btn confirm-btn" @click="confirmBindWechat">确定</button>
</view>
</view>
</uni-popup>
<!-- 新增:用户协议弹窗 -->
<uni-popup ref="agreementPopup" type="center" :mask-click="false">
<view class="agreement-popup">
<!-- 关闭按钮 -->
<view class="close-btn" @click="closeAgreementPopup">
<uni-icons type="closeempty" size="24" color="#999" />
</view>
<!-- 标题 -->
<view class="popup-title">
用户协议及隐私政策
</view>
<!-- 协议内容 -->
<view class="agreement-content">
<text class="agreement-text">
我已阅读并同意
</text>
<view class="agreement-links">
<text class="link" @click="navigateTo('1000022')">《用户协议》</text>
<text class="link" @click="navigateTo('1000021')">和《隐私政策》</text>
</view>
</view>
<!-- 按钮区域 -->
<view class="popup-buttons">
<!-- #ifdef MP-WEIXIN -->
<button class="popup-btn agree-btn" open-type="getPhoneNumber" @getphonenumber="getWxPhoneNumber">
同意并登录
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="popup-btn agree-btn" @click="handleAgreeAndLogin">
同意并登录
</button>
<!-- #endif -->
</view>
</view>
</uni-popup>
<!-- loading-->
<zero-loading />
<!-- loading-->
</template>
<script setup>
import {
ref,
computed,
onMounted
} from 'vue';
import {
onLoad,
onReady
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import AuthUtil from '@/sheep/api/member/auth';
import $store from '@/sheep/store';
import {
usePermissionStore
} from '@/sheep/store/permission';
import {
getUserPhone
} from './utils.js';
// 应用配置
const appName = ref('驾搭档');
const copyright = ref('©' + new Date().getFullYear() + ' 驾搭档 For HarmonyOS');
// 登录状态
let agreed = ref(false);
const loading = ref(false);
const phoneNumber = ref('');
const permissionStore = usePermissionStore();
// 新增:绑定微信弹窗相关数据
const bindWechatPopup = ref();
const showBindWechatPopup = ref(false);
const useWechatProfile = ref(true); // 默认允许使用微信头像和昵称
const isFranchiser = ref(0);
const noticeTitle = ref();
// 新增:协议弹窗相关
const agreementPopup = ref();
const univerifyManager = uni.getUniverifyManager()
onMounted(() => {
// 提前进行预登录
//preLoginHarmonyOS();
})
onReady(() => {
preLoginHarmonyOS();
})
// 关闭协议弹窗
const closeAgreementPopup = () => {
agreementPopup.value.close();
};
const preLoginHarmonyOS = () => {
if (!univerifyManager) return;
// 延迟执行,确保页面加载完成
setTimeout(() => {
univerifyManager.preLogin({
success: () => {
console.log('HarmonyOS预登录成功(提前准备)');
sheep.$helper.toast('一键登录准备就绪');
},
fail: (err) => {
console.log('HarmonyOS预登录失败(提前准备)', err);
uni.showToast({
title: '无法使用一键登录,请尝试其他方式。' + (err.errCode || ''),
icon: 'none',
duration: 3000
})
// 失败时也继续,可能在点击时重试
}
});
}, 500); // 延迟500ms,确保页面完全加载
};
function agreedShow() {
if (!agreed.value) {
// uni.showToast({
// title: '请先同意用户协议和隐私政策',
// icon: 'none',
// });
agreementPopup.value.open();
return;
}
}
//其它方式登录
const goToLogin = () => {
uni.navigateTo({
url: '/pages/kaoshi/login/login',
});
};
// 处理登录
const handleLogin = () => {
// 点击按钮后才检查是否同意协议
if (!agreed.value) {
// uni.showToast({
// title: '请先同意用户协议和隐私政策',
// icon: 'none',
// });
agreementPopup.value.open();
return;
}
loading.value = true;
handleNormalLogin();
};
// 微信小程序登录
const getWxPhoneNumber = async (e) => {
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
sheep.$helper.toast('快捷登录失败');
return;
}
agreed.value = true
let result = await sheep.$platform.useProvider().mobileLogin(e.detail, 'logIn');
if (result && result.userId) {
isFranchiser.value = result.isFranchiser;
if (isFranchiser.value) {
noticeTitle.value = '绑定微信方可提现操作';
} else {
noticeTitle.value = '绑定微信方可申请考不过补偿';
}
if (result.needBind) {
bindWechatPopup.value.open();
} else {
if (result.isFranchiser == 1) {
// 教练身份
permissionStore.setRole('admin'); //设为教练
uni.redirectTo({
url: '/pages/jiaolian',
});
} else {
permissionStore.setRole('user'); //设为学员
//学员身份
uni.redirectTo({
url: '/pages/exam',
});
}
}
} else {
uni.showToast({
title: '登录失败',
icon: 'none',
});
}
};
// 鸿蒙一键登录
const handleNormalLogin = () => {
// 获取univerifyManager实例
if (!univerifyManager) {
console.error('univerifyManager not available');
loading.value = false;
uni.showToast({
title: '当前环境不支持一键登录',
icon: 'none'
});
return;
}
// 预登录
console.log('预登录开始...')
univerifyManager.preLogin({
success: () => {
console.log('HarmonyOS预登录成功');
// 预登录成功,调用一键登录
univerifyManager.login({
success: (res) => {
console.log(res)
console.log('HarmonyOS一键登录成功, 临时凭证:', res.accessToken);
let authResult = {
access_token: res.accessToken,
openid: res.openId
}
// 调用云函数获取手机号
getPhoneNumber(authResult);
},
fail: (err) => {
console.log('HarmonyOS一键登录失败', err);
loading.value = false;
handleLoginError(err);
}
});
},
fail: (err) => {
console.log('HarmonyOS预登录失败', err);
loading.value = false;
uni.showToast({
title: '无法使用一键登录,请尝试其他方式。' + (err.errCode || ''),
icon: 'none',
duration: 3000
})
}
});
};
// 获取云函数手机号
const getPhoneNumber = async (authResult) => {
try {
console.log(authResult);
const res = await uniCloud.callFunction({
name: 'getmobile',
data: {
access_token: authResult.access_token,
openid: authResult.openid,
},
});
if (res.result.code === 0) {
// 获取手机号成功
phoneNumber.value = res.result.data.phoneNumber;
console.log('获取手机号成功:', phoneNumber.value);
// 使用手机号登录
doLoginWithPhone(phoneNumber.value);
} else {
// 云函数返回错误
console.error('云函数错误:', res.result);
uni.showToast({
title: '获取手机号失败,请重试',
icon: 'none',
});
loading.value = false;
}
} catch (err) {
// 网络或云函数调用失败
console.error('云函数调用失败:', err);
uni.showToast({
title: '网络异常,请检查网络连接',
icon: 'none',
});
loading.value = false;
}
};
// 使用手机号登录
const doLoginWithPhone = (phone) => {
let postData = {
mobile: phone,
};
AuthUtil.oneKeyLogin(postData)
.then((loginRes) => {
console.log(loginRes);
if (loginRes.code == 0) {
$store('user').setToken(loginRes.data.accessToken, loginRes.data.refreshToken);
univerifyManager.close()
isFranchiser.value = loginRes.data.isFranchiser;
if (isFranchiser.value) {
noticeTitle.value = '绑定微信方可提现操作';
} else {
noticeTitle.value = '绑定微信方可申请考不过补偿';
}
if (loginRes.data.needBind) {
bindWechatPopup.value.open();
} else {
if (loginRes.data.isFranchiser == 1) {
// 教练身份
permissionStore.setRole('admin'); //设为教练
uni.reLaunch({
url: '/pages/jiaolian',
});
} else {
permissionStore.setRole('user'); //设为学员
//学员身份
uni.reLaunch({
url: '/pages/exam',
});
}
}
} else {
uni.showToast({
title: loginRes.msg || '登录失败',
icon: 'none',
});
}
})
.catch((loginErr) => {
console.error('登录失败:', loginErr);
uni.showToast({
title: '登录失败',
icon: 'none',
});
});
};
// 自定义一键登录样式
const getCustomStyle = () => {
//配置详情https://uniapp.dcloud.net.cn/univerify.html
//https://blog.csdn.net/2301_79910265/article/details/144612587
return {
fullScreen: false, // 是否全屏显示
backgroundColor: '#ffffff', // 背景颜色
buttons: {
iconWidth: '45px', // 图标宽度
height: '45px', // 按钮高度
},
otherLoginButton: {
visible: false, // 是否显示其他登录按钮,默认值:true
},
privacyTerms: {
textColor: '#666666', // 基础文字颜色
linkTextColor: '#3D72FE', // 协议链接文字颜色
defaultCheckBoxState: false, // 条款勾选框初始状态 默认值: true
checkBoxSize: 18, // 可选 条款勾选框大小
},
};
};
// 导航到协议页面
const navigateTo = (type) => {
if (type == 'goBack') {
uni.redirectTo({
url: '/pages/exam',
});
} else {
uni.navigateTo({
url: `/pages/kaoshi/SinglePage?id=${type}`,
});
}
};
// 处理绑定微信弹窗中的复选框变化
const onWechatProfileChange = (e) => {
useWechatProfile.value = e.detail.value.length > 0;
};
// 关闭绑定微信弹窗
const closeBindWechatDialog = () => {
bindWechatPopup.value.close();
if (isFranchiser.value == 1) {
// 教练身份
permissionStore.setRole('admin'); //设为教练
uni.reLaunch({
url: '/pages/jiaolian',
});
} else {
permissionStore.setRole('user'); //设为学员
//学员身份
uni.reLaunch({
url: '/pages/exam',
});
}
};
// 确认绑定微信
const confirmBindWechat = async () => {
// 这里调用绑定微信的API
console.log('绑定微信,并使用微信头像和昵称:', useWechatProfile.value);
uni.login({
provider: 'weixin',
onlyAuthorize: true, // 微信登录仅请求授权认证
success: async function(res) {
let postData = {
code: res.code,
agreeToUpdateUserFace: useWechatProfile.value,
};
//console.log(postData)
const rest = await AuthUtil.bindWx(postData);
//console.log(rest)
// 绑定成功后关闭弹窗
closeBindWechatDialog();
},
});
};
// 处理同意协议并登录
const handleAgreeAndLogin = () => {
//#ifdef APP-PLUS || APP-HARMONY
// 设置已同意协议
agreed.value = true;
// 关闭协议弹窗
agreementPopup.value.close();
// 执行登录
loading.value = true;
handleNormalLogin();
//#endif
}
</script>
1 个回复
DCloud_UNI_OttoJi - 日常回复 uni-app/x 问题,如果艾特我没看到,请主动私信
参考错误码 30005 预登录失败 不具备一键登录的使用前提,设备不支持/未开启数据流量/其他原因
先自己找一下规律,对应的手机都插卡、登录账号了吗?https://uniapp.dcloud.net.cn/univerify.html