123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747 |
- <template>
- <div class="container">
- <div v-if="!hideMap" id="aMap" class="event_map" />
- <div class="box">
- <div class="event_title">
- {{ eventInfo.event_title || "暂无事件标题" }}
- </div>
- <div class="event_prop">
- <div class="event_type">
- <dict-tag :options="mm_event_type" :value="eventInfo.event_type" />
- </div>
- <div class="event_level">
- <dict-tag
- :options="mm_event_level"
- :value="eventInfo.event_level || '0'"
- />
- </div>
- <div class="event_status">
- <dict-tag :options="mm_event_state" :value="eventInfo.event_status" />
- </div>
- </div>
- <van-tabs v-model:active="active">
- <van-tab title="基础信息">
- <div class="event_tab">
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon6" />
- <div class="event-data-item-title">事件编号:</div>
- </div>
- <div class="event-data-item-value">{{ eventInfo.event_id }}</div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon1" />
- <div class="event-data-item-title">事件类型:</div>
- </div>
- <div class="event-data-item-value">
- <dict-tag
- :options="mm_event_type"
- :value="eventInfo.event_type"
- />
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon2" />
- <div class="event-data-item-title">事件等级:</div>
- </div>
- <div class="event-data-item-value">
- <dict-tag
- :options="mm_event_level"
- :value="eventInfo.event_level || '0'"
- />
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon3" />
- <div class="event-data-item-title">事件状态:</div>
- </div>
- <div class="event-data-item-value">
- <dict-tag
- :options="mm_event_state"
- :value="eventInfo.event_status"
- />
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon5" />
- <div class="event-data-item-title">事发地点:</div>
- </div>
- <div class="event-data-item-value">{{ eventInfo.address }}</div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon4" />
- <div class="event-data-item-title">事发时间:</div>
- </div>
- <div class="event-data-item-value">
- {{ eventInfo.event_time }}
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon4" />
- <div class="event-data-item-title">上报时间:</div>
- </div>
- <div class="event-data-item-value">
- {{ eventInfo.report_time }}
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon7" />
- <div class="event-data-item-title">伤亡情况:</div>
- </div>
- <div
- class="event-data-item-value blue"
- @click="handleUploadCasualties"
- >
- 去上报
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon8" />
- <div class="event-data-item-title">登记人:</div>
- </div>
- <div class="event-data-item-value">
- {{ eventInfo.reported_by }}
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon4" />
- <div class="event-data-item-title">登记时间:</div>
- </div>
- <div class="event-data-item-value">
- {{ eventInfo.reported_time }}
- </div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon9" />
- <div class="event-data-item-title">联系方式:</div>
- </div>
- <div class="event-data-item-value">{{ eventInfo.contact }}</div>
- </div>
- <div class="event-data-item">
- <div class="item-left">
- <i class="icon10" />
- <div class="event-data-item-title">事件来源:</div>
- </div>
- <div class="event-data-item-value">
- {{ eventInfo.event_source }}
- </div>
- </div>
- </div>
- </van-tab>
- <van-tab title="事件概要">
- <div class="event_tab">{{ eventInfo.event_description }}</div>
- </van-tab>
- <van-tab title="事件跟踪">
- <div class="event_tab">
- <van-steps direction="vertical" :active="0">
- <van-step
- v-for="(item, index) in eventTrackState.items"
- :key="item.id"
- >
- <h3>{{ item.title }}</h3>
- <p>{{ item.description }}</p>
- </van-step>
- </van-steps>
- </div>
- </van-tab>
- <van-tab title="匹配预案">
- <div class="event_tab2">
- <template
- v-if="
- !!eventInfo.plan_id &&
- !!eventInfo.plan_files &&
- eventInfo.plan_files.length > 0
- "
- >
- <div class="plan-content">
- <div class="content-header">
- <div class="plan-content-title">
- {{ eventInfo.plan_files[0]?.name }}
- </div>
- <i
- class="download-icon"
- @click="handleDownload(eventInfo.plan_files[0])"
- />
- </div>
- <div class="content-text">
- <div v-for="(item, index) in planFiles" :key="index">
- <div>{{ item.title }}</div>
- <div v-for="(item2, index2) in item.items" :key="index2">
- <div>{{ item2.title }}</div>
- <div v-html="item2.value" />
- </div>
- </div>
- </div>
- </div>
- </template>
- <template v-else>
- <div class="emptyIcon" />
- <div class="emptyText">未关联到对应预案</div>
- <van-button
- type="primary"
- size="small"
- @click="associationShow = true"
- >手工关联</van-button
- >
- </template>
- </div>
- </van-tab>
- <van-tab title="总结报告">
- <div class="event_tab2">
- <div
- v-if="eventInfo.summary_file && eventInfo.summary_file.length > 0"
- class="file-list"
- >
- <div
- v-for="(item, index) in eventInfo.summary_file"
- :key="index"
- class="item"
- @click="handleDownload2(item)"
- >
- {{ item.file_name }}
- </div>
- </div>
- <template v-else>
- <div class="emptyIcon2" />
- <div class="emptyText">暂未上传总结报告</div>
- <van-button
- type="primary"
- size="small"
- @click="handleUploadCasualties"
- >去上传</van-button
- >
- </template>
- </div>
- </van-tab>
- </van-tabs>
- </div>
- <div class="footer">
- <div
- style="
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- "
- >
- <van-button
- v-if="eventInfo.event_status == '0'"
- type="primary"
- @click="handleStartEvent"
- >开始指挥</van-button
- >
- <van-button
- v-if="eventInfo.event_status == '1'"
- type="primary"
- @click="handleEnterEvent"
- >进入指挥</van-button
- >
- <van-button
- v-if="eventInfo.event_status == '0' || eventInfo.event_status == '2'"
- type="danger"
- @click="handleCloseEvent"
- >关闭事件
- </van-button>
- </div>
- </div>
- <AssociationPlan
- v-model="associationShow"
- :eventId="eventId"
- @confirm="associationPlanConfirm"
- />
- <UploadEventCasualtiesDialog
- v-model="uploadCasualtiesState.show"
- :data="uploadCasualtiesState.form"
- @update:model-value="onUploadCasualtiesDialogClose"
- @confirm="onUploadCasualtiesDialogClose"
- />
- <StartEventDialog
- v-model="startEventState.show"
- :data="startEventState.form"
- @update:model-value="onStartEventDialogClose"
- />
- </div>
- </template>
- <script lang="ts" setup>
- import { getCurrentInstance, reactive, ref, toRefs, onMounted } from "vue";
- import { useRouter, useRoute } from "vue-router";
- import { getEventDetail, closeEvent } from "@/api/event";
- import UploadEventCasualtiesDialog from "./UploadEventCasualtiesDialog.vue";
- import { showDialog, showConfirmDialog } from "vant";
- import { useAMap } from "@/hooks/AMap/useAMap";
- import StartEventDialog from "@/views/event/StartEventDialog.vue";
- import { download2 } from "@/utils/request";
- import { getPlanDoc, listPlan } from "@/api/duty/eventing";
- import AssociationPlan from "@/views/event/AssociationPlan.vue";
- const router = useRouter();
- const route = useRoute();
- const proxy = getCurrentInstance()?.proxy;
- const { mm_event_type, mm_event_level, mm_event_state } = toRefs<any>(
- proxy?.useDict("mm_event_type", "mm_event_level", "mm_event_state")
- );
- const active = ref(0);
- const eventId = ref("");
- const data = reactive({
- eventInfo: {
- event_id: "",
- event_title: "",
- event_code: "",
- event_type: "",
- event_level: "",
- event_status: "",
- address: "",
- event_time: "",
- report_time: "",
- contact: "",
- event_source: "",
- event_description: "",
- reported_by: "",
- reported_time: "",
- longitude: "",
- latitude: "",
- plan_id: "",
- plan_name: "",
- summary_file: [],
- plan_files: [],
- // 伤亡情况
- deaths: "",
- injuries: "",
- missing: ""
- },
- eventTrackState: {
- active: 0,
- items: [
- {
- id: 0,
- title: "事件登记",
- description: ""
- }
- ]
- }
- });
- const { eventInfo, eventTrackState } = toRefs(data);
- const startEventState = reactive({
- show: false,
- form: {
- event_id: "",
- event_title: "",
- event_level: "",
- event_level_text: ""
- }
- });
- const handleStartEvent = () => {
- startEventState.form.event_id = eventInfo.value.event_id;
- startEventState.form.event_title = eventInfo.value.event_title;
- startEventState.form.event_level = eventInfo.value.event_level;
- startEventState.show = true;
- return false;
- };
- const handleEnterEvent = () => {
- router.push({
- path: "/leader/mobile_control",
- query: {
- event_id: eventId.value
- }
- });
- };
- // 关闭事件
- const handleCloseEvent = () => {
- if (eventInfo.value.plan_id === "") {
- showDialog({ message: "关闭事件前请先匹配预案" });
- return false;
- }
- if (eventInfo.value.summary_file.length === 0) {
- showDialog({ message: "关闭事件前请先上传总结报告" });
- return false;
- }
- showConfirmDialog({
- title: "提示",
- message: "关闭事件所有事项相关数据将不能再修改,是否继续?"
- }).then(() => {
- closeEvent({ eventId: eventId.value }).then(res => {
- refreshData();
- });
- });
- };
- let associationShow = ref(false);
- // 上报伤亡情况
- const uploadCasualtiesState = reactive({
- show: false,
- form: {
- event_id: "",
- deaths: "",
- injuries: "",
- missing: ""
- }
- });
- const handleUploadCasualties = () => {
- console.log("handleUploadCasualties");
- uploadCasualtiesState.form.event_id = eventId.value;
- uploadCasualtiesState.form.deaths = eventInfo.value.deaths;
- uploadCasualtiesState.form.injuries = eventInfo.value.injuries;
- uploadCasualtiesState.form.missing = eventInfo.value.missing;
- uploadCasualtiesState.show = true;
- };
- const onUploadCasualtiesDialogClose = t => {
- console.log("onUploadCasualtiesDialogClose", t);
- uploadCasualtiesState.show = false;
- if (t) {
- refreshData();
- }
- };
- const onStartEventDialogClose = t => {
- startEventState.show = false;
- console.log(startEventState.form);
- if (t) {
- getEventDetail({ event_id: eventId.value }).then(res => {
- eventInfo.value = res.data;
- eventTrackState.value = res.data.event_status_tracks;
- });
- }
- };
- let planFiles = ref([]);
- const getPlan = () => {
- getPlanDoc({ plan_id: eventInfo.value.plan_id }).then(res => {
- planFiles.value = res.data;
- });
- };
- const associationPlanConfirm = plan_id => {
- associationShow.value = false;
- eventInfo.value.plan_id = plan_id;
- getPlan();
- };
- const baseUrl = import.meta.env.VITE_BASE_API;
- // 下载方法
- const handleDownload = (file: any) => {
- download2(baseUrl + "/file/download/" + file.url, file.name);
- };
- const handleDownload2 = (file: any) => {
- download2(baseUrl + "/file/download/" + file.url, file.file_name);
- };
- onMounted(() => {
- refreshData();
- });
- let hideMap = ref(false);
- let map;
- const refreshData = () => {
- eventId.value = route.query.event_id as string;
- getEventDetail({ event_id: eventId.value }).then(res => {
- eventInfo.value = res.data;
- eventTrackState.value = res.data.event_status_tracks;
- if (!!eventInfo.value.plan_id) {
- getPlan(eventInfo.value.plan_id);
- }
- if (!eventInfo.value.longitude || !eventInfo.value.latitude) {
- hideMap.value.vlaue = true;
- } else {
- // 初始化地图
- const lnglat = [eventInfo.value.longitude, eventInfo.value.latitude];
- const { getMap } = useAMap({
- key: "30d3d8448efd68cb0b284549fd41adcf",
- version: "2.0",
- zoom: 16,
- center: lnglat,
- dragEnable: true,
- scrollWheel: true,
- // 加载完成事件
- onLoadCompleted: AMap => {
- map = getMap();
- let marker = new AMap.Marker({
- position: lnglat,
- icon: new AMap.Icon({
- size: new AMap.Size(22, 28), //图标所处区域大小
- imageSize: new AMap.Size(22, 28), //图标大小
- image:
- "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png"
- }),
- anchor: "bottom-center",
- offset: new AMap.Pixel(0, 0)
- });
- marker.setMap(map);
- }
- });
- }
- });
- };
- </script>
- <style lang="scss" scoped>
- .event_map {
- width: 100%;
- height: 170px;
- }
- .box {
- margin: 0 16px 16px;
- background-color: #ffffff;
- border-radius: 4px;
- box-shadow: 0 0 4px 0 #4554661a;
- }
- .event_title {
- font-weight: 600;
- min-height: 46px;
- background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
- padding: 12px;
- }
- .event_prop {
- padding: 0 12px;
- line-height: 4.8vmin;
- display: flex;
- flex-direction: row;
- justify-content: start;
- color: #999;
- font-size: 12px;
- .event_type {
- padding: 3px 10px;
- border: 0.8px solid #2c81ff;
- border-radius: 2px;
- color: #2c81ff;
- margin-right: 7px;
- }
- .event_level {
- padding: 3px 10px;
- border: 0.8px solid #2c81ff;
- border-radius: 2px;
- margin-right: 7px;
- color: #2c81ff;
- }
- .event_status {
- padding: 3px 10px;
- border: 0.8px solid #2c81ff;
- border-radius: 2px;
- color: #2c81ff;
- }
- }
- .event_tab {
- padding: 16px;
- color: #a6000000;
- .event-data-item {
- font-size: 14px;
- line-height: 8vmin;
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: space-between;
- .item-left {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- .icon1 {
- width: 17px;
- height: 16px;
- background: url("@/assets/images/event/icon1.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon2 {
- width: 17px;
- height: 16px;
- background: url("@/assets/images/event/icon2.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon3 {
- width: 17px;
- height: 16px;
- background: url("@/assets/images/event/icon3.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon4 {
- width: 17px;
- height: 16px;
- background: url("@/assets/images/event/icon4.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon5 {
- width: 16px;
- height: 16px;
- background: url("@/assets/images/event/icon5.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon6 {
- width: 16px;
- height: 16px;
- background: url("@/assets/images/event/icon6.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon7 {
- width: 16px;
- height: 16px;
- background: url("@/assets/images/event/icon7.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon8 {
- width: 16px;
- height: 16px;
- background: url("@/assets/images/event/icon8.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon9 {
- width: 16px;
- height: 16px;
- background: url("@/assets/images/event/icon9.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- .icon10 {
- width: 16px;
- height: 16px;
- background: url("@/assets/images/event/icon10.png") no-repeat;
- background-size: 100% 100%;
- margin-right: 7px;
- }
- }
- .event-data-item-title {
- color: #888;
- min-width: 5em;
- }
- .event-data-item-value {
- color: #888;
- }
- .blue {
- color: #1989fa;
- }
- }
- h3 {
- font-size: 4.2vmin;
- line-height: 8vmin;
- }
- }
- .event_tab2 {
- padding: 16px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- color: rgba(0, 0, 0, 0.65);
- }
- .footer {
- padding: 0 16px 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- .van-button {
- border-radius: 2px;
- width: 94px;
- height: 40px;
- font-size: 14px;
- &:first-child {
- margin-right: 24px;
- }
- }
- }
- .emptyIcon {
- width: 110px;
- height: 108px;
- background: url("@/assets/images/unrelatedPlan.png") no-repeat;
- background-size: 100% 100%;
- }
- .emptyIcon2 {
- width: 111px;
- height: 110px;
- background: url("@/assets/images/noReport.png") no-repeat;
- background-size: 100% 100%;
- }
- .emptyText {
- font-size: 14px;
- margin: 6px;
- color: rgba(0, 0, 0, 0.65);
- }
- .plan-content {
- .content-header {
- display: flex;
- justify-content: center;
- align-items: center;
- font-size: 14px;
- color: #2c81ff;
- font-weight: bold;
- padding: 5px 0;
- .plan-content-title {
- text-align: center;
- }
- .download-icon {
- flex-shrink: 0;
- display: inline-block;
- width: 15px;
- height: 14px;
- background: url("@/assets/images/download.png") no-repeat;
- background-size: 100% 100%;
- margin-left: 20px;
- }
- }
- .content-text {
- font-size: 14px;
- color: rgba(0, 0, 0, 0.65);
- max-height: 500px;
- overflow-y: auto;
- }
- }
- :deep(.van-tabs__wrap) {
- border-bottom: 1px solid #f6f6f6;
- }
- .file-list {
- width: 100%;
- .item {
- width: 100%;
- padding: 5px 0;
- color: #2c81ff;
- }
- }
- </style>
|