抢险工单新增,表格数据,完善公共组件以及函数

main
许宏杰 3 weeks ago
parent 138d256ad0
commit 93908a8b61

@ -8,4 +8,20 @@ export function getyjList(query) {
method: 'get',
params: query
})
}
//新增
export function addyj(data) {
return request({
url: '/bYjgd/add',
method: 'post',
data
})
}
// 修改
export function updateyj(data) {
return request({
url: '/bYjgd/edit',
method: 'post',
data
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -1,5 +1,5 @@
// cover some element-ui styles
@import './variables.module.scss';
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
@ -113,4 +113,38 @@
display: grid;
grid-template-columns: repeat(4, 1fr); /* 创建4列每列宽度相等 */
}
.el-cascader {
width: 100%;
}
.x-dialog{
padding: 0;
.el-dialog__header{
height: 50px;
line-height: 50px;
background-color:$--color-primary ;
padding: 0 10px;
.el-dialog__title{
font-size: 18px;
color: #fff;
letter-spacing: 1px;
font-family: 'MiSans-Medium';
}
.el-dialog__close{
color: #fff;
font-size: 18px;
font-weight: bold;
}
}
.dialog-data{
padding: 10px 10px 0 10px;
min-height: 200px;
}
.dialog-footer{
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
}
}

@ -104,7 +104,7 @@
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
// margin-top: 20px;
background-color: transparent !important;
}
@ -232,13 +232,15 @@
}
.text-success {
color: #1c84c6;
color: #3ED879;
}
.text-info {
color: #23c6c8;
}
.text-warning {
color: #f8ac59;
}

