206 lines
6.6 KiB
Vue
206 lines
6.6 KiB
Vue
<template>
|
|
<view class="card function-card">
|
|
<view class="card-header">
|
|
<view class="title">功能菜单</view>
|
|
<!-- <view class="header-actions">
|
|
<button class="btn-apple btn-primary" @tap="$emit('sync')">运营数据同步</button>
|
|
</view> -->
|
|
</view>
|
|
<view class="function-grid">
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'authentication')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/authentication.png" mode="aspectFit" alt="实名认证"></image>
|
|
</view>
|
|
<view :class="['function-name', realNameStatus === '已实名' ? 'text-primary' : '']">
|
|
{{ realNameStatus || '实名认证' }}
|
|
</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('sync')" role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/data.png" mode="aspectFit" alt="运营数据同步"></image>
|
|
</view>
|
|
<view class="function-name">运营数据同步</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'package-order')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/shop.png" mode="aspectFit" alt="套餐订购"></image>
|
|
</view>
|
|
<view class="function-name">套餐订购</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'order-list')" role="button"
|
|
tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/order.png" mode="aspectFit" alt="我的订单"></image>
|
|
</view>
|
|
<view class="function-name">我的订单</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" v-if="isDevice" @tap="$emit('enter', 'back')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/back.png" mode="aspectFit" alt="后台管理"></image>
|
|
</view>
|
|
<view class="function-name">后台管理</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" v-if="isDevice" @tap="$emit('enter', 'switch')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/change.png" mode="aspectFit" alt="切换运营商"></image>
|
|
</view>
|
|
<view class="function-name">切换运营商</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'asset-package')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/asset-package-history.png" mode="aspectFit" alt="资产套餐历史"></image>
|
|
</view>
|
|
<view class="function-name">资产套餐历史</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="handleBindPhone" role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/bind-phone.png" mode="aspectFit" alt="绑定手机号"></image>
|
|
</view>
|
|
<view :class="['function-name', alreadyBindPhone ? 'text-primary' : 'text-danger']">
|
|
{{ alreadyBindPhone ? '已绑定' : '未绑定' }}
|
|
</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'change-phone')" role="button"
|
|
tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/change-phone.png" mode="aspectFit" alt="更换手机号"></image>
|
|
</view>
|
|
<view class="function-name">更换手机号</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" v-if="isDevice"
|
|
@tap="$emit('enter', 'device-exchange')" role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/change.png" mode="aspectFit" alt="设备换货"></image>
|
|
</view>
|
|
<view class="function-name">设备换货</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'wallet')" role="button"
|
|
tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/wallet.png" mode="aspectFit" alt="钱包"></image>
|
|
</view>
|
|
<view class="function-name">{{ walletText }}</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" v-if="isDevice" @tap="$emit('enter', 'recover')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/recover.png" mode="aspectFit" alt="重启设备"></image>
|
|
</view>
|
|
<view class="function-name">重启设备</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" v-if="isDevice" @tap="$emit('enter', 'restart')"
|
|
role="button" tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/restart.png" mode="aspectFit" alt="恢复出厂"></image>
|
|
</view>
|
|
<view class="function-name">恢复出厂</view>
|
|
</view>
|
|
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'out')" role="button"
|
|
tabindex="0">
|
|
<view class="function-icon">
|
|
<image src="/static/out.png" mode="aspectFit" alt="退出登录"></image>
|
|
</view>
|
|
<view class="function-name">退出登录</view>
|
|
</view>
|
|
</view>
|
|
|
|
<slot></slot>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue';
|
|
|
|
const props = defineProps({
|
|
realNameStatus: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
alreadyBindPhone: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isDevice: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
walletBalance: {
|
|
type: [Number, String],
|
|
default: 0
|
|
}
|
|
});
|
|
|
|
const emit = defineEmits(['enter', 'sync']);
|
|
|
|
const formatWalletBalance = (balance) => {
|
|
const amount = Number(balance);
|
|
if (!Number.isFinite(amount) || amount === 0) return '0';
|
|
|
|
return (amount / 100).toFixed(2).replace(/\.?0+$/, '');
|
|
};
|
|
|
|
const walletText = computed(() => `钱包 (${formatWalletBalance(props.walletBalance)})`);
|
|
|
|
const handleBindPhone = () => {
|
|
if (props.alreadyBindPhone) {
|
|
return;
|
|
}
|
|
emit('enter', 'bind');
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.function-card {
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.function-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 16rpx;
|
|
width: 100%;
|
|
|
|
.function-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 20rpx;
|
|
|
|
.function-icon {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
image {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.function-name {
|
|
font-size: 28rpx;
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
text-align: center;
|
|
margin-top: 15rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.text-primary {
|
|
color: var(--primary) !important;
|
|
}
|
|
</style>
|