luogang 3 mesiacov pred
rodič
commit
ee929a14eb

+ 3 - 3
plus-ui-ts/src/api/system/device/index.ts

@@ -8,7 +8,7 @@ import { DeviceVO, DeviceForm, DeviceQuery } from '@/api/system/device/types';
  * @returns {*}
  */
 
-export const listDevice = (query?: DeviceQuery): AxiosPromise<DeviceVO[]> => {
+export const listDevice = (query) => {
   return request({
     url: '/system/device/list',
     method: 'get',
@@ -31,7 +31,7 @@ export const getDevice = (id: string | number): AxiosPromise<DeviceVO> => {
  * 新增设备-摄像机
  * @param data
  */
-export const addDevice = (data: DeviceForm) => {
+export const addDevice = (data) => {
   return request({
     url: '/system/device',
     method: 'post',
@@ -43,7 +43,7 @@ export const addDevice = (data: DeviceForm) => {
  * 修改设备-摄像机
  * @param data
  */
-export const updateDevice = (data: DeviceForm) => {
+export const updateDevice = (data) => {
   return request({
     url: '/system/device',
     method: 'put',

BIN
plus-ui-ts/src/assets/images/demo.mp4


+ 15 - 0
plus-ui-ts/src/assets/images/monitor-event.svg

@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 36.2722168" class="design-iconfont">
+  <defs>
+    <clipPath id="co767u2ld__j7r4tz3t9a">
+      <rect x="9" y="8" width="16" height="16" rx="0"/>
+    </clipPath>
+  </defs>
+  <g fill-rule="evenodd">
+    <path d="M16,36.2722C17.1428,36.2722,18.2575,31.8802,19.3325,31.6525C26.5695,30.1192,32,23.6938,32,16C32,7.16344,24.8366,0,16,0C7.16344,0,0,7.16344,0,16C0,23.7698,5.53827,30.246,12.8825,31.6965C13.8908,31.8956,14.9332,36.2722,16,36.2722Z" fill="#FFF"/>
+    <path d="M16,36.2722C17.1428,36.2722,18.2575,31.8802,19.3325,31.6525C26.5695,30.1192,32,23.6938,32,16C32,7.16344,24.8366,0,16,0C7.16344,0,0,7.16344,0,16C0,23.7698,5.53827,30.246,12.8825,31.6965C13.8908,31.8956,14.9332,36.2722,16,36.2722ZM16.0532,34.9775Q16.0402,34.9972,16.0277,35.0157L16.0239,35.0096Q15.7826,34.6213,15.2671,33.5102Q14.0604,30.9098,13.0763,30.7154Q7.86932,29.6871,4.45635,25.579Q1,21.4186,0.999999,16Q1,9.7868,5.3934,5.3934Q9.78679,1,16,0.999999Q22.2132,1,26.6066,5.3934Q31,9.78679,31,16Q31,21.3631,27.6068,25.5025Q24.2589,29.5866,19.1252,30.6742Q18.1356,30.8838,16.866,33.461Q16.3125,34.5845,16.0532,34.9775Z" fill="#DBDBDB"/>
+  </g>
+  <path fill="#FF3535" d="M16 3A13 13 0 1 0 16 29A13 13 0 1 0 16 3Z"/>
+  <g clip-path="url(#co767u2ld__j7r4tz3t9a)">
+    <path d="M12.35,18.700048828125L10.65,18.700048828125L10.65,16.550048828125L9,16.250048828125L9,23.150048828125L10.65,22.600048828125L10.65,20.200048828125L13.3,20.200048828125L14.75,18.250048828125L12.85,17.250048828125L12.35,18.700048828125ZM20.95,19.150048828125L24.8,16.700048828125L12.8,8.800048828125L11.4,8.800048828125L9.5,11.800048828125L9.5,12.800048828125L20.05,19.200048828125L20.95,19.200048828125L20.95,19.150048828125ZM19.5,19.650048828125L10.4,13.750048828125L9.45,14.750048828125L20,21.150048828125L20.95,21.150048828125L21.45,20.650048828125L21.95,19.200048828125C21.95,19.200048828125,20.55,20.200048828125,20.5,20.200048828125C19.95,19.850048828125,19.5,19.650048828125,19.5,19.650048828125Z" fill="#FFF" style="mix-blend-mode:passthrough"/>
+  </g>
+</svg>

+ 23 - 12
plus-ui-ts/src/views/device/deviceList/index.vue

@@ -48,7 +48,8 @@
       <el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="编号" align="center" prop="id" />
-        <el-table-column label="名称" align="center" prop="name" />
+        <el-table-column label="名称" align="center" show-overflow-tooltip prop="name" />
+        <el-table-column label="地址" align="center" show-overflow-tooltip prop="ext1.addr" />
         <el-table-column label="方向" align="center" prop="direction" />
         <el-table-column label="桩号" align="center" prop="zh" />
         <el-table-column label="经度" align="center" prop="lon" />
@@ -70,16 +71,21 @@
     <!-- 添加或修改设备-摄像机对话框 -->
     <el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body>
       <el-form ref="deviceFormRef" label-position="top" label-suffix=":" :model="form" label-width="80px">
-        <el-row>
-          <el-col :span="24">
+        <el-row :gutter="20">
+          <el-col :span="12">
             <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder="请输入名称" /> </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
+            <el-form-item label="地址" prop="ext1.addr">
+              <el-input v-model="form.ext1.addr" placeholder="请输入地址" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
             <el-form-item label="方向" prop="direction">
               <el-input v-model="form.direction" placeholder="请输入方向" />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="桩号" prop="zh">
               <el-input v-model="form.zh" placeholder="请输入桩号" />
             </el-form-item>
@@ -103,7 +109,7 @@
 
 <script setup name="Device" lang="ts">
 import { listDevice, getDevice, delDevice, addDevice, updateDevice } from '@/api/system/device';
-import { DeviceVO, DeviceQuery, DeviceForm } from '@/api/system/device/types';
+import { DeviceVO, DeviceForm } from '@/api/system/device/types';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
@@ -124,14 +130,16 @@ const dialog = reactive<DialogOption>({
   title: ''
 });
 
-const initFormData: DeviceForm = {
+const initFormData = {
   id: undefined,
   name: undefined,
   direction: undefined,
   zh: undefined,
   lon: undefined,
   lat: undefined,
-  ext1: undefined,
+  ext1: {
+    addr: undefined
+  } as any,
   ext2: undefined
 };
 const data = reactive({
@@ -144,8 +152,6 @@ const data = reactive({
     zh: undefined,
     lon: undefined,
     lat: undefined,
-    ext1: undefined,
-    ext2: undefined,
     params: {}
   }
 });
@@ -156,7 +162,10 @@ const { queryParams, form } = toRefs(data);
 const getList = async () => {
   loading.value = true;
   const res = await listDevice(queryParams.value);
-  deviceList.value = res.rows;
+  deviceList.value = res.rows.map((item) => ({
+    ...item,
+    ext1: item.ext1 && JSON.parse(item.ext1)
+  }));
   total.value = res.total;
   loading.value = false;
 };
@@ -221,7 +230,7 @@ const handleAdd = () => {
   dialog.visible = true;
   dialog.title = '添加设备';
   nextTick(() => {
-    initMap();
+    initMap(null);
   });
 };
 
@@ -230,6 +239,7 @@ const handleUpdate = async (row?: DeviceVO) => {
   reset();
   const _id = row?.id || ids.value[0];
   const res = await getDevice(_id);
+  res.data.ext1 && (res.data.ext1 = JSON.parse(res.data.ext1));
   Object.assign(form.value, res.data);
   dialog.visible = true;
   dialog.title = '修改设备';
@@ -248,6 +258,7 @@ const submitForm = () => {
   deviceFormRef.value?.validate(async (valid: boolean) => {
     if (valid) {
       buttonLoading.value = true;
+      form.value.ext1 = JSON.stringify(form.value.ext1);
       if (form.value.id) {
         await updateDevice(form.value).finally(() => (buttonLoading.value = false));
       } else {

+ 36 - 4
plus-ui-ts/src/views/index.vue

@@ -114,7 +114,10 @@
           />
         </div>
         <div style="margin-top: 10px">
-          <el-input v-model="queryParams.params.key" style="width: 210px" placeholder="输入地点关键词" :suffix-icon="Search" />
+          <el-select style="width: 210px" v-model="queryParams.params.deviceId" clearable placeholder="设备">
+            <el-option v-for="dict in deviceList" :key="dict.name" :label="dict.name" :value="dict.id"></el-option>
+          </el-select>
+          <el-input v-model="queryParams.params.key" style="margin-left: 10px; width: 165px" placeholder="输入地点关键词" :suffix-icon="Search" />
           <div style="margin-left: 10px">
             <el-button color="#1890FF" style="color: #fff" @click="getList">查询</el-button>
             <el-button @click="resetQuery">重置</el-button>
@@ -292,6 +295,7 @@
 import { Search } from '@element-plus/icons-vue';
 import BaseChart from '@/components/BaseChart/index.vue';
 import monitorIcon from '@/assets/images/monitor.svg';
+import monitorEventIcon from '@/assets/images/monitor-event.svg';
 import DPlayer from 'dplayer';
 import '@wangeditor/editor/dist/css/style.css'; // 引入 css
 import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
@@ -323,6 +327,7 @@ const queryParams = ref({
   params: {
     lx: undefined,
     key: undefined,
+    deviceId: undefined,
     beginCreateTime: '',
     endCreateTime: ''
   }
@@ -453,6 +458,7 @@ const reportForm = reactive({
 });
 const reportSeq = ref(0);
 const deviceList = ref([]);
+const hasEventDevices = ref([]);
 onMounted(() => {
   try {
     const map = new BMapGL.Map('map'); // 创建地图实例
@@ -641,6 +647,7 @@ const resetQuery = () => {
     params: {
       lx: undefined,
       key: undefined,
+      deviceId: undefined,
       beginCreateTime: '',
       endCreateTime: ''
     }
@@ -648,13 +655,30 @@ const resetQuery = () => {
   getList();
 };
 const getDeviceList = () => {
-  listDevice().then(({ code, rows }) => {
+  listDevice({}).then(async ({ code, rows }) => {
     if (code === 200) {
-      deviceList.value = rows;
+      await getHasEventDeviceList();
+      deviceList.value = rows.map((item) => {
+        let hasEvent = 0;
+        if (hasEventDevices.value.some((el) => el.id == item.id)) {
+          hasEvent = 1;
+        }
+        return {
+          ...item,
+          hasEvent
+        };
+      });
       showMarks();
     }
   });
 };
+const getHasEventDeviceList = async () => {
+  await listDevice({ params: { hasevent: '1' } }).then(({ code, rows }) => {
+    if (code === 200) {
+      hasEventDevices.value = rows;
+    }
+  });
+};
 onBeforeUnmount(() => {
   const editor = editorRef.value;
   if (editor == null) return;
@@ -666,8 +690,16 @@ const showMarks = () => {
     .filter((item) => item.lon && item.lat)
     .forEach((item) => {
       const pt = new BMapGL.Point(Number(item.lon), Number(item.lat));
-      const icon = new BMapGL.Icon(monitorIcon, new BMapGL.Size(30, 30));
+      const img = item.hasEvent == 1 ? monitorEventIcon : monitorIcon;
+      const icon = new BMapGL.Icon(img, new BMapGL.Size(30, 30));
       const marker = new BMapGL.Marker(pt, { icon });
+      marker.addEventListener('click', (e) => {
+        if (item.hasEvent == 1) {
+          queryParams.value.params.deviceId = item.id;
+          queryParams.value.pageNum = 1;
+          getList();
+        }
+      });
       bdmap.value.addOverlay(marker);
     });
 };