This commit is contained in:
lcw
2026-03-18 11:07:40 +08:00
parent 9fb505eb8e
commit c181530639
71 changed files with 2331 additions and 1027 deletions

View File

@ -1,7 +1,8 @@
<template>
<div :id="mapid" class="map"></div>
<div class="changeMap_box" v-if="props.isShow">
<!-- <el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况" style="--el-switch-color:#13ce66;--el-switch-off-color:#ff4949;" /> -->
<el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况"
style="--el-switch-color: #13ce66; --el-switch-off-color: #ff4949" />
<!-- <el-carousel type="card" height="75px" :autoplay="false" indicator-position="none" :initial-index="3" @change="onMapImageChange">
<el-carousel-item>
<div class="mapImageItem">
@ -30,8 +31,7 @@
</el-carousel> -->
<!-- 地图缩放 -->
<div class="zoomTargetBox">
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom">
</el-input-number>
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom"></el-input-number>
</div>
</div>
</template>
@ -44,7 +44,7 @@ import { getItem } from "@/utils/storage";
const conditionRoute = ref(true); //路况
const mMap = ref(null); //地图对象
const mapUtil = ref(null); //地图工具对象
const zoomTarget = ref(6);
const zoomTarget = ref(15);
const props = defineProps({
mapid: {
@ -70,12 +70,11 @@ const props = defineProps({
isShowDraw: {
type: Boolean,
default: false
},
}
});
try {
const userInfo = getItem("deptId")[0].deptCode;
} catch (error) {}
} catch (error) { }
let map;
let mapLayer;
let mapLayer1;
@ -89,66 +88,37 @@ onMounted(() => {
map = new EliMap({
id: props.mapid,
crs: "EPSG:3857",
crs: "EPSG:4490",
style: {
glyphs: "./fonts/{fontstack}/{range}.pbf",
center: [94.36,29.65],
zoom: 11
center: [94.36057012, 29.64276831],
zoom: 15
},
minZoom: 7,
minZoom: 5,
maxZoom: 18,
transformRequest: (url) => {
if (url.indexOf("TileMatrix=") != -1) {
const arr = url.split("TileMatrix=");
const arr1 = arr[1].split("&");
const nurl = `${arr[0]}&TileMatrix=${Number(arr1[0])}&${arr1[1]}&${arr1[2]}`;
}
}
});
window.map = map;
map.mapboxGLMap.on("load", () => {
map.addGaudLayer({
url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
})
map.addWMTSLayer(
"/PGIS_S_TileMapServer/Maps/XZDJ_DJ/EzMap"
,
{
Service: "getImage",
Type: "RGB",
ZoomOffset: "0",
V: "0.3",
Zoom: "{z}",
Row: "{y}",
Col: "{x}"
},
{
tileSize: 300
}
);
zoomTarget.value = map.mapboxGLMap.getZoom();
// 地图加载完成后发出事件
// emit('mapLoaded')
});
mapUtil.value = new MapUtil(map);
// map = new EliMap({
// id: props.mapid,
// crs: "EPSG:4490",
// style: {
// glyphs: "./fonts/{fontstack}/{range}.pbf",
// center: [94.36057012, 29.64276831],
// zoom: 15
// },
// minZoom: 7,
// maxZoom: 18,
// });
// window.map = map;
// map.mapboxGLMap.on("load", () => {
// map.addWMTSLayer(
// "/PGIS_S_TileMapServer/Maps/XZDJ_SL/EzMap"
// ,
// {
// Service: "getImage",
// Type: "RGB",
// ZoomOffset: "0",
// V: "0.3",
// Zoom: "{z}",
// Row: "{y}",
// Col: "{x}"
// },
// {
// tileSize: 300
// }
// );
// zoomTarget.value = map.mapboxGLMap.getZoom();
// });
// mapUtil.value = new MapUtil(map);
mapUtil.value.Drawplot(); //初始化加载绘制工具
// 设置地图中心点及图层
@ -184,6 +154,10 @@ onMounted(() => {
emitter.on("showSquire", (obj) => {
mapUtil.value.zdySquire(obj);
});
// 展示气泡框
emitter.on("makerPopup", (obj) => {
mapUtil.value.makerPopup(obj);
});
// 绘制图形 - 回显区域
emitter.on("drawShape", (res) => {
@ -289,7 +263,6 @@ const mapSetLayer = (id, source) => {
//获取地图绘制的数据
const resFun = (coord, type, flag, data) => {
emitter.emit("coordString", {
coord: coord,
type: type,
@ -303,12 +276,6 @@ const handleZoom = (val) => {
map.mapboxGLMap.setZoom(val);
};
emitter.on("map-resize", () => {
if (map && map.mapboxGLMap) {
map.mapboxGLMap.resize();
}
});
// 是否打开或者关闭路况
const handleSwitch = (val) => {
if (val) {
@ -325,6 +292,7 @@ onUnmounted(() => {
emitter.off("showPoint");
emitter.off("deletePointArea");
emitter.off("deletePointAreaOne");
emitter.off("makerPopup");
emitter.off("drawShape");
emitter.off("echoPlane");
emitter.off("removeEara");
@ -338,7 +306,6 @@ onUnmounted(() => {
emitter.off("diffusionCircle");
emitter.off("SsCircle");
emitter.off("ClearssCircle");
emitter.off("map-resize");
});
</script>
@ -361,29 +328,35 @@ onUnmounted(() => {
right: 398px;
bottom: 4px;
z-index: 9;
.mapImageItem {
border: 1px solid #08aae8;
background: rgb(9, 26, 70);
& > img {
&>img {
width: 100%;
height: 50px;
}
& > div {
&>div {
text-align: center;
position: relative;
top: -3px;
}
}
.zoomTargetBox {
margin-top: 10px;
margin-left: 23px;
}
::v-deep .el-input-number__decrease,
::v-deep .el-input-number__increase {
background: #133362;
color: #fff;
border: none;
}
::v-deep .el-input__inner {
background: #0c1641;
}

View File

@ -1,8 +1,7 @@
<template>
<div :id="mapid" class="map"></div>
<div class="changeMap_box" v-if="props.isShow">
<el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况"
style="--el-switch-color: #13ce66; --el-switch-off-color: #ff4949" />
<!-- <el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况" style="--el-switch-color:#13ce66;--el-switch-off-color:#ff4949;" /> -->
<!-- <el-carousel type="card" height="75px" :autoplay="false" indicator-position="none" :initial-index="3" @change="onMapImageChange">
<el-carousel-item>
<div class="mapImageItem">
@ -31,7 +30,8 @@
</el-carousel> -->
<!-- 地图缩放 -->
<div class="zoomTargetBox">
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom"></el-input-number>
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom">
</el-input-number>
</div>
</div>
</template>
@ -44,7 +44,7 @@ import { getItem } from "@/utils/storage";
const conditionRoute = ref(true); //
const mMap = ref(null); //
const mapUtil = ref(null); //
const zoomTarget = ref(15);
const zoomTarget = ref(6);
const props = defineProps({
mapid: {
@ -70,11 +70,12 @@ const props = defineProps({
isShowDraw: {
type: Boolean,
default: false
}
},
});
try {
const userInfo = getItem("deptId")[0].deptCode;
} catch (error) { }
} catch (error) {}
let map;
let mapLayer;
let mapLayer1;
@ -88,37 +89,66 @@ onMounted(() => {
map = new EliMap({
id: props.mapid,
crs: "EPSG:4490",
crs: "EPSG:3857",
style: {
glyphs: "./fonts/{fontstack}/{range}.pbf",
center: [94.36057012, 29.64276831],
zoom: 15
center: [94.36,29.65],
zoom: 11
},
minZoom: 5,
minZoom: 7,
maxZoom: 18,
transformRequest: (url) => {
if (url.indexOf("TileMatrix=") != -1) {
const arr = url.split("TileMatrix=");
const arr1 = arr[1].split("&");
const nurl = `${arr[0]}&TileMatrix=${Number(arr1[0])}&${arr1[1]}&${arr1[2]}`;
}
}
});
window.map = map;
map.mapboxGLMap.on("load", () => {
map.addWMTSLayer(
"/PGIS_S_TileMapServer/Maps/XZDJ_DJ/EzMap"
,
{
Service: "getImage",
Type: "RGB",
ZoomOffset: "0",
V: "0.3",
Zoom: "{z}",
Row: "{y}",
Col: "{x}"
},
{
tileSize: 300
}
);
map.addGaudLayer({
url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
})
zoomTarget.value = map.mapboxGLMap.getZoom();
//
// emit('mapLoaded')
});
mapUtil.value = new MapUtil(map);
// map = new EliMap({
// id: props.mapid,
// crs: "EPSG:4490",
// style: {
// glyphs: "./fonts/{fontstack}/{range}.pbf",
// center: [94.36057012, 29.64276831],
// zoom: 15
// },
// minZoom: 7,
// maxZoom: 18,
// });
// window.map = map;
// map.mapboxGLMap.on("load", () => {
// map.addWMTSLayer(
// "/PGIS_S_TileMapServer/Maps/XZDJ_SL/EzMap"
// ,
// {
// Service: "getImage",
// Type: "RGB",
// ZoomOffset: "0",
// V: "0.3",
// Zoom: "{z}",
// Row: "{y}",
// Col: "{x}"
// },
// {
// tileSize: 300
// }
// );
// zoomTarget.value = map.mapboxGLMap.getZoom();
// });
// mapUtil.value = new MapUtil(map);
mapUtil.value.Drawplot(); //
//
@ -154,10 +184,6 @@ onMounted(() => {
emitter.on("showSquire", (obj) => {
mapUtil.value.zdySquire(obj);
});
//
emitter.on("makerPopup", (obj) => {
mapUtil.value.makerPopup(obj);
});
// -
emitter.on("drawShape", (res) => {
@ -263,6 +289,7 @@ const mapSetLayer = (id, source) => {
//
const resFun = (coord, type, flag, data) => {
emitter.emit("coordString", {
coord: coord,
type: type,
@ -276,6 +303,12 @@ const handleZoom = (val) => {
map.mapboxGLMap.setZoom(val);
};
emitter.on("map-resize", () => {
if (map && map.mapboxGLMap) {
map.mapboxGLMap.resize();
}
});
//
const handleSwitch = (val) => {
if (val) {
@ -292,7 +325,6 @@ onUnmounted(() => {
emitter.off("showPoint");
emitter.off("deletePointArea");
emitter.off("deletePointAreaOne");
emitter.off("makerPopup");
emitter.off("drawShape");
emitter.off("echoPlane");
emitter.off("removeEara");
@ -306,6 +338,7 @@ onUnmounted(() => {
emitter.off("diffusionCircle");
emitter.off("SsCircle");
emitter.off("ClearssCircle");
emitter.off("map-resize");
});
</script>
@ -328,35 +361,29 @@ onUnmounted(() => {
right: 398px;
bottom: 4px;
z-index: 9;
.mapImageItem {
border: 1px solid #08aae8;
background: rgb(9, 26, 70);
&>img {
& > img {
width: 100%;
height: 50px;
}
&>div {
& > div {
text-align: center;
position: relative;
top: -3px;
}
}
.zoomTargetBox {
margin-top: 10px;
margin-left: 23px;
}
::v-deep .el-input-number__decrease,
::v-deep .el-input-number__increase {
background: #133362;
color: #fff;
border: none;
}
::v-deep .el-input__inner {
background: #0c1641;
}

View File

@ -0,0 +1,553 @@
<template>
<div v-loading="loadingPage" class="pageSearch searchBox main-container"
:style="`margin-bottom: ${marginBottom}px;background-color: ${backgroundColor}`">
<div class="filter-title">
<span class="filter-label"><el-icon>
<Filter />
</el-icon>筛选条件</span>
</div>
<div class="content-container">
<div class="box">
<div v-for="(item, index) in getArr" :key="index" class="item">
<div class="label" v-if="item.label">{{ item.label }}</div>
<!-- select -->
<el-select v-if="item.showType === 'select'" v-model="searchObj[item.prop]" :multiple="item.multiple"
:clearable="item.clearable" :filterable="item.filterable" :placeholder="item.placeholder" collapse-tags
collapse-tags-tooltip>
<el-option v-for="obj in getOptions[item.prop]" :key="obj.value" :label="obj.label || obj.lable"
:value="obj.value" />
</el-select>
<!-- input -->
<el-input v-else-if="item.showType === 'input'" class="input" v-model="searchObj[item.prop]"
:clearable="item.clearable" :placeholder="item.placeholder" />
<!-- input -->
<el-input v-else-if="item.showType === 'number'" class="input" v-model="searchObj[item.prop]"
:clearable="item.clearable" :placeholder="item.placeholder" type="number" />
<!-- 日期段选择器 -->
<el-date-picker v-else-if="item.showType === 'daterange'" v-model="searchObj[item.prop]" type="daterange"
unlink-panels :range-separator="item.rangeSeparator" :start-placeholder="item.startPlaceholder"
:end-placeholder="item.endPlaceholder" :shortcuts="item.shortcuts" :disabledDate="disabledDate"
value-format="YYYY-MM-DD" />
<el-date-picker v-else-if="item.showType === 'datetimerange'" v-model="searchObj[item.prop]"
type="datetimerange" unlink-panels :range-separator="item.rangeSeparator || ''"
:start-placeholder="item.startPlaceholder || '开始日期'" :end-placeholder="item.endPlaceholder || '结束日期'"
:shortcuts="item.shortcuts" value-format="YYYY-MM-DD HH:mm:ss" />
<el-date-picker v-else-if="item.showType === 'date'" v-model="searchObj[item.prop]" type="date"
:placeholder="item.placeholder" :disabled-date="disabledDate" :shortcuts="item.shortcuts"
value-format="YYYY-MM-DD">
</el-date-picker>
<el-date-picker v-else-if="item.showType === 'datetime'" v-model="searchObj[item.prop]" type="datetime"
:placeholder="item.placeholder" value-format="YYYY-MM-DD HH:mm:ss">
</el-date-picker>
<!-- checkbox -->
<template v-else-if="item.showType === 'department'">
<MOSTY.Department clearable v-model="searchObj[item.prop]" />
</template>
<!-- checkbox -->
<template v-else-if="item.showType === 'checkbox'">
<el-checkbox v-if="item.showSelectAll" v-model="item.checkAll" :indeterminate="item.isIndeterminate"
@change="
(val) => {
handleCheckAllChange(val, item);
}
">全选</el-checkbox>
<el-checkbox-group v-model="searchObj[item.prop]" @change="
(val) => {
handleCheckedCitiesChange(val, item);
}
">
<el-checkbox v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-checkbox>
</el-checkbox-group>
</template>
<!-- radio -->
<el-radio-group v-else-if="item.showType === 'radio'" v-model="searchObj[item.prop]" @change="
(val) => {
handleRadioChange(val, item);
}
">
<el-radio v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-radio>
</el-radio-group>
<!-- 级联选择 -->
<el-cascader v-else-if="item.showType === 'cascader'" v-model="searchObj[item.prop]" :props="item.props"
:show-all-levels="item.showAllLevels" :clearable="item.clearable" :options="getOptions[item.prop]"
:placeholder="item.placeholder" />
<div v-if="item.showType === 'Slot'">
<slot :name="item.prop"></slot>
</div>
<div v-if="item.showType === 'defaultSlot'">
<slot name="defaultSlot"></slot>
</div>
<div v-if="item.showType === 'nameSlot'">
<slot name="nameSlot"></slot>
</div>
</div>
</div>
<div class="button-container">
<div class="flex">
<el-button type="primary" @click="submit" size="small">确定</el-button>
<el-button type="" @click="reset" size="small">重置</el-button>
<slot> </slot>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {
ref,
reactive,
watchEffect,
getCurrentInstance,
watch,
computed
} from "vue";
import * as MOSTY from "@/components/MyComponents/index";
const { proxy } = getCurrentInstance();
const props = defineProps({
searchArr: {
type: Array,
default: () => {
return [
{
showType: "select",
prop: "selectKey",
options: [
{
value: 1,
label: "选择1"
}
],
defaultVal: "",
label: "选择",
dict: "" // 字典编码
},
{
showType: "input",
prop: "inputKey",
defaultVal: "",
label: "输入"
},
{
showType: "department",
prop: "deptKey",
defaultVal: "",
label: "输入"
},
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "输入"
},
{
showType: "date",
prop: "date",
defaultVal: ""
},
{
showType: "checkbox",
prop: "checkboxKey1",
options: [
{
value: 1,
label: "选择1"
}
],
defaultVal: ""
},
{
showType: "cascader",
prop: "cascaderKey",
label: "级联选择",
checkStrictly: false, //点击任意选中
defaultVal: ""
},
{
showType: "radio",
defaultVal: ""
},
{
showType: "defaultTime",
prop: "timeField",
options: []
}
];
}
},
marginBottom: {
type: Number,
default: 0
},
backgroundColor: {
type: String,
default: "rgb(255, 255, 255, 1)"
},
bool: {
type: Boolean,
default: true
}
});
let loadingPage = ref(false);
const emit = defineEmits(["submit", "reset"]);
let searchObj = reactive({});
// select 的一些默认配置
const selectDefault = {
clearable: true, // 是否可以清空
filterable: true, // 是否可以筛选
multiple: false, // 是否多选
placeholder: "请选择"
};
// 重新定义下拉框的选项
let getOptions = reactive({});
// input 的一些默认配置
const inputDefault = {
clearable: true, // 是否可以清空
placeholder: "请输入"
};
const shortcuts = [
{
text: "今天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 0);
return [start, end];
}
},
{
text: "昨天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
end.setTime(end.getTime() - 3600 * 1000 * 24 * 1);
return [start, end];
}
},
{
text: "最近7天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
}
},
{
text: "最近30天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
}
},
{
text: "最近90天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
}
}
];
// daterange 的一些默认配置
const daterangeDefault = {
rangeSeparator: "",
startPlaceholder: "开始日期",
endPlaceholder: "结束日期",
shortcuts: [], // 快捷选择
defaultShortcuts: true // 是否显示快捷选择 如果要自定义快捷选择传入一个shortcuts就可以了
};
// date 的一些默认配置
const defaultDate = {
clearable: true, // 是否可以清空
placeholder: "请输入",
shortcuts: [], // 快捷选择
defaultShortcuts: true // 是否显示快捷选择 如果要自定义快捷选择传入一个shortcuts就可以了
};
const dateShortcuts = [
{
text: "今天",
value: new Date()
},
{
text: "昨天",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
return date;
}
},
{
text: "7天前",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
return date;
}
},
{
text: "30天前",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 30);
return date;
}
},
{
text: "90天前",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 90);
return date;
}
}
];
// 设置不可选的日期
const disabledDate = (time) => {
return time.getTime() > Date.now();
};
// checkbox 的一些默认配置
const defaultCheckbox = reactive({
defaultVal: [],
checkAll: false, // 全选的值
isIndeterminate: false, // 控制全选按钮样式
showSelectAll: true // 是否显示全选
});
// 全选复选框的选中与不选中
const handleCheckAllChange = (val, obj) => {
searchObj[obj.prop] = val ? obj.checkboxValueArr : [];
obj.isIndeterminate = false;
};
// 单个复选框的选中与不选中
const handleCheckedCitiesChange = (value, obj) => {
const checkedCount = value.length;
obj.checkAll = checkedCount === obj.checkboxValueArr.length;
obj.isIndeterminate =
checkedCount > 0 && checkedCount < obj.checkboxValueArr.length;
};
//单选
const handleRadioChange = (val, obj) => {
console.log(val, obj);
};
// cascader 的一些默认配置
let defaultCascader = {
filterable: true, // 是否可以搜索
clearable: true, // 是否可以清空
placeholder: "请选择",
checkStrictly: true, // 控制是否父子联动(是否可以选择任意节点)
showAllLevels: false, // 是否显示完整路径
lazy: false, // 是否懒加载 当设置为false时就要传入options
portUrl: "", // 这里必须写 接口地址
props: {
label: "label",
value: "value",
children: "children"
},
options: []
};
// 在懒加载状态下cascader 的props的一些配置
const cascaderLazyProps = reactive({
value: "value",
label: "label",
lazy: false,
lazyLoad(node, resolve) {
// 这里要根据实际情况修改
const { level } = node;
let options = [];
switch (level) {
case 0:
options = [
{
value: 1,
label: "选择1",
leaf: false // 表示有下一级 必须有这个表示 不然获取不到值
},
{
value: 2,
label: "选择2",
leaf: false // 表示有下一级
},
{
value: 3,
label: "选择3",
leaf: false // 表示有下一级
},
{
value: 4,
label: "选择4",
leaf: true // 表示没有下一级了
}
];
break;
case 1:
options = [
{
value: 11,
label: "选择1_1",
leaf: true // 表示没有下一级了
},
{
value: 21,
label: "选择2_1",
leaf: true // 表示没有下一级了
},
{
value: 31,
label: "选择3_1",
leaf: true // 表示没有下一级了
},
{
value: 41,
label: "选择4_1",
leaf: true // 表示没有下一级了
}
];
}
resolve(options);
}
});
// 获取到传过来的参数
let getArr = reactive([]);
const submit = () => {
emit("submit", searchObj);
};
const reset = () => {
getArr.forEach((item) => {
searchObj[item.prop] = item.defaultVal;
});
emit("reset", true);
emit("submit", searchObj);
};
// 暴露searchObj给父组件
defineExpose({
searchObj,
submit,
reset
});
watchEffect(() => {
loadingPage.value = true;
let arr = JSON.parse(JSON.stringify(props.searchArr));
getArr = arr.map((item) => {
switch (item.showType) {
case "select":
item = { ...selectDefault, ...item };
item.options = reactive(item.options);
getOptions[item.prop] = item.options;
break;
case "input":
item = { ...inputDefault, ...item };
break;
case "daterange":
item = { ...daterangeDefault, ...item };
if (item.defaultShortcuts) item.shortcuts = shortcuts;
break;
case "date":
item = { ...defaultDate, ...item };
if (item.defaultShortcuts) {
item.shortcuts = dateShortcuts;
}
break;
case "checkbox":
item = reactive({ ...defaultCheckbox, ...item });
item.checkboxValueArr = item.options.map((obj) => {
return obj.value;
});
break;
case "cascader":
item = { ...defaultCascader, ...item };
if (item.lazy) {
cascaderLazyProps.checkStrictly = item.checkStrictly;
item.props = { ...cascaderLazyProps, ...(item.props || {}) };
delete item.options;
} else {
item.props = {
...defaultCascader.props,
...(item.props || {}),
...{ checkStrictly: item.checkStrictly }
};
getOptions[item.prop] = reactive(item.options);
}
break;
}
loadingPage.value = false;
searchObj[item.prop] = item.defaultVal;
return item;
});
});
</script>
<style lang="scss" scoped>
.pageSearch {
.main-container {
padding: 0;
}
.content-container {
display: flex;
padding: 0 15px;
}
.button-container {
display: flex;
flex-direction: column-reverse;
margin-bottom: 10px;
}
.filter-title {
display: flex;
align-items: center;
margin-bottom: 10px;
width: 100%;
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
padding: 5px 15px;
.filter-label {
display: flex;
align-items: center;
font-weight: bold;
color: #000;
margin-right: 10px;
white-space: nowrap;
}
.filter-line {
flex: 1;
height: 1px;
background-color: #ccc;
}
}
.box {
flex: 1;
display: flex;
flex-wrap: wrap;
.item {
display: flex;
margin-right: 12px;
margin-bottom: 15px;
}
.label {
margin: auto;
margin-right: 5px;
white-space: nowrap;
color: #000;
}
}
}
::v-deep .el-date-editor .el-range-separator {
color: #333;
}
</style>

View File

@ -1,77 +1,74 @@
<template>
<div v-loading="loadingPage" class="pageSearch searchBox main-container"
:style="`margin-bottom: ${marginBottom}px;background-color: ${backgroundColor}`">
<div class="filter-title">
<span class="filter-label"><el-icon>
<Filter />
</el-icon>筛选条件</span>
</div>
<div class="content-container">
<div class="box">
<div v-for="(item, index) in getArr" :key="index" class="item">
<div class="label" v-if="item.label">{{ item.label }}</div>
<div v-loading="loadingPage" class="query-wrap">
<div class="query-title">查询条件</div>
<div class="query-grid">
<div v-for="(item, index) in getArr" :key="index" class="query-cell">
<div class="cell-label">{{ item.label }}</div>
<div class="cell-control">
<!-- select -->
<el-select v-if="item.showType === 'select'" v-model="searchObj[item.prop]" :multiple="item.multiple"
:clearable="item.clearable" :filterable="item.filterable" :placeholder="item.placeholder" collapse-tags
collapse-tags-tooltip>
collapse-tags-tooltip class="control-select">
<el-option v-for="obj in getOptions[item.prop]" :key="obj.value" :label="obj.label || obj.lable"
:value="obj.value" />
</el-select>
<!-- input -->
<el-input v-else-if="item.showType === 'input'" class="input" v-model="searchObj[item.prop]"
:clearable="item.clearable" :placeholder="item.placeholder" />
<!-- input -->
<el-input v-else-if="item.showType === 'number'" class="input" v-model="searchObj[item.prop]"
<el-input v-else-if="item.showType === 'input'" class="control-input" v-model="searchObj[item.prop]"
:clearable="item.clearable" :placeholder="item.placeholder" />
<!-- input -->
<el-input v-else-if="item.showType === 'number'" class="control-input" v-model="searchObj[item.prop]"
:clearable="item.clearable" :placeholder="item.placeholder" type="number" />
<!-- 日期段选择器 -->
<el-date-picker v-else-if="item.showType === 'daterange'" v-model="searchObj[item.prop]" type="daterange"
unlink-panels :range-separator="item.rangeSeparator" :start-placeholder="item.startPlaceholder"
:end-placeholder="item.endPlaceholder" :shortcuts="item.shortcuts" :disabledDate="disabledDate"
value-format="YYYY-MM-DD" />
value-format="YYYY-MM-DD" class="control-date" />
<el-date-picker v-else-if="item.showType === 'datetimerange'" v-model="searchObj[item.prop]"
type="datetimerange" unlink-panels :range-separator="item.rangeSeparator || ''"
:start-placeholder="item.startPlaceholder || '开始日期'" :end-placeholder="item.endPlaceholder || '结束日期'"
:shortcuts="item.shortcuts" value-format="YYYY-MM-DD HH:mm:ss" />
:shortcuts="item.shortcuts" value-format="YYYY-MM-DD HH:mm:ss" class="control-date" />
<el-date-picker v-else-if="item.showType === 'date'" v-model="searchObj[item.prop]" type="date"
:placeholder="item.placeholder" :disabled-date="disabledDate" :shortcuts="item.shortcuts"
value-format="YYYY-MM-DD">
value-format="YYYY-MM-DD" class="control-date">
</el-date-picker>
<el-date-picker v-else-if="item.showType === 'datetime'" v-model="searchObj[item.prop]" type="datetime"
:placeholder="item.placeholder" value-format="YYYY-MM-DD HH:mm:ss">
:placeholder="item.placeholder" value-format="YYYY-MM-DD HH:mm:ss" class="control-date">
</el-date-picker>
<!-- checkbox -->
<template v-else-if="item.showType === 'department'">
<MOSTY.Department clearable v-model="searchObj[item.prop]" />
<MOSTY.Department clearable v-model="searchObj[item.prop]" class="control-select" />
</template>
<!-- checkbox -->
<template v-else-if="item.showType === 'checkbox'">
<el-checkbox v-if="item.showSelectAll" v-model="item.checkAll" :indeterminate="item.isIndeterminate"
@change="
<div class="checkbox-wrap">
<el-checkbox v-if="item.showSelectAll" v-model="item.checkAll" :indeterminate="item.isIndeterminate"
@change="
(val) => {
handleCheckAllChange(val, item);
}
">全选</el-checkbox>
<el-checkbox-group v-model="searchObj[item.prop]" @change="
(val) => {
handleCheckAllChange(val, item);
handleCheckedCitiesChange(val, item);
}
">全选</el-checkbox>
<el-checkbox-group v-model="searchObj[item.prop]" @change="
(val) => {
handleCheckedCitiesChange(val, item);
}
">
<el-checkbox v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-checkbox>
</el-checkbox-group>
" class="checkbox-group">
<el-checkbox v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-checkbox>
</el-checkbox-group>
</div>
</template>
<!-- radio -->
<el-radio-group v-else-if="item.showType === 'radio'" v-model="searchObj[item.prop]" @change="
(val) => {
handleRadioChange(val, item);
}
">
" class="radio-group">
<el-radio v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-radio>
</el-radio-group>
<!-- 级联选择 -->
<el-cascader v-else-if="item.showType === 'cascader'" v-model="searchObj[item.prop]" :props="item.props"
:show-all-levels="item.showAllLevels" :clearable="item.clearable" :options="getOptions[item.prop]"
:placeholder="item.placeholder" />
:placeholder="item.placeholder" class="control-select" />
<div v-if="item.showType === 'Slot'">
<slot :name="item.prop"></slot>
</div>
@ -82,16 +79,16 @@
<slot name="nameSlot"></slot>
</div>
</div>
</div>
<div class="button-container">
<div class="flex">
<el-button type="primary" @click="submit" size="small">确定</el-button>
<el-button type="" @click="reset" size="small">重置</el-button>
<slot> </slot>
</div>
</div>
<div class="query-action">
<div>
<slot> </slot>
</div>
<div>
<el-button type="primary" @click="submit" size="small">查询</el-button>
<el-button type="default" @click="reset" size="small">重置</el-button>
</div>
</div>
</div>
</template>
@ -485,69 +482,169 @@ watchEffect(() => {
});
</script>
<style lang="scss" scoped>
.pageSearch {
.main-container {
padding: 0;
}
.content-container {
display: flex;
padding: 0 15px;
}
.button-container {
display: flex;
flex-direction: column-reverse;
margin-bottom: 10px;
}
.filter-title {
display: flex;
align-items: center;
margin-bottom: 10px;
width: 100%;
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
padding: 5px 15px;
.filter-label {
display: flex;
align-items: center;
font-weight: bold;
color: #000;
margin-right: 10px;
white-space: nowrap;
}
.filter-line {
flex: 1;
height: 1px;
background-color: #ccc;
}
}
.box {
flex: 1;
display: flex;
flex-wrap: wrap;
.item {
display: flex;
margin-right: 12px;
margin-bottom: 15px;
}
.label {
margin: auto;
margin-right: 5px;
white-space: nowrap;
color: #000;
}
}
<style scoped lang="scss">
.query-wrap {
border: 1px solid #b8d3ff;
background: #fff;
}
::v-deep .el-date-editor .el-range-separator {
color: #333;
.query-title {
height: 32px;
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
line-height: 32px;
padding-left: 10px;
font-size: 16px;
font-weight: 700;
color: #0d2148;
border-bottom: 1px solid #b8d3ff;
}
.query-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.query-cell {
display: flex;
min-height: 40px;
border-right: 1px solid #b8d3ff;
border-bottom: 1px solid #b8d3ff;
}
.query-cell:nth-child(4n) {
border-right: 0;
}
.cell-label {
width: 130px;
flex-shrink: 0;
border-right: 1px solid #b8d3ff;
font-size: 14px;
color: #0d2148;
display: flex;
align-items: center;
justify-content: center;
white-space: nowrap;
}
.cell-control {
flex: 1;
min-width: 0;
padding: 4px 8px;
display: flex;
align-items: center;
overflow: hidden;
}
.cell-control.is-checkbox {
justify-content: center;
padding: 0;
}
.control-input,
.control-select,
.control-date {
width: 100%;
max-width: 100%;
min-width: 0;
}
:deep(.control-input .el-input__wrapper),
:deep(.control-select .el-select__wrapper),
:deep(.control-date .el-input__wrapper) {
width: 100%;
max-width: 100%;
min-height: 28px;
border-radius: 0;
box-shadow: 0 0 0 1px #b8d3ff inset;
}
:deep(.control-date.el-date-editor) {
width: 100%;
max-width: 100%;
min-width: 0;
}
:deep(.control-date.el-date-editor .el-range-input) {
min-width: 0;
}
:deep(.control-input .el-input__inner),
:deep(.control-select .el-select__placeholder),
:deep(.control-date .el-input__inner) {
font-size: 14px;
color: #0d2148;
}
:deep(.control-date .el-range-input) {
font-size: 14px;
color: #0d2148;
}
:deep(.control-date .el-range__icon),
:deep(.control-date .el-range__close-icon) {
line-height: 1;
}
.checkbox-wrap {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.radio-group {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
:deep(.checkbox-wrap .el-checkbox) {
margin-right: 0;
height: 100%;
display: flex;
align-items: center;
}
:deep(.checkbox-wrap .el-checkbox__inner) {
width: 14px;
height: 14px;
}
.query-action {
height: 36px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 8px;
}
:deep(.el-button--primary) {
background-color: #0f5bbd;
border-color: #0f5bbd;
}
:deep(.el-button--primary:hover) {
background-color: #1a73e8;
border-color: #1a73e8;
}
:deep(.el-button--default) {
background-color: #ffffff;
border-color: #dcdfe6;
color: #606266;
}
:deep(.el-button--default:hover) {
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
</style>

View File

@ -26,6 +26,7 @@ const checkAll = ref(false);
const isIndeterminate = ref(true);
const hasChecked = ref([]); //已经全选的数据
const checkedList = ref([]);
const isInit = ref(true); // 标记是否为初始化
watch(
() => props.data,
(val) => {
@ -38,16 +39,28 @@ watch(
immediate: true
}
);
// 监听hasChecked变化初始化完成后才触发changeData
watch(
hasChecked,
(val) => {
if (isInit.value) {
isInit.value = false;
return;
}
emits("changeData", val);
},
{ deep: true }
);
// 全选
function handleCheckAll(val) {
hasChecked.value = val ? checkedList.value : [];
isIndeterminate.value = false;
emits("changeData", hasChecked.value);
// emits 由 watch 处理
}
// 处理多选框改变
function handleCheckedChange(val) {
handleChange(val);////判断是否全选
emits("changeData", hasChecked.value);
// emits 由 watch 处理
}
//判断是否全选
function handleChange(val) {
@ -68,4 +81,4 @@ function handleChange(val) {
margin: 0 20px 0 4px;
}
}
</style>
</style>

View File

@ -23,7 +23,7 @@ import emitter from "@/utils/eventBus.js"; // 导入事件总线
import { qcckGet } from '@/api/qcckApi'
import Item from './item.vue'
import { AudioPlayerClass } from '@/utils/audioPlayer.js'
import {getItem} from '@/utils/storage.js'
import { getItem } from '@/utils/storage.js'
const dataList = ref([])
const timekeeping = ref(null)
const countdown = ref(0) // 倒计时时间(秒)
@ -33,7 +33,8 @@ const audioPlayers = ref({
'02': null, // 信息上报
'03': null, // 研判审批
'04': null, // 研判指令
'05': null // 线索下发
'05': null, // 线索下发,
'06': null, // 警情监测
})
// 音频文件路径映射
@ -41,7 +42,8 @@ const audioPaths = {
'02': require('@/assets/images/cjyp.mp3'),
'03': require('@/assets/images/ypbg.mp3'),
'04': require('@/assets/images/ypzl.mp3'),
'05': require('@/assets/images/xsyp.mp3')
'05': require('@/assets/images/xsyp.mp3'),
'06': require('@/assets/images/jqjc.mp3')
}
// 初始化音频播放器
@ -119,14 +121,14 @@ const dataModel = () => {
if (yjmasg.length > 0) {
emitter.emit('openYp', yjmasg[0].obj); // 触发音频播放
} else {
const data=res.filter(item=>item.sfzList.includes(idEntityCard.value))
const infoMasge =data.map(item => {
const data = res.filter(item => item.sfzList.includes(idEntityCard.value))
const infoMasge = data.map(item => {
return {
...item.obj,
typeMasgeLx: item.type
}
})
console.log(infoMasge);
console.log(infoMasge,"xxxxxxxxxxxx");
emitter.emit('webSocketMessage', infoMasge)
}
}

View File

@ -31,6 +31,14 @@
<div class="item-message" v-html="item.zlnr"></div>
<div class="item-time">{{ item.xtCjsj || '' }}</div>
</div>
<div class="test-item" v-if="item.typeMasgeLx == '06'" @click="goDetail(item.id, item.typeMasgeLx)">
<div class="item-header">
<div class="item-title">{{ item.gxdwmc || '' }}</div>
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
</div>
<div class="item-message" >{{ item.bcjjnr }}</div>
<div class="item-time">{{ item.bjsj || '' }}</div>
</div>
</template>
<script setup>
@ -65,6 +73,9 @@ const goDetail = (id, lx) => {
break;
case '05':
path = '/InstructionInformation'
break;
case '06':
path = '/policeReport'
break;
}
router.push({