Files
im-uniapp/components/hrm/detailPanels/leave.vue

286 lines
8.5 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="leave-detail-container">
<!-- 请假类型 - 单独行+类型图标 -->
<view class="detail-item single-item">
<text class="item-icon icon-type"></text>
<view class="item-label">请假类型</view>
<view class="item-value">{{ detail.leaveType || '无' }}</view>
</view>
<view class="detail-item single-item">
<text class="item-icon icon-type"></text>
<view class="item-label">请假时间</view>
<view class="item-value">{{ formatTime(detail.startTime) }} - {{ formatTime(detail.endTime) }}</view>
</view>
<!-- 请假时长 - 单独行+时钟图标 -->
<view class="detail-item single-item">
<text class="item-icon icon-hour"></text>
<view class="item-label">请假时长</view>
<view class="item-value">{{ detail.hours || '0' }} 小时</view>
</view>
<!-- 请假原因 - 单独行+备注图标适配多行文 -->
<view class="detail-item single-item reason-item">
<text class="item-icon icon-reason"></text>
<view class="item-label">请假原因</view>
<view class="item-value">{{ detail.reason || '无' }}</view>
</view>
<!-- 申请人 - 单独行+用户图标 -->
<view class="detail-item single-item">
<text class="item-icon icon-user"></text>
<view class="item-label">申请人</view>
<view class="item-value">{{ detail.createBy || '无' }}</view>
</view>
<!-- 申请时间 - 单独行+日历图标 -->
<view class="detail-item single-item">
<text class="item-icon icon-date"></text>
<view class="item-label">申请时间</view>
<view class="item-value">{{ formatTime(detail.createTime) || '无' }}</view>
</view>
<view class="detail-item single-item amount-item" @click="openPopup" v-if="detail.projectId">
<text class="item-icon icon-creator"></text>
<view class="item-label">项目名称</view>
<view class="item-value">{{ detail.projectName || '无' }}</view>
</view>
<view class="detail-item single-item amount-item" @click="openPopup" v-if="detail.projectId">
<text class="item-icon icon-creator"></text>
<view class="item-label">项目编号</view>
<view class="item-value">{{ detail.projectNum || '无' }}</view>
</view>
<view class="detail-item single-item amount-item" @click="openPopup" v-if="detail.projectId">
<text class="item-icon icon-creator"></text>
<view class="item-label">项目代号</view>
<view class="item-value">{{ detail.projectCode || '无' }}</view>
</view>
<uni-popup ref="popup" type="center">
<view class="detail-content" v-if="detail.projectId">
<view class="info-item">
<text class="info-label">项目名称</text>
<text class="info-value">{{ detail.projectName || '-' }}</text>
</view>
<view class="info-item">
<text class="info-label">项目编号</text>
<text class="info-value">{{ detail.projectNum || '-' }}</text>
</view>
<view class="info-item">
<text class="info-label">项目代号</text>
<text class="info-value">{{ detail.projectCode || '-' }}</text>
</view>
<view class="info-item">
<text class="info-label">项目类型</text>
<oa-dict-tag dict-type="sys_project_type" :value="detail.projectType" placeholder="-" />
</view>
<view class="info-item">
<text class="info-label">项目地址</text>
<text class="info-value">{{ detail.address || '-' }}</text>
</view>
<view class="info-item">
<text class="info-label">项目总金额</text>
<text class="info-value">{{ detail.funds || '-' }}</text>
</view>
<view class="info-item">
<text class="info-label">负责人</text>
<text class="info-value">{{ detail.functionary || '-' }}</text>
</view>
<view class="info-item">
<text class="info-label">备注</text>
<text class="info-value">{{ detail.remark || '-' }}</text>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { getLeaveReq } from '@/api/hrm/leave'
export default {
props: {
bizId: {
type: String,
required: true
}
},
data() {
return {
detail: {}
}
},
watch: {
bizId: {
handler(newVal) {
if (!newVal) return;
getLeaveReq(newVal)
.then(res => {
this.detail = res.data || {};
console.log(this.detail);
})
.catch(err => {
console.error('获取请假详情失败:', err);
uni.showToast({
title: '获取详情失败',
icon: 'none',
duration: 2000
});
});
},
immediate: true
}
},
methods: {
formatTime(timeStr) {
if (!timeStr) return ''
var str = String(timeStr).trim()
// 兼容后端常见时间格式:"2026-01-08 00:00:00" / "2026-01-08T00:00:00" / 时间戳
if (/^\d+$/.test(str)) {
var ts = Number(str)
if (!Number.isNaN(ts)) {
var d = new Date(ts)
if (!Number.isNaN(d.getTime())) {
return this.pad(d.getFullYear(), 4) + '-' + this.pad(d.getMonth() + 1) + '-' + this.pad(d.getDate())
}
}
}
str = str.replace('T', ' ')
var parts = str.split(' ')
return parts[0] || str
},
pad(n, len = 2) {
return String(n).padStart(len, '0')
},
openPopup() {
this.$refs.popup.open()
},
}
}
</script>
<style scoped>
/* 主容器 - 卡片化升级,柔和阴影+大圆角+合理内边距 */
.leave-detail-container {
background: #ffffff;
border-radius: 18rpx;
margin: 20rpx 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
box-sizing: border-box;
}
/* 基础项样式 - 统一flex布局、行高、间距 */
.detail-item {
display: flex;
align-items: flex-start;
line-height: 48rpx;
padding: 20rpx 0;
border-bottom: 1px solid #f9f9f9;
}
/* 最后一项移除下边框 */
.detail-item:last-child {
border-bottom: none;
}
/* 单独行项 - 基础适配 */
.single-item {
flex-direction: row;
}
/* 同行双项 - 核心布局 */
.double-item {
flex-direction: row;
justify-content: space-between;
}
/* 图标样式 - 统一尺寸/颜色,视觉点缀(主题色可自定义) */
.item-icon {
display: inline-block;
width: 32rpx;
height: 32rpx;
margin-right: 12rpx;
margin-top: 8rpx;
flex-shrink: 0;
background-size: 100% 100%;
background-repeat: no-repeat;
color: #409eff; /* 主题色,可替换为项目主色 */
}
/* 各字段专属图标使用Unicode图标无需额外引入直接替换即可 */
.icon-type { content: "\e645"; font-family: "iconfont"; }
.icon-time-start { content: "\e629"; font-family: "iconfont"; }
.icon-time-end { content: "\e62a"; font-family: "iconfont"; }
.icon-hour { content: "\e68f"; font-family: "iconfont"; }
.icon-reason { content: "\e614"; font-family: "iconfont"; }
.icon-user { content: "\e600"; font-family: "iconfont"; }
.icon-date { content: "\e637"; font-family: "iconfont"; }
/* 标签样式 - 固定宽度+右对齐,视觉规整 */
.item-label {
width: 160rpx;
font-size: 30rpx;
color: #909399;
font-weight: 500;
flex-shrink: 0;
}
/* 同行时间项的标签 - 适配窄宽度 */
.time-item .item-label {
width: 100rpx;
}
/* 内容值样式 - 弹性占比,适配多行文/长文本 */
.item-value {
flex: 1;
font-size: 30rpx;
color: #333333;
word-break: break-all;
}
/* 总金额突出 - 字体加粗+主题色,视觉重点 */
.amount-item .item-value {
color: #409eff;
font-weight: 600;
font-size: 32rpx;
}
/* 请假原因 - 适配多行文,增加行高 */
.reason-item .item-value {
line-height: 52rpx;
padding-top: 4rpx;
}
/* 同行时间项 - 各占近50%宽度,防止挤压 */
.time-item {
display: flex;
align-items: flex-start;
width: 48%;
}
/* 同行时间项分隔线 - 竖线分隔,提升辨识度 */
.split-line {
width: 1px;
height: 60rpx;
background-color: #f9f9f9;
margin: 8rpx 16rpx 0;
flex-shrink: 0;
}
.detail-content {
border: 1px solid #ccc; /* 边框 */
border-radius: 10px; /* 圆角 */
padding: 15px; /* 内边距 */
background-color: #f9f9f9; /* 背景色 */
}
.info-item {
display: flex; /* 使用 Flexbox 布局 */
justify-content: space-between; /* 在一行内均匀分布 */
margin-top: 10px; /* 上边距 */
}
.info-label {
color: #333; /* 标签颜色 */
font-weight: bold; /* 标签加粗 */
}
.info-value {
color: #666; /* 值的颜色 */
}
</style>