approvalMobile/src/views/applyList/detail.vue

273 lines
8.1 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.

<script setup>
import { ref,onMounted } from 'vue'
import router from '@/router'
import { useRoute } from 'vue-router'
import { showNotify } from 'vant'
import { detailsApi } from '@/api/apply';
const route = useRoute()
const loading = ref(false);
const params = ref(null)
const info = ref(null)
// 状态
const statusList = ref([
{text:'草稿',value:0},
{text:'申请中(安全员/技术员)',value:1},
{text:'申请中(车间主任)',value:2},
{text:'申请中(车间值班人员)',value:101},
{text:'各部门会签中',value:3},
{text:'审批中',value:4},
{text:'通过',value:5},
{text:'已关闭',value:97},
{text:'已撤回',value:98},
{text:'已驳回',value:99},
]);
// 匹配选项
const matchOptions = (arr,val) => {
const target = arr.find(item => item.value == val);
return target ? target.text : '';
}
// 路由跳转
const jumpTo = (val) => {
// 跳转已审批列表
if(val===0){
router.push({
path: '/applyList',
})
}
// 跳转待审批列表
if(val===1){
router.push({
path: '/waitList',
})
}
// 跳转联锁详情页
if(val===2){
router.push({
path: '/lockDetail',
query: { id: params.value.id, type: params.value.type },
})
}
}
// 同意
const agree = () => {
showNotify({ type: 'success', message: '同意成功' });
}
// 获取详情
const getDetail = async () => {
loading.value = true;
try {
const res = await detailsApi(params.value?.id);
info.value = res.data;
if(res.data?.status>=1 && res.data?.status<=4){
let allEmpty = res.data?.draft_apply_steps.every(item => item.draft_cosign_items.length === 0);
if(res.data?.draft_apply_steps?.length && !allEmpty){
info.value.steps = res.data?.draft_apply_steps;
}else{
info.value.steps = res.data?.apply_steps;
}
}else{
info.value.steps = res.data?.apply_steps;
}
} finally {
loading.value = false;
}
}
onMounted(() => {
if(route.query){
params.value = route.query;
getDetail();
}
})
</script>
<template>
<!-- 全屏加载遮罩层 -->
<div v-if="loading" class="global-loading-overlay">
<van-loading size="30px" color="#1989fa" vertical></van-loading>
</div>
<div class="main">
<div class="tab-box">
<p class="tab" :class="{'active':params?.type==='finish'}" @click="jumpTo(0)">已审批</p>
<p class="tab" :class="{'active':params?.type==='wait'}" @click="jumpTo(1)">待审批</p>
</div>
<template v-if="info">
<div class="detail">
<div class="row">
<div v-if="info.template_id==4">
<p v-if="info.status==1">申请中(车间值班人员)</p>
<p v-else>{{matchOptions(statusList,info.status)}}</p>
</div>
<div v-else>
<p v-if="info.status==5 || info.status==100">通过</p>
<p v-else>{{matchOptions(statusList,info.status)}}</p>
</div>
<p>申请摘除数量({{info.chain_count}})个</p>
</div>
<div class="row">
<p>岗位:{{info.chain_position}}</p>
<p>类型:{{info.template_name}}</p>
</div>
<div class="row">
<p>摘除理由:{{info.reasons}}</p>
</div>
<div class="row">
<p>计划摘除时间:{{info.plan_remove_time?.slice(0,16)}}</p>
</div>
<div class="row">
<p>计划恢复时间:{{info.plan_recover_time?.slice(0,16)}}</p>
</div>
<div class="row col">
<p class="blue-color">风险辨识</p>
<p>{{info.risk_description}}</p>
</div>
<div class="row col">
<p class="blue-color">安全措施</p>
<p>{{info.safety_measures}}</p>
</div>
<div class="row col">
<div class="timeline">
<div class="timeline-item" v-if="info.template_id==4">
<div class="left">
<p class="timeline-dot"></p>
<div class="txt">班长:</div>
<div class="txt">{{info?.apply_user?.realname}}</div>
</div>
</div>
<div class="timeline-item" v-if="info.template_id>=1 && info.template_id<=3">
<div class="left">
<p class="timeline-dot"></p>
<div class="txt">车间工程师:</div>
<div class="txt">{{info?.apply_user?.realname}}</div>
</div>
</div>
<template v-for="(item, index) in info?.steps || []" :key="index">
<template v-for="(sItem,sIndex) in (item.cosigns || item.cosign_items || item.draft_cosign_items)" :key="sIndex">
<div class="timeline-item">
<div class="left">
<p class="timeline-dot"></p>
<div class="txt">{{sItem.dept_name}}</div>
<div class="txt">{{sItem.user_name}}</div>
</div>
<div class="txt" v-if="sItem.signed_at">{{(sItem.signed_at)?.slice(0,16)}}</div>
</div>
</template>
</template>
</div>
</div>
</div>
<div class="btns">
<p class="btn" @click="jumpTo(params?.type==='finish'?0:1)">返回列表</p>
<p class="btn" @click="jumpTo(2)">联锁详情</p>
<p class="btn" v-if="params?.type==='wait'" @click="agree">同意</p>
<p class="btn" v-if="params?.type==='wait'">驳回</p>
</div>
</template>
<template v-else>
<van-empty description="暂无数据" />
</template>
</div>
</template>
<style scoped>
.blue-color {
color: #1989fa;
}
.main {
height: 100vh;
padding: 12px;
overflow: hidden;
font-size: 14px;
}
/* tab切换 */
.tab-box {
display: flex;
border: 1px solid #1989fa;
}
.tab {
width: 50%;
padding: 5px 0;
text-align: center;
font-size: 16px;
color: #1989fa;
}
.tab.active {
background-color: #1989fa;
color: #fff;
}
/* 详情 */
.detail {
margin-top: 12px;
height: calc(100vh - 120px);
overflow-y: auto;
border: 1px solid #f1f1f1;
border-radius: 2px;
padding: 10px;
}
.detail .row {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 10px;
gap: 10px;
}
.detail .col {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
}
.detail .row:first-child {
margin-top: 0;
}
/* 底部按钮 */
.btns {
margin-top: 12px;
display: flex;
gap: 12px;
}
.btns .btn {
width: 100%;
text-align: center;
padding: 8px 0;
border: 1px solid #eee;
border-radius: 2px;
}
/* 时间线 */
.timeline {
width: 100%;
position: relative;
display: flex;
flex-direction: column;
gap: 12px;
}
.timeline:before {
content: '';
width: 1px;
height: calc(100% - 6px);
background: #1989fa;
position: absolute;
top: 3px;
left: 6px;
}
.timeline-item {
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
}
.timeline-item .left {
display: flex;
align-items: center;
}
/* 圆点 */
.timeline-dot {
width: 12px;
height: 12px;
background: #1989fa;
border-radius: 50%;
margin-right: 10px;
}
</style>