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.

551 lines
17 KiB

<!-- 监督检查工程管理 -->
<script>
import { cloneDeep } from "lodash";
import { uploadFileData } from "@/api/system/upload";
import { listUser } from "@/api/management";
import {
getEnableSuperviseWayData,
getSuperviseEngineeringReportDetailsData,
addSuperviseEngineeringReportData,
} from "@/api/sluice";
export default {
name: "projectReport",
data() {
return {
activeName: "",
currentItem: null,
problemList: [],
personnelList: [],
formData: {
patrolName: "",
patrolUid: "",
problemList: [],
state: "",
taskId: "",
weather: "",
},
};
},
computed: {
// 进度条
calcStep() {
if (this.problemList.length) {
let sum = this.problemList.reduce((prev, cur) => {
return prev + cur.children.length;
}, 0);
let hasDoneLevel = this.problemList.reduce((prev, cur) => {
return (
prev +
cur.children.reduce((prev2, cur2) => {
return prev2 + (cur2.level ? 1 : 0);
}, 0)
);
}, 0);
return Math.floor((hasDoneLevel / sum) * 100);
} else {
return 0;
}
},
isDisabled() {
return (
this.formData.state === "1" || this.$route.query.type === "preview"
);
},
// 巡查人员
computedPatrolUid: {
get() {
return this.formData.patrolUid?.split(",").filter((v) => v) || [];
},
set(val) {
this.formData.patrolUid = val?.join(",") || "";
this.formData.patrolName = this.personnelList
.filter((v) => val.includes(v.id))
.map((v) => v.nickName)
.join(",");
},
},
},
methods: {
// 搜索用户
searchUser(e = null) {
listUser({
data: {
timeView: {
timeField: "create_time",
},
},
cv: {
name: "nickName",
type: "like",
value: e,
},
pageSize: 100,
pageNum: 1,
}).then((res) => {
this.personnelList = res.records;
});
},
async initData() {
const enableData = await getEnableSuperviseWayData({
wayId: this.$route.query.wayId,
});
if (enableData?.data?.itemList?.length) {
// 已完成提交状态的数据需要从详情中展示对应的部位
let newProblemList = [];
let list = [];
enableData.data.itemList.forEach((item, index) => {
if (index === 0) {
list.push({
id: item.id,
projectId: item.projectId,
projectName: item.projectName,
children: [
{
...item,
projectItemId: item.id,
problemDescribe: "",
siteSituationRecords: "",
siteSituationRecordsArr: [],
level: null,
},
],
});
} else {
let exitItem = list.find((v) => v.projectId === item.projectId);
if (!exitItem) {
list.push({
id: item.id,
projectId: item.projectId,
projectName: item.projectName,
children: [
{
...item,
projectItemId: item.id,
problemDescribe: "",
siteSituationRecords: "",
siteSituationRecordsArr: [],
level: null,
},
],
});
} else {
exitItem.children.push({
...item,
projectItemId: item.id,
problemDescribe: "",
siteSituationRecords: "",
siteSituationRecordsArr: [],
level: null,
});
}
}
});
this.activeName = list[0]?.projectId || "";
const detailRes = await getSuperviseEngineeringReportDetailsData(
this.$route.query.id
);
if (detailRes?.data && list.length) {
const { data } = detailRes;
this.formData.patrolName = data.patrolName;
this.formData.patrolUid = data.patrolUid;
this.formData.state = data.state;
this.formData.taskId = data.taskId;
this.formData.weather = data.weather;
this.formData.problemList = [];
const { problemList } = data;
list.forEach((item) => {
let exitItem = problemList?.find(
(v) => v.projectId === item.projectId
);
if (exitItem) {
item.newId = item.id === exitItem.id ? null : exitItem.id;
let itemTemp = cloneDeep(item);
itemTemp.children = [];
item.children.forEach((item2) => {
let exitItem2 = problemList.find(
(v) => v.projectItemId === item2.id
);
if (exitItem2) {
itemTemp.children.push(exitItem2);
item2.projectName = exitItem2.projectName;
item2.level = exitItem2.level;
item2.newId = item2.id === exitItem2.id ? null : exitItem2.id;
item2.problemDescribe = exitItem2.problemDescribe;
item2.siteSituationRecords = exitItem2.siteSituationRecords;
item2.siteSituationRecordsArr = exitItem2.siteSituationRecords
? exitItem2.siteSituationRecords.split(",")
: [];
exitItem2.siteSituationRecordsArr =
exitItem2.siteSituationRecords
? exitItem2.siteSituationRecords.split(",")
: [];
}
});
if (data.state === "1") {
newProblemList.push(itemTemp);
}
}
});
this.problemList = data.state === "1" ? newProblemList : list;
}
}
},
// 选中某个项目
handleClickItem(item) {
this.currentItem = item;
},
// 上传前
beforeUpload(e) {
if (this.currentItem.siteSituationRecordsArr?.length >= 99) {
this.$message.warning("最多上传99张图片");
return false;
}
return true;
},
handleUpload(e) {
const { file } = e;
let fData = new FormData();
fData.append("file", file);
uploadFileData(fData)
.then((res) => {
this.currentItem.siteSituationRecordsArr?.push(res.url);
})
.catch((err) => {
console.log("err >>>>> ", err);
});
},
// 处理提交数据
dealFormData() {
this.formData.taskId = this.$route.query.id;
this.formData.problemList = [];
this.problemList.forEach((item) => {
if (item.children.length) {
item.children.forEach((item2) => {
let problemItem = {
id: item2.newId || null,
level: item2.level,
problemDescribe:
!item2.level || item2.level === "0" || item2.level === "1"
? ""
: item2.problemDescribe,
siteSituationRecords:
!item2.level || item2.level === "0" || item2.level === "1"
? ""
: item2.siteSituationRecordsArr?.join(",") || "",
projectId: item2.projectId,
projectItemId: item2.projectItemId,
};
this.formData.problemList.push(problemItem);
});
}
});
return cloneDeep(this.formData);
},
handleSave() {
let data = this.dealFormData();
data.state = "0";
addSuperviseEngineeringReportData(data).then((res) => {
this.$message({
type: "success",
message: "保存成功",
});
});
},
handleSubmit() {
if (this.calcStep < 100) {
this.$message.warning("检查进度未达到100%,请检查");
return;
}
if (!this.formData.patrolUid) {
this.$message.warning("请选择巡查人员");
return;
}
// 二次确认提交
this.$confirm("是否确认提交?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let data = this.dealFormData();
data.state = "1";
addSuperviseEngineeringReportData(data).then((res) => {
this.$message({
type: "success",
message: "提交成功",
});
this.formData.state = "1";
this.$router.go(-1);
});
})
.catch(() => {});
},
},
created() {
this.searchUser();
this.initData();
},
mounted() {},
};
</script>
<template>
<div class="body slider-right">
<div class="top-title">工程问题上报</div>
<div class="table-box">
<div class="step-box">
<div
class="bar"
:style="{
left: `-${100 - calcStep}%`,
backgroundColor: `rgb(${255 - (255 * calcStep) / 100},${
0 + (255 * calcStep) / 100
},0)`,
}"
></div>
<div style="position: relative; z-index: 1" class="pl-4 font-14">
检查进度 {{ calcStep }}%
</div>
</div>
<div class="flex items-center mb-12">
<div>巡查人员</div>
<el-select
:disabled="isDisabled"
style="width: 240px"
class="ml-4"
v-model="computedPatrolUid"
multiple
filterable
remote
:remote-method="searchUser"
placeholder="请选择"
>
<el-option
v-for="item in personnelList"
:key="item.id"
:label="item.nickName"
:value="item.id"
>
</el-option>
</el-select>
<div class="ml-24">天气</div>
<el-input
:disabled="isDisabled"
class="ml-4"
style="width: 240px"
v-model="formData.weather"
placeholder="请输入"
/>
</div>
<template v-if="problemList.length">
<el-tabs v-model="activeName" type="card">
<el-tab-pane
v-for="item in problemList"
:key="item.id"
:label="item.projectName"
:name="item.projectId"
class="question-box"
>
<div
class="question-row w-full"
v-for="item2 in item.children"
:key="item2.id"
>
<div class="flex">
<div class="question-col flex-shrink-0">问题</div>
<div class="question-col flex-1">
{{ item2.content }}
<el-tooltip class="tooltip" effect="dark" placement="left">
<div slot="content">
<div>一般{{ item2.sameGrade || " " }}</div>
<div>较重{{ item2.heavyGrade || " " }}</div>
<div>严重{{ item2.seriousGrade || " " }}</div>
</div>
<i
class="el-icon-warning font-20"
style="color: #e6a23c"
></i>
</el-tooltip>
</div>
</div>
<div class="question-select">
<el-button
:disabled="isDisabled"
:type="item2.level === '0' ? 'primary' : ''"
@click="item2.level = '0'"
></el-button
>
<el-button
:disabled="isDisabled"
:type="item2.level === '1' ? 'primary' : ''"
@click="item2.level = '1'"
>一般</el-button
>
<el-button
:disabled="isDisabled"
:type="item2.level === '2' ? 'primary' : ''"
@click="item2.level = '2'"
>较重</el-button
>
<el-button
:disabled="isDisabled"
:type="item2.level === '3' ? 'primary' : ''"
@click="item2.level = '3'"
>严重</el-button
>
</div>
<div
class="question-row w-full"
v-if="['2', '3'].includes(item2.level)"
>
<div class="question-col flex-shrink-0">描述</div>
<div class="question-col flex-1">
<el-input
type="textarea"
v-model="item2.problemDescribe"
:rows="4"
:disabled="isDisabled"
placeholder="请输入内容"
/>
</div>
</div>
<div
class="question-row w-full"
v-if="['2', '3'].includes(item2.level)"
>
<div class="question-col flex-shrink-0">照片</div>
<div class="question-col flex-1">
<div class="flex flex-wrap">
<div
class="w-100 h-100 mr-12 mb-12"
v-for="(url, urlIndex) in item2.siteSituationRecordsArr"
:key="urlIndex"
>
<el-image
style="width: 200px; min-height: 100px; height: auto"
:src="url"
:preview-src-list="[url]"
>
<template #error>
<div
class="w-full flex justify-center items-center"
style="
height: 100px;
border: 1px solid #f0f0f0;
font-style: italic;
color: #ccc;
"
>
图片加载失败
</div>
</template>
</el-image>
</div>
</div>
<el-upload
action="#"
:disabled="isDisabled"
:http-request="handleUpload"
:auto-upload="true"
:before-upload="beforeUpload"
:showFileList="false"
accept=".jpg,.png,.jpeg"
1 year ago
:limit="99"
>
<el-button
type="primary"
@click="handleClickItem(item2)"
:disabled="isDisabled"
>上传</el-button
>
</el-upload>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
<div class="mt-30 flex justify-end" v-if="!isDisabled">
<el-button class="mr-12" @click="handleSave">保存</el-button>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</div>
</template>
<div v-else class="font-14 pt-20">-暂无数据-</div>
</div>
</div>
</template>
<style scoped lang="less">
.body {
width: 100%;
min-height: calc(100vh - 56px);
padding-left: 24px;
.top-title {
height: 40px;
background-color: white;
display: flex;
padding-left: 16px;
align-items: center;
font-weight: 600;
}
.table-box {
width: 100%;
height: calc(100vh - 56px - 64px);
margin-top: 24px;
padding: 16px;
background-color: white;
overflow: auto;
.step-box {
position: relative;
height: 32px;
width: 120px;
background-color: #f0f0f0;
border: 1px solid #999;
border-radius: 2px;
float: right;
display: flex;
align-items: center;
overflow: hidden;
.bar {
position: absolute;
top: 0;
left: -50%;
z-index: 0;
height: 100%;
width: 100%;
background-color: #1890ff;
border-radius: 2px;
transition: 0.5s all;
}
}
.question-box {
border: 1px solid #f0f0f0;
.question-row {
.question-col {
position: relative;
padding: 10px;
border-bottom: 1px solid #f0f0f0;
&:not(:last-child) {
border-right: 1px solid #f0f0f0;
}
.tooltip {
position: absolute;
top: 2px;
right: 2px;
}
}
.question-select {
padding: 10px;
border-bottom: 1px solid #f0f0f0;
}
}
}
}
}
</style>