Files
estate/src/views/system/Repair/repairMain.vue
2026-08-11 08:10:43 +08:00

388 lines
12 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>
<div class="ResidentMainBox p-2 w-full">
<PageHeader title="报修详情"></PageHeader>
<div class="ResidentMainBody">
<el-row :span="24" :gutter="20">
<el-col :span="16">
<!-- 车位信息 -->
<div class="mb-10">
<el-card>
<template #header>
<div class="card-header">
<span>报修房屋</span>
<span class="ml-20px color-blue cursor-pointer" @click="handleEdit">编辑</span>
</div>
</template>
<div class="w-full h-full CarInfoBox">
<el-row class="mb-20px">
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">报修房屋:</div>
<div class="main">{{ form.houseName }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">维修项目:</div>
<div class="main">{{ form.maintenanceItemName }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">问题描述</div>
<div class="main" style="font-size: small; max-width: 200px">
<span>{{ form.problem }}</span>
</div>
</div>
</el-col>
</el-row>
<el-row class="mb-20px">
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">报修人:</div>
<div class="main">{{ form.residentName }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">手机号码:</div>
<div class="main">{{ form.phone }}</div>
</div>
</el-col>
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">预约日期:</div>
<div class="main">{{ form.orderDate }}</div>
</div>
</el-col>
</el-row>
<el-row class="mb-20px">
<el-col :span="8">
<div class="carInfo_Item">
<div class="label">提交时间:</div>
<div class="main">{{ form.createTime }}</div>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<div class="carInfo_Item">
<div class="label">附件:</div>
<div class="main fileImagebox" v-if="form.problemImageUrlList.length > 0">
<el-image
:preview-teleported="true"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="form.problemImageUrlList"
show-progress
v-for="(item, index) in form.problemImageUrlList"
:initial-index="index"
:key="index"
:src="item"
lazy
class="carInfoImage"
></el-image>
</div>
</div>
</el-col>
</el-row>
</div>
</el-card>
</div>
<el-card>
<template #header>
<div class="card-header">
<span>分配工单</span>
</div>
</template>
<div class="repair w-full h-full flex flex-items-start mt-2">
<div class="title">维修师傅</div>
<div class="preivewBodybox flex-1 ml-5">
<repairUser :is-multiple="false" :username="form.repairName" :userid="form.repairUserId" @change="handleChange"> </repairUser>
<div class="actions mt-5">
<el-button v-if="form.problemStatus === '0'" @click="handleSend" type="primary">确定派单</el-button>
<el-button v-if="form.problemStatus === '1'" @click="handleChangeRepairUser" type="primary">变更人员</el-button>
<el-button @click="backRouter">返回</el-button>
</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card style="position: relative; height: 100%">
<template #header>
<div class="asideCardHeader w-full">
<div class="cardSubtitle">
<div class="line"></div>
<div class="subtitle">审批流程</div>
</div>
</div>
</template>
<div class="h-full w-full">
<StepTimeline :steps="stepList">
<template #title="{ item }">{{ item.title }}</template>
<template #subtitle="{ item }">{{ item.subtitle }}</template>
<template #time="{ item }">{{ item.time }}</template>
</StepTimeline>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import StepTimeline, { StepItem } from '@/components/StepTimeline/index.vue';
import repairUser from '@/components/Holder/repairUser.vue';
import PageHeader from '@/components/Pageheader/index.vue';
import { getRepair, updateRepair } from '@/api/system/Repair';
import { RepairVO } from '@/api/system/Repair/type';
import { listRepairProcess, updateRepairProcess } from '@/api/system/repairProcess';
const route = useRoute();
const router = useRouter();
interface formType extends RepairVO {
problemImageUrlList: string[];
}
const stepList = ref<StepItem[]>([
{ status: 'completed', title: '提交维修信息', subtitle: '等待提交', time: '', wrap: false },
{ status: 'pending', title: '待分配', subtitle: '等待物业派单中', time: '', wrap: true },
{ status: 'waiting', title: '维修', subtitle: '等待维修人员维修', time: '', wrap: false },
{ status: 'waiting', title: '完成维修', subtitle: '等待填写维修记录', time: '', wrap: false }
]);
const form = ref<formType>({
'id': '',
'houseId': '',
'maintenanceItemId': null,
'maintenanceItemName': null,
'problem': '',
'residentId': '',
'residentName': null,
'phone': '',
'orderDate': '',
'problemImageUrl': '',
'problemStatus': '',
'repairDes': '',
'repairImageUrl': '',
'repairId': '',
'repairName': '',
'houseName': '',
'repairUserId': '',
'item': null,
'projectType': null,
'updateTime': '',
'projectTypeStr': '',
'repairIsCheck': '1',
'manageIsCheck': '1',
'isCheckStr': null,
'repairPhone': null,
'repairRoleName': null,
'repairStatus': null,
'createTime': null,
problemImageUrlList: []
});
const userid = ref();
// 审核流程
const reviewInfo = ref({
'id': '',
'repairId': '',
'submitTime': '',
'submitStatus': '0',
'allocateTime': null,
'allocateStatus': '0',
'completeTime': null,
'completeStatus': '0'
});
// ! 房屋 ====================================================================================================
async function init() {
// 报修详情
getRepair(userid.value).then((res) => {
form.value = {
...form.value,
...res.data
};
try {
form.value.problemImageUrlList = form.value.problemImageUrl.split(',').filter((item) => item);
} catch {
form.value.problemImageUrlList = [];
}
// 获取保修审核状态
listRepairProcess({
repairId: res.data.id,
pageSize: 9999,
pageNum: 1
}).then((info) => {
reviewInfo.value = info.rows[info.rows.length - 1] || null;
handleReview();
});
});
}
// 处理审核╬╬
function handleReview() {
if (reviewInfo.value.submitStatus === '1') {
// 提交完成
stepList.value[0].status = 'completed';
stepList.value[0].subtitle = '提交成功';
stepList.value[1].status = 'pending';
stepList.value[1].subtitle = '等待物业派单中';
stepList.value[0].time = reviewInfo.value.submitTime;
if (reviewInfo.value.allocateStatus === '1') {
// 分配完成
stepList.value[1].status = 'completed';
stepList.value[1].title = '已分配';
stepList.value[1].subtitle = `${form.value.repairName ?? ''} ${form.value.repairPhone ?? ''}`;
stepList.value[1].time = reviewInfo.value.allocateTime;
stepList.value[2].status = 'pending';
stepList.value[2].subtitle = '等待维修人员维修';
// 维修完成
if (reviewInfo.value.completeStatus === '1') {
stepList.value[2].time = reviewInfo.value.completeTime;
stepList.value[2].status = 'completed';
stepList.value[2].subtitle = '维修完成';
stepList.value[3].status = 'completed';
stepList.value[3].subtitle = '填写维修记录';
}
}
} else {
stepList.value[0].status = 'waiting';
}
}
if (route.query.id) {
userid.value = route.query.id;
init();
}
/** 派单 */
function handleSend() {
if (form.value.repairUserId && form.value.repairUserId.trim()) {
// 已分配
form.value.problemStatus = '1';
updateRepair(form.value).then(() => {
form.value.problemStatus = '1';
reviewInfo.value.allocateTime = new Date().toLocaleString().replaceAll('/', '-');
if (form.value.repairUserId) {
reviewInfo.value.allocateStatus = '1';
} else {
reviewInfo.value.allocateStatus = '0';
}
updateRepairProcess(reviewInfo.value).then(() => {
backRouter();
});
});
} else {
ElMessage.warning('请选择维修人员');
}
}
// 是否变更人员
const isChangeUse = ref(false);
/** 选择维修人员 */
function handleChange(row) {
const oldValue = form.value.repairUserId;
isChangeUse.value = oldValue !== '' && oldValue !== row;
form.value.repairUserId = row;
}
function handleChangeRepairUser() {
if (form.value.repairUserId && form.value.repairUserId.trim()) {
handleSend();
} else {
ElMessage.warning('请选择维修人员');
}
}
/** 返回╬╬╬╬╬╬*/
function backRouter() {
router.push({
path: '/repair/repairlist'
});
}
function handleEdit() {
router.push({
path: '/repair/editRepair',
query: {
id: form.value.id
}
});
}
</script>
<style scoped lang="scss">
.ResidentMainBox {
display: flex;
flex-direction: column;
.ResidentMainBody {
margin-top: 20px;
flex: 1;
.CarInfoBox {
&.gridBox {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
gap: 20px;
row-gap: 40px;
}
.carInfo_Item {
display: flex;
align-items: flex-start;
font-size: 14px;
.label {
font-weight: 600;
width: 80px;
text-align: left;
padding-right: 10px;
white-space: nowrap;
}
.main {
word-break: break-word;
}
.carInfoImage {
margin: 10px;
width: 200px;
height: 150px;
}
}
}
.card-header,
.subtitle {
font-size: 15px;
}
.repair {
font-size: 16px;
}
.repairBox {
width: 350px;
height: 35px;
line-height: 35px;
border-radius: 5px;
border: 1px solid rgba(187, 187, 187, 1);
}
&:deep(div.el-step__head.is-process) {
& > div.el-step__line {
width: 0;
border: 1px dashed gray;
background: transparent;
}
}
&:deep(.el-step.is-vertical .el-step__line) {
top: 20px;
}
&:deep(div.el-step__head.is-finish) {
& > div.el-step__line {
width: 0;
border: 1px solid var(--el-color-primary);
background: transparent;
}
}
}
}
</style>