detail.vue 8.21 KB
<template>
	<el-dialog 
		title="报销申请详情" 
		:visible.sync="visible" 
		:close-on-click-modal="false"
		class="NCC-dialog NCC-dialog_center" 
		width="1200px"
		@close="handleClose"
		@update:visible="handleVisibleChange">
		<div class="detail-content" v-loading="loading">
			<!-- 基本信息卡片 -->
			<el-card class="info-card" shadow="hover">
				<div slot="header" class="card-header">
					<i class="el-icon-document"></i>
					<span class="card-title">基本信息</span>
				</div>
				<el-row :gutter="20">
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">申请编号:</label>
							<span class="info-value">{{ dataForm.id || '无' }}</span>
						</div>
					</el-col>
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">申请人:</label>
							<span class="info-value">{{ dataForm.applicationUserName || '无' }}</span>
						</div>
					</el-col>
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">门店:</label>
							<span class="info-value">{{ getStoreName(dataForm.applicationStoreId) || '无' }}</span>
						</div>
					</el-col>
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">申请时间:</label>
							<span class="info-value">{{ formatDate(dataForm.applicationTime) || '无' }}</span>
						</div>
					</el-col>
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">总金额:</label>
							<span class="info-value amount">{{ dataForm.amount || '无' }}</span>
						</div>
					</el-col>
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">审批状态:</label>
							<span class="info-value" :class="{'status-approved': dataForm.approveStatus === '已审批', 'status-pending': dataForm.approveStatus === '未审批'}">
								{{ dataForm.approveStatus || '无' }}
							</span>
						</div>
					</el-col>
				</el-row>
			</el-card>

			<!-- 购买物品清单卡片 -->
			<el-card class="info-card" shadow="hover" v-if="purchaseRecords && purchaseRecords.length > 0">
				<div slot="header" class="card-header">
					<i class="el-icon-shopping-cart-full"></i>
					<span class="card-title">购买物品清单</span>
				</div>
				<el-table 
					:data="purchaseRecords" 
					border
					size="small"
					style="width: 100%">
					<el-table-column type="index" label="序号" width="60" align="center" />
					<el-table-column prop="reimbursementCategoryName" label="分类名称" />
					<el-table-column prop="unitPrice" label="单价" align="right" />
					<el-table-column prop="quantity" label="数量" align="right" />
					<el-table-column prop="amount" label="总金额" align="right" />
					<el-table-column prop="purchaseTime" label="购买时间" width="120">
						<template slot-scope="scope">
							{{ formatDate(scope.row.purchaseTime) || '无' }}
						</template>
					</el-table-column>
					<el-table-column prop="memo" label="备注说明" min-width="150" show-overflow-tooltip />
				</el-table>
			</el-card>

			<!-- 审批信息卡片 -->
			<el-card class="info-card" shadow="hover" v-if="dataForm.approveStatus === '已审批'">
				<div slot="header" class="card-header">
					<i class="el-icon-check"></i>
					<span class="card-title">审批信息</span>
				</div>
				<el-row :gutter="20">
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">审批人:</label>
							<span class="info-value">{{ getUserName(dataForm.approveUser) || '无' }}</span>
						</div>
					</el-col>
					<el-col :span="8">
						<div class="info-item">
							<label class="info-label">审批时间:</label>
							<span class="info-value">{{ formatDate(dataForm.approveTime) || '无' }}</span>
						</div>
					</el-col>
				</el-row>
			</el-card>
		</div>
		<span slot="footer" class="dialog-footer">
			<el-button @click="visible = false">关 闭</el-button>
		</span>
	</el-dialog>
</template>

<script>
import request from '@/utils/request'

