This commit is contained in:
2026-09-24 10:41:35 +08:00
parent af8e8c4623
commit 75b8414605
+77 -57
View File
@@ -3,48 +3,56 @@
<fy-header title="我的" /> <fy-header title="我的" />
<fy-scroll class="edge-scroll" dock @refresh="reload"> <fy-scroll class="edge-scroll" dock @refresh="reload">
<view class="body"> <view class="body">
<view class="card profile"> <view class="profile" @click="goArchive">
<view class="row"> <image v-if="me && me.avatar" class="av" :src="me.avatar" mode="aspectFill" />
<image v-if="me && me.avatar" class="av" :src="me.avatar" mode="aspectFill" /> <view v-else class="av txt">{{ initial }}</view>
<view v-else class="av txt">{{ initial }}</view> <view class="info">
<view class="info"> <view class="nm">
<view class="nm"> <text class="name">{{ me ? me.name : '' }}</text>
<text class="name">{{ me ? me.name : '' }}</text> <text v-if="statusText" class="tag">{{ statusText }}</text>
<wd-tag type="success" plain>在职</wd-tag>
</view>
<text class="dept">{{ me ? (me.department + ' · ' + me.title) : '' }}</text>
<text class="ph">{{ phone }}{{ job }}</text>
</view> </view>
<text class="sub">{{ deptLine }}</text>
<text class="sub">{{ phone }}{{ job }}</text>
</view> </view>
<view class="stats"> <wd-icon name="qrcode" size="36rpx" color="#111827" />
<view class="s" @click="switchClock"> <text class="chev"></text>
<text class="n">{{ attendDays }}</text> </view>
<text class="l">本月出勤()</text>
</view> <view class="group">
<view class="s mid" @click="goTodo"> <view class="cell" @click="switchClock">
<text class="n">{{ todoCount }}</text> <wd-icon name="location" size="40rpx" color="#1677FF" />
<text class="l">待办申请()</text> <text class="ct">本月出勤</text>
</view> <text class="cv">{{ attendDays }} </text>
<view class="s"> <text class="chev"></text>
<text class="n ok">正常</text> </view>
<text class="l">考勤状态</text> <view class="cell" @click="goTodo">
</view> <wd-icon name="check-circle" size="40rpx" color="#16A34A" />
<text class="ct">待办申请</text>
<text class="cv">{{ todoCount }}</text>
<text class="chev"></text>
</view> </view>
</view> </view>
<view class="card menu"> <view v-if="menus.length" class="group">
<wd-cell-group border> <view v-for="a in menus" :key="a.id" class="cell" @click="open(a)">
<wd-cell v-for="a in menus" :key="a.id" :title="a.title" is-link @click="open(a)" /> <wd-icon :name="iconOf(a)" size="40rpx" :color="colorOf(a)" />
</wd-cell-group> <text class="ct">{{ a.title }}</text>
<text class="chev"></text>
</view>
</view> </view>
<view class="card menu"> <view class="group">
<wd-cell-group border> <view class="cell" @click="goPwd">
<wd-cell title="修改密码" is-link @click="goPwd" /> <wd-icon name="lock-on" size="40rpx" color="#576B95" />
<wd-cell is-link @click="logout"> <text class="ct">修改密码</text>
<template #title><text class="danger">退出登录</text></template> <text class="chev"></text>
</wd-cell> </view>
</wd-cell-group> </view>
<view class="group">
<view class="cell center" @click="logout">
<text class="danger">退出登录</text>
</view>
</view> </view>
</view> </view>
</fy-scroll> </fy-scroll>
@@ -56,6 +64,7 @@ import FyHeader from '../../components/fy-header.vue'
import FyScroll from '../../components/fy-scroll.vue' import FyScroll from '../../components/fy-scroll.vue'
import { store } from '../../utils/store.js' import { store } from '../../utils/store.js'
import { maskPhone } from '../../utils/format.js' import { maskPhone } from '../../utils/format.js'
import { tileVisual } from '../../utils/nav.js'
const ME_IDS = ['archive', 'salary', 'perf', 'expense', 'report', 'apply'] const ME_IDS = ['archive', 'salary', 'perf', 'expense', 'report', 'apply']
@@ -67,6 +76,13 @@ export default {
computed: { computed: {
me() { return store.me }, me() { return store.me },
initial() { return this.me ? this.me.name.slice(0, 1) : '我' }, initial() { return this.me ? this.me.name.slice(0, 1) : '我' },
statusText() {
return (this.me && this.me.employeeStatus) || '在职'
},
deptLine() {
if (!this.me) return ''
return [this.me.department, this.me.title].filter(Boolean).join(' · ')
},
phone() { return maskPhone(this.me && this.me.phone) }, phone() { return maskPhone(this.me && this.me.phone) },
job() { return this.me && this.me.jobId ? ' · 工号: ' + this.me.jobId : '' }, job() { return this.me && this.me.jobId ? ' · 工号: ' + this.me.jobId : '' },
todoCount() { return store.todoCount || 0 }, todoCount() { return store.todoCount || 0 },
@@ -81,6 +97,13 @@ export default {
}, },
onHide() { if (this.off) this.off() }, onHide() { if (this.off) this.off() },
methods: { methods: {
iconOf(a) { return tileVisual(a).name },
colorOf(a) { return tileVisual(a).color },
goArchive() {
const a = store.personalApps().find((x) => x.id === 'archive')
if (a) this.open(a)
else uni.navigateTo({ url: '/pages/me/archive' })
},
open(a) { open(a) {
if (a.url.startsWith('/pages/tabs/')) uni.switchTab({ url: a.url.split('?')[0] }) if (a.url.startsWith('/pages/tabs/')) uni.switchTab({ url: a.url.split('?')[0] })
else uni.navigateTo({ url: a.url }) else uni.navigateTo({ url: a.url })
@@ -108,27 +131,24 @@ export default {
</script> </script>
<style scoped> <style scoped>
.body { padding: 8rpx 28rpx 48rpx; } .body { padding: 16rpx 0 48rpx; background: #EDEDED; min-height: 100%; }
.profile { padding: 32rpx 28rpx 24rpx; } .profile {
.row { display: flex; align-items: center; } display: flex; align-items: center;
.av { width: 112rpx; height: 112rpx; border-radius: 50%; } background: #fff; padding: 48rpx 28rpx 40rpx; margin-bottom: 16rpx;
.av.txt { background: #1677FF; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 40rpx; font-weight: 650; } }
.info { margin-left: 24rpx; flex: 1; min-width: 0; } .av { width: 128rpx; height: 128rpx; border-radius: 12rpx; flex-shrink: 0; }
.av.txt { background: #1677FF; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 48rpx; font-weight: 650; }
.info { flex: 1; min-width: 0; margin: 0 20rpx; }
.nm { display: flex; align-items: center; gap: 12rpx; } .nm { display: flex; align-items: center; gap: 12rpx; }
.name { font-size: 36rpx; font-weight: 650; } .name { font-size: 40rpx; font-weight: 650; color: #111827; }
.st { font-size: 22rpx; background: #E8F8EF; color: #16A34A; padding: 4rpx 12rpx; border-radius: 8rpx; } .tag { font-size: 22rpx; color: #16A34A; background: #E8F8EF; border-radius: 8rpx; padding: 2rpx 10rpx; }
.dept, .ph { display: block; font-size: 24rpx; color: #6B7280; margin-top: 8rpx; } .sub { display: block; font-size: 26rpx; color: #6B7280; margin-top: 8rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stats { display: flex; margin-top: 28rpx; padding-top: 24rpx; border-top: 1rpx solid #F0F2F5; } .group { background: #fff; margin-bottom: 16rpx; }
.s { flex: 1; text-align: center; } .cell { display: flex; align-items: center; min-height: 108rpx; padding: 0 28rpx; gap: 24rpx; }
.mid { border-left: 1rpx solid #F0F2F5; border-right: 1rpx solid #F0F2F5; } .cell + .cell { border-top: 1rpx solid #EDEDED; }
.n { display: block; font-size: 34rpx; font-weight: 650; color: #111827; } .cell.center { justify-content: center; }
.n.ok { color: #16A34A; font-size: 28rpx; } .ct { flex: 1; font-size: 32rpx; color: #111827; }
.l { font-size: 22rpx; color: #6B7280; margin-top: 4rpx; } .cv { font-size: 28rpx; color: #9CA3AF; }
.menu { margin-top: 20rpx; overflow: hidden; } .chev { color: #C8C8C8; font-size: 36rpx; }
.mi { display: flex; align-items: center; min-height: 100rpx; padding: 0 28rpx; } .danger { font-size: 32rpx; color: #111827; }
.mi + .mi { border-top: 1rpx solid #F0F2F5; }
.ii { width: 48rpx; color: #1677FF; font-weight: 650; }
.it { flex: 1; font-size: 28rpx; }
.arr { color: #C4C9D4; font-size: 32rpx; }
.danger { color: #DC2626; }
</style> </style>