Compare commits

...

4 Commits

@ -1,27 +1,88 @@
import request from '@/utils/request'
import request from "@/utils/request";
// 查询参数列表
export function getyjList(query) {
return request({
url: '/bYjgd/page',
method: 'get',
params: query
})
url: "/bYjgd/page",
method: "get",
params: query,
});
}
//新增
export function addyj(data) {
return request({
url: '/bYjgd/add',
method: 'post',
data
})
url: "/bYjgd/add",
method: "post",
data,
});
}
// 修改
export function updateyj(data) {
return request({
url: '/bYjgd/edit',
method: 'post',
url: "/bYjgd/edit",
method: "post",
data,
});
}
//删除
export function delyj(query) {
return request({
url: "/bYjgd/delete",
method: "DELETE",
params: query,
});
}
//详情
export function getyjById(id) {
return request({
url: `/bYjgd/${id}`,
method: "get",
});
}
//组织架构
export function getDetListById(query) {
return request({
url: "/dept/tree",
method: "get",
params: query,
});
}
//勘察录入
export function intruderyj(data) {
return request({
url: "/bYjgd/kclr",
method: "post",
data
})
}
});
}
//退单
export function retreatyj(data) {
return request({
url: "/bYjgd/td",
method: "post",
data
});
}
//派发
export function distributeyj(data) {
return request({
url: "/bYjgd/distribution",
method: "post",
data
});
}
//处理反馈
export function feedBackyj(data) {
return request({
url: "/bYjgd/clfk",
method: "post",
data
});
}

