You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
420 lines
14 KiB
420 lines
14 KiB
<template> |
|
<view class="wrapper"> |
|
<template v-if="!loading"> |
|
<view class="header"> |
|
<view class="flex"> |
|
<view v-for="(item, index) in steps" class="step text-center" :active="index == activeIndex" :completed="index < activeIndex"> |
|
<text>{{ index + 1 }}</text> |
|
<text>{{ item }}</text> |
|
</view> |
|
</view> |
|
<view class="timer" v-if="!remainingDuration || remainingDuration >= 0"> |
|
<view class="flex between mb-8"> |
|
<text>剩余处理时间</text> |
|
<text>{{ formatTimeText(remainingDuration) }}</text> |
|
</view> |
|
<!-- <view class="progress"> |
|
<view class="progress-action" :style="{width: `${percentage}%`}" :type="getType()"></view> |
|
</view> --> |
|
</view> |
|
<view class="timer-danger flex between" v-else> |
|
<text>超时</text> |
|
<text>{{ formatTimeText(remainingDuration) }}</text> |
|
</view> |
|
</view> |
|
<tabs :options="tabOptions" :labelFull="true" v-model="current" /> |
|
<template v-if="current === 'info'"> |
|
<view class="container"> |
|
<view class="h1">问题信息</view> |
|
<view class="row" style="--label-width: 170rpx"> |
|
<view class="col col-24"> |
|
<view class="label">源头编号:</view> |
|
<view class="content">{{ negative.originId }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">问题发现时间:</view> |
|
<view class="content">{{ negative.discoveryTime }}</view> |
|
</view> |
|
<view class="col col-24" v-if="negative.happenTime"> |
|
<view class="label">问题发生时间:</view> |
|
<view class="content">{{ negative.happenTime }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">问题来源:</view> |
|
<view class="content">{{ negative.problemSources }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">业务类别:</view> |
|
<view class="content">{{ negative.businessTypeName }}</view> |
|
</view> |
|
<view class="col col-12" v-if="negative.responderName"> |
|
<view class="label">投诉反映人:</view> |
|
<view class="content">{{ negative.responderName }}</view> |
|
</view> |
|
<view class="col col-12" v-if="negative.responderName"> |
|
<view class="label">联系电话:</view> |
|
<view class="content">{{ negative.contactPhone }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">涉嫌问题:</view> |
|
<view class="content">{{ getDictLabelByArray(suspectProblems, negative.involveProblem) || '/' }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">涉及单位:</view> |
|
<view class="content">{{ negative.involveDepartName }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label" style="text-align: left;">事情简要描述</view> |
|
</view> |
|
<view class="col col-24 c">{{ negative.thingDesc }}</view> |
|
</view> |
|
</view> |
|
<view class="container" v-if="negative.checkStatusName"> |
|
<view class="h1">核查办理</view> |
|
<view class="row" style="--label-width: 170rpx"> |
|
<view class="col col-12"> |
|
<view class="label">核查情况:</view> |
|
<view class="content">{{ negative.checkStatusName }}</view> |
|
</view> |
|
<view class="col col-12" v-if="negative.isRectifyName"> |
|
<view class="label">是否已整改:</view> |
|
<view class="content">{{ negative.isRectifyName }}</view> |
|
</view> |
|
<view class="col col-12" v-if="negative.happenTime"> |
|
<view class="label">追责对象:</view> |
|
<view class="content">{{ getDictLabel(accountabilityTarget, negative.accountabilityTarget) }}</view> |
|
</view> |
|
<view class="col col-12" v-if="negative.rectifyRestrictionDays"> |
|
<view class="label">整改限制:</view> |
|
<view class="content">{{ negative.rectifyRestrictionDays }}天</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label" style="text-align: left;">问题核查情况</view> |
|
</view> |
|
<view class="col col-24 c">{{ negative.checkStatusDesc }}</view> |
|
<view class="col col-24" v-if="negative.rectifyDesc"> |
|
<view class="label" style="text-align: left;">问题整改情况</view> |
|
</view> |
|
<view class="col col-24 c" v-if="negative.rectifyDesc">{{ negative.rectifyDesc }}</view> |
|
<view class="col col-24" v-if="negative.unrectifyReason"> |
|
<view class="label" style="text-align: left;">问题未整改原因</view> |
|
</view> |
|
<view class="col col-24 c" v-if="negative.rectifyDesc">{{ negative.unrectifyReason }}</view> |
|
</view> |
|
</view> |
|
<view class="container" v-if="negative.checkStatusName" v-for="(item, index) in negative.blames"> |
|
<view class="h1">涉及人员{{ index + 1 }}</view> |
|
<view class="row" style="--label-width: 170rpx"> |
|
<view class="col col-12"> |
|
<view class="label">姓名:</view> |
|
<view class="content">{{ item.blameName }}</view> |
|
</view> |
|
<view class="col col-12"> |
|
<view class="label">警号:</view> |
|
<view class="content">{{ item.blameEmpNo }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">身份证:</view> |
|
<view class="content">{{ item.blameIdCode }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">人员属性:</view> |
|
<view class="content">{{ getDictLabel(personTypes, item.ivPersonTypeCode) }}</view> |
|
</view> |
|
<view class="col col-24" v-for="(problem, index) in item.problems"> |
|
<view class="label">问题类型{{ index + 1 }}:</view> |
|
<view class="content">{{ problem.oneLevelContent }} / {{ problem.twoLevelContent }} / {{ problem.threeLevelContent }}</view> |
|
</view> |
|
<template v-if="negative.checkStatus === '1' || negative.checkStatus === '2'"> |
|
<view class="col col-12" v-if="item.responsibilityTypeName"> |
|
<view class="label">责任类别:</view> |
|
<view class="content">{{ item.responsibilityTypeName }}</view> |
|
</view> |
|
<view class="col col-12" > |
|
<view class="label">主观方面:</view> |
|
<view class="content">{{ item.subjectiveAspectName }}</view> |
|
</view> |
|
<view class="col col-12" v-if="item.protectRightsName"> |
|
<view class="label">维权容错:</view> |
|
<view class="content">{{ item.protectRightsName }}</view> |
|
</view> |
|
<view class="col col-12" v-if="item.superviseMeasuresName"> |
|
<view class="label">督察措施:</view> |
|
<view class="content">{{ item.superviseMeasuresName }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">处置结果:</view> |
|
<view class="content">{{ item.handleResultName }} {{ item.handleResultNameOther }}</view> |
|
</view> |
|
</template> |
|
|
|
</view> |
|
<view class="h1">涉及领导</view> |
|
<view class="row" style="--label-width: 180rpx"> |
|
<view class="col col-12"> |
|
<view class="label">领导姓名:</view> |
|
<view class="content">{{ item.leadName }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">身份证:</view> |
|
<view class="content">{{ item.leadIdCode }}</view> |
|
</view> |
|
<template v-if="negative.checkStatus === '1' || negative.checkStatus === '2'"> |
|
<view class="col col-12"> |
|
<view class="label">责任类别:</view> |
|
<view class="content">{{ item.responsibilityTypeName }}</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">处置结果:</view> |
|
<view class="content">{{ item.leadHandleResultName }} {{ item.leadHandleResultNameOther }}</view> |
|
</view> |
|
</template> |
|
</view> |
|
</view> |
|
<view class="container" v-if="negative.files?.length"> |
|
<view class="h1">办结佐证材料</view> |
|
<file-list :files="negative.files" /> |
|
</view> |
|
|
|
</template> |
|
<template v-else> |
|
<view class="container"> |
|
<!-- <view class="action-history-header"> |
|
<text>总耗时</text> |
|
<text class="ml-8">{{ getTotalTime() }}</text> |
|
</view> --> |
|
<view class="body" > |
|
<view v-for="(item, index) in actionHistory" class="action-history"> |
|
<view class="action-history-info"> |
|
<text class="time mr-12">{{ item.crtTime }}</text> |
|
<text class="mr-4">{{ item.departName }}</text> |
|
<text class="mr-12">{{ item.crtName }}</text> |
|
<text class="primary uni-bold">{{ item.actionName }}</text> |
|
</view> |
|
<view class="flex-inline gap action-history-time"> |
|
<text class="info mr-12" v-if="index > 0">用时</text> |
|
<text class="primary" v-if="index > 0">{{ getTime(index) }}</text> |
|
</view> |
|
</view> |
|
</view> |
|
</view> |
|
</template> |
|
</template> |
|
<template v-else> |
|
<view class="header"> |
|
<view class="flex"> |
|
<view v-for="(item, index) in steps" class="step text-center"> |
|
<text>{{ index + 1 }}</text> |
|
<text>{{ item }}</text> |
|
</view> |
|
</view> |
|
<view class="timer"> |
|
<view class="flex mb-8"> |
|
<text>剩余处理时间 0</text> |
|
</view> |
|
</view> |
|
</view> |
|
<tabs :options="tabOptions" :labelFull="true" v-model="current" /> |
|
<view class="container"> |
|
<view class="h1">问题信息</view> |
|
<view class="row" style="--label-width: 170rpx"> |
|
<view class="col col-24"> |
|
<view class="label">源头编号:</view> |
|
<view class="content"> |
|
<skeleton width="50%" /> |
|
</view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">问题发现时间:</view> |
|
<view class="content"><skeleton width="50%" /></view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">问题来源:</view> |
|
<view class="content"><skeleton width="50%" /></view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">业务类别:</view> |
|
<view class="content"><skeleton width="50%" /></view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">涉嫌问题:</view> |
|
<view class="content"><skeleton /></view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label">涉及单位:</view> |
|
<view class="content"><skeleton width="50%" /></view> |
|
</view> |
|
<view class="col col-24"> |
|
<view class="label" style="text-align: left;">事情简要描述</view> |
|
</view> |
|
<skeleton width="100%" height="120rpx" /> |
|
</view> |
|
</view> |
|
</template> |
|
</view> |
|
</template> |
|
|
|
<script setup> |
|
import moment from 'moment' |
|
import { ref, defineProps, watch } from 'vue' |
|
import { formatTimeText, getDictLabel, getDictLabelByArray } from '@/common/util' |
|
import { getDictOptions } from '@/common/dict' |
|
|
|
const personTypes = getDictOptions('personType'); |
|
const suspectProblems = getDictOptions('suspectProblem'); |
|
const accountabilityTarget = getDictOptions('accountabilityTarget'); |
|
const steps = ['问题签收', '核查办理', '办结审批', '认定办结']; |
|
const activeIndex = ref(1) |
|
const tabOptions = [ |
|
{ |
|
text: '问题详情', |
|
value: 'info' |
|
}, |
|
{ |
|
text: '流转记录', |
|
value: 'flow' |
|
} |
|
] |
|
const current = ref('info') |
|
|
|
const props = defineProps({ |
|
data: { |
|
type: Object, |
|
default: {} |
|
}, |
|
loading: { |
|
type: Boolean, |
|
default: false |
|
} |
|
}); |
|
|
|
const negative = ref({}) |
|
const remainingDuration = ref(0) |
|
const actionHistory = ref([]) |
|
watch(() => props.data, (data) => { |
|
negative.value = data.negative |
|
remainingDuration.value = data.remainingDuration |
|
actionHistory.value = data.actionHistory |
|
}) |
|
|
|
function getTime(index) { |
|
console.log(moment(actionHistory.value[index].crtTime, 'YYYY-MM-DD HH:mm:ss')) |
|
return formatTimeText(moment(actionHistory.value[index].crtTime, 'YYYY-MM-DD HH:mm:ss').diff(moment(actionHistory.value[index - 1].crtTime, 'YYYY-MM-DD HH:mm:ss'), 'seconds')) |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.header { |
|
background-color: var(--primary-color); |
|
} |
|
.step { |
|
--background-color: #004CB5; |
|
width: 25%; |
|
color: #ACB7FF; |
|
height: 40rpx; |
|
line-height: 38rpx; |
|
border-top: 1rpx solid #4B60E4; |
|
border-bottom: 1rpx solid #4B60E4; |
|
box-sizing: border-box; |
|
position: relative; |
|
background-color: var(--background-color); |
|
text-align: center; |
|
font-size: 12px; |
|
&:before { |
|
display: block; |
|
content: ''; |
|
height: 25.87rpx; |
|
width: 25.87rpx; |
|
position: absolute; |
|
top: 5.5rpx; |
|
right: -13.43rpx; |
|
border-top: 1rpx solid #4B60E4; |
|
border-right: 1rpx solid #4B60E4; |
|
transform: rotate(45deg); |
|
z-index: 1; |
|
background-color: var(--background-color);; |
|
} |
|
&:last-child::before { |
|
display: none; |
|
} |
|
&[active=true] { |
|
--background-color: #f40000; |
|
border-color: #FF7474; |
|
color: #fff; |
|
&:before { |
|
border-color: #FF7474; |
|
} |
|
} |
|
&[completed=true] { |
|
color: #fff; |
|
} |
|
} |
|
.timer { |
|
padding: 12px; |
|
} |
|
.timer-danger { |
|
background: linear-gradient( 180deg, #FF5C37 0%, #E03021 100%); |
|
color: #fff; |
|
height: 45px; |
|
line-height: 45px; |
|
margin-top: 10px; |
|
padding: 0 10px; |
|
} |
|
.h1 { |
|
font-weight: 700; |
|
margin-bottom: 24rpx; |
|
} |
|
.c { |
|
background: #E7F2FF; |
|
padding: 24rpx; |
|
} |
|
.container { |
|
background-color: #fff; |
|
margin-bottom: 12rpx; |
|
} |
|
.wrapper { |
|
background-color: #f5f5f5; |
|
} |
|
|
|
.action-history-header { |
|
height: 52rpx; |
|
line-height: 52rpx; |
|
margin-bottom: 24rpx; |
|
} |
|
.action-history { |
|
margin-bottom: 16rpx; |
|
.action-history-info { |
|
margin-bottom: 16rpx; |
|
padding-left: 36rpx; |
|
position: relative; |
|
display: flex; |
|
align-items: center; |
|
&:before { |
|
content: ''; |
|
display: block; |
|
position: absolute; |
|
left: 0; |
|
top: 50%; |
|
transform: translate(-50%, -50%); |
|
width: 20rpx; |
|
height: 20rpx; |
|
background-color: #bfbfbf; |
|
border: 1px solid #f1fff1; |
|
border-radius: 50%; |
|
} |
|
.time { |
|
color: #999; |
|
font-size: 12px; |
|
} |
|
} |
|
.action-history-time { |
|
height: 56rpx; |
|
line-height: 56rpx; |
|
padding-left: 32rpx; |
|
padding-right: 40rpx; |
|
background: #F5F6FF; |
|
border-left: 2px solid #00D050; |
|
border-radius: 0 24rpx 24rpx 0; |
|
} |
|
} |
|
</style> |