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.
316 lines
8.1 KiB
316 lines
8.1 KiB
<template> |
|
<view class="header"> |
|
<view class="flex between top v-center"> |
|
<view class="flex v-center"> |
|
<fui-icon name="arrowleft" color="#fff" :size="50" @tap="goBack"></fui-icon> |
|
<view> |
|
<text class="label mr-6">受理编号</text> |
|
<text>{{ mailId }}</text> |
|
</view> |
|
</view> |
|
<view> |
|
<m-button class="flex v-center gap-4" :type="isFav? 'danger' :'primary'" @tap="handleFav"> |
|
<fui-icon name="star" color="#fff" :size="30"></fui-icon> |
|
<text>收藏</text> |
|
</m-button> |
|
</view> |
|
</view> |
|
<Steps /> |
|
<view class="timer" v-if="!mail.flowRemainingTime || mail.flowRemainingTime >= 0"> |
|
<view class="flex between mb-8"> |
|
<text>剩余处理时间</text> |
|
<text>{{ formatTimeText(mail.flowRemainingTime) }}</text> |
|
</view> |
|
<m-progress :percentage="mail.flowRemainingTimePercentage" /> |
|
</view> |
|
<view class="timer-danger flex between" v-else> |
|
<text>超时</text> |
|
<text>{{ formatTimeText(mail.flowRemainingTime) }}</text> |
|
</view> |
|
</view> |
|
<view class="body"> |
|
<fui-tabs :tabs="tabs" :short="false" @change="changeTab" :current="tabCurrent"></fui-tabs> |
|
<view style="height: calc(100% - 48px); overflow: auto;"> |
|
<component v-for="item in tabs" :is="components[item.template]" v-model="requestData" v-show="view === item.template" ref="templatesRef"></component> |
|
</view> |
|
</view> |
|
<view class="footer flex end gap"> |
|
<template v-if="workId"> |
|
<template v-for="item in actions" > |
|
<m-button size="large" :type="item.btnType" :plain="item.btnPlain" @tap="handleNext(item.key)" v-if="handleBtnShow(item.key)">{{ item.btnLabel }}</m-button> |
|
</template> |
|
|
|
</template> |
|
</view> |
|
|
|
<m-popup ref="approvalPopup" title="提交审批" placeholder="请输入审批意见" confirmText="审批通过" @confirm="sumbitApproval" /> |
|
<m-popup ref="mail110RejectPopup" title="不纳入信件" placeholder="请输入不纳入信件理由" confirmText="提交" @confirm="mail110Reject" /> |
|
<approval ref="approvalRef" v-model="requestData" @submit="(key) => handleNext(key)" /> |
|
<completion ref="completionRef" v-model="requestData" @submit="(key) => handleNext(key)" /> |
|
<MailReturn ref="mailReturnRef" v-model="requestData" @submit="(key) => handleNext(key)" /> |
|
|
|
</template> |
|
|
|
<script setup> |
|
import Steps from './components/steps.vue' |
|
import approval from './components/approval.vue' |
|
import MailReturn from './components/mail-return.vue' |
|
import completion from './components/completion.vue' |
|
|
|
import MainContactInfo from './templates/MainContactInfo.vue' |
|
import MailTypeForm from './templates/MailTypeForm.vue' |
|
import Flows from './templates/Flows.vue' |
|
import DeptSelectForm from './templates/DeptSelectForm.vue' |
|
import ApprovalOpinions from './templates/ApprovalOpinions.vue' |
|
import ContactWriter from './templates/ContactWriter.vue' |
|
import { onMounted } from "vue" |
|
|
|
const components = { |
|
'MainContactInfo': MainContactInfo, |
|
'MailTypeForm': MailTypeForm, |
|
'DeptSelectForm': DeptSelectForm, |
|
'Flows': Flows, |
|
'ApprovalOpinions': ApprovalOpinions, |
|
'ContactWriter': ContactWriter |
|
} |
|
|
|
import { ref, watch, provide, defineProps } from 'vue' |
|
import { workDetail } from '@/api/work' |
|
import { flowNext, mailDetail } from '@/api/mail' |
|
import { addFav, delFav } from '@/api/fav' |
|
import { getTabs } from './action' |
|
import { formatTimeText } from '@/common/util' |
|
import store from '@/store' |
|
|
|
const tabs = ref([ |
|
{ |
|
name: '信件信息', |
|
template: 'MainContactInfo' |
|
} |
|
]); |
|
const tabCurrent = ref(0) |
|
|
|
const view = ref('MainContactInfo') |
|
|
|
function changeTab(item) { |
|
view.value = item.template |
|
tabCurrent.value = item.index |
|
} |
|
|
|
function goBack() { |
|
uni.navigateBack({ |
|
delta: 1 |
|
}); |
|
} |
|
const props = defineProps({ |
|
mailId: { |
|
type: String |
|
}, |
|
workId: { |
|
type: String |
|
} |
|
}) |
|
|
|
const mail = ref({}) |
|
const flows = ref([]) |
|
const flowNode = ref({}) |
|
const actions = ref([]) |
|
const approvals = ref([]) |
|
const mailReturns = ref([]) |
|
const isFav = ref(false) |
|
watch(() => flowNode.value.key, (val) => { |
|
tabs.value = getTabs(val) |
|
}) |
|
async function getDetail() { |
|
let data; |
|
uni.showLoading({ |
|
title: '加载中' |
|
}); |
|
if (props.workId) { |
|
data = await workDetail({ |
|
mailId: props.mailId, |
|
workId: props.workId |
|
}) |
|
} else { |
|
data = await mailDetail(props.mailId) |
|
} |
|
uni.hideLoading(); |
|
mail.value = data.mail |
|
flowNode.value = data.flowNode |
|
flows.value = data.flows |
|
actions.value = data.actions |
|
if (data.approvals) { |
|
data.approvals.reverse() |
|
} |
|
approvals.value = data.approvals || []; |
|
mailReturns.value = data.mailReturns |
|
isFav.value = data.isFav |
|
} |
|
|
|
getDetail(); |
|
provide('mail', mail); |
|
provide('flows', flows); |
|
provide('approvals', approvals); |
|
provide('mailReturns', mailReturns); |
|
provide('flowNode', flowNode); |
|
|
|
const templatesRef = ref() |
|
const requestData = ref({}) |
|
const approvalPopup = ref() |
|
const approvalRef = ref() |
|
const completionRef = ref() |
|
const mailReturnRef = ref() |
|
const mail110RejectPopup = ref() |
|
|
|
// 是否显示该按钮 |
|
function handleBtnShow(key) { |
|
if (key === 'mail110Reject') { |
|
return mail.value.source === '110_report_complaints'; |
|
} |
|
const arr = ['reportLeader', 'applyExtension', 'applicationCompleted', 'save', 'interviewSave', 'initiateCountersign']; |
|
return arr.indexOf(key) === -1; |
|
} |
|
|
|
async function handleNext(key) { |
|
console.log(key) |
|
if (key === 'mail110Reject') { |
|
mail110RejectPopup.value.open() |
|
return |
|
} |
|
// 退回 |
|
if (key === 'return') { |
|
mailReturnRef.value.open() |
|
return |
|
} |
|
// 审批 |
|
if (key === 'approved') { |
|
if (isNeedLeaderApproval()) { |
|
approvalRef.value.open() |
|
} else { |
|
approvalPopup.value.open() |
|
} |
|
return |
|
} |
|
// 认定办结 |
|
if (key === 'approvedCompletion') { |
|
completionRef.value.open() |
|
return |
|
} |
|
if (key !== 'returnSubmit' && key !== 'mail110RejectSubmit') { |
|
for (let i = 0; i < templatesRef.value.length; i++) { |
|
if (templatesRef.value[i].validate) { |
|
try { |
|
await templatesRef.value[i].validate() |
|
} catch(e) { |
|
tabCurrent.value = 1 |
|
console.log('tabCurrent.value', tabCurrent.value) |
|
throw e |
|
} |
|
} |
|
} |
|
} |
|
flowNext({ |
|
mailId: props.mailId, |
|
nextActionKey: key, |
|
flowKey: flowNode.value.key, |
|
data: requestData.value |
|
}).then(() => { |
|
tabCurrent.value = 0 |
|
if (key === 'sign') { |
|
if (requestData.value.mailFirstCategory === '无效类' || requestData.value.mailFirstCategory === '终止类' || requestData.value.mailFirstCategory === '感谢信类') { |
|
uni.showToast({ |
|
title: '操作成功', |
|
type: 'success', |
|
duration: 3000 |
|
}) |
|
goBack() |
|
return |
|
} |
|
|
|
uni.showToast({ |
|
title: '签收成功', |
|
type: 'success', |
|
duration: 3000 |
|
}) |
|
getDetail() |
|
return |
|
} |
|
uni.showToast({ |
|
title: '操作成功', |
|
type: 'success' |
|
}) |
|
goBack() |
|
|
|
}) |
|
} |
|
|
|
function sumbitApproval(val) { |
|
requestData.value.approvalComment = val |
|
handleNext('approvedSubmit') |
|
} |
|
|
|
function mail110Reject(val) { |
|
requestData.value.reason = val |
|
handleNext('mail110RejectSubmit') |
|
} |
|
|
|
function isNeedLeaderApproval() { |
|
return mail.value.completeMethod === 'online' && (flowNode.value.key === 'second_approval' || flowNode.value.key === 'second_deputy_approval') |
|
} |
|
|
|
async function handleFav() { |
|
if (isFav.value) { |
|
isFav.value = false |
|
await delFav(props.mailId) |
|
} else { |
|
isFav.value = true |
|
await addFav(props.mailId) |
|
} |
|
} |
|
|
|
watch(() => mail.value.flowRemainingTime,(val) => { |
|
if (val > -3600 && val < 3600 && store.state.isWorkingDay) { |
|
setTimeout(() => { |
|
mail.value.flowRemainingTime -= 1 |
|
}, 1000) |
|
} |
|
}) |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.header { |
|
padding-top: 40px; |
|
font-size: 11px; |
|
background-color: var(--primary-color); |
|
color: #fff; |
|
.top { |
|
padding: 12px 8px; |
|
font-size: 12px; |
|
} |
|
.timer { |
|
padding: 12px; |
|
} |
|
.timer-danger { |
|
background: linear-gradient( 180deg, #FF5C37 0%, #E03021 100%); |
|
height: 45px; |
|
line-height: 45px; |
|
margin-top: 10px; |
|
padding: 0 10px; |
|
} |
|
} |
|
.body { |
|
font-size: 11px; |
|
background: #F1F1F1; |
|
height: calc(100vh - 121px - 94px); |
|
.fui-tabs__scrollbox { |
|
border-bottom: 1px solid #E5E5E5; |
|
} |
|
} |
|
|
|
.footer { |
|
padding: 8px 12px; |
|
background-color: #fff; |
|
height: 32px; |
|
border-top: 1px solid #e5e5e5; |
|
} |
|
</style> |