f
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { onShareAppMessage, onShareTimeline, onShow } from '@dcloudio/uni-app'
|
||||
import { onUnmounted, ref } from 'vue'
|
||||
import { clearAuthStorage, getUserDetail, postAuthSendSmsBindMobile, postUserBindMobile } from '@/api'
|
||||
import { hasToken, saveAuthSession } from '@/utils/session'
|
||||
import { ref } from 'vue'
|
||||
import { getUserDetail } from '@/api'
|
||||
import { hasToken } from '@/utils/session'
|
||||
import { useBindMobile } from '@/composables/useBindMobile'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
@@ -30,14 +31,22 @@ const userDesc = ref('')
|
||||
const hasBoundMobile = ref(false)
|
||||
const wxNickStorage = ref('')
|
||||
|
||||
const bindModalOpen = ref(false)
|
||||
const bindPhone = ref('')
|
||||
const bindCode = ref('')
|
||||
const bindSending = ref(false)
|
||||
const bindSubmitting = ref(false)
|
||||
const bindCountingDown = ref(false)
|
||||
const bindCountdown = ref(60)
|
||||
let bindSmsTimer: ReturnType<typeof setInterval> | null = null
|
||||
const {
|
||||
bindVisible: bindModalOpen,
|
||||
bindPhone,
|
||||
bindCode,
|
||||
bindSending,
|
||||
bindSubmitting,
|
||||
bindCountingDown,
|
||||
bindCountdown,
|
||||
isBindPhoneValid,
|
||||
openBindModal,
|
||||
closeBindModal,
|
||||
onBindPhoneInput,
|
||||
onBindCodeInput,
|
||||
sendBindSms,
|
||||
submitBindMobile,
|
||||
} = useBindMobile(refreshUserCard)
|
||||
|
||||
const coopModalOpen = ref(false)
|
||||
|
||||
@@ -68,30 +77,10 @@ function loadWxNickFromStorage() {
|
||||
}
|
||||
}
|
||||
|
||||
function clearBindSmsTimer() {
|
||||
if (bindSmsTimer) {
|
||||
clearInterval(bindSmsTimer)
|
||||
bindSmsTimer = null
|
||||
}
|
||||
function openBindModalFromProfile() {
|
||||
openBindModal()
|
||||
}
|
||||
|
||||
function startBindCountdown() {
|
||||
clearBindSmsTimer()
|
||||
bindCountingDown.value = true
|
||||
bindCountdown.value = 60
|
||||
bindSmsTimer = setInterval(() => {
|
||||
if (bindCountdown.value > 0) {
|
||||
bindCountdown.value--
|
||||
}
|
||||
else {
|
||||
clearBindSmsTimer()
|
||||
bindCountingDown.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const isBindPhoneValid = () => /^1[3-9]\d{9}$/.test(bindPhone.value)
|
||||
|
||||
async function refreshUserCard() {
|
||||
isLogin.value = hasToken()
|
||||
if (!isLogin.value) {
|
||||
@@ -148,19 +137,6 @@ onShow(() => {
|
||||
|
||||
function handleUserTap() {
|
||||
if (isLogin.value) {
|
||||
uni.showActionSheet({
|
||||
itemList: ['退出登录'],
|
||||
success(res) {
|
||||
if (res.tapIndex === 0) {
|
||||
clearAuthStorage()
|
||||
isLogin.value = false
|
||||
nickname.value = ''
|
||||
userDesc.value = ''
|
||||
hasBoundMobile.value = false
|
||||
uni.showToast({ title: '已退出', icon: 'none' })
|
||||
}
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url: '/pages/login' })
|
||||
@@ -193,77 +169,8 @@ async function syncWxNickname() {
|
||||
// #endif
|
||||
}
|
||||
|
||||
function openBindModal() {
|
||||
bindPhone.value = ''
|
||||
bindCode.value = ''
|
||||
bindModalOpen.value = true
|
||||
}
|
||||
|
||||
function closeBindModal() {
|
||||
bindModalOpen.value = false
|
||||
clearBindSmsTimer()
|
||||
bindCountingDown.value = false
|
||||
}
|
||||
|
||||
function onBindPhoneInput(e: { detail?: { value?: string } }) {
|
||||
const raw = e.detail?.value ?? ''
|
||||
bindPhone.value = String(raw).replace(/\D/g, '').slice(0, 11)
|
||||
}
|
||||
|
||||
function onBindCodeInput(e: { detail?: { value?: string } }) {
|
||||
const raw = e.detail?.value ?? ''
|
||||
bindCode.value = String(raw).replace(/\D/g, '').slice(0, 6)
|
||||
}
|
||||
|
||||
async function sendBindSms() {
|
||||
if (bindSending.value || bindCountingDown.value)
|
||||
return
|
||||
if (!isBindPhoneValid()) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
bindSending.value = true
|
||||
try {
|
||||
const res = await postAuthSendSmsBindMobile({ mobile: bindPhone.value }) as { code?: number }
|
||||
if (res && res.code === 200) {
|
||||
uni.showToast({ title: '验证码已发送', icon: 'none' })
|
||||
startBindCountdown()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
bindSending.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function submitBindMobile() {
|
||||
if (!isBindPhoneValid()) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (bindCode.value.length < 6) {
|
||||
uni.showToast({ title: '请输入 6 位验证码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
bindSubmitting.value = true
|
||||
try {
|
||||
const res = await postUserBindMobile({
|
||||
mobile: bindPhone.value,
|
||||
code: bindCode.value,
|
||||
}) as { code?: number, data?: { accessToken: string, refreshAfter: number | string, accessExpire: number | string } }
|
||||
if (res && res.code === 200 && res.data) {
|
||||
saveAuthSession(res.data)
|
||||
uni.showToast({ title: '绑定成功', icon: 'success' })
|
||||
closeBindModal()
|
||||
await refreshUserCard()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
bindSubmitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function goHistoryReport() {
|
||||
uni.switchTab({ url: '/pages/report' })
|
||||
uni.navigateTo({ url: '/pages/report' })
|
||||
}
|
||||
|
||||
function goFreeValuation() {
|
||||
@@ -296,11 +203,11 @@ function goLegalAuthorization() {
|
||||
}
|
||||
|
||||
function goIllegalCode() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
uni.navigateTo({ url: '/pages/toolbox/query?key=jtwfcode' })
|
||||
}
|
||||
|
||||
function goOilPrice() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
uni.navigateTo({ url: '/pages/toolbox/query?key=oilprice' })
|
||||
}
|
||||
|
||||
function goHelp() {
|
||||
@@ -319,10 +226,6 @@ function goSettings() {
|
||||
function goServiceFallback() {
|
||||
uni.showToast({ title: '请在微信小程序内使用在线客服', icon: 'none' })
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
clearBindSmsTimer()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -349,7 +252,7 @@ onUnmounted(() => {
|
||||
</view>
|
||||
<!-- 已登录未绑定手机 -->
|
||||
<view v-if="isLogin && !hasBoundMobile" class="profile-actions">
|
||||
<view class="action-btn" @tap.stop="openBindModal">
|
||||
<view class="action-btn" @tap.stop="openBindModalFromProfile">
|
||||
<view class="action-icon i-carbon-phone" />
|
||||
<text class="action-text">绑定手机号</text>
|
||||
</view>
|
||||
@@ -406,20 +309,18 @@ onUnmounted(() => {
|
||||
<!-- ═══ 区块3: 常用工具 ═══ -->
|
||||
<view class="section">
|
||||
<view class="section-title">常用工具</view>
|
||||
<view class="tool-list">
|
||||
<view class="tool-row" @tap="goOilPrice">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(23,104,255,0.08)">
|
||||
<view class="tool-row-icon i-carbon-gas-station" style="color: #1768ff" />
|
||||
<view class="quick-grid">
|
||||
<view class="quick-item" @tap="goOilPrice">
|
||||
<view class="quick-icon-wrap" style="background: rgba(23,104,255,0.08)">
|
||||
<view class="quick-icon i-carbon-gas-station" style="color: #1768ff" />
|
||||
</view>
|
||||
<text class="tool-row-name">实时油价查询</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">实时油价查询</text>
|
||||
</view>
|
||||
<view class="tool-row" @tap="goIllegalCode">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(250,140,22,0.08)">
|
||||
<view class="tool-row-icon i-carbon-search" style="color: #fa8c16" />
|
||||
<view class="quick-item" @tap="goIllegalCode">
|
||||
<view class="quick-icon-wrap" style="background: rgba(250,140,22,0.08)">
|
||||
<view class="quick-icon i-carbon-search" style="color: #fa8c16" />
|
||||
</view>
|
||||
<text class="tool-row-name">违章代码查询</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">违章代码查询</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -427,57 +328,52 @@ onUnmounted(() => {
|
||||
<!-- ═══ 区块4: 服务与支持 ═══ -->
|
||||
<view class="section">
|
||||
<view class="section-title">服务与支持</view>
|
||||
<view class="tool-list">
|
||||
<button class="tool-row tool-row-btn no-border" open-type="contact" hover-class="tool-row-hover">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(19,194,94,0.08)">
|
||||
<view class="tool-row-icon i-carbon-chat" style="color: #13c25e" />
|
||||
</view>
|
||||
<view class="tool-row-text">
|
||||
<text class="tool-row-name">在线客服</text>
|
||||
<text class="tool-row-sub">周一至周日 9:00-20:00</text>
|
||||
<view class="quick-grid">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="quick-item quick-item-btn" open-type="contact" hover-class="quick-item-hover">
|
||||
<view class="quick-icon-wrap" style="background: rgba(19,194,94,0.08)">
|
||||
<view class="quick-icon i-carbon-chat" style="color: #13c25e" />
|
||||
</view>
|
||||
<text class="quick-name">在线客服</text>
|
||||
</button>
|
||||
<view class="tool-row" @tap="goHelp">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(114,46,209,0.08)">
|
||||
<view class="tool-row-icon i-carbon-help" style="color: #722ed1" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<view class="quick-item" @tap="goServiceFallback">
|
||||
<view class="quick-icon-wrap" style="background: rgba(19,194,94,0.08)">
|
||||
<view class="quick-icon i-carbon-chat" style="color: #13c25e" />
|
||||
</view>
|
||||
<text class="tool-row-name">帮助中心</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">在线客服</text>
|
||||
</view>
|
||||
<view class="tool-row" @tap="goAbout">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.08)">
|
||||
<view class="tool-row-icon i-carbon-information" style="color: #4e5969" />
|
||||
<!-- #endif -->
|
||||
<view class="quick-item" @tap="goHelp">
|
||||
<view class="quick-icon-wrap" style="background: rgba(114,46,209,0.08)">
|
||||
<view class="quick-icon i-carbon-help" style="color: #722ed1" />
|
||||
</view>
|
||||
<text class="tool-row-name">关于我们</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">帮助中心</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- ═══ 区块5: 法律条款 ═══ -->
|
||||
<view class="section">
|
||||
<view class="section-title">法律条款</view>
|
||||
<view class="tool-list">
|
||||
<view class="tool-row" @tap="goLegalUserAgreement">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||
<view class="tool-row-icon i-carbon-document-blank" style="color: #86909c" />
|
||||
<view class="quick-item" @tap="goAbout">
|
||||
<view class="quick-icon-wrap" style="background: rgba(78,89,105,0.08)">
|
||||
<view class="quick-icon i-carbon-information" style="color: #4e5969" />
|
||||
</view>
|
||||
<text class="tool-row-name">用户协议</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">关于我们</text>
|
||||
</view>
|
||||
<view class="tool-row" @tap="goLegalPrivacyPolicy">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||
<view class="tool-row-icon i-carbon-security" style="color: #86909c" />
|
||||
<view class="quick-item" @tap="goLegalUserAgreement">
|
||||
<view class="quick-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||
<view class="quick-icon i-carbon-document-blank" style="color: #86909c" />
|
||||
</view>
|
||||
<text class="tool-row-name">隐私政策</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">用户协议</text>
|
||||
</view>
|
||||
<view class="tool-row no-border" @tap="goLegalAuthorization">
|
||||
<view class="tool-row-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||
<view class="tool-row-icon i-carbon-certificate" style="color: #86909c" />
|
||||
<view class="quick-item" @tap="goLegalPrivacyPolicy">
|
||||
<view class="quick-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||
<view class="quick-icon i-carbon-security" style="color: #86909c" />
|
||||
</view>
|
||||
<text class="tool-row-name">授权书</text>
|
||||
<text class="tool-row-arrow">›</text>
|
||||
<text class="quick-name">隐私政策</text>
|
||||
</view>
|
||||
<view class="quick-item" @tap="goLegalAuthorization">
|
||||
<view class="quick-icon-wrap" style="background: rgba(78,89,105,0.06)">
|
||||
<view class="quick-icon i-carbon-certificate" style="color: #86909c" />
|
||||
</view>
|
||||
<text class="quick-name">授权书</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -735,7 +631,7 @@ onUnmounted(() => {
|
||||
.quick-icon-wrap {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 24rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
Reference in New Issue
Block a user