完成一键登录和支付功能
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* 登录弹窗组件使用示例
|
||||
*
|
||||
* 该组件提供了统一的登录拦截功能,可以在任何页面使用
|
||||
*/
|
||||
|
||||
## 方式一:在页面中直接使用LoginModal组件
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<view>
|
||||
<!-- 其他内容 -->
|
||||
|
||||
<!-- 引入登录弹窗 -->
|
||||
<LoginModal
|
||||
ref="loginModalRef"
|
||||
v-model="showLoginModal"
|
||||
title="登录后享受更多服务"
|
||||
subtitle="登录即表示同意相关协议"
|
||||
:show-close="true"
|
||||
:mask-closable="true"
|
||||
@loginSuccess="onLoginSuccess"
|
||||
@loginError="onLoginError"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, nextTick } from 'vue'
|
||||
import { registerLoginModal } from '@/common/hooks/useLoginGuard.js'
|
||||
import LoginModal from '@/components/global/LoginModal.vue'
|
||||
|
||||
const showLoginModal = ref(false)
|
||||
const loginModalRef = ref(null)
|
||||
|
||||
// 注册到全局
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (loginModalRef.value) {
|
||||
registerLoginModal(loginModalRef.value)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 显示登录弹窗
|
||||
function showLogin() {
|
||||
showLoginModal.value = true
|
||||
}
|
||||
|
||||
// 登录成功回调
|
||||
function onLoginSuccess(result) {
|
||||
console.log('登录成功', result)
|
||||
// 刷新页面数据等
|
||||
}
|
||||
|
||||
// 登录失败回调
|
||||
function onLoginError(error) {
|
||||
console.log('登录失败', error)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 方式二:使用 useLoginGuard Hook
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useLoginGuard } from '@/common/hooks/useLoginGuard.js'
|
||||
|
||||
const { requireLogin, checkLogin } = useLoginGuard()
|
||||
|
||||
// 示例1:需要登录才能执行的操作
|
||||
async function handleBookCourse() {
|
||||
// 检查是否已登录
|
||||
if (!checkLogin()) {
|
||||
return
|
||||
}
|
||||
// 执行预约操作...
|
||||
}
|
||||
|
||||
// 示例2:弹窗式登录(推荐)
|
||||
async function handlePurchase() {
|
||||
const loggedIn = await requireLogin({
|
||||
title: '请先登录',
|
||||
subtitle: '登录后即可购买会员卡',
|
||||
onSuccess: (user) => {
|
||||
console.log('登录成功,用户信息:', user)
|
||||
}
|
||||
})
|
||||
|
||||
if (loggedIn) {
|
||||
// 执行购买操作
|
||||
await purchaseCard()
|
||||
}
|
||||
}
|
||||
|
||||
// 示例3:安全执行函数
|
||||
async function handleCheckIn() {
|
||||
const result = await requireLogin().safeExecute(async () => {
|
||||
// 只有登录后才能执行这里的代码
|
||||
return await checkInApi()
|
||||
})
|
||||
|
||||
if (result) {
|
||||
uni.showToast({ title: '签到成功' })
|
||||
}
|
||||
}
|
||||
|
||||
// 示例4:包装API调用
|
||||
async function handleGetCoupons() {
|
||||
const { callLoggedInApi } = useLoginGuard()
|
||||
|
||||
try {
|
||||
const coupons = await callLoggedInApi(getCouponsApi, [], {
|
||||
title: '领取优惠券'
|
||||
})
|
||||
console.log('优惠券列表:', coupons)
|
||||
} catch (e) {
|
||||
if (e.message === '用户未登录') {
|
||||
// 用户未登录,弹窗已显示
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 方式三:在组件中使用登录守卫Mixin
|
||||
|
||||
```vue
|
||||
<script>
|
||||
import { loginGuardMixin } from '@/common/hooks/useLoginGuard.js'
|
||||
|
||||
export default {
|
||||
mixins: [loginGuardMixin()],
|
||||
|
||||
methods: {
|
||||
async onQuickAction(type) {
|
||||
// 自动检查登录状态
|
||||
if (!await this.ensureLogin()) {
|
||||
return
|
||||
}
|
||||
|
||||
// 已登录,执行操作
|
||||
if (type === 'book') {
|
||||
this.goToBooking()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 登录弹窗组件Props说明
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| modelValue | Boolean | false | 控制显示/隐藏 |
|
||||
| title | String | '登录后享受更多服务' | 弹窗标题 |
|
||||
| subtitle | String | '登录即表示同意相关协议' | 弹窗副标题 |
|
||||
| showClose | Boolean | true | 是否显示关闭按钮 |
|
||||
| modalStyle | String | 'center' | 弹窗样式:'center'居中,'bottom'底部 |
|
||||
| maskClosable | Boolean | true | 点击遮罩是否关闭 |
|
||||
| onLoginSuccess | Function | null | 登录成功回调 |
|
||||
| onLoginError | Function | null | 登录失败回调 |
|
||||
|
||||
## 登录弹窗组件Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|--------|------|----------|
|
||||
| update:modelValue | 显示状态变化 | Boolean |
|
||||
| loginSuccess | 登录成功 | Object: 登录结果 |
|
||||
| loginError | 登录失败 | Error: 错误对象 |
|
||||
| close | 弹窗关闭 | - |
|
||||
|
||||
## 登录弹窗组件暴露的方法
|
||||
|
||||
| 方法名 | 说明 | 参数 |
|
||||
|--------|------|------|
|
||||
| show() | 显示弹窗 | - |
|
||||
| hide() | 隐藏弹窗 | - |
|
||||
| switchCard(card) | 切换登录方式 | 'phone'一键登录 / 'sms'验证码登录 |
|
||||
|
||||
## 全局登录拦截示例
|
||||
|
||||
在 `App.vue` 中注册全局登录弹窗:
|
||||
|
||||
```vue
|
||||
<script>
|
||||
import LoginModal from '@/components/global/LoginModal.vue'
|
||||
import { registerLoginModal } from '@/common/hooks/useLoginGuard.js'
|
||||
|
||||
export default {
|
||||
components: { LoginModal },
|
||||
onLaunch() {
|
||||
// 注册全局登录弹窗
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.globalLoginModal) {
|
||||
registerLoginModal(this.$refs.globalLoginModal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view id="app">
|
||||
<router-view />
|
||||
<LoginModal ref="globalLoginModal" />
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
## API路径配置
|
||||
|
||||
登录弹窗组件使用的API路径定义在 `@/api/main.js`:
|
||||
|
||||
```javascript
|
||||
// 一键登录
|
||||
export function phoneLogin(data) {
|
||||
return request.post('/auth/phone/login', data)
|
||||
}
|
||||
|
||||
// 短信验证码登录
|
||||
export function smsLogin(data) {
|
||||
return request.post('/auth/phone/sms/login', data)
|
||||
}
|
||||
|
||||
// 发送验证码
|
||||
export function sendSmsCode(phone) {
|
||||
return request.post('/auth/phone/sms/send', { phone })
|
||||
}
|
||||
```
|
||||
|
||||
如需修改API路径,请编辑 `main.js` 文件中的相应函数。
|
||||
Reference in New Issue
Block a user