Browse Source

修改提交

wangqin
Joe 10 months ago
parent
commit
34ff14f60b
  1. 75
      ruoyi-ui/src/views/JiHeExpressway/components/Descriptions.vue
  2. 2
      ruoyi-ui/src/views/JiHeExpressway/components/Dialog/utils.js
  3. 39
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/Proxy.vue
  4. 56
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/components/Text.vue
  5. 49
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/index.vue
  6. 15
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/utils/defaultValue.js
  7. 4
      ruoyi-ui/src/views/JiHeExpressway/components/Video/index.vue
  8. 14
      ruoyi-ui/src/views/JiHeExpressway/images/deviceType/ball_active.svg
  9. 5
      ruoyi-ui/src/views/JiHeExpressway/images/layer/事件专题/感知事件.svg
  10. 5
      ruoyi-ui/src/views/JiHeExpressway/images/layer/事件专题/感知事件_active.svg
  11. 5
      ruoyi-ui/src/views/JiHeExpressway/images/layer/事件专题/感知事件_fault.svg
  12. 4
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/DrivingGuidance/index.vue
  13. 166
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/PerceiveEvent/index.vue
  14. 165
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/TrafficIncidents/index.vue
  15. 131
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/ViewDetails/index.vue
  16. 3
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/HomeFilter/index.vue
  17. 4
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/index.vue
  18. 63
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/buttonEvent.js
  19. 41
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/httpList.js
  20. 11
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/layerImages.js
  21. 35
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/map.js
  22. 96
      ruoyi-ui/src/views/JiHeExpressway/utils/enum.js

75
ruoyi-ui/src/views/JiHeExpressway/components/Descriptions.vue