@ -34,7 +34,7 @@ $base-sub-menu-background: #D8E3FF;
$base-sub-menu-hover: rgba(0, 0, 0, 0.06);
//
$--color-primary: #409EFF;
$--color-primary: #4776EB;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
@ -71,6 +71,7 @@ $--color-info: #909399;
:root {
/* 亮色模式变量 */
--sidebar-bg: #{$menuBg};
--sidebar-text: #{$menuText};
--menu-hover: #{$menuHover};

@ -2,8 +2,9 @@
<div>
<template v-for="(item, index) in options">
<template v-if="values.includes(item.value)">
<!-- && (item.elTagClass == '' || item.elTagClass == null) -->
<span
v-if="(item.elTagType == 'default' || item.elTagType == '') && (item.elTagClass == '' || item.elTagClass == null)"
v-if="(item.elTagType == 'default' || item.elTagType == '') "
:key="item.value"
:index="index"
:class="item.elTagClass"
@ -15,7 +16,7 @@
:index="index"
:type="item.elTagType"
:class="item.elTagClass"
>{{ item.label + " " }}</el-tag>
>{{ item.label + " " }}{{item.elTagType}}</el-tag>
</template>
</template>
<template v-if="unmatch && showValue">

@ -0,0 +1,51 @@
export default {
method: {
chinaCRS: mars3d.ChinaCRS.GCJ02, // 标识坐标系
},
scene: {
center: {"lat":31.167163,"lng":121.430428,"alt":36454.4,"heading":357.1,"pitch":-89.8},
// sceneMode:2,
showSun: false, //太阳
showMoon: false, //月亮
showSkyAtmosphere: false, //大气层外光圈
fog: false, //雾化
fxaa: false, //快速抗锯齿
scene3DOnly: true,
requestRenderMode: true,
},
terrain: {
show: false, //地形
},
control: {
toolbar: false,
homeButton: false,
zoom: false,
distanceLegend: false,
sceneModePicker: false,
locationBar: false,
compass:false
// contextmenu: { preventDefault: false, hasDefault: false },
},
mouse: {
enabledMoveTarget: false,
},
basemaps: [
{
id: 2017,
pid: 10,
name: "蓝色底图",
icon: "//data.mars3d.cn/img/thumbnail/basemap/bd-c-midnight.png",
type: "gaode",
layer: "vec",
chinaCRS: "GCJ02",
invertColor: true,
filterColor: "#1D264D",
brightness: 0.6,
contrast: 1.8,
gamma: 0.3,
hue: 1,
saturation: 0,
show: true,
},
],
};

@ -2,10 +2,13 @@
<div class="table-operation">
<div class="table-operation-box">
<div class="operation-header">
<el-button type="primary" v-if="showSub" @click="clickSub()"
> </el-button
>
<el-button @click="handlerBack()"> </el-button>
<div class="operation-title">{{ getTitle }}</div>
<section>
<el-button type="primary" v-if="showSub" @click="clickSub()"
> </el-button
>
<el-button @click="handlerBack()"> </el-button>
</section>
</div>
<div class="operation-panel">
<slot></slot>
@ -15,7 +18,10 @@
</template>
<script setup>
import { useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();
const emits = defineEmits(["handlerSub"]);
const props = defineProps({
@ -23,12 +29,22 @@ const props = defineProps({
type: Boolean,
default: true,
},
title: {
type: String,
default: "",
},
});
const getTitle = computed(() => {
if (props.title) return props.title;
return route.meta.title;
});
const handlerBack = () => {
router.back();
};
const clickSub = () => {
console.log(route);
emits("handlerSub");
};
</script>
@ -49,11 +65,15 @@ const clickSub = () => {
padding: 0 10px;
display: flex;
align-items: center;
flex-direction: row-reverse;
justify-content: space-between;
gap: 10px;
height: 50px;
border-bottom: 1px solid #e5eaf3;
}
.operation-title {
font-size: 18px;
font-family: "MiSans-Medium";
}
.operation-panel {
height: calc(100% - 50px);

@ -3,27 +3,33 @@
<div class="filtrate-row">
<slot name="search"></slot>
</div>
<div class="table-list">
<div class="table-operation">
<el-button
type="primary"
plain
v-show="options.add"
icon="Plus"
@click="clickAdd()"
>录入</el-button
>
<el-button
type="primary"
plain
v-show="options.export"
icon="Download"
@click="clickExport()"
>导出</el-button
>
<div class="table-pagination">
<div class="table-operation">
<el-button
type="primary"
plain
v-show="options.add"
icon="Plus"
@click="clickAdd()"
>录入</el-button
>
<el-button
type="primary"
plain
v-show="options.export"
icon="Download"
@click="clickExport()"
>导出</el-button
>
</div>
<div class="table-el">
<slot name="table"></slot>
</div>
</div>
<div class="table-el">
<slot name="table"></slot>
<div class="pagination">
<slot name="pagination"></slot>
</div>
</div>
</div>
@ -70,14 +76,27 @@ const clickExport = () => {
gap: 10px;
}
.table-list {
padding-bottom: 0px !important;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
gap: 25px;
.table-pagination {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
gap: 20px;
}
.table-el {
flex: 1;
overflow: hidden;
}
.pagination {
display: flex;
align-items: center;
justify-content: flex-end;
height: 65px;
}
}
</style>

@ -27,7 +27,7 @@ import './permission' // permission control
import { useDict } from '@/utils/dict'
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'
import{setActiveMenu,getTableHeaderStyle } from "@/utils/common.js"
import{setActiveMenu,getTableHeaderStyle ,getTablerowStyle} from "@/utils/common.js"
// 分页组件
import Pagination from '@/components/Pagination'
@ -61,6 +61,7 @@ app.config.globalProperties.selectDictLabel = selectDictLabel
app.config.globalProperties.selectDictLabels = selectDictLabels
app.config.globalProperties.setActiveMenu = setActiveMenu
app.config.globalProperties.getTableHeaderStyle = getTableHeaderStyle
app.config.globalProperties.getTablerowStyle = getTablerowStyle
// 全局组件挂载

@ -1,6 +1,7 @@
import router from "@/router";
import axios from "axios";
import cache from "@/plugins/cache.js";
const gaodeKey = "bd665f6310bb41cdaea4494ec86fcbfa";
/**
* 处理如 新增-修改-详情页面设置菜单选中高亮项
* @param {*} path
@ -12,7 +13,7 @@ export function setActiveMenu(path) {
/**
* 设置表格头部样式
* @returns
* @returns
*/
export function getTableHeaderStyle() {
return {
@ -20,6 +21,35 @@ export function getTableHeaderStyle() {
height: "42px !important",
color: "#474A59",
fontSize: "16px",
fontFamily: 'MiSans-Medium',
fontFamily: "MiSans-Medium",
};
}
export function getTablerowStyle() {
return {
color: "#474A59",
padding:"11px 0 !important",
fontSize: "16px",
fontFamily: 'MiSans-Medium'
};
}
export async function gaodeAddress(locations) {
const res = await axios({
method: "get",
url: `https://restapi.amap.com/v3/geocode/regeo?location=${locations}&key=${gaodeKey}`,
});
return res.data.regeocode;
}
export async function gaodePOI(keyword) {
const res = await axios({
method: "get",
url: `https://restapi.amap.com/v3/place/text`,
params: {
key: gaodeKey,
keywords: keyword,
city: "上海市",
},
});
return res.data.pois;
}

@ -1,12 +0,0 @@
<template>
<div>
应急抢险工单详情
</div>
</template>
<script setup>
</script>
<style scoped>
</style>

@ -1,12 +0,0 @@
<template>
<tableOperation @handlerSub="handlerSub"></tableOperation>
</template>
<script setup>
/**
* 提交
*/
const handlerSub = () => {};
</script>
<style scoped></style>

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

@ -1,129 +1,151 @@
<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="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
<!-- 加根元素防止控制台报错 -->
<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-form-item>
<el-form-item label="工单状态" prop="status">
<el-input
v-model="queryParams.status"
placeholder="请输入"
clearable
<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-form-item>
<el-form-item label="录入时间" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入"
clearable
<el-table-column
label="录入时间"
align="center"
key="createTime"
prop="createTime"
/>
</el-form-item>
<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-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
<el-table-column
label="操作"
align="center"
width="150"
class-name="small-padding fixed-width"
>
<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"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column
label="用户编号"
align="center"
key="userId"
prop="userId"
/>
<el-table-column
label="响应标题"
align="center"
key="userId"
prop="userId"
/>
<el-table-column
label="响应等级"
align="center"
key="userId"
prop="userId"
</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"
/>
<el-table-column
label="响应部门"
align="center"
key="userId"
prop="userId"
/>
<el-table-column
label="响应时间"
align="center"
key="userId"
prop="userId"
/>
<el-table-column
label="响应状态"
align="center"
key="userId"
prop="userId"
/>
<el-table-column
label="操作"
align="center"
width="150"
class-name="small-padding fixed-width"
>
</el-table-column>
</el-table>
</template>
</tablePage>
</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, gdlevel } = proxy.useDict("gdlx", "gdlevel")
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,
gdms: undefined,
gdType: undefined,
gdLevel: undefined,
status: undefined,
current: 1,
size: 10,
},
@ -142,7 +164,6 @@ onMounted(() => {
const getList = async () => {
loading.value = true;
const res = await getyjList(queryParams.value);
console.log(res)
loading.value = false;
list.value = res.data.records;
total.value = res.data.total;
@ -166,16 +187,14 @@ const resetQuery = () => {
/**
* 新增
*/
const handlerAdd =()=>{
proxy.setActiveMenu();
router.push({ path: "/emergency-rescue/workOrder-operation" });
}
const handlerAdd = () => {
open.value = true;
title.value = "抢险工单录入";
};
/**
* 导出
*/
const handlerExport=()=>{
}
const handlerExport = () => {};
const handlerInfo = () => {
proxy.setActiveMenu();

@ -0,0 +1,321 @@
<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>
Loading…
Cancel
Save