Files
im-uniapp/components/hrm/detailPanels/reimburse.vue
砂糖 d1eb3d61cf feat(审批): 新增审批中心页面及功能优化
- 新增审批中心页面,包含待审批任务列表展示和筛选功能
- 优化各审批类型详情页,增加项目信息展示和弹窗查看功能
- 在报销、用印、请假、出差详情页添加项目信息展示区域和详情弹窗
- 调整消息中心CC列表,增加未读状态红点标识
- 更新tabbar配置,新增审批入口图标和路由
- 优化部分页面交互细节和样式调整
2026-02-05 15:52:09 +08:00

300 lines
8.7 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="reimburse-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.reimburseType || '无' }}</view>
</view>
<!-- 总金额 - 单独突出显示带金额图标+主题色 -->
<view class="detail-item single-item amount-item">
<text class="item-icon icon-amount"></text>
<view class="item-label">总金额</view>
<view class="item-value">{{ detail.totalAmount || '无' }}</view>
</view>
<!-- 报销原因 - 带原因图标适配多行文 -->
<view class="detail-item single-item multi-line">
<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 multi-line">
<text class="item-icon icon-remark"></text>
<view class="item-label">备注</view>
<view class="item-value">{{ detail.remark || '无' }}</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-user"></text>
<view class="item-label">申请时间</view>
<view class="item-value">{{ formatTime(detail.createTime) || '无' }}</view>
</view>
<!-- 更新人 - 带编辑用户图标 -->
<view class="detail-item single-item">
<text class="item-icon icon-update-user"></text>
<view class="item-label">更新人</view>
<view class="item-value">{{ detail.updateBy || '无' }}</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 { getReimburseReq } from '@/api/hrm/reimburse.js'
export default {
props: {
bizId: {
type: String,
required: true
}
},
data() {
return {
detail: {}
}
},
watch: {
bizId: {
handler(newVal) {
// 空值判断,避免无效请求
if (!newVal) return;
// 接口请求增加错误捕获和loading提示
uni.showLoading({ title: '加载中...' });
getReimburseReq(newVal)
.then(res => {
this.detail = res.data || {};
console.log('报销详情:', this.detail);
})
.catch(err => {
console.error('获取报销详情失败:', err);
uni.showToast({
title: '获取详情失败',
icon: 'none',
duration: 2000
});
})
.finally(() => {
uni.hideLoading();
});
},
immediate: true
}
},
methods: {
/**
* 时间格式化方法
* 将 "2026-01-08 00:00:00" 格式化为 "2026-01-08"
* @param {String} timeStr - 原始时间字符串
* @returns {String} 格式化后的日期
*/
formatTime(timeStr) {
if (!timeStr) return '';
const [datePart] = timeStr.split(' ');
return datePart;
},
openPopup() {
this.$refs.popup.open()
},
/**
* 状态文本转换
* 将接口返回的英文状态转为中文展示
* @param {String} status - 原始状态值
* @returns {String} 中文状态文本
*/
getStatusText(status) {
const statusMap = {
'pending': '待处理',
'approved': '已批准',
'rejected': '已驳回',
'completed': '已完成'
};
return statusMap[status] || '未知状态';
}
}
}
</script>
<style scoped>
/* 主容器 - 与请假详情完全一致的卡片风格,柔和阴影+大圆角+合理内边距 */
.reimburse-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;
}
/* 图标样式 - 与请假详情统一规范Unicode图标无需额外引入主题色可自定义 */
.item-icon {
display: inline-block;
width: 32rpx;
height: 32rpx;
margin-right: 12rpx;
margin-top: 8rpx;
flex-shrink: 0;
color: #409eff; /* 统一主题色,与请假详情保持一致 */
font-family: "iconfont";
}
/* 各字段专属语义化图标Unicode直接替换即可 */
.icon-apply { content: "\e600"; }
.icon-type { content: "\e645"; }
.icon-amount { content: "\e62e"; }
.icon-reason { content: "\e614"; }
.icon-remark { content: "\e634"; }
.icon-user { content: "\e6b8"; }
.icon-create-time { content: "\e629"; }
.icon-update-time { content: "\e684"; }
.icon-update-user { content: "\e64c"; }
/* 标签样式 - 固定宽度+视觉统一,同行时间项标签窄化适配 */
.item-label {
width: 160rpx;
font-size: 30rpx;
color: #909399;
font-weight: 500;
flex-shrink: 0;
padding-top: 2rpx;
}
.time-item .item-label {
width: 100rpx;
}
/* 内容值样式 - 弹性占比,适配长文本,统一字号 */
.item-value {
flex: 1;
font-size: 30rpx;
color: #333333;
word-break: break-all;
}
/* 多行文适配 - 报销原因/备注,加大行高 */
.multi-line .item-value {
line-height: 52rpx;
padding-top: 4rpx;
}
/* 总金额突出 - 字体加粗+主题色,视觉重点 */
.amount-item .item-value {
color: #409eff;
font-weight: 600;
font-size: 32rpx;
}
/* 同行时间项 - 各占48%宽度,防止挤压 */
.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>