export default {
	name: 'ReimbursementApplicationDetail',
	data() {
		return {
			visible: false,
			loading: false,
			dataForm: {},
			purchaseRecords: [],
			storeOptions: [],
			userMap: {}
		}
	},
	methods: {
		init(id) {
			this.visible = true
			this.loading = true
			this.dataForm = {}
			this.purchaseRecords = []
			this.userMap = {}
			
			// 加载门店列表
			this.loadStoreOptions()
			
			// 加载详情数据
			request({
				url: `/api/Extend/LqReimbursementApplication/${id}`,
				method: 'GET'
			}).then(res => {
				this.dataForm = res.data || {}
				// 如果有关联的购买记录,加载购买记录详情
				if (this.dataForm.purchaseRecordsId) {
					this.loadPurchaseRecords(this.dataForm.purchaseRecordsId)
				}
				// 加载用户信息
				this.loadUserInfo()
				this.loading = false
			}).catch(() => {
				this.loading = false
				this.$message.error('加载详情失败')
			})
		},
		// 加载门店列表
		loadStoreOptions() {
			request({
				url: '/api/Extend/LqMdxx',
				method: 'GET',
				data: {
					currentPage: 1,
					pageSize: 1000
				}
			}).then(res => {
				if (res.data && res.data.list) {
					this.storeOptions = res.data.list
				}
			}).catch(() => {
				this.storeOptions = []
			})
		},
		// 加载购买记录
		loadPurchaseRecords(purchaseRecordsId) {
			if (!purchaseRecordsId) {
				this.purchaseRecords = []
				return
			}
			// 处理逗号分隔的ID字符串
			const normalizedStr = purchaseRecordsId.replace(/[\r\n]+/g, ',').replace(/\s+/g, '')
			const ids = normalizedStr.split(',').map(id => id.trim()).filter(id => id && id !== '')
			
			if (ids.length === 0) {
				this.purchaseRecords = []
				return
			}
			
			// 批量加载购买记录
			Promise.all(ids.map(id => {
				return request({
					url: `/api/Extend/LqPurchaseRecords/${id}`,
					method: 'GET'
				}).then(res => res.data).catch(() => null)
			})).then(results => {
				this.purchaseRecords = results.filter(item => item !== null)
			})
		},
		// 加载用户信息
		loadUserInfo() {
			const userIds = []
			if (this.dataForm.approveUser) {
				userIds.push(this.dataForm.approveUser)
			}
			
			// 去重
			const uniqueUserIds = [...new Set(userIds)]
			
			// 批量加载用户信息
			Promise.all(uniqueUserIds.map(userId => {
				return request({
					url: `/api/permission/Users/${userId}`,
					method: 'GET'
				}).then(res => {
					if (res.data) {
						this.userMap[userId] = res.data.realName || res.data.account || userId
					}
				}).catch(() => {
					this.userMap[userId] = userId
				})
			}))
		},
		// 获取门店名称
		getStoreName(storeId) {
			if (!storeId) return ''
			const store = this.storeOptions.find(item => item.id === storeId)
			return store ? store.dm : ''
		},
		// 获取用户名称
		getUserName(userId) {
			if (!userId) return ''
			return this.userMap[userId] || userId
		},
		// 格式化日期
		formatDate(timestamp) {
			if (!timestamp) return ''
			const date = new Date(timestamp)
			const year = date.getFullYear()
			const month = String(date.getMonth() + 1).padStart(2, '0')
			const day = String(date.getDate()).padStart(2, '0')
			return `${year}-${month}-${day}`
		},
		// 关闭弹窗
		handleClose() {
			this.visible = false
			this.dataForm = {}
			this.purchaseRecords = []
			this.userMap = {}
			this.$emit('close')
		},
		// 处理 visible 变化
		handleVisibleChange(val) {
			this.visible = val
			if (!val) {
				this.handleClose()
			}
		}
	}
}
</script>

<style lang="scss" scoped>
/* 详情内容 */
.detail-content {
	max-height: 70vh;
	overflow-y: auto;
	padding: 0 10px;
}

/* 信息卡片 */
.info-card {
	margin-bottom: 20px;
	border-radius: 8px;
	overflow: hidden;
}

.card-header {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 16px;
	font-weight: 600;
	color: #303133;
}

.card-header i {
	font-size: 18px;
	color: #409EFF;
}

.card-title {
	font-size: 16px;
	font-weight: 600;
}

/* 信息项 */
.info-item {
	margin-bottom: 16px;
}

.info-label {
	display: inline-block;
	font-weight: 500;
	color: #606266;
	margin-right: 8px;
}

.info-value {
	color: #303133;
	font-size: 14px;
}

.info-value.amount {
	color: #E6A23C;
	font-weight: 600;
}

.status-approved {
	color: #67C23A;
	font-weight: 600;
}

.status-pending {
	color: #E6A23C;
	font-weight: 600;
}
</style>