| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- <template>
- <view class="user-detail-page">
- <NavBar title="用户详情" bgColor="#ffd53f" color="#5c4314"></NavBar>
- <view class="user-hero">
- <image :src="user.avatarUrl || 'https://img.icons8.com/?size=256&id=23235&format=png'" class="avatar" mode="aspectFill"></image>
- <view class="hero-info">
- <text class="user-name">{{ user.name || '-' }}</text>
- <text class="gender-text" v-if="user.gender !== undefined">({{ user.gender === 1 ? '女' : '男' }})</text>
- </view>
- <text class="user-phone">{{ user.phone || '-' }}</text>
- <view class="tag-list" v-if="user.tags && user.tags.length > 0">
- <text class="tag-item" v-for="tag in user.tags" :key="tag.id">{{ tag.name }}</text>
- </view>
- </view>
- <view class="info-card">
- <view class="section-title">基本信息</view>
- <view class="info-row"><text class="label">状态</text><text class="value" :class="{ 'orange': user.status === 0 }">{{ user.status === 0 ? '正常' : '禁用' }}</text></view>
- <view class="info-row"><text class="label">所属区域</text><text class="value">{{ user.areaName || '-' }}</text></view>
- <view class="info-row"><text class="label">所属站点</text><text class="value">{{ user.stationName || '-' }}</text></view>
- <view class="info-row"><text class="label">所属品牌</text><text class="value">{{ user.tenantName || '-' }}</text></view>
- <view class="info-row"><text class="label">录入时间</text><text class="value">{{ user.createTime || '-' }}</text></view>
-
- <view class="section-title">居住信息</view>
- <view class="info-row"><text class="label">详细住址</text><text class="value">{{ user.address || '-' }}</text></view>
- <view class="info-row"><text class="label">房屋类型</text><text class="value">{{ getHouseTypeLabel(user.houseType) }}</text></view>
- <view class="info-row"><text class="label">入门方式</text><text class="value">{{ user.entryMethod === 'password' ? '密码' : (user.entryMethod === 'key' ? '钥匙' : user.entryMethod || '-') }}</text></view>
- <view class="info-row"><text class="label">开门详情</text><text class="value">{{ user.entryMethod === 'password' ? (user.entryPassword || '-') : (user.keyLocation || '-') }}</text></view>
-
- <view class="info-row" v-if="user.remark" style="margin-top:20rpx;"><text class="label">备注</text><text class="value">{{ user.remark }}</text></view>
- </view>
- <button class="edit-btn" @click="goToEdit">编辑用户资料</button>
- </view>
- </template>
- <script setup>
- import { ref } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import NavBar from '@/components/nav-bar/index.vue'
- import { getCustomer } from '@/api/archieves/customer'
- import { listAreaStation } from '@/api/system/areaStation'
- import customerEnums from '@/json/customer.json'
- const { houseTypeOptions } = customerEnums
- // 将房屋类型 value 转换为中文标签
- const getHouseTypeLabel = (val) => {
- const item = houseTypeOptions.find(o => o.value === val)
- return item ? item.label : (val || '-')
- }
- const user = ref({})
- onLoad((options) => {
- if (options.id) {
- loadDetail(options.id)
- }
- })
- const loadDetail = async (id) => {
- try {
- uni.showLoading({ title: '加载中...' })
- const [stationRes, userRes] = await Promise.all([
- listAreaStation().catch(() => []),
- getCustomer(id)
- ])
- const data = userRes || {}
- const allNodes = Array.isArray(stationRes) ? stationRes : (stationRes?.data || [])
- if (data.areaId) {
- const area = allNodes.find(n => String(n.id) === String(data.areaId))
- data.areaName = area ? area.name : '-'
- }
- if (data.stationId) {
- const station = allNodes.find(n => String(n.id) === String(data.stationId))
- data.stationName = station ? station.name : '-'
- }
- user.value = data
- } catch(err) {
- console.error(err)
- } finally {
- uni.hideLoading()
- }
- }
- const goToEdit = () => {
- if (!user.value.id) return
- uni.navigateTo({ url: `/pages/my/user/edit/index?id=${user.value.id}` })
- }
- </script>
- <style lang="scss" scoped>
- .user-detail-page { min-height: 100vh; background: #f7f8fa; padding-bottom: 160rpx; }
- .user-hero { background: linear-gradient(150deg, #ffd53f, #ff9500); padding: 40rpx 40rpx 60rpx; display: flex; flex-direction: column; align-items: center; }
- .avatar { width: 160rpx; height: 160rpx; border-radius: 50%; border: 8rpx solid #fff; margin-bottom: 20rpx; background:#fff; }
- .hero-info { display: flex; align-items: center; margin-bottom: 8rpx; }
- .user-name { font-size: 40rpx; font-weight: 800; color: #5c4314; }
- .gender-text { font-size: 30rpx; color: #5c4314; margin-left: 8rpx; opacity: 0.8; }
- .user-phone { font-size: 28rpx; color: #5c4314; opacity: 0.8; }
- .tag-list { display: flex; flex-wrap: wrap; gap: 12rpx; justify-content: center; margin-top: 16rpx; }
- .tag-item { background: rgba(255,255,255,0.3); color: #5c4314; font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 16rpx; }
- .info-card { background: #fff; border-radius: 32rpx 32rpx 0 0; margin-top: -40rpx; padding: 40rpx 32rpx; position: relative; z-index: 3; }
- .section-title { font-size: 32rpx; font-weight: bold; color: #333; margin: 32rpx 0 16rpx; display: flex; align-items: center; }
- .section-title::before { content: ''; display: inline-block; width: 6rpx; height: 28rpx; background: #ffd53f; margin-right: 12rpx; border-radius: 4rpx; }
- .section-title:first-child { margin-top: 0; }
- .info-row { display: flex; justify-content: space-between; padding: 24rpx 0; border-bottom: 2rpx solid #EEEEEE; }
- .info-row:last-child { border-bottom: none; }
- .label { font-size: 28rpx; color: #999; flex-shrink: 0; margin-right: 20rpx; }
- .value { font-size: 28rpx; color: #333; font-weight: 500; text-align: right; word-break: break-all; }
- .value.orange { color: #ff9800; }
- .edit-btn { margin: 40rpx 32rpx; width: calc(100% - 64rpx); height: 96rpx; background: linear-gradient(90deg, #ffd53f, #ff9500); color: #fff; border: none; border-radius: 48rpx; font-size: 32rpx; font-weight: bold; line-height: 96rpx; }
- </style>
|