@ -1,29 +1,37 @@
<template> <template>
<div class='Descriptions keep-ratio' origin="left" :style="getStyle()"> <div class='Descriptions keep-ratio' origin="left" :style="getStyle()">
<div class="item" v-for="(item, index) in list" :key="`${item.key || item.label}${index}`" <div class="item" v-for="(item, index) in getResolveList" :key="`${item.key || item.label}${index}`"
:style="[gridStyle(item, index), transformStyle(itemStyle)]"> :style="[gridStyle(item, index), transformStyle(itemStyle)]">
<div class="title text" :style="transformStyle(titleStyle)"> <div class="text title" :style="{
<slot :name="`title-${item.key || item.label}`" :data="item">
{{ item.label || '-' }}:
</slot>
</div>
<div class="content text" :style="{
...transformStyle(titleStyle), ...transformStyle(titleStyle),
...getDisplayColor(item) width: labelWidth
}"> }">
<slot :name="`content-${item.key || item.label}`" :data="item"> <p>
{{ getText(item) || '-' }} <slot :name="`title-${item.key || item.label}`" :data="item">
</slot> {{ item.label || '-' }}
</slot>
</p>:
</div> </div>
<ContentText :style="transformStyle(titleStyle)" class="content text" :data="data" :_config="item">
<template #default="{ value }">
<slot :name="`content-${item.key || item.label}`" :value="value" :data="item">
{{ value }}
</slot>
</template>
</ContentText>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import * as EnumMap from "@screen/utils/enum.js" import { getContent } from "@screen/components/FormConfig/utils/index.js"
import ContentText from "@screen/components/FormConfig/components/Text.vue"
export default { export default {
name: 'Descriptions', name: 'Descriptions',
components: {
ContentText
},
props: { props: {
data: { data: {
type: Object, type: Object,
@ -45,6 +53,7 @@ export default {
type: String, type: String,
default: "2" default: "2"
}, },
labelWidth: String,
titleStyle: { titleStyle: {
type: [String, Object], type: [String, Object],
default: null default: null
@ -66,17 +75,19 @@ export default {
}) })
}, },
getText() { getText() {
return (item) => { return (item) => getContent(this.data, item)
const result = this.data[item.key]; },
getResolveList() {
if (item.enum) return EnumMap[item.enum][result]?.text; return this.list.reduce((prev, data) => {
const templateResult = item.key?.replace(/\$\{[^}]+\}/g, (key) => this.data[key.slice(2, -1)] || "-"); if (typeof data.visible === 'function') {
if (!data.visible(data)) return prev;
}
if (templateResult && templateResult != item.key) return templateResult prev.push(data);
return result || item.text; return prev
} }, [])
} }
}, },
methods: { methods: {
@ -98,19 +109,7 @@ export default {
return prev; return prev;
}, {}); }, {});
}, }
getDisplayColor(item) {
const style = {};
if (item.enum) {
const config = EnumMap[item.enum][this.data[item.key]];
if (config?.color) style.color = config.color;
}
return style;
},
} }
} }
</script> </script>
@ -126,17 +125,23 @@ export default {
font-weight: 400; font-weight: 400;
color: #FFF; color: #FFF;
line-height: 18px; line-height: 18px;
display: flex;
align-items: center;
gap: 3px; gap: 3px;
display: flex;
} }
.item { .item {
display: flex; display: flex;
align-items: center;
gap: 6px; gap: 6px;
.title { .title {
color: #3DE8FF; color: #3DE8FF;
p {
width: 100%;
text-align: justify;
text-align-last: justify;
}
} }
.content { .content {

2
ruoyi-ui/src/views/JiHeExpressway/components/Dialog/utils.js

@ -19,8 +19,6 @@ export function moveable(container, { target } = {}) {
const move = (e) => { const move = (e) => {
const { clientX, clientY } = e; const { clientX, clientY } = e;
console.log(clientX, clientY, "move");
container.style.transform = `translate3d(${ container.style.transform = `translate3d(${
clientX - x + lastPosition.clientX clientX - x + lastPosition.clientX
}px, ${clientY - y + lastPosition.clientY}px, 0)`; }px, ${clientY - y + lastPosition.clientY}px, 0)`;

39
ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/Proxy.vue

@ -0,0 +1,39 @@
<template>
<component :is="getComponent(item.type)" v-bind="getBindData(item)" v-model="obverseValue"
v-on="resolveListeners(item.ons)" :_config="item" />
</template>
<script>
export default {
name: 'Proxy',
inject: ['getComponent', 'getBindData', "getFormData"],
props: {
value: {},
item: Object
},
computed: {
obverseValue: {
get() {
return this.value
},
set(value) {
this.$emit("update:value", value)
}
}
},
methods: {
resolveListeners(callbacks) {
if (!callbacks) return;
const result = {};
for (const key in callbacks) {
result[key] = (...args) => callbacks[key](...args, this.getFormData(), this)
}
return result
},
}
}
</script>

56
ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/components/Text.vue

@ -0,0 +1,56 @@
<template>
<div class='TextData'>
<slot :value="getValue">
{{ getValue || '-' }}
</slot>
</div>
</template>
<script>
import * as EnumMap from "@screen/utils/enum.js";
import { get as pathGet } from "lodash";
export default {
name: 'TextData',
props: {
value: [String, Number],
data: Object,
_config: Object
},
computed: {
getValue() {
const item = this._config;
const result = this.data ? pathGet(this.data, item.key) : this.value;
if (item.enum) return EnumMap[item.enum][result]?.text || "-";
if (!this.data) return result;
const templateResult = item.key?.replace(
/\$\{[^}]+\}/g,
(key) => pathGet(this.data, key.slice(2, -1)) || "-"
);
if (templateResult && templateResult != item.key) return templateResult;
return result || item.text || "-";
},
getDisplayColor() {
const style = {};
if (this._config.enum) {
const config = EnumMap[this._config.enum][this.value];
if (config?.color) style.color = config.color;
}
return style;
},
},
}
</script>
<style lang='scss' scoped>
.TextData {}
</style>

49
ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/index.vue

@ -4,8 +4,9 @@
<ElFormItem class="formItem" :rules="getRules(item)" v-if="formItemVisible(item)" :key="item.key" <ElFormItem class="formItem" :rules="getRules(item)" v-if="formItemVisible(item)" :key="item.key"
:label="item.label" :style="gridStyle(item, index)"> :label="item.label" :style="gridStyle(item, index)">
<slot :name="item.key" :data="item" :formData="modelFormData"> <slot :name="item.key" :data="item" :formData="modelFormData">
<component :is="getComponent(item.type)" v-bind="getBindData(item)" v-model="modelFormData[item.key]" <ProxyCom :value="getValue(item)" :item="item" @update:value="data => updateValue(item, data)" />
v-on="resolveListeners(item.ons)" /> <!-- <component :is="getComponent(item.type)" v-bind="getBindData(item)" v-model="modelFormData[item.key]"
v-on="resolveListeners(item.ons)" /> -->
</slot> </slot>
</ElFormItem> </ElFormItem>
</template> </template>
@ -13,8 +14,11 @@
</template> </template>
<script> <script>
import { resolveName } from "./utils/index" import { resolveName } from "./utils/index";
import { reduceDefaultValue } from "./utils/defaultValue" import { reduceDefaultValue } from "./utils/defaultValue";
import { set as pathSet, get as pathGet } from "lodash";
import ProxyCom from "./Proxy.vue";
const files = require.context('./components', true, /^.\/[^/]+\/index\.vue$|^.\/[^/]+.vue$/); const files = require.context('./components', true, /^.\/[^/]+\/index\.vue$|^.\/[^/]+.vue$/);
@ -29,13 +33,13 @@ const components = files.keys().reduce((prev, key) => {
export default { export default {
name: 'FormConfig', name: 'FormConfig',
components: { components: {
// FormInput, ProxyCom
// FormTimePicker
}, },
provide() { provide() {
return { return {
getComponent: this.getComponent, getComponent: this.getComponent,
getBindData: this.getBindData getBindData: this.getBindData,
getFormData: () => this.modelFormData
} }
}, },
props: { props: {
@ -65,7 +69,8 @@ export default {
column: { column: {
type: [String, Number], type: [String, Number],
default: "3" default: "3"
} },
value: Object
}, },
model: { model: {
prop: 'value', prop: 'value',
@ -73,11 +78,12 @@ export default {
}, },
data() { data() {
return { return {
formData: this.value || {} formData: {}
} }
}, },
created() { created() {
this.reset(); this.reset(true);
console.log("%c [ this.formData ]-82-「index.vue」", "font-size:15px; background:#9c7eed; color:#e0c2ff;", this.formData);
}, },
computed: { computed: {
modelFormData: { modelFormData: {
@ -86,6 +92,7 @@ export default {
}, },
set(data) { set(data) {
this.formData = data; this.formData = data;
this.$emit('update:value', this.formData); this.$emit('update:value', this.formData);
} }
}, },
@ -108,20 +115,14 @@ export default {
} }
}, },
methods: { methods: {
resolveListeners(callbacks) { getValue(item) {
return pathGet(this.formData, item.key)
if (!callbacks) return; },
updateValue(item, data) {
const result = {}; pathSet(this.modelFormData, item.key, data);
for (const key in callbacks) {
result[key] = (...args) => callbacks[key](...args, this.modelFormData, this)
}
return result
}, },
reset() { reset(isFirst) {
return this.modelFormData = reduceDefaultValue(this.formList); return this.modelFormData = reduceDefaultValue(this.formList, isFirst ? this.value : {});
}, },
getStyle() { getStyle() {
return { return {
@ -215,7 +216,7 @@ export default {
// font-family: PingFang SC, PingFang SC; // font-family: PingFang SC, PingFang SC;
font-weight: 400; font-weight: 400;
color: #3DE8FF; color: #3DE8FF;
line-height: 19px; line-height: unset;
// -webkit-background-clip: text; // -webkit-background-clip: text;
// -webkit-text-fill-color: transparent; // -webkit-text-fill-color: transparent;
} }

15
ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/utils/defaultValue.js

@ -1,4 +1,5 @@
import { resolveName } from "./index"; import { resolveName } from "./index";
import { set as pathSet, get as pathGet } from "lodash";
export const presetDefaultValue = { export const presetDefaultValue = {
Select(item) { Select(item) {
@ -19,7 +20,9 @@ export const presetDefaultValue = {
}, },
}; };
export function getDefaultValue(item) { export function getDefaultValue(item, data) {
if (data && typeof data !== "object") return data;
if (item.hasOwnProperty("default")) return item.default; if (item.hasOwnProperty("default")) return item.default;
const getValue = presetDefaultValue[resolveName(item.type)]; const getValue = presetDefaultValue[resolveName(item.type)];
@ -27,11 +30,17 @@ export function getDefaultValue(item) {
return typeof getValue === "function" ? getValue(item) : null; return typeof getValue === "function" ? getValue(item) : null;
} }
export function reduceDefaultValue(formList) { export function reduceDefaultValue(formList, data) {
if (!Array.isArray(formList)) return null; if (!Array.isArray(formList)) return null;
return formList.reduce((prev, cur) => { return formList.reduce((prev, cur) => {
if (cur.key) prev[cur.key] = getDefaultValue(cur); if (cur.key)
pathSet(
prev,
cur.key,
getDefaultValue(cur, pathGet(data || {}, cur.key))
);
// prev[cur.key] = getDefaultValue(cur, pathGet(data || {}, cur.key));
return prev; return prev;
}, {}); }, {});

4
ruoyi-ui/src/views/JiHeExpressway/components/Video/index.vue

@ -114,8 +114,8 @@ export default {
.video-stream { .video-stream {
width: 100%; width: 100%;
// height: 100%; height: 100%;
height: 240px; // height: 240px;
} }
} }
</style> </style>

14
ruoyi-ui/src/views/JiHeExpressway/images/deviceType/ball_active.svg

@ -0,0 +1,14 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 10232">
<g id="Frame" clip-path="url(#clip0_507_49)">
<path id="Vector" d="M16.0002 13.451C16.3331 13.4513 16.6584 13.5502 16.9351 13.7353C17.2118 13.9204 17.4274 14.1834 17.5546 14.4911C17.6819 14.7987 17.715 15.1372 17.6499 15.4636C17.5848 15.7901 17.4244 16.09 17.1889 16.3253C16.9534 16.5606 16.6535 16.7208 16.3269 16.7857C16.0004 16.8505 15.662 16.8171 15.3545 16.6897C15.0469 16.5622 14.7841 16.3464 14.5991 16.0696C14.4142 15.7928 14.3155 15.4674 14.3155 15.1345C14.3158 14.6879 14.4935 14.2597 14.8094 13.944C15.1253 13.6283 15.5536 13.451 16.0002 13.451ZM16.0002 12.1082C15.4014 12.1082 14.8161 12.2857 14.3182 12.6184C13.8203 12.9511 13.4323 13.4239 13.2031 13.9771C12.974 14.5303 12.914 15.139 13.0308 15.7263C13.1476 16.3136 13.436 16.8531 13.8594 17.2765C14.2828 17.6999 14.8223 17.9882 15.4095 18.105C15.9968 18.2219 16.6056 18.1619 17.1588 17.9328C17.712 17.7036 18.1848 17.3156 18.5175 16.8177C18.8502 16.3198 19.0277 15.7345 19.0277 15.1357C19.0277 14.3327 18.7087 13.5627 18.141 12.9949C17.5732 12.4271 16.8031 12.1082 16.0002 12.1082Z" fill="#FFDB82"/>
<path id="Vector_2" d="M16.0006 6C10.9558 6 6.86621 10.0896 6.86621 15.1343C6.86621 20.1791 10.9563 24.2684 16.0006 24.2684C21.0448 24.2684 25.1347 20.1791 25.1347 15.1343C25.1347 10.0896 21.0453 6 16.0006 6ZM16.0006 7.51694C16.1633 7.51694 16.3225 7.56521 16.4578 7.65565C16.5932 7.74608 16.6987 7.87463 16.761 8.02502C16.8232 8.17541 16.8395 8.3409 16.8078 8.50056C16.776 8.66021 16.6976 8.80686 16.5825 8.92197C16.4674 9.03708 16.3208 9.11546 16.1611 9.14722C16.0015 9.17898 15.836 9.16268 15.6856 9.10038C15.5352 9.03809 15.4067 8.9326 15.3162 8.79725C15.2258 8.6619 15.1775 8.50277 15.1775 8.33999C15.1775 8.23189 15.1987 8.12485 15.2401 8.02498C15.2814 7.92511 15.3421 7.83437 15.4185 7.75793C15.4949 7.6815 15.5857 7.62087 15.6856 7.57952C15.7854 7.53817 15.8925 7.51691 16.0006 7.51694ZM16.0006 19.5655C15.1241 19.5656 14.2673 19.3057 13.5385 18.8188C12.8097 18.3319 12.2417 17.6398 11.9063 16.83C11.5708 16.0203 11.483 15.1293 11.654 14.2696C11.825 13.41 12.2471 12.6204 12.8668 12.0006C13.4866 11.3809 14.2762 10.9588 15.1358 10.7878C15.9955 10.6168 16.8865 10.7046 17.6963 11.04C18.506 11.3755 19.1981 11.9435 19.685 12.6723C20.1719 13.4011 20.4318 14.2579 20.4317 15.1343C20.4317 15.7163 20.3171 16.2925 20.0944 16.8301C19.8717 17.3677 19.5453 17.8562 19.1339 18.2677C18.7224 18.6791 18.2339 19.0055 17.6963 19.2282C17.1587 19.4509 16.5825 19.5655 16.0006 19.5655Z" fill="#FFDB82"/>
<path id="Vector_3" d="M15.9997 25.4203C14.1167 25.4232 12.2693 24.9068 10.6608 23.9277L8.58887 25.9999H23.4106L21.3384 23.9277C19.73 24.9068 17.8827 25.4233 15.9997 25.4203Z" fill="#FFDB82"/>
</g>
</g>
<defs>
<clipPath id="clip0_507_49">
<rect width="20" height="20" fill="white" transform="translate(6 6)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

5
ruoyi-ui/src/views/JiHeExpressway/images/layer/事件专题/感知事件.svg

@ -0,0 +1,5 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 427319027">
<path id="Vector" d="M15.8568 13.2606C13.9313 13.2606 12.3697 14.8426 12.3697 16.794C12.3697 18.7462 13.9321 20.3283 15.8568 20.3283C17.7815 20.3283 19.3438 18.7462 19.3438 16.794C19.3438 14.8426 17.7815 13.2606 15.8568 13.2606ZM10.548 11.2377C7.83975 14.386 7.84446 19.1125 10.548 22.2867L11.6247 21.1959C9.51609 18.6339 9.51609 14.8804 11.6333 12.3403L10.5488 11.2377H10.548ZM9.14514 9.81441L8.0936 8.74951C4.0509 12.9698 4.04382 20.5656 8.06766 24.7977L9.14435 23.7069C5.66986 19.7459 5.66593 13.751 9.14435 9.81441H9.14514ZM21.1774 11.2369L20.0928 12.3356C22.21 14.8804 22.214 18.6291 20.1038 21.1928L21.1805 22.2836C23.8809 19.1125 23.8809 14.3852 21.1774 11.2377V11.2369ZM23.6357 8.7503L22.5833 9.8152C26.0594 13.7487 26.0555 19.7467 22.5833 23.71L23.6577 24.8024C27.6847 20.5664 27.6737 12.9706 23.6357 8.7503Z" fill="#0FD4FF"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 969 B

5
ruoyi-ui/src/views/JiHeExpressway/images/layer/事件专题/感知事件_active.svg

@ -0,0 +1,5 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 427319028">
<path id="Vector" d="M15.8568 13.2606C13.9313 13.2606 12.3697 14.8426 12.3697 16.794C12.3697 18.7462 13.9321 20.3283 15.8568 20.3283C17.7815 20.3283 19.3438 18.7462 19.3438 16.794C19.3438 14.8426 17.7815 13.2606 15.8568 13.2606ZM10.548 11.2377C7.83975 14.386 7.84446 19.1125 10.548 22.2867L11.6247 21.1959C9.51609 18.6339 9.51609 14.8804 11.6333 12.3403L10.5488 11.2377H10.548ZM9.14514 9.81441L8.0936 8.74951C4.0509 12.9698 4.04382 20.5656 8.06766 24.7977L9.14435 23.7069C5.66986 19.7459 5.66593 13.751 9.14435 9.81441H9.14514ZM21.1774 11.2369L20.0928 12.3356C22.21 14.8804 22.214 18.6291 20.1038 21.1928L21.1805 22.2836C23.8809 19.1125 23.8809 14.3852 21.1774 11.2377V11.2369ZM23.6357 8.7503L22.5833 9.8152C26.0594 13.7487 26.0555 19.7467 22.5833 23.71L23.6577 24.8024C27.6847 20.5664 27.6737 12.9706 23.6357 8.7503Z" fill="#FFDB82"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 969 B

5
ruoyi-ui/src/views/JiHeExpressway/images/layer/事件专题/感知事件_fault.svg

@ -0,0 +1,5 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Frame 427319029">
<path id="Vector" d="M15.8568 13.2606C13.9313 13.2606 12.3697 14.8426 12.3697 16.794C12.3697 18.7462 13.9321 20.3283 15.8568 20.3283C17.7815 20.3283 19.3438 18.7462 19.3438 16.794C19.3438 14.8426 17.7815 13.2606 15.8568 13.2606ZM10.548 11.2377C7.83975 14.386 7.84446 19.1125 10.548 22.2867L11.6247 21.1959C9.51609 18.6339 9.51609 14.8804 11.6333 12.3403L10.5488 11.2377H10.548ZM9.14514 9.81441L8.0936 8.74951C4.0509 12.9698 4.04382 20.5656 8.06766 24.7977L9.14435 23.7069C5.66986 19.7459 5.66593 13.751 9.14435 9.81441H9.14514ZM21.1774 11.2369L20.0928 12.3356C22.21 14.8804 22.214 18.6291 20.1038 21.1928L21.1805 22.2836C23.8809 19.1125 23.8809 14.3852 21.1774 11.2377V11.2369ZM23.6357 8.7503L22.5833 9.8152C26.0594 13.7487 26.0555 19.7467 22.5833 23.71L23.6577 24.8024C27.6847 20.5664 27.6737 12.9706 23.6357 8.7503Z" fill="#FF5F5F"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 969 B

4
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/DrivingGuidance/index.vue

@ -23,14 +23,13 @@
import Dialog from "@screen/components/Dialog/index.vue"; import Dialog from "@screen/components/Dialog/index.vue";
import Button from "@screen/components/Buttons/Button.vue" import Button from "@screen/components/Buttons/Button.vue"
import Descriptions from '@screen/components/Descriptions.vue'; import Descriptions from '@screen/components/Descriptions.vue';
import CustomControlVideo from '@screen/components/CustomControlVideo/index.vue';
import DeviceControlDialog from "./components/DeviceControlDialog.vue" import DeviceControlDialog from "./components/DeviceControlDialog.vue"
import { getRoadInfoByStakeMark, getProduct } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" import { getRoadInfoByStakeMark, getProduct } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js"
import Video from "@screen/components/Video" import Video from "@screen/components/Video"
import { dialogDelayVisible } from "./../mixin" import { dialogDelayVisible } from "./../mixin"
// G35 K094+079 //
export default { export default {
name: 'DrivingGuidance', name: 'DrivingGuidance',
mixins: [dialogDelayVisible], mixins: [dialogDelayVisible],
@ -38,7 +37,6 @@ export default {
Dialog, Dialog,
Button, Button,
Descriptions, Descriptions,
CustomControlVideo,
DeviceControlDialog, DeviceControlDialog,
Video Video
}, },

166
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/PerceiveEvent/index.vue

@ -0,0 +1,166 @@
<template>
<Dialog v-model="obverseVisible" title="感知事件">
<div class="PerceiveEvent">
<Video class="item-video" />
<div class="chart"></div>
<Form class="form" :value="data" ref="FormConfigRef" :formList="formList" column="1" />
</div>
<template #footer>
<Button>误操作</Button>
<Button style="background-color: rgba(0, 179, 204, 0.3);">取消</Button>
<Button>确定</Button>
</template>
</Dialog>
</template>
<script>
import Dialog from "@screen/components/Dialog/index.vue";
import Button from "@screen/components/Buttons/Button.vue"
import Descriptions from '@screen/components/Descriptions.vue';
import Video from "@screen/components/Video";
import Form from '@screen/components/FormConfig';
// import { getRoadInfoByStakeMark, getProduct } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js"
import { dialogDelayVisible } from "./../mixin"
//
export default {
name: 'PerceiveEvent',
mixins: [dialogDelayVisible],
components: {
Dialog,
Button,
Descriptions,
Video,
Form
},
data() {
return {
activeName: 'first',
deviceControlVisible: false,
data: {
deviceType: "行车诱导",
deviceStation: "k094+079",
roadName: "G35济泽高速",
direction: "1",
deviceState: "0",
deviceVendors: "XXX厂家",
time: "2023/01/02 09:09:09"
},
formList: [
{
label: "报警时间:",
key: "warningTime",
type: "text",
},
{
label: "事件地点:",
key: "stakeMarkId",
type: "text",
},
{
label: "事件来源:",
key: "warningSource",
type: "text",
enum: "InfoWarningSource"
},
{
label: "事件类型:",
key: "warningType",
type: "select",
options: {
options: []
}
},
{
label: "细分类型:",
key: "warningSubclass",
type: "select",
},
{
label: "事件描述:",
key: "desc.duration",
options: {
type: "textarea",
maxlength: 100,
autosize: { minRows: 6, maxRows: 6 },
showWordLimit: true,
}
},
{
label: "影响车道:",
key: "lane",
type: "RadioGroup",
options: {
activeColor: "linear-gradient(180deg, #37E7FF 0%, #009BCC 100%)",
options: [
{
key: "0",
label: "应急",
},
{
key: "1",
label: "行",
},
{
key: "2",
label: "行2",
},
{
key: "3",
label: "行3",
},
{
key: "4",
label: "行4",
},
],
},
},
{
label: "持续时长:",
key: "parseOtherConfig.duration",
type: "text",
},
{
label: "天气情况:",
key: "createTime8",
type: "text",
},
]
}
},
async created() {
this.data = { ...this.dialogData, roadName: null }
console.log("%c [ this.data ]-108-「index.vue」", "font-size:15px; background:#1be811; color:#5fff55;", this.data);
},
methods: {
}
}
</script>
<style lang='scss' scoped>
.PerceiveEvent {
width: 870px;
color: #fff;
display: grid;
grid-template-columns: 1.2fr 1fr;
grid-template-rows: repeat(2, 1fr);
gap: 9px;
.item-video {
grid-area: 1/1/1/1;
}
.chart {
grid-area: 2/1/2/1;
background-color: #fff;
}
.form {
grid-area: 1/2/3/3;
}
}
</style>

165
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/TrafficIncidents/index.vue

@ -0,0 +1,165 @@
<template>
<Dialog v-model="obverseVisible" :title="dialogData._itemData && dialogData._itemData.title">
<div class="TrafficIncidents">
<Descriptions labelWidth="72px" :list="list" :data="data" style="gap: 18px" column="7" />
</div>
</Dialog>
</template>
<script>
import Dialog from "@screen/components/Dialog/index.vue";
import Descriptions from '@screen/components/Descriptions.vue';
// import { getRoadInfoByStakeMark, getProduct } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js"
import request from "@/utils/request";
import { dialogDelayVisible } from "./../mixin"
//
export default {
name: 'TrafficIncidents',
mixins: [dialogDelayVisible],
components: {
Dialog,
Descriptions,
},
data() {
return {
activeName: 'first',
deviceControlVisible: false,
data: {
deviceType: "行车诱导",
deviceStation: "k094+079",
roadName: "G35济泽高速",
direction: "1",
deviceState: "0",
deviceVendors: "XXX厂家",
},
list: [
{
label: '机构',
key: "origin",
gridColumn: '3'
},
{
label: '高速名称',
key: "roadName",
gridColumn: '3'
},
{
label: '感知时间',
key: "occurrenceTime",
gridColumn: '3',
visible: () => this.isPerceived
},
{
label: '桩号',
key: "stakeMark",
gridColumn: '3'
},
{
label: '事件源',
key: "stringEventSource",
gridColumn: '3'
},
{
label: '车道列表',
key: "roadName23",
gridColumn: '2'
},
{
label: '事件状态',
key: "eventState",
enum: "EventType",
gridColumn: '2'
},
{
label: '经/纬度',
key: "${longitude} / ${latitude}",
gridColumn: '3'
},
{
label: '发生时间',
key: "occurrenceTime",
gridColumn: '3'
},
{
label: '行驶方向',
key: "direction",
enum: "CameraDirectionEnum",
gridColumn: '3'
},
{
label: '完结时间',
key: "endTime",
gridColumn: '3'
},
{
label: '事件描述',
key: "description",
gridColumn: '5'
},
]
}
},
async created() {
this.data = { ...this.dialogData };
request({
url: `/business/trafficIncidents/getEventInfo/${this.dialogData.id}`,
method: "get"
})
.then(({ code, data }) => {
if (code != 200) return;
this.data = { ...data, ...this.data };
console.log(data)
}).catch((err) => {
});
},
methods: {
handleClickTabs() { }
}
}
</script>
<style lang='scss' scoped>
.TrafficIncidents {
width: 600px;
color: #fff;
display: flex;
flex-direction: column;
.camera-video {
flex: 1.5;
}
.tabs {
flex: 1;
display: flex;
flex-direction: column;
::v-deep {
.el-tabs__content {
flex: 1;
.el-tab-pane {
height: 100%;
}
}
}
}
.bottom {
margin-top: 12px;
display: flex;
gap: 9px;
align-items: center;
justify-content: end;
>div {
font-size: 16px;
padding: 6px 12px;
}
}
}
</style>

131
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/ViewDetails/index.vue

@ -1,131 +0,0 @@
<template>
<Dialog class="ViewDetails">
<div class="list-content">
<div class="list-item">
<span class="label">&nbsp;&nbsp;</span>
<span class="value">XX运管中心</span>
</div>
<div class="list-item">
<span class="label">高速名称</span>
<span class="value">G35济菏高速</span>
</div>
<div class="list-item">
<span class="label">感知时间</span>
<span class="value">2023-11-30 17:32:18</span>
</div>
<div class="list-item">
<span class="label"> &emsp;&emsp; </span>
<span class="value">K081+411</span>
</div>
<div class="list-item">
<span class="label"> </span>
<span class="value">视频AI</span>
</div>
<div class="list-item">
<span class="label">车道列表</span>
<span class="value">3</span>
<span class="event">事件状态</span>
<span class="event-value">上报</span>
</div>
<div class="list-item">
<span class="label"> / 纬度</span>
<span class="value">117.253,34.867</span>
</div>
<div class="list-item">
<span class="label">发生时间</span>
<span class="value">2023-11-06 17:09:55</span>
</div>
<div class="list-item">
<span class="label">行驶方向</span>
<span class="value">济南方向</span>
</div>
<div class="list-item">
<span class="label">完结时间</span>
<span class="value">2023-11-06 17:09:55</span>
</div>
<div class="list-item-describe">
<span class="label">事件描述</span>
<span class="value">2023-11-30 17:32:18 G35 K081+411 下行方向发生
撒撤落物(撒落物)事件</span>
</div>
</div>
<div class="video-presentation"></div>
</Dialog>
</template>
<script>
import Dialog from "@screen/components/Dialog/index.vue";
//
export default {
name: 'ViewDetails',
}
</script>
<style lang='scss' scoped>
.ViewDetails {
.video-presentation {
width: 100%;
height: 216px;
margin-top: 10px;
background: #00ebc1;
img {
width: 100%;
height: 100%;
}
}
.list-content {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.list-item {
width: 230px;
height: 35px;
display: flex;
align-items: center;
.label {
width: 90px;
display: inline-block;
font-size: 14px;
color: #3de8ff;
}
.labels {
width: 120px;
display: inline-block;
font-size: 14px;
color: #3de8ff;
}
.value {
font-size: 14px;
color: #ffffff;
display: flex;
align-items: center;
img {
display: inline-block;
// width: 20px;
// height: 20px;
margin-left: 10px;
}
}
.event {
font-size: 14px;
color: #3de8ff;
margin-left: 20px;
}
.event-value {
color: #19e1b1;
}
}
}
}
</style>

3
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/HomeFilter/index.vue

@ -5,14 +5,13 @@
<img src="@screen/images/home-filter/filter.svg"> <img src="@screen/images/home-filter/filter.svg">
</Button> </Button>
<div class="body"> <div class="body">
<div class="title"> <div class="title">
设备筛选 设备筛选
</div> </div>
<Form labelWidth="72px" column="1" class="form" ref="FormConfigRef" :formList="formList" /> <Form labelWidth="72px" column="1" class="form" ref="FormConfigRef" :formList="formList" />
<div class="footer"> <div class="footer">
<Button style="background-color: rgba(0, 179, 204, .3);" @click.native="handleResetForm"> <Button style="background-color: rgba(0, 179, 204, .3);" @click.native="handleResetForm">
重置 重置
</Button> </Button>

4
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/index.vue

@ -43,6 +43,8 @@ import Bg1 from "@screen/components/Decorations/bg-1.vue"
import DrivingGuidance from "./../Dialogs/DrivingGuidance/index.vue" import DrivingGuidance from "./../Dialogs/DrivingGuidance/index.vue"
import Camera from "./../Dialogs/Camera/index.vue"; import Camera from "./../Dialogs/Camera/index.vue";
import Broadcast from "./../Dialogs/Broadcast/index.vue"; import Broadcast from "./../Dialogs/Broadcast/index.vue";
import TrafficIncidents from "./../Dialogs/TrafficIncidents/index.vue";
import PerceiveEvent from "./../Dialogs/PerceiveEvent/index.vue";
import InfoBoard from "./../InfoBoard" import InfoBoard from "./../InfoBoard"
export default { export default {
@ -53,6 +55,8 @@ export default {
DrivingGuidance, DrivingGuidance,
InfoBoard, InfoBoard,
Broadcast, Broadcast,
TrafficIncidents,
PerceiveEvent,
Bg1 Bg1
}, },
data() { data() {

63
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/buttonEvent.js

@ -1,4 +1,8 @@
import { getDeviceList, getEventTopicList } from "./httpList"; import {
getDeviceList,
getEventTopicList,
getPerceiveEventList,
} from "./httpList";
import { delay } from "@screen/utils/common"; import { delay } from "@screen/utils/common";
import { Message } from "element-ui"; import { Message } from "element-ui";
import { EventTopics } from "@screen/utils/enum.js"; import { EventTopics } from "@screen/utils/enum.js";
@ -7,7 +11,7 @@ import { setMarkToMap } from "./map";
const cameraIcon = { const cameraIcon = {
// 球机 // 球机
"00": require("@screen/images/deviceType/ball.svg"), "00": require("@screen/images/deviceType/ball_active.svg"),
"01": require("@screen/images/deviceType/ball_fault.svg"), "01": require("@screen/images/deviceType/ball_fault.svg"),
}; };
@ -69,7 +73,7 @@ export const eventMap = {
.finally(() => loadingMessage.close()); .finally(() => loadingMessage.close());
if (!data) return; if (!data) return;
if (!data.length) return Message.warning(`没有${item.title}设备数据!`); if (!data.length) return Message.warning(`没有${item.title}事件数据!`);
eventMap[`地图路测设备/map_close`](item); eventMap[`地图路测设备/map_close`](item);
@ -92,6 +96,7 @@ export const eventMap = {
"地图路测设备/map_close"(item) { "地图路测设备/map_close"(item) {
cacheRemoveFunc[`地图路测设备/${item.title}`]?.(); cacheRemoveFunc[`地图路测设备/${item.title}`]?.();
}, },
// 事件 需要在地图显示的 // 事件 需要在地图显示的
async "地图事件专题/map"(item) { async "地图事件专题/map"(item) {
const loadingMessage = Message.info({ const loadingMessage = Message.info({
@ -121,12 +126,16 @@ export const eventMap = {
data, data,
(extData) => { (extData) => {
this.dialogConfig = { this.dialogConfig = {
component: null, component: "TrafficIncidents",
data: { data: {
...extData, ...extData,
parseOtherConfig: JSON.parse(extData.otherConfig || "{}"), parseOtherConfig: JSON.parse(extData.otherConfig || "{}"),
_itemData: item,
}, },
}; };
},
{
stateCallback: () => true,
} }
// config.options // config.options
); );
@ -134,4 +143,50 @@ export const eventMap = {
"地图事件专题/map_close"(item) { "地图事件专题/map_close"(item) {
cacheRemoveFunc[`地图事件专题/${item.title}`]?.(); cacheRemoveFunc[`地图事件专题/${item.title}`]?.();
}, },
// 感知事件
async "事件专题/感知事件"(item) {
const loadingMessage = Message.info({
message: `${item.title}位置加载中...`,
duration: 0,
customClass: "loading-message",
iconClass: "el-icon-loading",
});
const data = await getPerceiveEventList()
.then(async (data) => {
await delay(600);
return data;
})
.catch(() => {})
.finally(() => loadingMessage.close());
if (!data) return;
if (!data?.length) return Message.warning(`没有${item.title}数据!`);
eventMap[`事件专题/感知事件_close`](item);
cacheRemoveFunc[`事件专题/${item.title}`] = await setMarkToMap.call(
this,
item,
data,
(extData) => {
this.dialogConfig = {
component: "PerceiveEvent",
data: {
...extData,
parseOtherConfig: JSON.parse(extData.otherConfig || "{}"),
},
};
},
{
stateCallback: () => true,
}
// config.options
);
},
"事件专题/感知事件_close"(item) {
cacheRemoveFunc[`事件专题/${item.title}`]?.();
},
}; };

41
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/httpList.js

@ -175,7 +175,10 @@ const DeviceTypeMap = {
*/ */
export function getDeviceList(deviceType) { export function getDeviceList(deviceType) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!deviceType) return reject(); if (!deviceType) {
Message.error(`${DeviceTypeMap[deviceType]}设备加载失败!`);
return reject();
}
request({ request({
url: "/business/device/query", url: "/business/device/query",
@ -250,11 +253,15 @@ export function getProduct(productId) {
} }
/** /**
* 交通事件 列表 根据类型获取
* @param {number} eventType * @param {number} eventType
*/ */
export function getEventTopicList(eventType) { export function getEventTopicList(eventType) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!eventType) return reject(); if (!eventType) {
Message.error(`事件加载失败!`);
return reject();
}
request({ request({
url: `/business/trafficIncidents/getEventList/${eventType}`, url: `/business/trafficIncidents/getEventList/${eventType}`,
@ -263,13 +270,39 @@ export function getEventTopicList(eventType) {
.then(({ code, data }) => { .then(({ code, data }) => {
if (code != 200) { if (code != 200) {
reject(); reject();
return Message.error(`${DeviceTypeMap[deviceType]}事件加载失败!`); return Message.error(`事件加载失败!`);
} }
resolve(data); resolve(data);
}) })
.catch(() => { .catch(() => {
Message.error(`${DeviceTypeMap[deviceType]}事件加载失败!`); Message.error(`事件加载失败!`);
reject();
});
});
}
/**
* 感知事件根据类型获取
* @param {number} eventType
*/
export function getPerceiveEventList() {
return new Promise((resolve, reject) => {
request({
url: `/perceivedEvents/warning/perceivedEventsList`,
method: "POST",
data: {},
})
.then(({ code, rows }) => {
if (code != 200) {
reject();
return Message.error(`事件加载失败!`);
}
resolve(rows);
})
.catch(() => {
Message.error(`事件加载失败!`);
reject(); reject();
}); });
}); });

11
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/layerImages.js

@ -11,10 +11,15 @@ export function getLayerData() {
const resultData = []; const resultData = [];
layerData.keys().forEach((item) => { layerData.keys().forEach((item) => {
const [_, topic, title] = item.match(/[^/]+/g); const [_, topic, file] = item.match(/[^/]+/g);
const fileName = file.match(/[^._]+/)[0];
switch (topic) { switch (topic) {
case "事件专题": case "事件专题":
if (!EventTopics[title.match(/[^._]+/)[0]]) return; if (
!EventTopics[fileName.match(/[^._]+/)[0]] &&
!["感知事件"].includes(fileName)
)
return;
break; break;
} }
if (!layerDatas[topic]) { if (!layerDatas[topic]) {
@ -29,7 +34,7 @@ export function getLayerData() {
layerDatas[topic].children.push({ layerDatas[topic].children.push({
id: item, id: item,
title: title.replace(".svg", ""), title: fileName,
status: "", status: "",
}); });
}); });

35
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/map.js

@ -98,7 +98,7 @@ export async function setMarkToMap(
item, item,
data, data,
_markerClick, _markerClick,
{ iconCallback, content } = {} { iconCallback, content, stateCallback } = {}
) { ) {
const { mapIns } = this.getMap(); const { mapIns } = this.getMap();
@ -108,18 +108,18 @@ export async function setMarkToMap(
normal || normal ||
require(`@screen/images/layer${item.id.replace( require(`@screen/images/layer${item.id.replace(
/^\.|[^/]+(?=.svg$)/g, /^\.|[^/]+(?=.svg$)/g,
(data) => (data === "." ? "" : `${data}`) (data) => (data === "." ? "" : `${data}_active`)
)}`); )}`);
const fault = const fault =
fault || fault ||
require(`@screen/images/layer${item.id.replace( require(`@screen/images/layer${item.id.replace(
/^\.|[^/]+(?=.svg$)/g, /^\.|[^/]+(?=.svg$)/g,
(data) => (data === "." ? "" : `${data}_fault`) (data) => (data === "." ? `` : `${data}_fault`)
)}`); )}`);
const faultBg = require(`@screen/images/mapBg/fault.svg`); const faultBg = require(`@screen/images/mapBg/fault.svg`);
const normalBg = require(`@screen/images/mapBg/normal.svg`); const normalBg = require(`@screen/images/mapBg/active.svg`);
const markerClick = (e) => { const markerClick = (e) => {
const extData = e.target.getExtData(); const extData = e.target.getExtData();
@ -130,9 +130,13 @@ export async function setMarkToMap(
const markerCluster = await setMarkerCluster( const markerCluster = await setMarkerCluster(
mapIns, mapIns,
data.map((item) => { data.map((item) => {
const currentState =
typeof stateCallback === "function"
? stateCallback(item)
: item.deviceState == 1;
const deviceIcon = const deviceIcon =
typeof iconCallback === "function" && typeof iconCallback === "function" && iconCallback(currentState, item);
iconCallback(item.deviceState == 1, item);
return { return {
weight: 1, weight: 1,
@ -142,26 +146,21 @@ export async function setMarkToMap(
content: content:
content || content ||
`<div style=" `<div style="
background-image: url(${ background-image: url(${currentState ? normalBg : faultBg});
item.deviceState == 1 ? normalBg : faultBg
});
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
width: 51px; width: 51px;
height: 51px; height: 51px;
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
"> ">
<img style=" <img style="
min-width: 18px; min-width: 24px;
min-height: 18px; min-height: 24px;
max-width: 18px; width: 24px;
max-height: 18px; height: 24px;
margin-bottom: 12px; margin-top: 8.1px;
" src='${ " src='${deviceIcon ? deviceIcon : currentState ? normal : fault}'
deviceIcon ? deviceIcon : item.deviceState == 1 ? normal : fault
}'
> >
</div>`, </div>`,
}; };

96
ruoyi-ui/src/views/JiHeExpressway/utils/enum.js

@ -85,3 +85,99 @@ export const EventTopics = {
异常天气: 10, 异常天气: 10,
其他事件: 11, 其他事件: 11,
}; };
// 事件类型 eventType
export const EventType = {
0: "待确认",
1: "处理中",
2: "已完成",
};
// 信息来源 warningSource
export const InfoWarningSource = {
1: {
text: "视频AI",
},
2: {
text: "雷达识别",
},
3: {
text: "锥桶",
},
4: {
text: "护栏碰撞",
},
5: {
text: "扫码报警",
},
6: {
text: "非机预警",
},
};
// 事件主类 warningType
export const WarningType = {
1: "交通拥堵",
2: "行人",
3: "非机动车",
4: "停车",
5: "倒车/逆行",
6: "烟火",
7: "撒落物",
8: "异常天气",
9: "护栏碰撞",
};
// 事件主类的子类(上方) warningSubclass
export const WarningSubclass = {
1: {
"1-1": "拥堵",
"1-2": "缓行",
},
2: {
"2-1": "普通行人",
"2-2": "工作人员",
},
3: {
"3-1": "摩托车",
"3-2": "自行车",
"3-3": "三轮车",
},
4: {
"4-1": "非工程车",
"4-2": "工程车",
"4-3": "主路有车",
"4-4": "匝道有车",
"4-5": "车辆故障",
"4-6": "交通事故",
"4-7": "应急车道被占用",
"4-8": "车离开应急车道",
"4-9": "其他",
},
5: {
"5-1": "倒车_逆行",
},
6: {
"6-1": "烟火",
},
7: {
"7-1": "撒落物",
},
8: {
"8-1": "雨",
"8-2": "冰雹",
"8-3": "风",
"8-4": "雾",
"8-5": "高温",
"8-6": "积水",
"8-7": "路面湿滑",
"8-8": "路面结冰",
"8-9": "道路能见度低",
"8-10": "道路团雾",
},
9: {
"9-1": "只碰撞不倾斜",
"9-2": "只倾斜无碰撞",
"9-3": "碰撞后倾斜",
},
};

Loading…
Cancel
Save