Files
oa_app/pages/tabs/me.vue
T
2026-09-23 16:52:48 +08:00

135 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page">
<fy-header title="我" />
<view class="body">
<view class="card profile">
<view class="row">
<image v-if="me && me.avatar" class="av" :src="me.avatar" mode="aspectFill" />
<view v-else class="av txt">{{ initial }}</view>
<view class="info">
<view class="nm">
<text class="name">{{ me ? me.name : '' }}</text>
<text class="st">在职</text>
</view>
<text class="dept">{{ me ? (me.department + ' · ' + me.title) : '' }}</text>
<text class="ph">{{ phone }}{{ job }}</text>
</view>
</view>
<view class="stats">
<view class="s" @click="switchClock">
<text class="n">{{ attendDays }}</text>
<text class="l">本月出勤()</text>
</view>
<view class="s mid" @click="goTodo">
<text class="n">{{ todoCount }}</text>
<text class="l">待办申请()</text>
</view>
<view class="s">
<text class="n ok">正常</text>
<text class="l">考勤状态</text>
</view>
</view>
</view>
<view class="card menu">
<view v-for="a in menus" :key="a.id" class="mi" @click="open(a)">
<text class="ii">{{ a.icon }}</text>
<text class="it">{{ a.title }}</text>
<text class="arr"></text>
</view>
</view>
<view class="card menu">
<view class="mi" @click="goPwd">
<text class="ii">🔑</text>
<text class="it">修改密码</text>
<text class="arr"></text>
</view>
<view class="mi danger" @click="logout">
<text class="ii"></text>
<text class="it">退出登录</text>
</view>
</view>
</view>
</view>
</template>
<script>
import FyHeader from '../../components/fy-header.vue'
import { store } from '../../utils/store.js'
import { maskPhone } from '../../utils/format.js'
const ME_IDS = ['archive', 'salary', 'perf', 'expense', 'report', 'apply']
export default {
components: { FyHeader },
data() {
return { off: null }
},
computed: {
me() { return store.me },
initial() { return this.me ? this.me.name.slice(0, 1) : '我' },
phone() { return maskPhone(this.me && this.me.phone) },
job() { return this.me && this.me.jobId ? ' · 工号: ' + this.me.jobId : '' },
todoCount() { return store.todoCount || 0 },
attendDays() { return (store.attendance || []).length || 0 },
menus() {
return store.personalApps().filter((a) => ME_IDS.includes(a.id))
}
},
onShow() {
if (store.phase !== 'app') uni.reLaunch({ url: '/pages/login/login' })
this.off = store.on(() => this.$forceUpdate())
},
onHide() { if (this.off) this.off() },
methods: {
open(a) {
if (a.url.startsWith('/pages/tabs/')) uni.switchTab({ url: a.url.split('?')[0] })
else uni.navigateTo({ url: a.url })
},
switchClock() { uni.switchTab({ url: '/pages/tabs/clock' }) },
goTodo() {
if (store.can('personal', 'approve')) uni.navigateTo({ url: '/pages/todo/list' })
},
goPwd() { uni.navigateTo({ url: '/pages/password/password' }) },
logout() {
uni.showModal({
title: '退出登录',
content: '确定退出当前账号?',
success: (r) => {
if (r.confirm) {
store.logout()
uni.reLaunch({ url: '/pages/login/login' })
}
}
})
}
}
}
</script>
<style scoped>
.body { padding: 16rpx 24rpx 40rpx; }
.profile { padding: 28rpx; }
.row { display: flex; align-items: center; }
.av { width: 112rpx; height: 112rpx; border-radius: 50%; }
.av.txt { background: #004ac6; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 40rpx; font-weight: 700; }
.info { margin-left: 20rpx; flex: 1; min-width: 0; }
.nm { display: flex; align-items: center; gap: 12rpx; }
.name { font-size: 34rpx; font-weight: 700; }
.st { font-size: 20rpx; background: rgba(108, 248, 187, 0.3); color: #006c49; padding: 2rpx 12rpx; border-radius: 999rpx; }
.dept, .ph { display: block; font-size: 22rpx; color: #737686; margin-top: 6rpx; }
.stats { display: flex; margin-top: 24rpx; padding-top: 20rpx; border-top: 1rpx solid #eaedff; }
.s { flex: 1; text-align: center; }
.mid { border-left: 1rpx solid #eaedff; border-right: 1rpx solid #eaedff; }
.n { display: block; font-size: 36rpx; font-weight: 700; color: #004ac6; }
.n.ok { color: #006c49; font-size: 30rpx; }
.l { font-size: 20rpx; color: #737686; }
.menu { margin-top: 20rpx; overflow: hidden; }
.mi { display: flex; align-items: center; padding: 28rpx 24rpx; border-bottom: 1rpx solid #eaedff; }
.ii { width: 48rpx; }
.it { flex: 1; font-size: 28rpx; }
.arr { color: #c3c6d7; }
.danger .it { color: #ba1a1a; }
</style>