Files
threeonecheck_web/pages/checklist/detail.vue

330 lines
7.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="page">
<view v-if="loading" class="loading-wrap">
<text class="loading-text">加载中...</text>
</view>
<template v-else>
<!-- 基本信息 -->
<view class="section-card">
<view class="section-title">基本信息</view>
<view class="info-row">
<text class="info-label">检查表名称</text>
<text class="info-value">{{ detail.name || '-' }}</text>
</view>
<view class="info-row">
<text class="info-label">分派单位</text>
<text class="info-value">{{ detail.deptName || '-' }}</text>
</view>
<view class="info-row">
<text class="info-label">检查表类型</text>
<text class="info-value">{{ typeLabel }}</text>
</view>
<view class="info-row">
<text class="info-label">模式</text>
<text class="info-value">{{ runModeLabel }}</text>
</view>
<view class="info-row">
<text class="info-label">执行人员</text>
<text class="info-value">{{ executorLabel }}</text>
</view>
<view class="info-row">
<text class="info-label">循环周期</text>
<text class="info-value">{{ cycleLabel }}</text>
</view>
<view class="info-row column">
<text class="info-label">检查说明</text>
<view class="info-block">
<rich-text v-if="detail.description" :nodes="detail.description"></rich-text>
<text v-else class="info-empty">-</text>
</view>
</view>
</view>
<!-- 关联表项 -->
<view class="section-card">
<view class="section-title">关联表项</view>
<view class="related-box">
<image class="related-icon" src="/static/jianchabiao/biaodan.svg" mode="aspectFit"></image>
<text class="related-text">{{ detail.itemNames || '-' }}</text>
</view>
</view>
<!-- 检查项明细 -->
<view class="section-card">
<view class="section-title">
检查项明细
<text class="item-count">{{ checkItems.length }}</text>
</view>
<view v-if="checkItems.length === 0" class="empty-block">暂无检查项</view>
<view v-else class="item-list">
<view
v-for="(item, index) in checkItems"
:key="item.pointId || index"
class="item-row"
>
<text class="item-no">{{ index + 1 }}</text>
<view class="item-content">
<text class="item-name">{{ item.checkItemName || '-' }}</text>
<text v-if="item.industryName" class="item-industry">{{ item.industryName }}</text>
</view>
</view>
</view>
</view>
<!-- 计划安排 -->
<view class="section-card">
<view class="section-title">计划安排</view>
<view class="info-row">
<text class="info-label">仅工作日</text>
<text class="info-value">{{ weekendLabel }}</text>
</view>
<view class="info-row">
<text class="info-label">计划开始日期</text>
<text class="info-value">{{ formatDate(detail.planStartTime) }}</text>
</view>
<view class="info-row">
<text class="info-label">计划结束日期</text>
<text class="info-value">{{ formatDate(detail.planEndTime) }}</text>
</view>
</view>
</template>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getOneTableInfo } from '@/request/api.js'
const loading = ref(true)
const oneTableId = ref('')
const detail = ref({})
const checkItems = ref([])
const typeMap = { 1: '日常检查', 2: '专项检查', 3: '设备检查' }
const cycleMap = { 1: '每天一次', 2: '每周', 3: '每月', 4: '每季度' }
const runModeMap = { 1: '单人完成', 2: '全员', 3: '指定分组', 4: '排班模式' }
const weekendMap = { 1: '包含周末', 2: '不包含周末' }
const typeLabel = computed(() => detail.value.typeName || typeMap[detail.value.type] || '-')
const cycleLabel = computed(() => detail.value.cycleName || cycleMap[detail.value.cycle] || '-')
const runModeLabel = computed(() => detail.value.runModeName || runModeMap[detail.value.runMode] || '-')
const weekendLabel = computed(() => detail.value.isWeekendName || weekendMap[detail.value.isWeekend] || '-')
const executorLabel = computed(() => {
const runMode = Number(detail.value.runMode)
if (runMode === 2) return '全员'
if (runMode === 4) {
const rosterItems = detail.value.rosterItems || []
if (rosterItems.length > 0) {
return rosterItems.map((item) => item.identityName).filter(Boolean).join('、') || '-'
}
return '-'
}
return detail.value.executorIdentityName || detail.value.executorName || '-'
})
const formatDate = (value) => {
if (!value) return '-'
return String(value).split(' ')[0]
}
const fetchDetail = async () => {
if (!oneTableId.value) return
loading.value = true
try {
const res = await getOneTableInfo(oneTableId.value)
if (res.code === 0) {
const data = res.data || {}
detail.value = data
checkItems.value = data.itemDetailList || []
} else {
uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' })
}
} catch (error) {
console.error('获取检查计划详情失败:', error)
uni.showToast({ title: '获取详情失败', icon: 'none' })
} finally {
loading.value = false
}
}
onLoad((options) => {
oneTableId.value = options.id || ''
if (!oneTableId.value) {
uni.showToast({ title: '缺少检查表ID', icon: 'none' })
loading.value = false
return
}
fetchDetail()
})
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #EBF2FC;
padding: 24rpx;
padding-bottom: 40rpx;
box-sizing: border-box;
}
.loading-wrap {
padding: 120rpx 0;
text-align: center;
}
.loading-text {
font-size: 28rpx;
color: #999;
}
.section-card {
background: #fff;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.04);
}
.section-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
padding-left: 16rpx;
border-left: 6rpx solid #2667E9;
}
.item-count {
font-size: 26rpx;
font-weight: 400;
color: #999;
}
.info-row {
display: flex;
align-items: flex-start;
padding: 18rpx 0;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
&.column {
flex-direction: column;
}
}
.info-label {
width: 180rpx;
flex-shrink: 0;
font-size: 26rpx;
color: #999;
line-height: 1.5;
}
.info-value {
flex: 1;
font-size: 28rpx;
color: #333;
line-height: 1.5;
word-break: break-all;
}
.info-block {
width: 100%;
margin-top: 12rpx;
padding: 20rpx;
background: #f8f9fb;
border: 1rpx solid #ebeef5;
border-radius: 8rpx;
font-size: 28rpx;
color: #606266;
line-height: 1.6;
box-sizing: border-box;
}
.info-empty {
color: #c0c4cc;
}
.related-box {
display: flex;
align-items: flex-start;
gap: 12rpx;
padding: 20rpx;
background: #f8f9fb;
border: 1rpx solid #ebeef5;
border-radius: 8rpx;
}
.related-icon {
flex-shrink: 0;
width: 36rpx;
height: 36rpx;
margin-top: 4rpx;
}
.related-text {
flex: 1;
font-size: 28rpx;
color: #333;
line-height: 1.5;
word-break: break-all;
}
.empty-block {
text-align: center;
padding: 40rpx 0;
font-size: 26rpx;
color: #999;
}
.item-list {
border-top: 1rpx solid #f0f0f0;
}
.item-row {
display: flex;
align-items: flex-start;
gap: 16rpx;
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
padding-bottom: 0;
}
}
.item-no {
width: 36rpx;
font-size: 26rpx;
color: #999;
line-height: 1.5;
flex-shrink: 0;
}
.item-content {
flex: 1;
min-width: 0;
}
.item-name {
display: block;
font-size: 28rpx;
color: #333;
line-height: 1.5;
word-break: break-all;
}
.item-industry {
display: inline-block;
margin-top: 8rpx;
font-size: 24rpx;
color: #999;
}
</style>