Files
2026-03-13 14:32:24 +08:00

319 lines
8.0 KiB
Vue
Raw Permalink 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="container">
<uni-section title="隐患申报详情" type="line" class="mb-10" />
<view v-if="detail.id" class="detail-content">
<!-- 基本信息卡片 -->
<uni-card title="基本信息" :is-shadow="true" class="info-card">
<view class="info-grid">
<view class="info-row">
<text class="info-label">申报类型</text>
<text class="info-value">{{ detail.declarationLabel || '-' }}</text>
</view>
<view class="info-row">
<text class="info-label">申报人</text>
<text class="info-value">{{ detail.applyUser || '-' }}</text>
</view>
<view class="info-row">
<text class="info-label">申报时间</text>
<text class="info-value">{{ formatDate(detail.occurTime) }}</text>
</view>
</view>
</uni-card>
<!-- 申报内容卡片 -->
<uni-card title="申报内容" :is-shadow="true" class="content-card">
<view class="content-text">
{{ detail.requirementDescription || '暂无内容' }}
</view>
<view v-if="detail.remark" class="remark-section">
<text class="remark-label">备注</text>
<text class="remark-text">{{ detail.remark }}</text>
</view>
</uni-card>
<!-- 图片展示卡片 -->
<uni-card title="相关图片" :is-shadow="true" class="image-card" v-if="imageArray(detail.declarationImg).length > 0">
<view class="image-grid">
<view v-for="(img, idx) in imageArray(detail.declarationImg)" :key="idx" class="image-item">
<image :src="imageUrl(img)" mode="aspectFill" class="detail-image" @click="previewImage(img, detail.declarationImg)" />
</view>
</view>
</uni-card>
<!-- 无图片提示 -->
<uni-card title="相关图片" :is-shadow="true" class="image-card" v-else>
<view class="no-image-tip">
<uni-icons type="image" size="40" color="#ccc"></uni-icons>
<text class="no-image-text">暂无相关图片</text>
</view>
</uni-card>
<!-- 操作按钮 -->
<view class="action-buttons" v-if="detail.status === '0' || detail.status === 0">
<button class="edit-btn" size="default" type="primary" @click="editDeclaration">编辑申报</button>
</view>
</view>
<!-- 加载状态 -->
<view v-else-if="loading" class="loading-state">
<uni-load-more status="loading" />
</view>
<!-- 错误状态 -->
<view v-else class="error-state">
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
<text class="error-text">数据加载失败或记录不存在</text>
<button size="mini" type="default" @click="goBack">返回列表</button>
</view>
</view>
</template>
<script>
import { getSafetyDeclaration } from '@/api/sidebar/sidebar.js'
import { listData } from '@/api/system/dict/data.js'
import config from '@/config'
export default {
name: "FilingDetail",
data() {
return {
id: null,
detail: {},
loading: false,
typeDict: []
}
},
async onLoad(options) {
this.id = options?.id || null
if (this.id) {
await this.initDict()
await this.fetchDetail()
}
},
methods: {
async initDict() {
try {
const typeData = await listData({ dictType: 'hs_declaration_type' })
this.typeDict = typeData.rows || []
} catch (e) {
console.error('获取字典数据失败:', e)
this.typeDict = []
}
},
async fetchDetail() {
if (!this.id) return
try {
this.loading = true
const res = await getSafetyDeclaration(this.id)
this.detail = res?.data || {}
// 设置申报类型标签
if (this.detail.declarationType) {
const typeItem = this.typeDict.find(i => String(i.dictValue) === String(this.detail.declarationType))
this.detail.declarationLabel = typeItem ? typeItem.dictLabel : this.detail.declarationType
}
} catch (e) {
console.error('获取详情失败:', e)
uni.showToast({
title: '获取详情失败',
icon: 'error'
})
} finally {
this.loading = false
}
},
imageArray(declarationImg) {
if (!declarationImg) return []
if (typeof declarationImg === 'string') {
return declarationImg.split(',').filter(Boolean)
}
return declarationImg.filter(Boolean)
},
imageUrl(path) {
if (!path) return ''
return config.baseUrl + path
},
previewImage(current, all) {
const urls = this.imageArray(all).map(p => this.imageUrl(p))
uni.previewImage({
current: this.imageUrl(current),
urls
})
},
formatDate(val) {
if (!val) return '-'
try {
const d = new Date(val)
const y = d.getFullYear()
const m = String(d.getMonth() + 1).padStart(2, '0')
const dd = String(d.getDate()).padStart(2, '0')
const hh = String(d.getHours()).padStart(2, '0')
const mm = String(d.getMinutes()).padStart(2, '0')
return `${y}-${m}-${dd} ${hh}:${mm}`
} catch (e) {
return val
}
},
getStatusText(status) {
const statusMap = {
'0': '待处理',
'1': '处理中',
'2': '已完成',
'3': '已关闭'
}
return statusMap[status] || '未知'
},
getStatusType(status) {
const typeMap = {
'0': 'error', // 待处理 - 红色
'1': 'warning', // 处理中 - 橙色
'2': 'success', // 已完成 - 绿色
'3': 'info' // 已关闭 - 蓝色
}
return typeMap[status] || 'default'
},
editDeclaration() {
if (!this.detail.id) return
this.$tab.navigateTo(`/pages/work/sidebar/safetyDeclaratio/index?id=${this.detail.id}`)
},
goBack() {
this.$tab.navigateBack()
}
}
}
</script>
<style lang="scss">
.container {
padding: 15px;
background-color: #f8f9fa;
min-height: 100vh;
}
.mb-10 {
margin-bottom: 15px;
}
.detail-content {
.info-card,
.content-card,
.image-card {
margin-bottom: 15px;
border-radius: 12px;
overflow: hidden;
}
.info-grid {
.info-row {
display: flex;
align-items: center;
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
.info-label {
font-size: 14px;
color: #666;
min-width: 80px;
flex-shrink: 0;
}
.info-value {
font-size: 14px;
color: #333;
flex: 1;
}
}
}
.content-text {
font-size: 15px;
line-height: 1.6;
color: #333;
margin-bottom: 15px;
}
.remark-section {
padding-top: 15px;
border-top: 1px solid #eee;
.remark-label {
font-size: 14px;
color: #666;
margin-right: 8px;
}
.remark-text {
font-size: 14px;
color: #333;
line-height: 1.5;
}
}
.image-grid {
display: flex;
flex-wrap: wrap;
gap: 10px;
.image-item {
.detail-image {
width: 100px;
height: 100px;
border-radius: 8px;
background: #f5f5f5;
border: 2px solid #fff;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.2s ease;
&:active {
transform: scale(0.95);
}
}
}
}
.no-image-tip {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
.no-image-text {
margin-top: 10px;
font-size: 14px;
color: #999;
}
}
.action-buttons {
margin-top: 20px;
padding: 20px 0;
.edit-btn {
width: 100%;
border-radius: 25px;
font-size: 16px;
font-weight: 600;
}
}
}
.loading-state,
.error-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
.error-text {
margin: 15px 0;
font-size: 14px;
color: #999;
text-align: center;
}
}
</style>