first commit
This commit is contained in:
982
src/pages/mine.vue
Normal file
982
src/pages/mine.vue
Normal file
@@ -0,0 +1,982 @@
|
||||
<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'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '我的',
|
||||
navigationStyle: 'default',
|
||||
navigationBarBackgroundColor: '#ffffff',
|
||||
navigationBarTextStyle: 'black',
|
||||
// 微信小程序:允许使用 open-type="share" 与右上角转发
|
||||
enableShareAppMessage: true,
|
||||
enableShareTimeline: true,
|
||||
},
|
||||
})
|
||||
|
||||
/** 商务合作弹窗中的二维码图:将图片放到 `src/static/` 后改为 `/static/xxx.png` 或填网络地址 */
|
||||
const BUSINESS_COOP_QR_SRC = ''
|
||||
|
||||
const SHARE_TITLE = '全能查 — 买车先查车况,更安心'
|
||||
const SHARE_PATH = '/pages/index'
|
||||
|
||||
const WX_NICK_KEY = 'wx_display_name'
|
||||
|
||||
const isLogin = ref(false)
|
||||
const nickname = ref('')
|
||||
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 coopModalOpen = ref(false)
|
||||
|
||||
onShareAppMessage(() => ({
|
||||
title: SHARE_TITLE,
|
||||
path: SHARE_PATH,
|
||||
}))
|
||||
|
||||
onShareTimeline(() => ({
|
||||
title: SHARE_TITLE,
|
||||
query: '',
|
||||
}))
|
||||
|
||||
function maskMobile(plain: string) {
|
||||
const s = (plain || '').trim()
|
||||
if (s.length >= 11)
|
||||
return `${s.slice(0, 3)}****${s.slice(-4)}`
|
||||
return s || ''
|
||||
}
|
||||
|
||||
function loadWxNickFromStorage() {
|
||||
try {
|
||||
const n = uni.getStorageSync(WX_NICK_KEY)
|
||||
wxNickStorage.value = typeof n === 'string' && n ? n : ''
|
||||
}
|
||||
catch {
|
||||
wxNickStorage.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
function clearBindSmsTimer() {
|
||||
if (bindSmsTimer) {
|
||||
clearInterval(bindSmsTimer)
|
||||
bindSmsTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
nickname.value = ''
|
||||
userDesc.value = ''
|
||||
hasBoundMobile.value = false
|
||||
return
|
||||
}
|
||||
loadWxNickFromStorage()
|
||||
try {
|
||||
const res = await getUserDetail() as {
|
||||
code?: number
|
||||
data?: { userInfo?: { mobile?: string, nickName?: string } }
|
||||
}
|
||||
if (res && res.code === 200 && res.data?.userInfo) {
|
||||
const u = res.data.userInfo
|
||||
const mobile = (u.mobile || '').trim()
|
||||
const apiNick = (u.nickName || '').trim()
|
||||
hasBoundMobile.value = /^1[3-9]\d{9}$/.test(mobile)
|
||||
if (hasBoundMobile.value) {
|
||||
nickname.value = maskMobile(mobile)
|
||||
userDesc.value = '已绑定手机号,可同步历史报告与收藏'
|
||||
}
|
||||
else {
|
||||
nickname.value = wxNickStorage.value || apiNick || '微信用户'
|
||||
userDesc.value = '绑定手机号后,可同步历史报告与收藏'
|
||||
}
|
||||
}
|
||||
else {
|
||||
nickname.value = wxNickStorage.value || '已登录'
|
||||
userDesc.value = '获取资料失败,请稍后下拉刷新'
|
||||
}
|
||||
}
|
||||
catch {
|
||||
nickname.value = wxNickStorage.value || '已登录'
|
||||
userDesc.value = '网络异常,请稍后重试'
|
||||
}
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
void refreshUserCard()
|
||||
// #ifdef MP-WEIXIN
|
||||
try {
|
||||
uni.showShareMenu({
|
||||
withShareTicket: true,
|
||||
menus: ['shareAppMessage', 'shareTimeline'],
|
||||
})
|
||||
}
|
||||
catch {
|
||||
/* ignore */
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
|
||||
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' })
|
||||
}
|
||||
|
||||
/** 微信小程序:用户主动触发才可调 getUserProfile */
|
||||
async function syncWxNickname() {
|
||||
// #ifdef MP-WEIXIN
|
||||
try {
|
||||
const res = await new Promise<{ userInfo?: { nickName?: string } }>((resolve, reject) => {
|
||||
uni.getUserProfile({
|
||||
desc: '用于在本页展示昵称',
|
||||
lang: 'zh_CN',
|
||||
success: resolve,
|
||||
fail: reject,
|
||||
})
|
||||
})
|
||||
const name = res.userInfo?.nickName?.trim()
|
||||
if (name) {
|
||||
uni.setStorageSync(WX_NICK_KEY, name)
|
||||
wxNickStorage.value = name
|
||||
if (!hasBoundMobile.value)
|
||||
nickname.value = name
|
||||
uni.showToast({ title: '昵称已更新', icon: 'none' })
|
||||
}
|
||||
}
|
||||
catch {
|
||||
uni.showToast({ title: '需要您确认授权', icon: 'none' })
|
||||
}
|
||||
// #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' })
|
||||
}
|
||||
|
||||
function goFreeValuation() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
}
|
||||
|
||||
/** 非微信小程序:无 open-type=share,仅提示 */
|
||||
function goShareFallback() {
|
||||
uni.showToast({ title: '请在微信小程序内使用分享', icon: 'none' })
|
||||
}
|
||||
|
||||
function openCoopModal() {
|
||||
coopModalOpen.value = true
|
||||
}
|
||||
|
||||
function closeCoopModal() {
|
||||
coopModalOpen.value = false
|
||||
}
|
||||
|
||||
function goLegalUserAgreement() {
|
||||
uni.navigateTo({ url: '/pages/legal/user-agreement' })
|
||||
}
|
||||
|
||||
function goLegalPrivacyPolicy() {
|
||||
uni.navigateTo({ url: '/pages/legal/privacy-policy' })
|
||||
}
|
||||
|
||||
function goLegalAuthorization() {
|
||||
uni.navigateTo({ url: '/pages/legal/authorization' })
|
||||
}
|
||||
|
||||
function goIllegalCode() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
}
|
||||
|
||||
function goOilPrice() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
}
|
||||
|
||||
function goHelp() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
}
|
||||
|
||||
function goAbout() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
}
|
||||
|
||||
function goSettings() {
|
||||
uni.showToast({ title: '敬请期待', icon: 'none' })
|
||||
}
|
||||
|
||||
/** 非微信小程序:无 open-type=contact */
|
||||
function goServiceFallback() {
|
||||
uni.showToast({ title: '请在微信小程序内使用在线客服', icon: 'none' })
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
clearBindSmsTimer()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="page-root">
|
||||
<scroll-view scroll-y class="scrollarea">
|
||||
<view class="page">
|
||||
<view class="banner mine-banner">
|
||||
<view class="banner-text">
|
||||
<view class="banner-title">
|
||||
买车先查车况,更安心
|
||||
</view>
|
||||
<view class="banner-sub">
|
||||
减少隐蔽事故车、泡水车、调表车风险
|
||||
</view>
|
||||
</view>
|
||||
<view class="banner-illustration">
|
||||
<view class="car-illus" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card mine-user">
|
||||
<view class="mine-user-main" @tap="handleUserTap">
|
||||
<view class="mine-avatar-placeholder" />
|
||||
<view class="mine-user-text">
|
||||
<view class="mine-user-name">
|
||||
{{ isLogin ? nickname : '您还没有登录,立即登录' }}
|
||||
</view>
|
||||
<view class="mine-user-desc">
|
||||
{{ isLogin ? userDesc : '登录后可同步历史报告与收藏' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view v-if="isLogin && !hasBoundMobile" class="mine-user-extra">
|
||||
<text class="extra-link" @tap.stop="syncWxNickname">同步微信昵称</text>
|
||||
<text class="extra-dot">·</text>
|
||||
<text class="extra-hint">绑定手机后优先显示手机号</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view
|
||||
v-if="isLogin && !hasBoundMobile"
|
||||
class="mine-bind-row"
|
||||
@tap.stop="openBindModal"
|
||||
>
|
||||
<text class="mine-bind-text">绑定手机号</text>
|
||||
<text class="mine-bind-arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card">
|
||||
<view class="grid-4">
|
||||
<view class="grid-item" @tap="goHistoryReport">
|
||||
<view class="icon-tool i-carbon-document" />
|
||||
<view class="grid-text">
|
||||
历史报告
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-item" @tap="goFreeValuation">
|
||||
<view class="icon-tool i-carbon-chart-line" />
|
||||
<view class="grid-text">
|
||||
免费估值
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="grid-item grid-item-btn" open-type="share" hover-class="grid-item-hover">
|
||||
<view class="icon-tool i-carbon-share" />
|
||||
<view class="grid-text">
|
||||
分享好友
|
||||
</view>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<view class="grid-item" @tap="goShareFallback">
|
||||
<view class="icon-tool i-carbon-share" />
|
||||
<view class="grid-text">
|
||||
分享好友
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view class="grid-item" @tap="openCoopModal">
|
||||
<view class="icon-tool i-carbon-enterprise" />
|
||||
<view class="grid-text">
|
||||
商务合作
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card list-card">
|
||||
<view class="list-item" @tap="goLegalUserAgreement">
|
||||
<view class="list-icon i-carbon-document-blank" />
|
||||
<text class="list-text">用户协议</text>
|
||||
</view>
|
||||
<view class="list-item" @tap="goLegalPrivacyPolicy">
|
||||
<view class="list-icon i-carbon-security" />
|
||||
<text class="list-text">隐私政策</text>
|
||||
</view>
|
||||
<view class="list-item" @tap="goLegalAuthorization">
|
||||
<view class="list-icon i-carbon-certificate" />
|
||||
<text class="list-text">授权书</text>
|
||||
</view>
|
||||
<view class="list-item" @tap="goHelp">
|
||||
<view class="list-icon i-carbon-help" />
|
||||
<text class="list-text">帮助中心</text>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
<button
|
||||
class="list-item list-item-contact no-border"
|
||||
open-type="contact"
|
||||
hover-class="list-item-contact-hover"
|
||||
>
|
||||
<view class="list-icon i-carbon-chat" />
|
||||
<view class="service-row">
|
||||
<text class="list-text">在线客服</text>
|
||||
<text class="service-time">人工客服 周一至周日 9:00-20:00</text>
|
||||
</view>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view v-if="coopModalOpen" class="coop-mask" @tap.self="closeCoopModal">
|
||||
<view class="coop-dialog" @tap.stop>
|
||||
<view class="coop-title">
|
||||
商务合作
|
||||
</view>
|
||||
<view class="coop-hint">
|
||||
扫码添加商务微信(图片路径可在代码中配置)
|
||||
</view>
|
||||
<image
|
||||
v-if="BUSINESS_COOP_QR_SRC"
|
||||
class="coop-qr"
|
||||
:src="BUSINESS_COOP_QR_SRC"
|
||||
mode="aspectFit"
|
||||
show-menu-by-longpress
|
||||
/>
|
||||
<view v-else class="coop-qr-placeholder">
|
||||
<text class="coop-qr-placeholder-text">二维码图片路径待定</text>
|
||||
<text class="coop-qr-placeholder-text coop-qr-placeholder-sub">请将图片放入 static 目录,并在 mine.vue 中为 BUSINESS_COOP_QR_SRC 赋值</text>
|
||||
</view>
|
||||
<view class="coop-close" @tap="closeCoopModal">
|
||||
知道了
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="bindModalOpen" class="bind-mask" @tap.self="closeBindModal">
|
||||
<view class="bind-sheet" @tap.stop>
|
||||
<view class="bind-sheet-title">
|
||||
绑定手机号
|
||||
</view>
|
||||
<view class="bind-field">
|
||||
<text class="bind-label">手机号</text>
|
||||
<input
|
||||
class="bind-input"
|
||||
type="digit"
|
||||
:value="bindPhone"
|
||||
:maxlength="11"
|
||||
placeholder="请输入手机号"
|
||||
placeholder-class="bind-ph"
|
||||
confirm-type="done"
|
||||
@input="onBindPhoneInput"
|
||||
>
|
||||
</view>
|
||||
<view class="bind-field bind-field-row">
|
||||
<view class="bind-field-grow">
|
||||
<text class="bind-label">验证码</text>
|
||||
<input
|
||||
class="bind-input"
|
||||
type="digit"
|
||||
:value="bindCode"
|
||||
:maxlength="6"
|
||||
placeholder="6 位短信码"
|
||||
placeholder-class="bind-ph"
|
||||
confirm-type="done"
|
||||
@input="onBindCodeInput"
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
class="bind-sms"
|
||||
:class="{ disabled: bindSending || bindCountingDown || !isBindPhoneValid() }"
|
||||
@tap="sendBindSms"
|
||||
>
|
||||
{{ bindCountingDown ? `${bindCountdown}s` : '获取验证码' }}
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="bind-submit"
|
||||
:class="{ disabled: bindSubmitting || !isBindPhoneValid() || bindCode.length < 6 }"
|
||||
@tap="submitBindMobile"
|
||||
>
|
||||
确认绑定
|
||||
</view>
|
||||
<view class="bind-cancel" @tap="closeBindModal">
|
||||
取消
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-root {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
padding: 24rpx 24rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.banner {
|
||||
display: flex;
|
||||
padding: 32rpx 28rpx;
|
||||
margin-bottom: 24rpx;
|
||||
background: linear-gradient(135deg, #fff7f0 0%, #ffffff 100%);
|
||||
border-radius: 24rpx;
|
||||
box-shadow:
|
||||
0 18rpx 40rpx rgba(15, 35, 52, 0.05),
|
||||
0 0 0 1rpx rgba(226, 229, 239, 0.9);
|
||||
}
|
||||
|
||||
.banner-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.banner-sub {
|
||||
font-size: 24rpx;
|
||||
color: #4e5969;
|
||||
}
|
||||
|
||||
.banner-illustration {
|
||||
width: 180rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.car-illus {
|
||||
width: 160rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 16rpx;
|
||||
background: linear-gradient(145deg, #ffe8dc 0%, #ffc9a8 100%);
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx 24rpx 20rpx;
|
||||
margin-bottom: 24rpx;
|
||||
border: 1rpx solid #e5e6f0;
|
||||
box-shadow:
|
||||
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
|
||||
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
||||
}
|
||||
|
||||
.mine-user {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.mine-user-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mine-avatar-placeholder {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f2f3f5;
|
||||
margin-right: 20rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mine-user-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mine-user-name {
|
||||
font-size: 28rpx;
|
||||
color: #1d2129;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.mine-user-desc {
|
||||
font-size: 22rpx;
|
||||
color: #86909c;
|
||||
}
|
||||
|
||||
.mine-user-extra {
|
||||
margin-top: 16rpx;
|
||||
padding-top: 16rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
font-size: 22rpx;
|
||||
color: #86909c;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.extra-link {
|
||||
color: #1768ff;
|
||||
}
|
||||
|
||||
.extra-dot {
|
||||
margin: 0 8rpx;
|
||||
color: #c9cdd4;
|
||||
}
|
||||
|
||||
.extra-hint {
|
||||
color: #86909c;
|
||||
}
|
||||
|
||||
.mine-bind-row {
|
||||
margin-top: 12rpx;
|
||||
padding: 16rpx 0 4rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.mine-bind-text {
|
||||
font-size: 26rpx;
|
||||
color: #1768ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mine-bind-arrow {
|
||||
font-size: 36rpx;
|
||||
color: #1768ff;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.bind-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bind-sheet {
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
padding: 28rpx 28rpx calc(28rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bind-sheet-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
margin-bottom: 24rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bind-field {
|
||||
margin-bottom: 20rpx;
|
||||
padding-bottom: 12rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.bind-field-row {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.bind-field-grow {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.bind-label {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #86909c;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.bind-input {
|
||||
width: 100%;
|
||||
height: 72rpx;
|
||||
font-size: 30rpx;
|
||||
color: #1d2129;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bind-ph {
|
||||
color: #c9cdd4;
|
||||
}
|
||||
|
||||
.bind-sms {
|
||||
flex-shrink: 0;
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #1768ff;
|
||||
background: #f0f5ff;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bind-sms.disabled {
|
||||
color: #c9cdd4;
|
||||
background: #f7f8fa;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bind-submit {
|
||||
margin-top: 12rpx;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
background: linear-gradient(90deg, #1768ff 0%, #4d94ff 100%);
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
|
||||
.bind-submit.disabled {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bind-cancel {
|
||||
margin-top: 20rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #86909c;
|
||||
padding: 12rpx;
|
||||
}
|
||||
|
||||
.grid-4 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
width: 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 8rpx;
|
||||
}
|
||||
|
||||
.grid-item-btn {
|
||||
margin: 0;
|
||||
padding: 8rpx 0 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
line-height: normal;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.grid-item-btn::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.grid-item-hover {
|
||||
opacity: 0.88;
|
||||
}
|
||||
|
||||
.coop-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1001;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.coop-dialog {
|
||||
width: 100%;
|
||||
max-width: 600rpx;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 36rpx 32rpx 28rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.coop-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
text-align: center;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.coop-hint {
|
||||
font-size: 24rpx;
|
||||
color: #86909c;
|
||||
text-align: center;
|
||||
margin-bottom: 28rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.coop-qr {
|
||||
display: block;
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
margin: 0 auto 28rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.coop-qr-placeholder {
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
margin: 0 auto 28rpx;
|
||||
border-radius: 12rpx;
|
||||
border: 2rpx dashed #dcdfe6;
|
||||
background: #fafbfc;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24rpx;
|
||||
box-sizing: border-box;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.coop-qr-placeholder-text {
|
||||
font-size: 22rpx;
|
||||
color: #86909c;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.coop-qr-placeholder-sub {
|
||||
font-size: 20rpx;
|
||||
color: #c9cdd4;
|
||||
}
|
||||
|
||||
.coop-close {
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
background: linear-gradient(90deg, #1768ff 0%, #4d94ff 100%);
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
|
||||
.icon-tool {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-bottom: 8rpx;
|
||||
color: #1768ff;
|
||||
}
|
||||
|
||||
.grid-text {
|
||||
font-size: 24rpx;
|
||||
color: #4e5969;
|
||||
}
|
||||
|
||||
.list-card {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
height: 96rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.list-item-contact {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
text-align: left;
|
||||
line-height: inherit;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.list-item-contact::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.list-item-contact-hover {
|
||||
background: rgba(23, 104, 255, 0.06);
|
||||
}
|
||||
|
||||
.list-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
flex-shrink: 0;
|
||||
color: #1768ff;
|
||||
}
|
||||
|
||||
.no-border {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.list-text {
|
||||
font-size: 26rpx;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
.service-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.service-time {
|
||||
font-size: 22rpx;
|
||||
color: #ffb020;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user