| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609 |
- <script setup lang="ts">
- import dayjs from 'dayjs'
- import { keyBy } from 'lodash-es'
- import { ref } from 'vue'
- import { useRoute, useRouter } from 'vue-router'
- import { useMessage, useToast } from 'wot-design-uni'
- import { confirmDoneTask, getTaskDetail } from '@/api/schedule/task'
- import { authStatusOptions, taskLevelOptions, taskStatusOptions } from '@/utils/dicts'
- const message = useMessage()
- const toast = useToast()
- // 定义页面配置,注册路由
- definePage({
- excludeLoginPath: true,
- })
- // 状态管理
- const isExpanded = ref(false)
- const router = useRouter()
- const route = useRoute()
- const taskId = ref(Number(route.query.id))
- const taskInfo: any = ref({})
- const taskOther: any = ref({})
- const taskResult: any = ref({})
- // 切换更多内容显示/隐藏
- function toggleMore() {
- isExpanded.value = !isExpanded.value
- }
- async function dealConfirmTaskEvent() {
- // 二次弹框确认
- message.confirm({
- msg: `确认完成任务 ${taskInfo.value.taskName} 吗?`,
- title: '确认完成',
- }).then(async () => {
- try {
- await confirmDoneTask(taskInfo.value.id || 0)
- toast.success('确认完成任务成功')
- await init()
- }
- catch {
- toast.error('操作失败')
- }
- }).catch(() => {
- return
- })
- }
- // 查看详情按钮点击事件
- async function dealTaskEvent() {
- // 根据任务类型进行判断
- let params: any = {}
- let isModelPage = false
- switch (taskInfo.value.formType) {
- case 'inspection': {
- uni.navigateTo({
- url: `/pages/schedule/details/deal/inspection?id=${taskId.value}&checkId=${taskInfo.value.taskList[0].id}`,
- })
- return
- }
- case 'confirm': {
- await dealConfirmTaskEvent()
- return
- }
- case 'form': {
- if (
- ['annualExamination_task', 'replacement_task'].includes(
- taskInfo.value.subFormType,
- )
- ) {
- try {
- // await dealAnnualExaminationTask()
- }
- catch {
- // ElMessage.error('处理任务失败')
- }
- return
- }
- params = {
- taskId: taskInfo.value.taskList?.[0]?.id || '',
- taskName: taskInfo.value.taskName,
- taskList: taskInfo.value.taskList || [],
- remark: taskResult.value.content,
- stationId: taskInfo.value.stationId || 0,
- subFormType: taskInfo.value.subFormType,
- attachmentUrl: taskResult.value.images,
- }
- if (
- [
- 'ambulance_check',
- 'emergency_protection_monthly_check',
- 'filter_maintenance',
- 'fire_extinguisher_check',
- ].includes(taskInfo.value.subFormType)
- ) {
- isModelPage = true
- }
- break
- }
- case 'upload': {
- uni.navigateTo({
- url: `/pages/schedule/details/deal/upload?id=${taskId.value}`,
- })
- return
- }
- default: {
- // return ElMessage.error('当前任务无法处理')
- }
- }
- // if (isModelPage) {
- // pageModalApi.open()
- // }
- // else {
- // dealDrawerApi.setData(params).open()
- // }
- }
- // 查看详情按钮点击事件2
- function viewDetails2() {
- uni.navigateTo({
- url: '/pages/schedule/details/taskmanagement/index2',
- })
- }
- function viewDetails3() {
- uni.navigateTo({
- url: '/pages/schedule/details/taskdetails/index',
- })
- }
- /**
- * 获取任务时间
- * @returns 任务时间字符串
- */
- function getTaskTime() {
- return `${dayjs(taskInfo.value.startTime).format('MM-DD HH:mm')}~${dayjs(taskInfo.value.endTime).format('MM-DD HH:mm')}`
- }
- /**
- * 下载文件
- * @param file 文件对象或链接
- * @param fileName 文件名
- */
- function downloadFile(file: any, fileName: string) {
- // 这里实现文件下载逻辑
- console.log('downloadFile:', file, fileName)
- }
- async function init() {
- const res: any = await getTaskDetail(taskId.value)
- taskInfo.value = res.data || {}
- if (!taskInfo.value.status) {
- taskInfo.value.status = 0
- }
- // 假设从接口返回数据中获取taskOther和taskResult
- taskOther.value.taskTypeName = taskInfo.value?.formTypeName || '-'
- if (!taskInfo.value.executorName && taskInfo.value.taskList?.length) {
- taskInfo.value.executorName = taskInfo.value.taskList[0].executorName
- }
- if (taskInfo.value.formType === 'photo') {
- const result = taskInfo.value?.taskList?.[0] || {}
- if (result.remark) {
- taskResult.value.content = result.remark
- }
- if (result?.attachmentUrl?.length) {
- taskResult.value.images = result.attachmentUrl
- }
- }
- else if (taskInfo.value.formType === 'upload') {
- // attachmentUrl
- const result = taskInfo.value?.taskList?.[0] || {}
- if (result.remark) {
- taskResult.value.content = result.remark
- }
- if (result?.attachmentUrl?.length) {
- taskResult.value.files = result.attachmentUrl
- taskResult.value.fileNames = result.attachmentName.split(',')
- }
- }
- else {
- // taskResult.value = taskInfo.value?.taskList?.[0] || {};
- }
- if (taskInfo.value?.taskTemplate) {
- taskOther.value.taskFrequencyName
- = taskInfo.value?.taskTemplate?.taskFrequencyName || '-'
- }
- }
- // 状态标签配置
- const statusConfig: any = keyBy(taskStatusOptions, 'value')
- // 优先级标签配置
- const priorityConfig: any = keyBy(taskLevelOptions, 'value')
- // 授权状态标签配置
- const authStatusConfig: any = keyBy(authStatusOptions, 'value')
- onMounted(async () => {
- await init()
- })
- </script>
- <template>
- <view class="details-box">
- <!-- 标题区域 -->
- <view class="details-box-title">
- <view class="details-box-title-text">
- {{ taskInfo.taskName || '任务详情' }}
- </view>
- </view>
- <!-- 标签区域 -->
- <view class="tags-box">
- <view class="tag">
- {{ priorityConfig[taskInfo.level]?.label || taskInfo.level }}
- </view>
- <view class="tag">
- {{ statusConfig[`${taskInfo.status || 0}`]?.label || taskInfo.status }}
- </view>
- <view class="tag">
- {{ authStatusConfig[taskInfo.authStatus || 0]?.label || taskInfo.authStatus }}
- </view>
- </view>
- <!-- 任务描述 -->
- <view class="section">
- <view class="section-title">
- 任务描述
- </view>
- <view class="task-description" v-html="taskInfo.description || '暂无'" />
- </view>
- <!-- 标准指引 -->
- <view class="section">
- <view class="section-title">
- 任务信息
- </view>
- <view class="standard-guide">
- <view class="guide-item">
- <view class="guide-label">
- 场站
- </view>
- <view class="guide-value">
- {{ taskInfo.stationName || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 标准指引
- </view>
- <view class="guide-value">
- {{ taskInfo.standardGuide || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 执行人
- </view>
- <view class="guide-value">
- {{ taskInfo.executorName || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 计划时间
- </view>
- <view class="guide-value">
- {{ taskInfo.displayDate || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 创建
- </view>
- <view class="guide-value">
- {{ taskInfo.createBy || '' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 任务类型
- </view>
- <view class="guide-value">
- {{ taskInfo.subFormTypeName || taskOther.taskTypeName || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 任务负责人
- </view>
- <view class="guide-value">
- {{ taskInfo.taskLeaderName || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 任务频率
- </view>
- <view class="guide-value">
- {{ taskOther.taskFrequencyName || '-' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 任务时间
- </view>
- <view class="guide-value">
- {{ getTaskTime() || '-' }}
- </view>
- </view>
- <!-- <view class="guide-item">
- <view class="guide-label">
- 任务描述
- </view>
- <view class="guide-value">
- {{ taskInfo.description || '-' }}
- </view>
- </view> -->
- <view v-if="taskInfo.descriptionFilesUrl && taskInfo.descriptionFilesUrl.length > 0" class="guide-item">
- <view class="guide-label">
- 详情附件
- </view>
- <view class="guide-value">
- <!-- 使用wot-ui样式显示附件 -->
- <view class="attachment-list">
- <wd-tag
- v-for="(file, index) in taskInfo.descriptionFilesUrl"
- :key="index"
- custom-class="attachment-tag"
- type="primary"
- plain
- >
- 附件{{ index + 1 }}
- </wd-tag>
- </view>
- </view>
- </view>
- <view v-if="taskResult.handleContent || taskInfo.cancelReason" class="guide-item">
- <view class="guide-label">
- 处理情况
- </view>
- <view class="guide-value">
- {{ taskResult.handleContent || taskInfo.cancelReason || '' }}
- </view>
- </view>
- <view class="guide-item">
- <view class="guide-label">
- 处理时间
- </view>
- <view class="guide-value">
- {{ taskInfo.completeTime || taskInfo.cancelTime || '-' }}
- </view>
- </view>
- <view v-if="taskResult.files && taskResult.files.length > 0" class="guide-item">
- <view class="guide-label">
- 处理附件
- </view>
- <view class="guide-value">
- <!-- 使用wot-ui样式显示附件列表 -->
- <view class="attachment-list">
- <wd-tag
- v-for="(file, index) in taskResult.files"
- :key="index"
- custom-class="attachment-tag"
- type="success"
- plain
- @click="downloadFile(file, taskResult.fileNames[index] || `附件${index + 1}`)"
- >
- {{ taskResult.fileNames[index] || `附件${index + 1}` }}
- </wd-tag>
- </view>
- </view>
- </view>
- </view>
- </view>
- <!-- 查看更多 -->
- <!-- <view class="more-btn" @tap="toggleMore">
- <text class="arrow">点击查看更多</text>
- <wd-icon
- class="arrow"
- :name="isExpanded ? 'arrow-up' : 'arrow-down'"
- size="20px"
- />
- </view> -->
- <!-- 更多内容(默认隐藏) -->
- <view v-if="isExpanded" class="more-content">
- <view class="section">
- <view class="section-title">
- 注意事项
- </view>
- <view class="notice-content">
- <view class="notice-item">
- • 巡视过程中请注意安全,佩戴好防护装备
- </view>
- <view class="notice-item">
- • 发现异常情况请及时记录并上报
- </view>
- <view class="notice-item">
- • 确保所有检查项目都已完成并签字确认
- </view>
- </view>
- </view>
- </view>
- <view class="detail-btn" @tap="dealTaskEvent">
- <text>处理任务</text>
- </view>
- <!-- <view class="detail-btn" @tap="viewDetails2">
- <text>查 看 详 情2</text>
- </view>
- <view class="detail-btn" @tap="viewDetails3">
- <text>查 看 详 情3</text>
- </view> -->
- </view>
- </template>
- <style lang="scss" scoped>
- .details-box {
- display: flex;
- flex-direction: column;
- padding: 30rpx 24rpx;
- background-color: #ffffff;
- .details-box-title {
- margin-bottom: 24rpx;
- .details-box-title-text {
- font-size: 48rpx;
- font-weight: 500;
- color: #31373d;
- }
- }
- // 标签样式
- .tags-box {
- display: flex;
- gap: 12rpx;
- margin-bottom: 24rpx;
- .tag {
- padding: 8rpx 16rpx;
- border-radius: 14rpx;
- font-size: 24rpx;
- font-weight: 400;
- color: #215acd;
- background-color: #e8f3ff;
- }
- }
- // 通用区块样式
- .section {
- margin-bottom: 32rpx;
- .section-title {
- font-size: 36rpx;
- font-weight: 500;
- color: #31373d;
- margin-bottom: 20rpx;
- }
- }
- // 任务描述样式
- .task-description {
- padding: 0 0 24rpx 0;
- border-bottom: 1rpx solid #e5e5e5;
- // 针对HTML内容的样式
- & :deep(ol),
- & :deep(ul) {
- padding-left: 32rpx;
- margin: 0;
- }
- & :deep(li) {
- font-size: 28rpx;
- font-weight: 400;
- color: #31373d;
- line-height: 52rpx;
- margin-bottom: 8rpx;
- }
- & :deep(p) {
- font-size: 28rpx;
- font-weight: 400;
- color: #31373d;
- line-height: 52rpx;
- margin: 0 0 12rpx 0;
- }
- }
- // 标准指引样式
- .standard-guide {
- .guide-item {
- display: flex;
- margin-bottom: 24rpx;
- &:last-child {
- margin-bottom: 0;
- }
- .guide-label {
- width: 160rpx;
- font-size: 28rpx;
- color: #6c757d;
- font-weight: 400;
- }
- .guide-value {
- flex: 1;
- font-size: 28rpx;
- font-weight: 400;
- color: #31373d;
- }
- }
- }
- // 查看更多按钮
- .more-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8rpx;
- margin: 32rpx 0;
- text {
- font-size: 32rpx;
- color: #3498db;
- }
- .arrow {
- font-size: 24rpx;
- color: #215acd;
- }
- }
- // 查看详情按钮
- .detail-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 96rpx;
- background-color: #215acd;
- border-radius: 14rpx;
- margin-bottom: 32rpx;
- position: fixed;
- bottom: 32rpx;
- left: 24rpx;
- right: 24rpx;
- z-index: 999;
- text {
- font-size: 32rpx;
- color: #ffffff;
- font-weight: 500;
- }
- }
- // 更多内容样式
- .more-content {
- margin-bottom: 32rpx;
- .notice-content {
- background-color: #f8f9fa;
- padding: 24rpx;
- border-radius: 12rpx;
- .notice-item {
- font-size: 32rpx;
- color: #31373d;
- line-height: 52rpx;
- margin-bottom: 12rpx;
- &:last-child {
- margin-bottom: 0;
- }
- }
- }
- }
- // 附件列表样式
- .attachment-list {
- display: flex;
- flex-wrap: wrap;
- gap: 12rpx;
- .attachment-tag {
- margin-bottom: 12rpx;
- }
- }
- }
- :deep(.attachment-tag) {
- margin-right: 12rpx;
- margin-bottom: 12rpx;
- }
- </style>
|