@ -138,8 +138,9 @@
}
.dialog-data{
padding: 10px 10px 0 10px;
min-height: 200px;
min-height: 100px;
max-height: 800px;
overflow-y: auto;
}
.dialog-footer{
display: flex;

@ -16,7 +16,7 @@
:index="index"
:type="item.elTagType"
:class="item.elTagClass"
>{{ item.label + " " }}{{item.elTagType}}</el-tag>
>{{ item.label + " " }}</el-tag>
</template>
</template>
<template v-if="unmatch && showValue">
@ -80,4 +80,11 @@ function handleArray(array) {
.el-tag + .el-tag {
margin-left: 10px;
}
.el-tag {
font-size: 14px;
/* color: #FFFFFF; */
padding:0 12px;
font-weight: 500;
}
</style>

@ -32,6 +32,7 @@
<slot name="pagination"></slot>
</div>
</div>
<slot></slot>
</div>
</template>

@ -11,6 +11,7 @@ const useUserStore = defineStore(
id: '',
name: '',
avatar: '',
deptId:'',
roles: [],
permissions: []
}),
@ -47,6 +48,7 @@ const useUserStore = defineStore(
this.roles = ['ROLE_DEFAULT']
}
this.id = user.userId
this.deptId = user.deptId
this.name = user.userName
this.avatar = avatar
resolve(res)

@ -1 +0,0 @@
export { default as operation } from './operation.vue'

@ -1,158 +0,0 @@
<template>
<!-- 加根元素防止控制台报错 -->
<section style="height: 100%">
<tablePage @handlerAdd="handlerAdd()" @handlerExport="handlerExport()">
<template #search>
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px" class="search-form">
<el-form-item label="工单地址" prop="gdms">
<el-input v-model="queryParams.gdms" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="工单类型" prop="gdType">
<el-input v-model="queryParams.gdType" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="工单等级" prop="gdLevel">
<el-input v-model="queryParams.gdLevel" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="工单状态" prop="status">
<el-input v-model="queryParams.status" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="录入时间" prop="userName">
<el-input v-model="queryParams.userName" placeholder="请输入" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
</template>
<template #table>
<el-table v-loading="loading" :data="list" height="100%" :header-cell-style="proxy.getTableHeaderStyle"
:cell-style="proxy.getTablerowStyle">
<!-- <el-table-column type="selection" width="50" align="center" /> -->
<el-table-column label="工单地址" align="center" key="address" prop="address" />
<el-table-column label="工单类型" align="center" key="gdType" prop="gdType">
<template #default="scope">
<dict-tag :options="gdlx" :value="scope.row.gdType" />
</template>
</el-table-column>
<el-table-column label="工单等级" align="center" key="gdLevel" prop="gdLevel" />
<el-table-column label="录入时间" align="center" key="createTime" prop="createTime" />
<el-table-column label="工单状态" align="center" key="status" prop="status">
<template #default="scope">
<dict-tag :options="gd_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="400" class-name="small-padding fixed-width ">
<template #default="scope">
<div class="table-operation-row">
<section v-show="scope.row.status == 0">
<el-button link type="primary" icon="FolderAdd">勘察录入</el-button>
<el-button link type="primary" icon="FolderRemove">退单</el-button>
</section>
<section v-show="scope.row.status == 1">
<el-button link type="primary" icon="User">派发</el-button>
<el-button link type="primary" icon="Edit">编辑</el-button>
</section>
<section v-show="scope.row.status == 4">
<el-button link type="primary" icon="ChatRound">处理反馈</el-button>
<el-button link type="primary" icon="Bell">消息催办</el-button>
<el-button link type="primary" icon="Switch">转派</el-button>
</section>
<section>
<el-button link type="primary" icon="View">查看</el-button>
<el-button link type="primary" icon="Delete"
v-show="scope.row.status != 0 && scope.row.status != 3">删除</el-button>
</section>
</div>
</template>
</el-table-column>
</el-table>
</template>
<template #pagination>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.current"
v-model:limit="queryParams.size" @pagination="getList" />
</template>
</tablePage>
<!-- 工单 -->
<operation v-model="open" :title="title" @confirm="getList()"></operation>
</section>
</template>
<script setup>
import { operation } from "./index";
import { getyjList } from "@/api/emergency-rescue";
import { onMounted } from "vue";
const { proxy } = getCurrentInstance();
const { gdlx, gd_status } = proxy.useDict("gdlx", "gd_status");
const loading = ref(false);
const list = ref([]);
const open = ref(false);
const title = ref("");
const total = ref(0);
const router = useRouter();
const data = reactive({
form: {},
queryParams: {
gdms: undefined,
gdType: undefined,
gdLevel: undefined,
status: undefined,
current: 1,
size: 10,
},
rules: {},
});
const { queryParams, form, rules } = toRefs(data);
onMounted(() => {
getList();
});
/**
* 获取列表数据
*/
const getList = async () => {
loading.value = true;
const res = await getyjList(queryParams.value);
loading.value = false;
list.value = res.data.records;
total.value = res.data.total;
};
/**
* 搜索
*/
const handleQuery = () => {
queryParams.value.pageNum = 1;
};
/**
* 重置查询条件
*/
const resetQuery = () => {
proxy.resetForm("queryRef");
handleQuery();
};
/**
* 新增
*/
const handlerAdd = () => {
open.value = true;
title.value = "抢险工单录入";
};
/**
* 导出
*/
const handlerExport = () => { };
const handlerInfo = () => {
proxy.setActiveMenu();
router.push({ path: "/emergency-rescue/workInfo-info" });
};
</script>
<style lang="scss" scoped></style>

@ -1,321 +0,0 @@
<template>
<el-dialog
:title="title"
v-model="visible"
width="35%"
class="x-dialog"
destroy-on-close
>
<el-form class="dialog-data" :model="form" ref="formRef" label-width="78px">
<el-form-item label="工单地址:" prop="address">
<div class="map">
<MarsMap
:url="configUrl"
:options="getMapOptions"
map-key="workOrder"
@onload="marsOnload"
/>
</div>
<el-input
v-model="form.address"
placeholder="请输入"
clearable
@keyup.enter="handleSearch"
>
<template #prepend>
<el-button icon="MapLocation" />
</template>
</el-input>
<div class="serch-list" v-show="gaodePOIList.length > 0">
<div
clss="list-item"
:class="currentId === item.id ? 'activeitem' : ''"
v-for="item in gaodePOIList"
:key="item.id"
@click="handleCograph(item)"
>
{{ item.name }}
</div>
</div>
</el-form-item>
<el-form-item label="工单类型:" prop="gdType">
<el-radio-group v-model="form.gdType">
<el-radio :value="dict.value" v-for="dict in gdlx">{{
dict.label
}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="简要描述:" prop="gdms">
<el-select v-model="form.gdms" placeholder="请选择" clearable>
<el-option
v-for="dict in gdms"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="选派人员:" prop="pqrs">
<el-cascader
v-model="form.pqrs"
:options="deptList"
:props="cascaderProps"
@expand-change="handleChange"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="visible = false" icon="CloseBold">取消</el-button>
<el-button type="primary" icon="Select" @click="confirm()"
>确定</el-button
>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { addyj, updateyj } from "@/api/emergency-rescue";
import MarsMap from "@/components/mars-work/mars-map.vue";
import mapOptions from "@/components/mars-work/mapOptions";
import markerIcon from "@/assets/images/map-marker.png";
import { gaodeAddress, gaodePOI } from "@/utils/common.js";
import { deptTreeSelect } from "@/api/system/user";
import { onMounted } from "vue";
const { proxy } = getCurrentInstance();
const { gdlx, gdms } = proxy.useDict("gdlx", "gdms");
const deptList = ref([]);
const gaodePOIList = ref([]);
const currentId = ref(0);
const cascaderProps = {
value: "id",
};
const props = defineProps({
title: {
type: String,
default: "",
},
modelValue: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:modelValue", "confirm"]);
//
const configUrl = "lib/config/config.json";
let mapData = null;
let mapLayer = {};
let entity = null;
const data = reactive({
form: {
id: null,
address: undefined, //
clbz: undefined, //
clfa: undefined, //
clhtp: undefined, //
clms: undefined, //
createBy: undefined, //
createId: undefined, //id
createTime: undefined, //
deptId: undefined, //id
dflx: undefined, //
gdLevel: undefined, //
gdType: undefined, //
gdms: undefined, //
gdtp: undefined, //
lat: undefined, //
lon: undefined, //
pqcl: undefined, //
pqrs: undefined, //
reason: undefined, //退
status: undefined, // 0:1:,2:退.3:,4:
zyxt: undefined, //
},
rules: {},
});
const { queryParams, form, rules } = toRefs(data);
const visible = ref(props.modelValue);
// modelValue
watch(
() => props.modelValue,
(val) => {
visible.value = val;
}
);
watch(visible, (val) => {
emit("update:modelValue", val);
});
onMounted(() => {
getDeptTree();
});
/**
* 提交
*/
const confirm = () => {
proxy.$refs["formRef"].validate(async (valid) => {
if (valid) {
if (form.value.id) {
} else {
await addyj(form.value);
proxy.$modal.msgSuccess("新增成功");
}
emit("confirm");
visible.value = false;
}
});
};
/**
* 地址搜索
*/
const handleSearch = async () => {
if (!form.value.address) {
proxy.$modal.msgWarning("请输入关键字");
return;
}
const res = await gaodePOI(form.value.address);
gaodePOIList.value = res;
};
/**
* 结果上图
* @param item
*/
const handleCograph = (item) => {
if (currentId.value != item.id) {
const point = item.location.split(",");
handleMapClick(parseFloat(point[0]), parseFloat(point[1]));
mapData.flyToGraphic(mapLayer.marker, { radius: 300 });
currentId.value = item.id;
form.value.address = item.name;
}
};
/**
* 级联变化
*/
const handleChange = (value) => {};
const getDeptTree = async () => {
const res = await deptTreeSelect();
deptList.value = res.data;
console.log(deptList.value);
};
/**
* 获取系统组织架构
*/
/**
* 获取地图配置
*/
const getMapOptions = computed(() => {
mapOptions.scene.sceneMode = 2;
mapOptions.basemaps[0] = {
pid: 10,
name: "高德电子",
type: "gaode",
icon: "//data.mars3d.cn/img/thumbnail/basemap/gaode_vec.png",
layer: "vec",
show: true,
};
return mapOptions;
});
/**
* 地图初始化成功
* @param map
*/
const marsOnload = (map) => {
mapData = map;
mapLayer.marker = new mars3d.layer.GraphicLayer({
allowDrillPick: true,
});
mapData.addLayer(mapLayer.marker);
map.on(mars3d.EventType.click, async ({ cartesian }) => {
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
const res = await gaodeAddress(`${longitude},${latitude}`);
form.value.address = res.formatted_address;
handleMapClick(longitude, latitude);
});
if (form.value.longitude && form.value.latitude) {
handleMapClick(form.value.longitude, form.value.latitude);
map.flyToGraphic(mapLayer.marker, { radius: 300 });
}
};
/**
* @description: 处理地图点击
* @private
* @param {number} longitude 经度
* @param {number} latitude 纬度
* @returns
*/
const handleMapClick = (longitude, latitude) => {
if (entity) {
entity.position = [longitude, latitude];
} else {
entity = new mars3d.graphic.BillboardEntity({
position: [longitude, latitude],
style: {
image: markerIcon,
width: 35,
height: 36,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
});
mapLayer.marker?.addGraphic(entity);
}
form.value.lat = longitude; //
form.value.lon = latitude; //
};
onUnmounted(() => {
if (mapData) {
mapData.destroy();
mapData = null;
}
mapLayer.marker?.clear();
mapLayer = null;
entity = null;
});
</script>
<style lang="scss" scoped>
.map {
height: 400px;
width: 100%;
border: 1px solid #ccc;
margin-bottom: 15px;
}
.map-gps {
height: 25px;
width: 25px;
}
.serch-list {
width: 100%;
min-height: 50px;
max-height: 250px;
overflow-y: auto;
border: 1px solid #ccc;
& > div {
cursor: pointer;
padding: 3px 10px;
font-size: 14px;
}
& > div:hover,
.activeitem {
background-color: #4776eb;
color: white;
font-weight: bold;
}
}
</style>

@ -0,0 +1,112 @@
<template>
<el-dialog
:title="title"
v-model="visible"
width="25%"
class="x-dialog"
:destroy-on-close="true"
>
<el-form
class="dialog-data"
:model="form"
:rules="rules"
ref="formRef"
label-width="88px"
>
<el-form-item label="退单原因:" prop="reason">
<el-select v-model="form.reason" placeholder="请选择" clearable>
<el-option
v-for="dict in dictReason"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handlerClose()" icon="CloseBold">取消</el-button>
<el-button type="primary" icon="Select" @click="confirm()"
>确定</el-button
>
</div>
</template>
</el-dialog>
</template>
<script setup>
const { proxy } = getCurrentInstance();
import { retreatyj } from "@/api/emergency-rescue";
const props = defineProps({
title: {
type: String,
default: "工单退单",
},
dictReason: {
type: Array,
default: () => [],
},
id: {
type: Number,
},
modelValue: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:modelValue", "confirm"]);
const data = reactive({
form: {
reason: undefined,
},
rules: {
reason: [{ required: true, message: "请选择退单原因", trigger: "blur" }],
},
});
const { form, rules } = toRefs(data);
const visible = ref(props.modelValue);
const handlerClose = () => {
visible.value = false;
proxy.resetForm("formRef");
};
const confirm = () => {
proxy.$refs["formRef"].validate(async (valid) => {
if (valid) {
await retreatyj({
id: props.id,
reason:form.value.reason,
});
proxy.$modal.msgSuccess("退单成功");
emit("confirm");
handlerClose();
}
});
};
// modelValue
watch(
() => props.modelValue,
(val) => {
visible.value = val;
}
);
watch(visible, (val) => {
emit("update:modelValue", val);
});
</script>
<style scoped>
.dialog-data {
width: 100%;
display: flex;
align-items: center;
& > div {
width: 100%;
}
}
</style>

@ -0,0 +1,114 @@
<template>
<el-dialog
:title="title"
v-model="visible"
width="25%"
class="x-dialog"
:destroy-on-close="true"
>
<el-form
class="dialog-data"
:model="form"
:rules="rules"
ref="formRef"
label-width="88px"
>
<el-form-item label="选择班组:" prop="deptId">
<el-cascader
v-model="form.deptId"
:options="deptList"
:props="cascaderProps"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handlerClose()" icon="CloseBold">取消</el-button>
<el-button type="primary" icon="Select" @click="confirm()"
>确定</el-button
>
</div>
</template>
</el-dialog>
</template>
<script setup>
const { proxy } = getCurrentInstance();
import { distributeyj } from "@/api/emergency-rescue";
const props = defineProps({
title: {
type: String,
default: "",
},
deptList: {
type: Array,
default: () => [],
},
id: {
type: Number,
},
modelValue: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:modelValue", "confirm"]);
const cascaderProps = {
value: "deptId",
label: "deptName",
};
const data = reactive({
form: {
deptId: [],
},
rules: {
deptId: [{ required: true, message: "请选择办组人员", trigger: "blur" }],
},
});
const { form, rules } = toRefs(data);
const visible = ref(props.modelValue);
const handlerClose = () => {
visible.value = false;
proxy.resetForm("formRef");
};
const confirm = () => {
proxy.$refs["formRef"].validate(async (valid) => {
if (valid) {
const deptId = form.value.deptId[form.value.deptId.length - 1];
await distributeyj({
id: props.id,
deptId: deptId,
});
proxy.$modal.msgSuccess(`${title}成功`);
emit("confirm");
handlerClose();
}
});
};
// modelValue
watch(
() => props.modelValue,
(val) => {
visible.value = val;
}
);
watch(visible, (val) => {
emit("update:modelValue", val);
});
</script>
<style scoped>
.dialog-data {
width: 100%;
display: flex;
align-items: center;
& > div {
width: 100%;
}
}
</style>

@ -0,0 +1,103 @@
<template>
<el-dialog
:title="title"
v-model="visible"
width="25%"
class="x-dialog"
:destroy-on-close="true"
>
<el-form
class="dialog-data"
:model="form"
:rules="rules"
ref="formRef"
label-width="100px"
>
<el-form-item label="处理描述:" prop="clms">
<el-input
v-model="form.clms"
:rows="2"
type="textarea"
placeholder="请填写"
/>
</el-form-item>
<el-form-item label="处理后照片:" prop="clhtp">
<ImageUpload v-model="form.clhtp"></ImageUpload>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handlerClose()" icon="CloseBold">取消</el-button>
<el-button type="primary" icon="Select" @click="confirm()"
>确定</el-button
>
</div>
</template>
</el-dialog>
</template>
<script setup>
const { proxy } = getCurrentInstance();
import { feedBackyj } from "@/api/emergency-rescue";
const props = defineProps({
title: {
type: String,
default: "工单处理反馈",
},
id: {
type: Number,
},
modelValue: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:modelValue", "confirm"]);
const data = reactive({
form: {
id: null,
clhtp: undefined,
clms: undefined,
},
rules: {
clhtp: [{ required: true, message: "请上传处理后图片", trigger: "blur" }],
clms: [{ required: true, message: "请填写处理描述", trigger: "blur" }],
},
});
const { form, rules } = toRefs(data);
const visible = ref(props.modelValue);
const handlerClose = () => {
visible.value = false;
proxy.resetForm("formRef");
};
const confirm = () => {
proxy.$refs["formRef"].validate(async (valid) => {
if (valid) {
form.value.id = props.id;
await feedBackyj(form.value);
proxy.$modal.msgSuccess(`反馈成功`);
emit("confirm");
handlerClose();
}
});
};
// modelValue
watch(
() => props.modelValue,
(val) => {
visible.value = val;
}
);
watch(visible, (val) => {
emit("update:modelValue", val);
});
</script>
<style scoped>
</style>

@ -0,0 +1,475 @@
<template>
<el-dialog
:title="title"
v-model="visible"
width="35%"
class="x-dialog"
:destroy-on-close="true"
append-to-body
@closed="handlerClose()"
>
<el-form
class="dialog-data"
:model="form"
:rules="rules"
ref="formRef"
label-width="88px"
>
<el-form-item label="工单地址:" prop="address">
<div class="map">
<MarsMap
:url="configUrl"
:options="getMapOptions"
map-key="workOrder"
@onload="marsOnload"
/>
</div>
<el-input
v-model="form.address"
placeholder="请输入"
clearable
@keyup.enter="handleSearch"
>
<template #prepend>
<el-button icon="MapLocation" />
</template>
</el-input>
<div class="serch-list" v-show="gaodePOIList.length > 0">
<div
clss="list-item"
:class="currentId === item.id ? 'activeitem' : ''"
v-for="item in gaodePOIList"
:key="item.id"
@click="handleCograph(item)"
>
{{ item.name }}
</div>
</div>
</el-form-item>
<el-form-item label="工单类型:" prop="gdType">
<el-radio-group v-model="form.gdType" @change="changeType()">
<el-radio :value="parseInt(dict.value)" v-for="dict in dict.gdlx">{{
dict.label
}}</el-radio>
</el-radio-group>
</el-form-item>
<section v-if="id">
<el-form-item label="倒伏类型:" prop="dflx" v-if="form.gdType == 0">
<el-checkbox-group v-model="form.dflx">
<el-checkbox
v-for="dict in dict.dflx"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-checkbox-group>
</el-form-item>
<el-form-item label="工单照片:" prop="gdtp">
<ImageUpload v-model="form.gdtp"></ImageUpload>
</el-form-item>
<el-form-item label="工单等级:" prop="gdLevel">
<el-radio-group v-model="form.gdLevel">
<el-radio
:value="parseInt(dict.value)"
v-for="dict in dict.gdlevel"
>{{ dict.label }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="处置方案:" prop="clfa">
<el-select v-model="form.clfa" placeholder="请选择" clearable>
<el-option
v-for="dict in dict.clfa"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="派遣人数:" prop="pqrs">
<el-input v-model="form.pqrs" placeholder="请输入" clearable>
<template #suffix>
<span></span>
</template>
</el-input>
</el-form-item>
<el-form-item label="派遣车辆:" prop="pqcl">
<el-input v-model="form.pqcl" placeholder="请输入" clearable>
<template #suffix>
<span></span>
</template>
</el-input>
</el-form-item>
<el-form-item label="资源协调:" prop="zyxt">
<el-checkbox-group v-model="form.zyxt">
<el-checkbox
v-for="dict in dict.zyxt"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-checkbox-group>
</el-form-item>
</section>
<section v-else>
<el-form-item label="简要描述:" prop="gdms">
<el-select v-model="form.gdms" placeholder="请选择" clearable>
<el-option
v-for="dict in dict.gdms"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
<el-form-item label="选派人员:" prop="zzjg">
<el-cascader
v-model="form.zzjg"
:options="dict.deptList"
:props="cascaderProps"
@change="handleChange"
/>
</el-form-item>
</section>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handlerClose()" icon="CloseBold">取消</el-button>
<el-button type="primary" icon="Select" @click="confirm()"
>确定</el-button
>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { addyj, updateyj, intruderyj, getyjById } from "@/api/emergency-rescue";
import MarsMap from "@/components/mars-work/mars-map.vue";
import mapOptions from "@/components/mars-work/mapOptions";
import markerIcon from "@/assets/images/map-marker.png";
import { gaodeAddress, gaodePOI } from "@/utils/common.js";
const { proxy } = getCurrentInstance();
const gaodePOIList = ref([]);
const currentId = ref(0);
const cascaderProps = {
value: "deptId",
label: "deptName",
};
const props = defineProps({
title: {
type: String,
default: "",
},
dict: {
type: Object,
default: {
gdlx: [],
dflx: [],
gdlevel: [],
clfa: [],
zyxt: [],
gdms: [],
deptList: [],
},
},
id: {
type: Number,
},
modelValue: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:modelValue", "confirm"]);
//
const configUrl = "lib/config/config.json";
let mapData = null;
let mapLayer = {};
let entity = null;
const data = reactive({
form: {
id: null,
address: undefined, //
clbz: undefined, //
clfa: undefined, //
clhtp: undefined, //
clms: undefined, //
createBy: undefined, //
createId: undefined, //id
createTime: undefined, //
deptId: undefined, //id
dflx: [], //
gdLevel: undefined, //
gdType: undefined, //
gdms: undefined, //
gdtp: undefined, //
lat: undefined, //
lon: undefined, //
pqcl: undefined, //
pqrs: undefined, //
reason: undefined, //退
status: undefined, // 0:1:,2:退.3:,4:
zyxt: [], //
zzjg: [],
},
rules: {
address: [{ required: true, message: "请填写工单地址", trigger: "blur" }],
gdType: [{ required: true, message: "请选择工单类型", trigger: "blur" }],
gdms: [{ required: true, message: "请选择简要描述", trigger: "blur" }],
zzjg: [{ required: true, message: "请选择选派人员", trigger: "blur" }],
dflx: [{ required: true, message: "请选择倒伏类型", trigger: "blur" }],
gdtp: [{ required: true, message: "请上传工单照片", trigger: "blur" }],
gdLevel: [{ required: true, message: "请选择工单等级", trigger: "blur" }],
clfa: [{ required: true, message: "请选择处置方案", trigger: "blur" }],
pqrs: [{ required: true, message: "请填写派遣人数", trigger: "blur" }],
pqcl: [{ required: true, message: "请填写派遣车辆", trigger: "blur" }],
zyxt: [{ required: true, message: "请选择资源协调", trigger: "blur" }],
},
});
const { form, rules } = toRefs(data);
const visible = ref(props.modelValue);
// modelValue
watch(
() => props.modelValue,
(val) => {
visible.value = val;
}
);
watch(visible, (val) => {
emit("update:modelValue", val);
});
const changeType = () => {
form.value.dflx = [];
};
/**
* 提交
*/
const confirm = () => {
proxy.$refs["formRef"].validate(async (valid) => {
if (valid) {
form.value.zzjg = filterArray(form.value.zzjg, "join");
form.value.dflx = filterArray(form.value.dflx, "join");
form.value.zyxt = filterArray(form.value.zyxt, "join");
if (form.value.id) {
if (form.value.status === 0) {
await intruderyj(form.value);
proxy.$modal.msgSuccess(`${props.title}成功`);
}
if(form.value.status === 1){
await updateyj(form.value)
proxy.$modal.msgSuccess(`编辑成功`);
}
} else {
await addyj(form.value);
proxy.$modal.msgSuccess("新增成功");
}
try {
emit("confirm");
handlerClose();
} catch {
form.value.zzjg = form.value.zzjg.split(",");
}
}
});
};
/**
* 获取详情
*/
const getInfo = async (val) => {
if (!props.id || !visible.value) return;
console.log(props.id, visible.value);
const res = await getyjById(props.id);
res.data.zzjg = res.data.zzjg.split(",").map((item) => parseInt(item));
res.data.zyxt = filterArray(res.data.zyxt);
res.data.dflx = filterArray(res.data.dflx);
form.value = res.data;
if (form.value.lat && form.value.lon && mapData) {
nextTick(() => {
handleMapClick(form.value.lat, form.value.lon);
mapData.flyToGraphic(mapLayer.marker, { radius: 300 });
});
}
};
const filterArray = (data, type) => {
if (!type) {
if (data) {
return data.split(",");
} else {
return [];
}
} else {
if (data) {
return data.join();
} else {
return "";
}
}
};
/**
*
*/
const handlerClose = () => {
visible.value = false;
proxy.resetForm("formRef");
gaodePOIList.value = [];
if (mapData) {
mapData.destroy();
mapData = null;
mapLayer.marker?.clear();
entity = null;
}
};
/**
* 地址搜索
*/
const handleSearch = async () => {
if (!form.value.address) {
proxy.$modal.msgWarning("请输入关键字");
return;
}
const res = await gaodePOI(form.value.address);
gaodePOIList.value = res;
};
/**
* 结果上图
* @param item
*/
const handleCograph = (item) => {
if (currentId.value != item.id) {
const point = item.location.split(",");
handleMapClick(parseFloat(point[0]), parseFloat(point[1]));
mapData.flyToGraphic(mapLayer.marker, { radius: 300 });
currentId.value = item.id;
form.value.address = item.name;
}
};
/**
* 级联取人员deptID
*/
const handleChange = (value) => {
form.value.deptId = value[value.length - 1];
};
/**
* 获取地图配置
*/
const getMapOptions = computed(() => {
mapOptions.scene.sceneMode = 2;
mapOptions.basemaps[0] = {
pid: 10,
name: "高德电子",
type: "gaode",
icon: "//data.mars3d.cn/img/thumbnail/basemap/gaode_vec.png",
layer: "vec",
show: true,
};
return mapOptions;
});
/**
* 地图初始化成功
* @param map
*/
const marsOnload = (map) => {
mapData = map;
mapLayer.marker = new mars3d.layer.GraphicLayer({
allowDrillPick: true,
});
mapData.addLayer(mapLayer.marker);
map.on(mars3d.EventType.click, async ({ cartesian }) => {
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
const res = await gaodeAddress(`${longitude},${latitude}`);
form.value.address = res.formatted_address;
handleMapClick(longitude, latitude);
});
getInfo();
};
/**
* @description: 处理地图点击
* @private
* @param {number} longitude 经度
* @param {number} latitude 纬度
* @returns
*/
const handleMapClick = (longitude, latitude) => {
if (!isPositiveDecimal(longitude)) longitude = parseFloat(longitude);
if (!isPositiveDecimal(latitude)) latitude = parseFloat(latitude);
console.log(entity, "sss");
if (entity) {
entity.position = [longitude, latitude];
} else {
entity = new mars3d.graphic.BillboardEntity({
position: [longitude, latitude],
style: {
image: markerIcon,
width: 35,
height: 36,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
});
mapLayer.marker?.addGraphic(entity);
}
form.value.lat = longitude; //
form.value.lon = latitude; //
};
const isPositiveDecimal = (num) => {
return typeof num === "number" && num >= 0 && !Number.isInteger(num);
};
</script>
<style lang="scss" scoped>
.map {
height: 400px;
width: 100%;
border: 1px solid #ccc;
margin-bottom: 15px;
}
.map-gps {
height: 25px;
width: 25px;
}
.serch-list {
width: 100%;
min-height: 50px;
max-height: 250px;
overflow-y: auto;
border: 1px solid #ccc;
& > div {
cursor: pointer;
padding: 3px 10px;
font-size: 14px;
}
& > div:hover,
.activeitem {
background-color: #4776eb;
color: white;
font-weight: bold;
}
}
</style>

@ -0,0 +1,4 @@
export { default as operation } from './components/operation.vue'
export { default as chargeBack } from './components/chargeBack.vue'
export { default as distriBute } from './components/distriBute.vue'
export { default as feedBack } from './components/feedBack.vue'

@ -0,0 +1,429 @@
<template>
<tablePage @handlerAdd="handlerAdd()" @handlerExport="handlerExport()">
<template #search>
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
label-width="68px"
class="search-form"
>
<el-form-item label="工单地址" prop="address">
<el-input
v-model="queryParams.address"
placeholder="请输入"
clearable
/>
</el-form-item>
<el-form-item label="工单类型" prop="gdType">
<el-select
v-model="queryParams.gdType"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in gdlx"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="工单等级" prop="gdLevel">
<el-select
v-model="queryParams.gdLevel"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in gdlevel"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="工单状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in gd_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="录入时间" prop="userName">
<el-date-picker
type="datetimerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY/MM/DD ddd"
time-format="A hh:mm:ss"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
</template>
<template #table>
<el-table
v-loading="loading"
:data="list"
height="100%"
:header-cell-style="proxy.getTableHeaderStyle"
:cell-style="proxy.getTablerowStyle"
>
<!-- <el-table-column type="selection" width="50" align="center" /> -->
<el-table-column
label="工单地址"
align="center"
key="address"
prop="address"
/>
<el-table-column
label="工单类型"
align="center"
key="gdType"
prop="gdType"
>
<template #default="scope">
<dict-tag :options="gdlx" :value="scope.row.gdType" />
</template>
</el-table-column>
<el-table-column
label="工单等级"
align="center"
key="gdLevel"
prop="gdLevel"
>
<template #default="scope">
<dict-tag :options="gdlevel" :value="scope.row.gdLevel" />
</template>
</el-table-column>
<el-table-column
label="录入时间"
align="center"
key="createTime"
prop="createTime"
>
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="工单状态"
align="center"
key="status"
prop="status"
>
<template #default="scope">
<dict-tag :options="gd_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="400"
class-name="small-padding fixed-width "
>
<template #default="scope">
<div class="table-operation-row">
<section v-show="scope.row.status == 0">
<el-button
link
type="primary"
icon="FolderAdd"
@click="handlerEdit(scope.row, 1)"
>勘察录入</el-button
>
<el-button
link
type="primary"
icon="FolderRemove"
@click="handlerRetreat(scope.row)"
>退单</el-button
>
</section>
<section v-show="scope.row.status == 1">
<el-button
link
type="primary"
icon="User"
@click="handlerDistriBute(scope.row, '派发')"
>派发</el-button
>
<el-button
link
type="primary"
icon="Edit"
@click="handlerEdit(scope.row)"
>编辑</el-button
>
</section>
<section v-show="scope.row.status == 3">
<el-button
link
type="primary"
icon="Switch"
@click="handlerDistriBute(scope.row, '转派')"
>转派</el-button
>
<el-button
link
type="primary"
icon="ChatRound"
@click="handleFeedBack(scope.row)"
>处理反馈</el-button
>
<el-button link type="primary" icon="Bell">消息催办</el-button>
</section>
<section>
<el-button
link
type="primary"
icon="View"
@click="handlerInfo(scope.row)"
>查看</el-button
>
<el-button
link
type="primary"
icon="Delete"
v-show="scope.row.status != 0 && scope.row.status != 3"
@click="handlerDel(scope.row.id)"
>删除</el-button
>
</section>
</div>
</template>
</el-table-column>
</el-table>
</template>
<template #pagination>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.current"
v-model:limit="queryParams.size"
@pagination="getList"
/>
</template>
<!-- 工单 -->
<operation
:dict="{
gdlx,
dflx,
gdlevel,
clfa,
zyxt,
gdms,
deptList,
}"
v-model="open"
:id="workId"
:title="title"
@confirm="getList()"
></operation>
<!-- 退单 -->
<chargeBack
v-model="retreat"
:id="workId"
:dictReason="reason"
@confirm="getList()"
></chargeBack>
<!-- 派发 -->
<distriBute
:id="workId"
:title="title"
v-model="distributeView"
:deptList="deptList"
@confirm="getList()"
></distriBute>
<!-- 处理反馈 -->
<feedBack v-model="feedBackView" :id="workId" @confirm="getList()" />
</tablePage>
</template>
<script setup>
import { operation, chargeBack, distriBute, feedBack } from "./index";
import { getyjList, delyj, getDetListById } from "@/api/emergency-rescue";
import { ref } from "vue";
import { onMounted } from "vue";
import useUserStore from "@/store/modules/user";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const deptList = ref([]);
const { gdlx, gdms, gdlevel, clfa, zyxt, dflx, gd_status, reason } =
proxy.useDict(
"gdlx",
"gdms",
"gdlevel",
"clfa",
"zyxt",
"dflx",
"gd_status",
"reason"
);
const workId = ref(null);
const loading = ref(false);
const list = ref([]);
const open = ref(false);
const retreat = ref(false);
const distributeView = ref(false);
const feedBackView = ref(false);
const title = ref("");
const total = ref(0);
const router = useRouter();
const data = reactive({
form: {},
queryParams: {
address: undefined,
gdType: undefined,
gdLevel: undefined,
status: undefined,
current: 1,
size: 10,
},
rules: {},
});
const { queryParams, form, rules } = toRefs(data);
onMounted(() => {
getList();
getDeptTree();
});
/**
* 获取列表数据
*/
const getList = async () => {
loading.value = true;
const res = await getyjList(queryParams.value);
loading.value = false;
list.value = res.data.records;
total.value = res.data.total;
};
/**
* 获取系统组织架构
*/
const getDeptTree = async () => {
const res = await getDetListById({
deptId: userStore.deptId,
});
deptList.value = res;
};
/**
* 搜索
*/
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/**
* 重置查询条件
*/
const resetQuery = () => {
proxy.resetForm("queryRef");
handleQuery();
};
/**
* 处理反馈
* @param row
*/
const handleFeedBack = (row) => {
workId.value = row.id;
feedBackView.value = true;
};
/**
* 派发
*/
const handlerDistriBute = (row, text) => {
workId.value = row.id;
title.value = text;
distributeView.value = true;
};
/**
* 退单
* @param id
*/
const handlerRetreat = (row) => {
workId.value = row.id;
retreat.value = true;
};
/**
*
* 勘察录入
* @param row
*/
const handlerEdit = (row, status) => {
workId.value = row.id;
title.value = status ? "勘察录入" : "编辑工单";
open.value = true;
};
/**
* 新增
*/
const handlerAdd = () => {
workId.value = null;
open.value = true;
title.value = "抢险工单录入";
};
/**
* 删除
* @param id
*/
const handlerDel = (id) => {
proxy.$modal
.confirm('是否确认删除参数编号为"' + id + '"的数据项?')
.then(function () {
return delyj({ idList: id });
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
};
/**
* 导出
*/
const handlerExport = () => {
proxy.download("/bYjgd/export", {}, `抢险工单.xlsx`);
};
/**
* 详情
*/
const handlerInfo = () => {
proxy.setActiveMenu();
router.push("/emergency/workOrder-info");
};
</script>
<style lang="scss" scoped></style>

@ -0,0 +1,10 @@
<template>
<tableOperation>11111</tableOperation>
</template>
<script setup>
</script>
<style scoped>
</style>

@ -99,8 +99,8 @@ const router = useRouter();
const { proxy } = getCurrentInstance();
const loginForm = ref({
username: "",
password: "",
username: "admin",
password: "admin123",
rememberMe: false,
code: "",
uuid: "",
@ -162,7 +162,7 @@ function handleLogin() {
loading.value = false;
//
if (captchaEnabled.value) {
getCode();
// getCode();
}
});
}

@ -1,4 +1,5 @@
export { default as navigationBar } from './navigationBar.vue'
export { default as navigationBar } from './navigationBar.vue'
export { default as panelBlock } from './panel-block.vue'

@ -0,0 +1,41 @@
<template>
<div class="panel-block">
<div class="panel-block__header">{{ title }}</div>
<div class="panel-block__body"></div>
</div>
</template>
<script setup>
const props = defineProps({
title: {
type: String,
default: "",
},
});
</script>
<style scoped lang="scss">
.panel-block {
width: 100%;
display: flex;
flex-direction: column;
gap: 10px;
}
.panel-block__header {
height: 35px;
line-height: 30px;
padding-left: 38px;
width:324px;
background-image: url("@/assets/images/visualization/panel-block-title.png");
background-size: 100% 100%;
font-size: 16px;
font-weight: bold;
font-family: "Alimama ShuHeiTi-Bold";
color: #ffffff;
letter-spacing: 1px;
}
.panel-block__body {
width: 100%;
flex: 1;
}
</style>

@ -1,5 +1,18 @@
<template>
<div class="emergency-container">
<div class="main-left">
<panelBlock title="应急抢险资源"></panelBlock>
<panelBlock title="应急抢险工单"></panelBlock>
<panelBlock title="工单派发及完成率分析"></panelBlock>
</div>
<div class="main-right">
<panelBlock title="最新预警信息"></panelBlock>
<panelBlock title="工单数量变化分析"></panelBlock>
<panelBlock title="工作量统计分析"></panelBlock>
</div>
<div class="main-bottom">
<panelBlock title="最新应急抢险工单"></panelBlock>
</div>
<MarsMap
:url="configUrl"
:options="mapOptions"
@ -15,7 +28,7 @@ import mapOptions from "../mapOptions";
import { onUnmounted } from "vue";
import wallImg from "@/assets/images/visualization/fence-top.png";
import areaBg from "@/assets/images/visualization/area-bg.png";
import { panelBlock } from "@/views/visualization/components/index";
//
const configUrl = "lib/config/config.json";
let mapData = null;
@ -33,12 +46,12 @@ const initAreaCover = async () => {
});
};
const inintEntity = (data, fill=false, height, ) => {
const inintEntity = (data, fill = false, height) => {
const polylineGraphic = new mars3d.graphic.PolygonEntity({
positions: data.positions,
style: {
fill:fill,
materialType: "Image",
fill: fill,
materialType: "Image2",
materialOptions: {
image: areaBg,
opacity: 1,
@ -48,6 +61,9 @@ const inintEntity = (data, fill=false, height, ) => {
},
workMaterialType: "Image",
stRotationDegree: 6,
outline: fill,
outlineWidth: 2,
outlineColor: "#8EF4FF",
height: height,
},
});
@ -83,7 +99,7 @@ const initStyleFeatures = async () => {
url: "/lib/geoJson/park-rectangle.json",
});
const arr = mars3d.Util.geoJsonToGraphics(jsonData); // geojson
inintEntity(arr[0], false);
inintEntity(arr[0], false);
};
/**
@ -121,8 +137,42 @@ onUnmounted(() => {
});
</script>
<style scoped>
<style lang="scss" scoped>
.emergency-container {
position: relative;
height: 100%;
.main-left,
.main-right {
position: absolute;
z-index: 10;
top: 0;
box-sizing: border-box;
padding-top: calc(96px + 34px);
padding-bottom: 34px;
width: 16%;
height: 100%;
display: flex;
flex-direction: column;
&>div{
flex: 1;
}
}
.main-left {
left: 42px;
}
.main-right {
right: 42px;
}
.main-bottom {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
height:calc((100% / 3) - 20px);
z-index: 10;
width:55%;
padding-bottom: 34px;
}
}
</style>

Loading…
Cancel
Save