| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650 |
- <template>
- <el-card class="pl30 pt20 mt30" style="width: 1000px">
- <div class="df jcsb" v-if="templateDetail.id">
- <div>
- <div class="df aic jcsb mb10">
- <div class="df aic">
- <div class="c6 mr30">消防安检名称:</div>
- <div class="c6 mr30">{{ templateDetail.securityCheckName }}</div>
- </div>
- </div>
- <div class="df aic mb10">
- <div class="c6 mr30">消防安检目标:</div>
- <div class="c6 mr30">{{ templateDetail.securityCheckTarget }}</div>
- </div>
- <div class="df aic">
- <div class="c6 mr30">消防安检重点:</div>
- <div class="c6 mr30">{{ templateDetail.securityCheckFocus }}</div>
- </div>
- </div>
- <div>
- <div class="c6 mr30 mb10">
- <span class="mr10">总分:</span>
- {{ templateDetail.totalScore }}
- <span class="ml30 mr10">实际得分:</span>
- {{ templateDetail.actualScore }}
- </div>
- <div class="c6 mr30">
- <span class="mr20">通过项目:</span>
- {{ templateDetail.finishCheckItem }} /
- {{ templateDetail.totalCheckItem }}
- </div>
- </div>
- </div>
- <el-divider />
- <div>
- <div class="c6 mb20">船舶信息</div>
- <div class="df aic mb20">
- <div class="ship-label">船名</div>
- <div class="ship-text">{{ shipDetail.shipname }}</div>
- <div class="ship-label">船东姓名</div>
- <div class="ship-text">{{ shipDetail.shipOwnerName }}</div>
- <div class="ship-label">船东手机号</div>
- <div class="ship-text">{{ shipDetail.shipOwnerPhone }}</div>
- <div class="ship-label">MMSI</div>
- <div class="ship-text">{{ shipDetail.mmsi }}</div>
- <div class="ship-label">IMO</div>
- <div class="ship-text">{{ shipDetail.imo }}</div>
- </div>
- <div class="df aic mb20">
- <div class="ship-label">船龄</div>
- <div class="ship-text">
- {{ shipDetail.age }}
- <span class="unit">年</span>
- </div>
- <div class="ship-label">船长</div>
- <div class="ship-text">
- {{ shipDetail.length }}
- <span class="unit">米</span>
- </div>
- <div class="ship-label">船宽</div>
- <div class="ship-text">
- {{ shipDetail.breadth }}
- <span class="unit">米</span>
- </div>
- <div class="ship-label">吨位</div>
- <div class="ship-text">
- {{ shipDetail.loadTons }}
- <span class="unit">吨</span>
- </div>
- <div class="ship-label">满载吃水</div>
- <div class="ship-text">
- {{ shipDetail.draught }}
- <span class="unit">米</span>
- </div>
- </div>
- </div>
- <el-divider />
- <div v-if="status != 1">
- <div class="df aic">
- <div class="mr20">选择安全检查员(可多选):</div>
- <el-select
- class="mr20"
- v-model="checkedUsers"
- value-key="key"
- multiple
- style="width: 300px"
- placeholder="请选择检查员"
- clearable
- >
- <el-option
- v-for="item in checkUsers"
- :key="item.key"
- :label="item.value"
- :value="item"
- />
- </el-select>
- <el-button type="primary" @click="saveFireSafetyCheckUser()">
- 保存
- </el-button>
- </div>
- <el-divider />
- </div>
- <div :id="mapId" class="map-container"></div>
- <el-divider />
- <div class="mt40 fs16 c6">安检项目</div>
- <div
- class="mb20 mt30 fs14 c6"
- v-for="item in templateDetail.fileInspectionItems"
- >
- <div class="df aic">
- <div class="ml20 mr10 item-title">检查项目名称:</div>
- <div class="mr30 item-text">{{ item.checkItemName }}</div>
- <div class="mr10 item-title">检查项目类型:</div>
- <div class="mr30 item-text">{{ item.checkItemTypeName }}</div>
- <div class="mr10 item-title">检查项目备注:</div>
- <div class="mr10 item-text">{{ item.checkItemRemark }}</div>
- </div>
- <div class="df aic">
- <div class="mt10 ml20">
- <div v-if="item.viewUrl">
- <el-image
- v-if="isImage(item.fileKey)"
- style="width: 200px; height: 200px"
- :src="item.viewUrl"
- :preview-src-list="[item.viewUrl]"
- fit="cover"
- ></el-image>
- <div class="video-box" v-else>
- <img
- class="play-icon"
- style="width: 50px; height: 50px"
- src="../../assets/play.png"
- alt=""
- @click="showModal(item)"
- />
- <video
- style="width: 200px; height: 200px"
- :src="item.viewUrl"
- ></video>
- </div>
- </div>
- <el-empty
- v-else
- style="width: 220px"
- class="p10"
- :image-size="100"
- description="暂无图片"
- />
- <div
- class="df aic jcsa mt10"
- style="width: 200px"
- v-if="item.auditStatus == 0"
- >
- <el-button
- @click="checkFireSafetyItem(item.id, 1)"
- class="ml10"
- size="small"
- type="primary"
- :disabled="!item.viewUrl"
- >
- 通过
- </el-button>
- <el-button
- @click="checkFireSafetyItem(item.id, 2)"
- size="small"
- type="danger"
- :disabled="!item.viewUrl"
- >
- 不通过
- </el-button>
- </div>
- <div v-else class="df aic jcsa mt10" style="width: 200px">
- <el-tag
- class="ml-2"
- :type="item.auditStatus == 1 ? 'success' : 'danger'"
- >
- {{ item.auditStatus == 1 ? "已通过" : "未通过" }}
- </el-tag>
- </div>
- </div>
- <div class="mt10 ml20" v-for="item1 in item.histories">
- <div v-if="item1.viewUrl">
- <el-image
- v-if="isImage(item1.fileKey)"
- style="width: 200px; height: 200px"
- :src="item1.viewUrl"
- :preview-src-list="[item1.viewUrl]"
- fit="cover"
- ></el-image>
- <div class="video-box" v-else>
- <img
- class="play-icon"
- style="width: 50px; height: 50px"
- src="../../assets/play.png"
- alt=""
- @click="showModal(item1)"
- />
- <video
- style="width: 200px; height: 200px"
- :src="item1.viewUrl"
- ></video>
- </div>
- </div>
- <el-empty
- v-else
- style="width: 220px"
- class="p10"
- :image-size="100"
- description="暂无图片"
- />
- <div class="df aic jcsa mt10" style="width: 200px">
- <el-tag
- class="ml-2"
- :type="item1.auditStatus == 1 ? 'success' : 'danger'"
- >
- {{ item1.auditStatus == 1 ? "已通过" : "未通过" }}
- </el-tag>
- </div>
- </div>
- </div>
- <el-divider />
- </div>
- <el-dialog
- v-model="isModalVisable"
- destroy-on-close
- title="视频查看"
- style="width: 400px"
- >
- <div class="video-mark-box">
- <video
- style="width: 100%; height: auto"
- autoplay
- controls
- :src="currentItem.downloadUrl"
- ></video>
- <div class="video-mark">
- <div class="mb10">{{ shipDetail.shipname }}</div>
- <div class="mb10">{{ currentItem.uploadTime }}</div>
- <div class="mb10">
- {{ currentItem.province }}·{{ currentItem.city }}·{{
- currentItem.district
- }}
- </div>
- <div class="mb10">
- {{ currentItem.week }} {{ currentItem.weather }}
- {{ currentItem.temperature }} ℃
- </div>
- <div class="mb10">真实 实时 精准</div>
- </div>
- </div>
- </el-dialog>
- <el-form
- ref="ruleFormRef"
- :model="ruleForm"
- :rules="rules"
- label-width="auto"
- class="demo-ruleForm"
- status-icon
- >
- <!-- <el-form-item label="Activity time">
- <el-col :span="11">
- <el-form-item prop="date1">
- <el-date-picker
- v-model="ruleForm.date1"
- type="date"
- label="Pick a date"
- placeholder="Pick a date"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col class="text-center" :span="2">
- <span class="text-gray-500">-</span>
- </el-col>
- <el-col :span="11">
- <el-form-item prop="date2">
- <el-time-picker
- v-model="ruleForm.date2"
- label="Pick a time"
- placeholder="Pick a time"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-form-item> -->
- <el-form-item label="问题整改" prop="problems">
- <el-input
- v-model="ruleForm.problems"
- type="textarea"
- :disabled="status == 1"
- />
- </el-form-item>
- <el-form-item label="整改意见" prop="rectificationOpinions">
- <el-input v-model="ruleForm.rectificationOpinions" type="textarea" />
- </el-form-item>
- <el-form-item>
- <div>
- <div class="df aic">
- <div class="mr10 item-title">安全检查员:</div>
- <div class="mr30">
- {{ fireInspectionInfo.promiseeShippingAccountNames }}
- </div>
- </div>
- <div class="df aic">
- <div class="mr10 item-title">承诺人:</div>
- <div class="mr30">
- {{ shipDetail.shipOwnerName }}
- {{
- fireInspectionInfo.promiseeShippingAccountNames
- ? `,${fireInspectionInfo.promiseeShippingAccountNames}`
- : ""
- }}
- </div>
- </div>
- <div class="df aic">
- <div class="mr10 item-title">承诺整改时间:</div>
- <div class="mr10 item-text">
- {{ fireInspectionInfo.rectificationTime || "即查即改" }}
- </div>
- </div>
- </div>
- <div class="df aic jcfe" style="width: 100%">
- <!-- <el-button @click="resetForm(ruleFormRef)">重置</el-button> -->
- <el-button
- type="primary"
- @click="saveFireSafetyCheckRectification(ruleFormRef)"
- >
- 保存整改意见
- </el-button>
- </div>
- </el-form-item>
- </el-form>
- <el-divider />
- </el-card>
- </template>
- <script setup>
- import { ref, h, reactive, toRefs, onMounted } from "vue";
- import { ElNotification, ElMessageBox, ElMessage } from "element-plus";
- import store from "../../store";
- import router from "../../router";
- import md5 from "md5";
- import api from "../../apis/fetch";
- import { useRoute } from "vue-router";
- import _ from "lodash";
- import { subTimeStr } from "../../utils/utils";
- import { Picture as IconPicture } from "@element-plus/icons-vue";
- const route = useRoute();
- let templateDetail = ref({
- items: [],
- });
- let shipDetail = ref({});
- const fireInspectionInfo = ref({});
- async function getFireSafetyCheckDetail(shipSecurityCheckId) {
- let { data } = await api.getFireSafetyCheckDetail({
- shipSecurityCheckId,
- });
- if (data.status == 0) {
- status.value = data.result.status;
- templateDetail.value = data.result;
- shipDetail.value = data.result.ship;
- coordinates.value = data.result.coordinates;
- fireInspectionInfo.value = data.result.fireInspectionInfo;
- ruleForm.value.problems = fireInspectionInfo.value.problems;
- ruleForm.value.rectificationOpinions =
- fireInspectionInfo.value.rectificationOpinions;
- }
- initMap();
- }
- async function checkFireSafetyItem(shipSecurityCheckItemId, auditStatus) {
- let shipSecurityCheckId = route.query.id;
- const loading = ElLoading.service({
- lock: true,
- text: "正在提交...",
- background: "rgba(0, 0, 0, 0.7)",
- });
- let { data } = await api.checkFireSafetyItem({
- shipSecurityCheckId,
- shipSecurityCheckItemId,
- auditStatus,
- });
- loading.close();
- if (data.status == 0) {
- ElNotification({
- title: "成功",
- message: data.msg,
- type: "success",
- duration: 1500,
- });
- getFireSafetyCheckDetail(shipSecurityCheckId);
- }
- }
- function isImage(url) {
- let imgArr = ["jpg", "jpeg", "png", "gif"];
- let lastIndex = url.lastIndexOf(".");
- return imgArr.indexOf(url.substring(lastIndex + 1, url.length)) != -1;
- }
- let isModalVisable = ref(false);
- let currentItem = ref({});
- function showModal(item) {
- currentItem.value = item;
- isModalVisable.value = true;
- }
- const weeks = ref([
- "星期一",
- "星期二",
- "星期三",
- "星期四",
- "星期五",
- "星期六",
- "星期日",
- ]);
- const checkUsers = ref([]);
- const checkedUsers = ref([]);
- async function getFireSafetyCheckUser() {
- let { data } = await api.getFireSafetyCheckUser({});
- checkUsers.value = data.result;
- }
- async function saveFireSafetyCheckUser() {
- if (checkedUsers.value.length === 0) {
- ElMessage({
- message: "请至少选择一名人员",
- type: "warning",
- });
- return;
- }
- let checkedUserIds = checkedUsers.value.map((item) => item.key);
- let checkedUserNames = checkedUsers.value.map((item) => item.value);
- const loading = ElLoading.service({
- lock: true,
- text: "正在保存...",
- background: "rgba(0, 0, 0, 0.7)",
- });
- let { data } = await api.saveFireSafetyCheckUser({
- shipSecurityCheckId: route.query.id,
- shippingAccountIds: checkedUserIds.join(","),
- shippingAccountNames: checkedUserNames.join(","),
- });
- loading.close();
- if (data.status == 0) {
- ElNotification({
- title: "成功",
- message: data.msg,
- type: "success",
- duration: 1500,
- });
- getFireSafetyCheckDetail(route.query.id);
- } else {
- ElNotification({
- title: "失败",
- message: data.msg,
- type: "error",
- duration: 1500,
- });
- }
- console.log(data);
- }
- let map = ref({});
- let mapId = ref(`map${route.query.id}`);
- const coordinates = ref([]);
- function initMap() {
- let c;
- let longitude = 121.524761;
- let latitude = 31.228721;
- // if (medias.value.length) {
- // c = Math.floor(medias.value.length / 2);
- // longitude = medias.value[c].longitude;
- // latitude = medias.value[c].latitude;
- // }
- map.value = new AMap.Map(mapId.value, {
- zoom: 16, //级别
- center: [longitude, latitude], //中心点坐标
- mapStyle: "amap://styles/f48d96805f5fa7f5aada657c5ee37017",
- zoomEnable: false,
- dragEnable: false,
- });
- let toolBar = new AMap.ToolBar({
- position: {
- top: "40px",
- right: "40px",
- },
- });
- let hawkEye = new AMap.HawkEye({
- opened: false,
- });
- map.value.addControl(toolBar);
- map.value.addControl(hawkEye);
- let markers = [];
- for (let i of coordinates.value) {
- let content = `<div style='width:160px'>
- <img src='https://frontend-1255802371.cos.ap-shanghai.myqcloud.com/green-circle.png' style='display:block;width:20px;height:20px;margin:6px auto'/
- </div>`;
- let marker = new AMap.Marker({
- content,
- zIndex: 5,
- position: new AMap.LngLat(i.longitude, i.latitude),
- offset: new AMap.Pixel(-75, i.audit == 1 ? -195 : -30),
- });
- markers.push(marker);
- }
- let overlayGroups = new AMap.OverlayGroup(markers);
- map.value.on("complete", function () {
- let t = setTimeout(() => {
- map.value.add(overlayGroups);
- map.value.setFitView(markers, true, [200, 50, 0, 0], 18);
- clearTimeout(t);
- }, 2000);
- });
- }
- const ruleFormRef = ref(null);
- const ruleForm = ref({
- problems: "",
- rectificationOpinions: "",
- });
- const rules = ref({
- problems: [
- {
- required: true,
- message: "请填写问题",
- trigger: "blur",
- },
- ],
- rectificationOpinions: [
- {
- required: true,
- message: "请填写整改意见",
- trigger: "blur",
- },
- ],
- });
- const saveFireSafetyCheckRectification = async (formEl) => {
- if (!formEl) return;
- formEl.validate(async (valid, fields) => {
- if (valid) {
- const loading = ElLoading.service({
- lock: true,
- text: "正在保存...",
- background: "rgba(0, 0, 0, 0.7)",
- });
- let { data } = await api.saveFireSafetyCheckRectification({
- ...ruleForm.value,
- shipSecurityCheckId: route.query.id,
- });
- loading.close();
- if (data.status == 0) {
- ElNotification.success({
- title: "成功",
- duration: 1500,
- message: data.msg,
- });
- } else {
- ElNotification.error({
- title: "失败",
- duration: 2000,
- message: data.msg,
- });
- }
- getFireSafetyCheckDetail(route.query.id);
- } else {
- console.log("error submit!", fields);
- }
- });
- };
- const resetForm = (formEl) => {
- if (!formEl) return;
- formEl.resetFields();
- };
- const status = ref(0);
- onMounted(() => {
- getFireSafetyCheckDetail(route.query.id);
- getFireSafetyCheckUser();
- });
- </script>
- <style scoped>
- .ship-label {
- width: 80px;
- color: #666;
- font-size: 14px;
- text-align: right;
- margin-right: 10px;
- }
- .ship-text {
- width: 100px;
- color: #333;
- font-size: 14px;
- }
- .item-title {
- width: 100px;
- }
- .item-text {
- width: 120px;
- }
- .video-box {
- position: relative;
- width: 200px;
- height: 200px;
- }
- .play-icon {
- position: absolute;
- z-index: 100;
- top: calc(50% - 25px);
- left: calc(50% - 25px);
- transition: all 0.5s;
- }
- .play-icon:hover {
- transform: scale(1.2);
- }
- .video-mark-box {
- position: relative;
- }
- .video-mark {
- position: absolute;
- bottom: 70px;
- left: 15px;
- font-size: 16px;
- font-weight: 700;
- z-index: 100;
- color: #fff;
- }
- .map-container {
- width: 100%;
- height: 500px;
- }
- </style>
|