Browse Source

Merge branch 'develop' of http://39.106.31.193:9211/mengff/jihe-hs into develop

wangqin
王钦 1 year ago
parent
commit
e719797021
  1. 47
      ruoyi-ui/src/api/commandDispatch/index.js
  2. 27
      ruoyi-ui/src/views/JiHeExpressway/components/Descriptions.vue
  3. 170
      ruoyi-ui/src/views/JiHeExpressway/components/TimeLine/LineClick/index.vue
  4. 169
      ruoyi-ui/src/views/JiHeExpressway/components/TimeLine/TimeLine1/index.vue
  5. 178
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/Broadcast/components/BroadcastParamMulti.vue
  6. 361
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/FatigueWakesUp/components/DeviceControlDialog.vue
  7. 421
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/FatigueWakesUp/components/DeviceParam.vue
  8. 137
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/SmartDevice/components/DeviceParams.vue
  9. 207
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/SmartDevice/components/DeviceParamsMulti.vue
  10. 42
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/HomeFrameControl/index.vue
  11. 8
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/httpList.js
  12. 2
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/index.vue
  13. 41
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/CrowdnessIndicatorRankings/index.vue
  14. 55
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/DispatchLiaison/index.vue
  15. 356
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/DisposalProcess/DialogVisible/index.vue
  16. 194
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/DisposalProcess/index.vue
  17. 2566
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/EventInformation/components/EditEventInformationDialog/data.js
  18. 200
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/EventInformation/components/EditEventInformationDialog/index.vue
  19. 7
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/EventInformation/index.vue
  20. 29
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/EventDetailDialog/index.vue
  21. 18
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/FormEvent/PresetFormItems.js
  22. 4
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/FormEvent/data.js
  23. 2
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/FormEvent/index.vue
  24. 6
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/plan/addAndEditDialog/ScopeTable.vue
  25. 4
      ruoyi-ui/src/views/JiHeExpressway/pages/control/event/plan/addAndEditDialog/index.vue
  26. 29
      ruoyi-ui/src/views/JiHeExpressway/pages/maintenanceOperations/statisticalAnalysis/index.vue
  27. 19
      ruoyi-ui/src/views/JiHeExpressway/utils/common.js
  28. 4
      ruoyi-ui/vue.config.js

47
ruoyi-ui/src/api/commandDispatch/index.js

@ -1,7 +1,7 @@
import request from "@/utils/request";
// 查询事件气象
export function WeatherForecast(lng, lat) {
export function getWeatherForecast(lng, lat) {
return request({
url:
"/weatherForecast/queryTheSpecifiedLatitudeAndLongitudeWeather/" +
@ -13,10 +13,53 @@ export function WeatherForecast(lng, lat) {
}
// 查询调度联络
export function commandDispatch(data) {
export function postCommandDispatch(data) {
return request({
url: "/business/warning/commandAndDispatch",
method: "post",
data,
});
}
// 处置过程节点
export function getProcessNode(eventId) {
return request({
url: "/dc/system/event/getProcessNode/" + eventId,
method: "get",
});
}
// 处置过程记录
export function getProcessList(eventId) {
return request({
url: "/system/process/list/?eventId=" + eventId,
method: "get",
});
}
// 处置过程发送
export function postProcess(data) {
return request({
url: "/system/process",
method: "post",
data,
});
}
// 解除事件
export function postCompleteEvent(data) {
return request({
url: "/dc/system/event/completeEvent",
method: "post",
data,
});
}
// 无需清障
export function postNoSkipClear(data) {
return request({
url: "/dc/system/event/skipClear",
method: "post",
data,
});
}

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

@ -1,16 +1,8 @@
<template>
<div class="Descriptions keep-ratio" origin="left" :style="getStyle()">
<div
class="item"
v-for="(item, index) in getResolveList"
:key="`${item.key || item.label}${index}`"
:style="[gridStyle(item, index), transformStyle(itemStyle)]"
v-if="item.visible != false"
>
<div
class="text title"
:style="{ ...transformStyle(titleStyle), width: labelWidth }"
>
<div class="item" v-for="(item, index) in getResolveList" :key="`${item.key || item.label}${index}`"
:style="[gridStyle(item, index), transformStyle(itemStyle)]" v-if="item.visible != false">
<div v-if="!item.labelHidden" class="text title" :style="{ ...transformStyle(titleStyle), width: labelWidth }">
<p>
<slot :name="`title-${item.key || item.label}`" :data="item">
{{ item.label || "-" }}
@ -18,18 +10,9 @@
</p>
:
</div>
<ContentText
:style="transformStyle(titleStyle)"
class="content text"
:data="data"
:_config="item"
>
<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"
>
<slot :name="`content-${item.key || item.label}`" :value="value" :data="item">
{{ value }}
</slot>
</template>

170
ruoyi-ui/src/views/JiHeExpressway/components/TimeLine/LineClick/index.vue

@ -1,5 +1,5 @@
<template>
<div :class='["TimeLine1", { "auto-size": autoSize }]' ref="TimeLine1Ref">
<div :class="['TimeLine1', { 'auto-size': autoSize }]" ref="TimeLine1Ref">
<!-- 节点 -->
<div class="node" v-for="(item, index) in data" :key="index" ref="nodeRefs">
<span class="top-label keep-ratio-bottom">
@ -8,33 +8,49 @@
</slot>
</span>
<div class="center">
<div class="line" v-if="!index" :style="{ width: `${nodeLinesWidth[-1]}px` }" />
<div class="circle keep-ratio" :style="{ '--active-color': !item.isActive ? normalColor : activeColor }">
</div>
<div class="line" :style="{
width: `${nodeLinesWidth[index]}px`,
borderImage: getBorderImageStyle(item),
}" />
<div
class="line"
v-if="!index"
:style="{ width: `${nodeLinesWidth[-1]}px` }"
/>
<div
class="circle keep-ratio"
:style="{
'--active-color': !item.isActive ? normalColor : activeColor,
}"
></div>
<div
class="line"
:style="{
width: `${nodeLinesWidth[index]}px`,
borderImage: getBorderImageStyle(item),
}"
/>
</div>
<slot name="bottom-label" :data="item">
<div class="bottom keep-ratio" @click="onClick(item)"
:style="{ backgroundImage: `url(${require(`./images/bg${item.isActive ? '-active' : ''}.svg`)})` }">
<div
class="bottom keep-ratio"
@click="onClick(item)"
:style="{
backgroundImage: `url(${require(`./images/bg${
item.isActive ? '-active' : ''
}.svg`)})`,
}"
>
{{ item.label }}
</div>
</slot>
</div>
</div>
</template>
<script>
function getPositionAtCenter(element) {
const { top, left } = element.getBoundingClientRect();
return {
x: left,
y: top
y: top,
};
}
@ -42,73 +58,87 @@ function getDistanceBetweenElements(domA, domB) {
const domAPosition = getPositionAtCenter(domA);
const domBPosition = getPositionAtCenter(domB);
return Math.hypot(domAPosition.x - domBPosition.x, domAPosition.y - domBPosition.y);
return Math.hypot(
domAPosition.x - domBPosition.x,
domAPosition.y - domBPosition.y
);
}
export default {
name: 'TimeLine1',
name: "TimeLine1",
props: {
data: {
type: Array,
default: () => Array.from({ length: 15 }).map(() => ({
time: "16.36",
label: "阿发",
isActive: false
}))
default: () =>
Array.from({ length: 15 }).map(() => ({
time: "16.36",
label: "阿发",
isActive: false,
})),
},
activeColor: {
type: String,
default: "#39D5BF"
default: "#39D5BF",
},
normalColor: {
type: String,
default: "#ccc"
default: "#ccc",
},
lineActiveColor: {
type: String,
default: "linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)}) 2 2"
default:
"linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)}) 2 2",
},
lineNormalColor: {
type: String,
default: null
default: null,
},
//
autoSize: {
type: Boolean,
default: true
default: true,
},
filterDistance: {
type: Function,
default: null
}
default: null,
},
},
data() {
return {
nodeLinesWidth: {}
}
nodeLinesWidth: {},
};
},
watch: {
data: {
handler(data) {
let needFilter = false
let needFilter = false;
const nodeLinesWidth = [];
const filterDistance = num => needFilter ? this.filterDistance(num) : num;
const filterDistance = (num) =>
needFilter ? this.filterDistance(num) : num;
const removeDistance = 20 + 4 * 2;
function getDistance(index) {
return filterDistance(getDistanceBetweenElements(
this.$refs.nodeRefs[index].querySelector('.center'),
this.$refs.nodeRefs[index + 1].querySelector('.center'))
) - removeDistance
};
return (
filterDistance(
getDistanceBetweenElements(
this.$refs.nodeRefs[index].querySelector(".center"),
this.$refs.nodeRefs[index + 1].querySelector(".center")
)
) - removeDistance
);
}
function getSpecialDistance(index) {
return filterDistance(getDistanceBetweenElements(
this.$refs.nodeRefs[index].parentElement,
this.$refs.nodeRefs[index].querySelector('.center'))
) - removeDistance
return (
filterDistance(
getDistanceBetweenElements(
this.$refs.nodeRefs[index].parentElement,
this.$refs.nodeRefs[index].querySelector(".center")
)
) - removeDistance
);
}
const getLineWidths = () => {
@ -117,52 +147,60 @@ export default {
data.forEach((_, index) => {
if (index === data.length - 1) {
if (this.autoSize) {
nodeLinesWidth[-1] = getSpecialDistance.call(this, 0)
nodeLinesWidth[data.length - 1] = getSpecialDistance.call(this, data.length - 1)
nodeLinesWidth[-1] = getSpecialDistance.call(this, 0);
nodeLinesWidth[data.length - 1] = getSpecialDistance.call(
this,
data.length - 1
);
}
return
};
return;
}
nodeLinesWidth[index] = getDistance.call(this, index);
});
this.nodeLinesWidth = nodeLinesWidth;
}
};
this.$nextTick(() => {
const timeLine1RefDom = this.$refs.TimeLine1Ref;
if (timeLine1RefDom.clientWidth != timeLine1RefDom.getBoundingClientRect().width) {
needFilter = true
if (
timeLine1RefDom.clientWidth !=
timeLine1RefDom.getBoundingClientRect().width
) {
needFilter = true;
}
getLineWidths();
})
});
},
immediate: true
}
immediate: true,
},
},
methods: {
getBorderImageStyle(item) {
const linearColor = item.isActive ? (this.lineActiveColor || `${this.activeColor}, ${this.activeColor}`) : (this.lineNormalColor || `${this.normalColor}, ${this.normalColor}`)
const linearColor = item.isActive
? this.lineActiveColor || `${this.activeColor}, ${this.activeColor}`
: this.lineNormalColor || `${this.normalColor}, ${this.normalColor}`;
return `linear-gradient(90deg, ${linearColor}) 2 2`
return `linear-gradient(90deg, ${linearColor}) 2 2`;
},
onClick(item) {
this.data.forEach(it => {
this.data.forEach((it) => {
if (it.id == item.id) {
it.isActive = true;
} else {
it.isActive = false;
}
})
this.$emit('update:tableData', item.id);
});
this.$emit("update:tableData", item.id);
// console.log('data', item)
}
}
}
},
},
};
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
div.auto-size {
justify-content: space-between;
overflow: hidden;
@ -187,7 +225,7 @@ div.auto-size {
font-size: 14px;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
color: #ffffff;
display: flex;
flex-wrap: nowrap;
overflow: auto;
@ -215,7 +253,7 @@ div.auto-size {
position: relative;
.circle {
border: 1px solid var(--active-color, #39D5BF);
border: 1px solid var(--active-color, #39d5bf);
border-radius: 50%;
width: 15px;
height: 15px;
@ -230,18 +268,22 @@ div.auto-size {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: var(--active-color, #39D5BF);
background-color: var(--active-color, #39d5bf);
}
}
.line {
position: absolute;
height: 0px;
opacity: 1;
border: 2px solid;
//border-image: linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)) 2 2;
border-image: linear-gradient(90deg, rgb(204, 204, 204), rgb(204, 204, 204)) 2 / 1 / 0 stretch;
border-image: linear-gradient(
90deg,
rgb(204, 204, 204),
rgb(204, 204, 204)
)
2 / 1 / 0 stretch;
&:first-child {
right: calc(50% + 8px + 6px);

169
ruoyi-ui/src/views/JiHeExpressway/components/TimeLine/TimeLine1/index.vue

@ -1,5 +1,5 @@
<template>
<div :class='["TimeLine1", { "auto-size": autoSize }]' ref="TimeLine1Ref">
<div :class="['TimeLine1', { 'auto-size': autoSize }]" ref="TimeLine1Ref">
<!-- 节点 -->
<div class="node" v-for="(item, index) in data" :key="index" ref="nodeRefs">
<span class="top-label keep-ratio-bottom">
@ -8,33 +8,48 @@
</slot>
</span>
<div class="center">
<div class="line" v-if="!index" :style="{ width: `${nodeLinesWidth[-1]}px` }" />
<div class="circle keep-ratio" :style="{ '--active-color': !item.isActive ? normalColor : activeColor }">
</div>
<div class="line" :style="{
width: `${nodeLinesWidth[index]}px`,
borderImage: getBorderImageStyle(item),
}" />
<div
class="line"
v-if="!index"
:style="{ width: `${nodeLinesWidth[-1]}px` }"
/>
<div
class="circle keep-ratio"
:style="{
'--active-color': !item.isActive ? normalColor : activeColor,
}"
></div>
<div
class="line"
:style="{
width: `${nodeLinesWidth[index]}px`,
borderImage: getBorderImageStyle(item),
}"
/>
</div>
<slot name="bottom-label" :data="item">
<div class="bottom keep-ratio"
:style="{ backgroundImage: `url(${require(`./images/bg${item.isActive ? '-active' : ''}.svg`)})` }">
<div
class="bottom keep-ratio"
:style="{
backgroundImage: `url(${require(`./images/bg${
item.isActive ? '-active' : ''
}.svg`)})`,
}"
>
{{ item.label }}
</div>
</slot>
</div>
</div>
</template>
<script>
function getPositionAtCenter(element) {
const { top, left } = element.getBoundingClientRect();
return {
x: left,
y: top
y: top,
};
}
@ -42,73 +57,87 @@ function getDistanceBetweenElements(domA, domB) {
const domAPosition = getPositionAtCenter(domA);
const domBPosition = getPositionAtCenter(domB);
return Math.hypot(domAPosition.x - domBPosition.x, domAPosition.y - domBPosition.y);
return Math.hypot(
domAPosition.x - domBPosition.x,
domAPosition.y - domBPosition.y
);
}
export default {
name: 'TimeLine1',
name: "TimeLine1",
props: {
data: {
type: Array,
default: () => Array.from({ length: 15 }).map(() => ({
time: "16.36",
label: "阿发",
isActive: false
}))
default: () =>
Array.from({ length: 15 }).map(() => ({
time: "16.36",
label: "阿发",
isActive: false,
})),
},
activeColor: {
type: String,
default: "#39D5BF"
default: "#39D5BF",
},
normalColor: {
type: String,
default: "#ccc"
default: "#ccc",
},
lineActiveColor: {
type: String,
default: "linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)}) 2 2"
default:
"linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)}) 2 2",
},
lineNormalColor: {
type: String,
default: null
default: null,
},
//
autoSize: {
type: Boolean,
default: true
default: true,
},
filterDistance: {
type: Function,
default: null
}
default: null,
},
},
data() {
return {
nodeLinesWidth: {}
}
nodeLinesWidth: {},
};
},
watch: {
data: {
handler(data) {
let needFilter = false
let needFilter = false;
const nodeLinesWidth = [];
const filterDistance = num => needFilter ? this.filterDistance(num) : num;
const filterDistance = (num) =>
needFilter ? this.filterDistance(num) : num;
const removeDistance = 20 + 4 * 2;
function getDistance(index) {
return filterDistance(getDistanceBetweenElements(
this.$refs.nodeRefs[index].querySelector('.center'),
this.$refs.nodeRefs[index + 1].querySelector('.center'))
) - removeDistance
};
return (
filterDistance(
getDistanceBetweenElements(
this.$refs.nodeRefs[index].querySelector(".center"),
this.$refs.nodeRefs[index + 1].querySelector(".center")
)
) - removeDistance
);
}
function getSpecialDistance(index) {
return filterDistance(getDistanceBetweenElements(
this.$refs.nodeRefs[index].parentElement,
this.$refs.nodeRefs[index].querySelector('.center'))
) - removeDistance
return (
filterDistance(
getDistanceBetweenElements(
this.$refs.nodeRefs[index].parentElement,
this.$refs.nodeRefs[index].querySelector(".center")
)
) - removeDistance
);
}
const getLineWidths = () => {
@ -117,41 +146,49 @@ export default {
data.forEach((_, index) => {
if (index === data.length - 1) {
if (this.autoSize) {
nodeLinesWidth[-1] = getSpecialDistance.call(this, 0)
nodeLinesWidth[data.length - 1] = getSpecialDistance.call(this, data.length - 1)
nodeLinesWidth[-1] = getSpecialDistance.call(this, 0);
nodeLinesWidth[data.length - 1] = getSpecialDistance.call(
this,
data.length - 1
);
}
return
};
return;
}
nodeLinesWidth[index] = getDistance.call(this, index);
});
this.nodeLinesWidth = nodeLinesWidth;
}
};
this.$nextTick(() => {
const timeLine1RefDom = this.$refs.TimeLine1Ref;
if (timeLine1RefDom.clientWidth != timeLine1RefDom.getBoundingClientRect().width) {
needFilter = true
if (
timeLine1RefDom.clientWidth !=
timeLine1RefDom.getBoundingClientRect().width
) {
needFilter = true;
}
getLineWidths();
})
});
},
immediate: true
}
immediate: true,
},
},
methods: {
getBorderImageStyle(item) {
const linearColor = item.isActive ? (this.lineActiveColor || `${this.activeColor}, ${this.activeColor}`) : (this.lineNormalColor || `${this.normalColor}, ${this.normalColor}`)
const linearColor = item.isActive
? this.lineActiveColor || `${this.activeColor}, ${this.activeColor}`
: this.lineNormalColor || `${this.normalColor}, ${this.normalColor}`;
return `linear-gradient(90deg, ${linearColor}) 2 2`
}
}
}
return `linear-gradient(90deg, ${linearColor}) 2 2`;
},
},
};
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
div.auto-size {
justify-content: space-between;
overflow: hidden;
@ -176,7 +213,7 @@ div.auto-size {
font-size: 14px;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
color: #ffffff;
display: flex;
flex-wrap: nowrap;
overflow: auto;
@ -192,8 +229,9 @@ div.auto-size {
min-width: 90px;
.top-label {
line-height: 16px;
height: 24px;
line-height: 12px;
height: 20px;
text-align: center;
}
.center {
@ -202,9 +240,10 @@ div.auto-size {
justify-content: center;
gap: 6px;
position: relative;
margin-top: 5px;
.circle {
border: 1px solid var(--active-color, #39D5BF);
border: 1px solid var(--active-color, #39d5bf);
border-radius: 50%;
width: 15px;
height: 15px;
@ -219,17 +258,21 @@ div.auto-size {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: var(--active-color, #39D5BF);
background-color: var(--active-color, #39d5bf);
}
}
.line {
position: absolute;
height: 0px;
opacity: 1;
border: 2px solid;
border-image: linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)) 2 2;
border-image: linear-gradient(
90deg,
rgba(59, 216, 188, 1),
rgba(29, 171, 215, 1)
)
2 2;
&:first-child {
right: calc(50% + 8px + 6px);

178
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/Broadcast/components/BroadcastParamMulti.vue

@ -0,0 +1,178 @@
<template>
<div class="body">
<div class="right" :style="{ width: isMultiControl ? '100%' : undefined }">
<div class="top-content">
<Video v-if="!isMultiControl" class="item-video" :pileNum="pileNum" />
<label style="width: 99px;">发布内容: </label>
<ElInput type="textarea" v-model="releaseMessage" :autosize="{ minRows: 3, maxRows: 3 }" :maxlength="150"
showWordLimit placeholder="请输入发布内容" />
</div>
<!-- <div class="footer">
<Button @click.native="handleSubmit" :loading="submitting">
确定
</Button>
<Button style="background-color: rgba(0, 179, 204, 0.3)" @click.native="cancelClick">
取消
</Button>
</div> -->
</div>
</div>
</template>
<script>
import Dialog from "@screen/components/Dialog/index.vue";
import Button from "@screen/components/Buttons/Button.vue";
import Video from "@screen/components/Video";
import CheckboxGroup from "@screen/components/FormConfig/components/ElCheckboxGroup.vue";
import request from "@/utils/request";
import { batchFunctions } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js";
import { multiResultShow } from "@screen/utils/common";
import { Message } from "element-ui";
export default {
name: "BroadcastReleases",
components: {
Dialog,
Button,
Video,
CheckboxGroup,
},
model: {
prop: "visible",
event: "update:value",
},
props: {
visible: Boolean,
pileNum: String,
otherConfig: String,
isMultiControl: Boolean,
selectItems: {
type: Array,
default: () => []
}
},
data() {
return {
submitting: false,
checkList: [],
releaseMessage: null,
// musicList: [],
};
},
computed: {
modelVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:value", val);
},
},
},
created() {
// getDeviceList(5).then((data) => {
// if (Array.isArray(data))
// this.musicList = data.map((item) => ({
// ...item,
// disabled: item.deviceState != 1,
// }));
// });
},
methods: {
cancelClick() {
this.$emit("update:activeIcon", null);
this.$emit("update:submitting", false);
// this.submitting = false;
},
handleSubmit() {
const selectItems = this.selectItems.map(item => JSON.parse(item));
const checkList = selectItems.map(item => JSON.parse(item.otherConfig));
if (!this.releaseMessage?.trim())
return Message.error("发布内容不能为空!");
if (!selectItems.length)
return Message.error("请至少选择一个设备!");
// this.submitting = true;
this.$emit("update:submitting", true);
batchFunctions(
{
"devices": selectItems,
"functions": [
{
"functionId": "1",//便
"params": {
name: "task-3",
outVol: "6",
priority: "1",
text: this.releaseMessage.trim(),
repeatTimes: "3",
termList: checkList,
functionType: "startPaTts",
}
}
]
})
.then((data) => {
multiResultShow(data.data, item => item.result.retCode == 0, "广播设置");
})
.finally(() => {
// this.submitting = false;
this.$emit("update:submitting", false);
});
},
},
};
</script>
<style lang="scss" scoped>
.body {
display: flex;
gap: 9px;
height: 100%;
padding-right: 9px;
margin-top: 15px;
.right {
display: flex;
flex-direction: column;
justify-content: space-between;
.top-content {
display: flex;
flex-direction: row;
// gap: 9px;
align-items: center;
.item-video {
width: 545px;
}
label {
font-size: 15px;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #3de8ff;
line-height: 19px;
vertical-align: middle;
text-align: right;
padding-right: 12px;
box-sizing: border-box;
}
}
}
}
.footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 9px;
}
</style>

361
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/FatigueWakesUp/components/DeviceControlDialog.vue

@ -1,86 +1,8 @@
<template>
<Dialog v-model="modelVisible" title="设备操作" width="910px">
<div class="DeviceControlDialog">
<ElTabs v-model="activeName" class="tabs" @tab-click="tabClick">
<ElTabPane label="一般模式" name="first">
<Form v-model="formData" class="form" ref="FormConfigRef" :formList="formList1" column="1"
labelWidth="120px" />
</ElTabPane>
<ElTabPane label="自定义模式" name="second">
<!-- <div style="display: flex; margin: 20px 0">
<p style="width: 115px">工作时长():</p>
<el-input-number v-model="onWorkStatus2" :min="0" :max="999" label="工作时长(s分):"></el-input-number>
</div> -->
<Table :data="tableData">
<ElTableColumn prop="ds" label="段数"></ElTableColumn>
<ElTableColumn prop="time" width="120" label="时间(毫秒)">
<template slot-scope="scope">
<div style="display: flex">
<el-input-number style="width: 120px" v-model="scope.row.time" :min="0"></el-input-number>
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="A" label="线路A">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.A" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="B" label="线路B">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.B" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="C" label="线路C">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.C" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="D" label="线路D">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.D" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="E" label="线路E">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.E" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="F" label="线路F">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.F" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="G" label="线路G">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.G" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="H" label="线路H">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.H" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
</Table>
</ElTabPane>
</ElTabs>
<DeviceParam v-model="modelVisible" ref="DeviceParam" :deviceId="this.deviceId" :productId="this.productId">
</DeviceParam>
</div>
<template #footer>
@ -100,7 +22,7 @@ import Button from "@screen/components/Buttons/Button.vue";
import Form from "@screen/components/FormConfig";
import request from "@/utils/request";
import { Message } from "element-ui";
import DeviceParam from "./DeviceParam.vue";
export default {
name: "DeviceControlDialog",
components: {
@ -108,6 +30,7 @@ export default {
Button,
Form,
Table,
DeviceParam,
},
model: {
prop: "visible",
@ -121,153 +44,11 @@ export default {
data() {
return {
submitting: false,
activeName: "first",
onWorkStatus2: 0,
formData: {},
duan: [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
],
tableData: [
// {
// ds: 'A',
// time: 0,
// A: false,
// B: false,
// C: false,
// D: false,
// E: false,
// F: false,
// G: false,
// H: false,
// }
],
formList1: [
{
label: "工作模式:",
key: "controlType",
type: "select",
default: "1",
options: {
options: [
{
value: "0",
label: "激光关闭",
},
{
value: "1",
label: "常亮模式",
},
{
value: "2",
label: "间隔100ms闪烁模式",
},
{
value: "3",
label: "间隔200ms闪烁模式",
},
{
value: "4",
label: "间隔500ms闪烁模式",
},
{
value: "5",
label: "2次闪烁模式",
},
{
value: "6",
label: "SOS模式",
},
{
value: "7",
label: "自定义模式",
},
],
},
},
{
label: "工作时长(分):",
key: "onWorkStatus",
required: true,
default: 0,
type: "inputNumber",
options: {
min: 0,
max: 999,
},
},
],
formList2: [
{
label: "工作模式:",
key: "controlType",
type: "RadioGroup",
default: "00",
options: {
type: "circle",
options: [
{
key: "00",
label: "常量",
},
{
key: "01",
label: "闪烁",
},
],
},
},
{
label: "线路选择:",
key: "onWorkStatus2",
required: true,
type: "select",
options: {
placeholder: "请选择",
},
},
{
label: "工作时长:",
key: "onWorkStatus",
required: true,
type: "select",
options: {
placeholder: "请选择",
},
},
],
rules: {
onWorkStatus: [
{ required: true, message: "工作时长不能为空", trigger: "blur" },
],
},
};
},
computed: {
modelVisible: {
get() {
if (this.visible) {
// this.deviceId = 'K82+285';
this.initData();
}
return this.visible;
},
set(val) {
@ -275,141 +56,9 @@ export default {
},
},
},
// watch: {
// modelVisible: {
// immediate: true,
// handler(bool) {
// if (!bool) return;
// // this.requestURL();
// }
// }
// },
methods: {
async initData() {
//
let result = await this.requestURL("ASKMD");
// if (result.data == 7) {
// this.activeName = "second";
// this.tabClick();
// } else {
this.formData.controlType = result.data + "" || "1";
//
let resultTime = await this.requestURL("ASKTM");
this.formData.onWorkStatus = resultTime.data || 0;
this.activeName = "first";
// }
},
async requestURL(functionId, options = {}) {
let result = await request({
url: `/business/device/functions/${this.deviceId}/${functionId}`,
method: "post",
data: options,
});
if (result.code != 200) return Message.error(result?.msg);
//SETMDASKMDSETTMASKTMSETDFASKDF
console.log("aaaa", result);
return result;
},
async tabClick() {
if (this.activeName == "second") {
//
let result = await request({
url: `/business/device/properties/latest/${this.deviceId}`,
method: "get",
});
if (result.code != 200) return Message.error(result?.msg);
this.tableData = [];
let tData = [];
result.data.forEach((item) => {
if (item.property == "TM") {
this.onWorkStatus2 = item.value;
} else if (item.property == "MD") {
} else {
let data = JSON.parse(item.formatValue || {});
tData.push({ ...data, ds: item.property });
}
});
tData.sort((a, b) => a.ds.toUpperCase().localeCompare(b.ds.toUpperCase()));
this.tableData = tData;
} else {
//
let resultTime = await this.requestURL("ASKTM");
this.formData.onWorkStatus = resultTime.data || 0;
this.activeName = "first";
}
},
async handleSubmit() {
if (this.activeName == "first") {
//
this.$refs.FormConfigRef.validate().then(async (formData) => {
console.log("formData", formData);
//
await this.requestURL("SETMD", { SET: formData.controlType });
//
let res = await this.requestURL("SETTM", {
SET: formData.onWorkStatus,
});
console.log("res", res);
if (res.code == 200) {
Message.success("设置成功!");
this.$emit("update:value", false);
}
});
} else if (this.activeName == "second") {
//
let rData = [];
this.tableData.forEach((it, index) => {
rData.push({
functionId: "SETDF",
params: {
order: 7,
time: it.time,
numberOfSegments: it.ds || this.duan[index],
A: Number(it.A),
B: Number(it.B),
C: Number(it.C),
D: Number(it.D),
E: Number(it.E),
F: Number(it.F),
G: Number(it.G),
H: Number(it.H),
}
});
});
//
let res = await request({
url: `/business/device/batchFunctions`,
method: "post",
// data: {
// deviceId: this.deviceId,
// functionId: "SETDF",
// params: rData,
// },
data: {
devices: [{
iotDeviceId: this.deviceId,
id: this.productId,
deviceType: 10
}],
functions: rData
}
});
if (res.code == 200) {
Message.success("设置成功!");
this.$emit("update:value", false);
}
//
// let res = await this.requestURL("SETTM", { SET: this.onWorkStatus2 });
// if (res.code == 200) {
// Message.success("");
// this.$emit("update:value", false);
// }
}
this.$refs.DeviceParam?.handleSubmit();
},
},
};

421
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/FatigueWakesUp/components/DeviceParam.vue

@ -0,0 +1,421 @@
<template>
<div :style="{
'max-height': isMultiControl ? '250px' : undefined, 'overflow-y': isMultiControl ? 'auto' : undefined,
'margin-left': isMultiControl ? '14px' : undefined
}">
<ElTabs v-model="activeName" class="tabs" @tab-click="tabClick">
<ElTabPane label="一般模式" name="first">
<Form v-model="formData" class="form" ref="FormConfigRef" :formList="formList1" column="1" labelWidth="120px" />
</ElTabPane>
<ElTabPane label="自定义模式" name="second">
<!-- <div style="display: flex; margin: 20px 0">
<p style="width: 115px">工作时长():</p>
<el-input-number v-model="onWorkStatus2" :min="0" :max="999" label="工作时长(s分):"></el-input-number>
</div> -->
<Table :data="tableData">
<ElTableColumn prop="ds" label="段数"></ElTableColumn>
<ElTableColumn prop="time" width="120" label="时间(毫秒)">
<template slot-scope="scope">
<div style="display: flex">
<el-input-number style="width: 120px" v-model="scope.row.time" :min="0"></el-input-number>
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="A" label="线路A">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.A" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="B" label="线路B">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.B" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="C" label="线路C">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.C" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="D" label="线路D">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.D" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="E" label="线路E">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.E" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="F" label="线路F">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.F" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="G" label="线路G">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.G" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
<ElTableColumn prop="H" label="线路H">
<template slot-scope="scope">
<el-switch active-value="1" inactive-value="0" v-model="scope.row.H" active-color="#13ce66"
inactive-color="#C9C9C9">
</el-switch>
</template>
</ElTableColumn>
</Table>
</ElTabPane>
</ElTabs>
</div>
</template>
<script>
import Table from "@screen/components/Table.vue";
import Dialog from "@screen/components/Dialog/index.vue";
import Button from "@screen/components/Buttons/Button.vue";
import Form from "@screen/components/FormConfig";
import request from "@/utils/request";
import { Message } from "element-ui";
import { batchFunctions } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js";
import { multiResultShow } from "@screen/utils/common";
export default {
name: "DeviceControlDialog",
components: {
Dialog,
Button,
Form,
Table,
},
model: {
prop: "visible",
event: "update:value",
},
props: {
visible: Boolean,
deviceId: String,
productId: String,
isMultiControl: Boolean,
selectItems: {
type: Array,
default: () => []
}
},
data() {
return {
submitting: false,
activeName: "first",
onWorkStatus2: 0,
formData: {},
duan: [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
],
tableData: [
// {
// ds: 'A',
// time: 0,
// A: false,
// B: false,
// C: false,
// D: false,
// E: false,
// F: false,
// G: false,
// H: false,
// }
],
formList1: [
{
label: "工作模式:",
key: "controlType",
type: "select",
default: "1",
options: {
options: [
{
value: "0",
label: "激光关闭",
},
{
value: "1",
label: "常亮模式",
},
{
value: "2",
label: "间隔100ms闪烁模式",
},
{
value: "3",
label: "间隔200ms闪烁模式",
},
{
value: "4",
label: "间隔500ms闪烁模式",
},
{
value: "5",
label: "2次闪烁模式",
},
{
value: "6",
label: "SOS模式",
},
{
value: "7",
label: "自定义模式",
},
],
},
},
{
label: "工作时长(分):",
key: "onWorkStatus",
required: true,
default: 0,
type: "inputNumber",
options: {
min: 0,
max: 999,
},
},
],
formList2: [
{
label: "工作模式:",
key: "controlType",
type: "RadioGroup",
default: "00",
options: {
type: "circle",
options: [
{
key: "00",
label: "常量",
},
{
key: "01",
label: "闪烁",
},
],
},
},
{
label: "线路选择:",
key: "onWorkStatus2",
required: true,
type: "select",
options: {
placeholder: "请选择",
},
},
{
label: "工作时长:",
key: "onWorkStatus",
required: true,
type: "select",
options: {
placeholder: "请选择",
},
},
],
rules: {
onWorkStatus: [
{ required: true, message: "工作时长不能为空", trigger: "blur" },
],
},
};
},
mounted() {
if (!this.isMultiControl)
this.initData();
},
methods: {
async initData() {
//
let result = await this.requestURL("ASKMD");
// if (result.data == 7) {
// this.activeName = "second";
// this.tabClick();
// } else {
this.formData.controlType = result.data + "" || "1";
//
let resultTime = await this.requestURL("ASKTM");
this.formData.onWorkStatus = resultTime.data || 0;
this.activeName = "first";
// }
},
async requestURL(functionId, options = {}) {
let result = await request({
url: `/business/device/functions/${this.deviceId}/${functionId}`,
method: "post",
data: options,
});
if (result.code != 200) return Message.error(result?.msg);
//SETMDASKMDSETTMASKTMSETDFASKDF
return result;
},
async tabClick() {
if (this.activeName == "second") {
if (this.isMultiControl)
this.tableData = this.duan.map(item => {
return {
ds: item,
time: 0,
A: false,
B: false,
C: false,
D: false,
E: false,
F: false,
G: false,
H: false,
}
});
else {
//
let result = await request({
url: `/business/device/properties/latest/${this.deviceId}`,
method: "get",
});
if (result.code != 200) return Message.error(result?.msg);
this.tableData = [];
let tData = [];
result.data.forEach((item) => {
if (item.property == "TM") {
this.onWorkStatus2 = item.value;
} else if (item.property == "MD") {
} else {
let data = JSON.parse(item.formatValue || {});
tData.push({ ...data, ds: item.property });
}
});
tData.sort((a, b) => a.ds.toUpperCase().localeCompare(b.ds.toUpperCase()));
this.tableData = tData;
}
} else {
if (!this.isMultiControl) {
//
let resultTime = await this.requestURL("ASKTM");
this.formData.onWorkStatus = resultTime.data || 0;
this.activeName = "first";
}
}
},
async handleSubmit() {
if (this.isMultiControl && !this.selectItems.length) {
return Message.error("请至少选择一个设备!");
}
const selectItems = this.selectItems.map(item => JSON.parse(item));
let devices;
if (this.isMultiControl) devices = selectItems;
else devices = [{
iotDeviceId: this.deviceId,
id: this.productId,
deviceType: 10
}]
if (this.activeName == "first") {
//
this.$refs.FormConfigRef.validate().then(async (formData) => {
//
// await this.requestURL("SETMD", { SET: formData.controlType });
//
// let res = await this.requestURL("SETTM", {
// SET: formData.onWorkStatus,
// });
let res = await batchFunctions({
devices: devices,
functions: [
{ "functionId": "SETMD", "params": { SET: formData.controlType } },//
{
"functionId": "SETTM", "params": { //
SET: formData.onWorkStatus,
}
}
]
});
if (res.code == 200) {
Message.success("设置成功!");
this.$emit("update:value", false);
}
});
} else if (this.activeName == "second") {
//
let rData = [];
this.tableData.forEach((it, index) => {
rData.push({
functionId: "SETDF",
params: {
order: 7,
time: it.time,
numberOfSegments: it.ds || this.duan[index],
A: Number(it.A),
B: Number(it.B),
C: Number(it.C),
D: Number(it.D),
E: Number(it.E),
F: Number(it.F),
G: Number(it.G),
H: Number(it.H),
}
});
});
//
let res = await batchFunctions({
devices: devices,
functions: rData
});
if (res.code == 200) {
Message.success("设置成功!");
this.$emit("update:value", false);
}
//
// let res = await this.requestURL("SETTM", { SET: this.onWorkStatus2 });
// if (res.code == 200) {
// Message.success("");
// this.$emit("update:value", false);
// }
}
},
},
};
</script>
<style lang="scss" scoped></style>

137
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/SmartDevice/components/DeviceParams.vue

@ -4,9 +4,11 @@
<Descriptions :list="devicesList" style="gap: 18px;" column="5">
<template v-for="item in devicesList.slice(0, -1)" #[`content-${getSlotKey(item.key)}`]="{ data }">
<span>{{ data.text }}</span>
<Switcher v-if="!disabled" class="switcher" :activeOption="activeOption" :value="data.state"
<Switcher v-if="!disabled" class="switcher" :activeOption="activeOption" :value="data.state"
@change="(value) => handleSwitcherChange(value, data)" />
<ElTag style="margin-left: 20px;" v-else effect="dark" :type="data.state?'':'info'">{{ data.state?'开':'关' }}</ElTag>
<ElTag style="margin-left: 20px;" v-else effect="dark" :type="data.state ? '' : 'info'">{{ data.state ? '开' :
'关' }}
</ElTag>
</template>
</Descriptions>
</div>
@ -49,93 +51,93 @@ export default {
},
created() {
Promise.all([this.getAc(), this.getDc()]).then(res=>{
// if (result.code != 200) return;
Promise.all([this.getAc(), this.getDc()]).then(res => {
// if (result.code != 200) return;
let ac = res[0].data;
let dc = res[1].data;
let deviceInfo = _.merge({}, ac, dc);
const typeMap = {
ac: '220v',
dc: '12v',
}
for (const key in deviceInfo.formatValue) {
// electricity
// voltage
if (key.includes('electricity')) {
const args = key.match(/[a-z]+|[0-9]+$/g);
const typeMap = {
ac: '220v',
dc: '12v',
}
for (const key in deviceInfo.formatValue) {
// electricity
// voltage
if (key.includes('electricity')) {
const args = key.match(/[a-z]+|[0-9]+$/g);
const type = args[0], num = args.slice(-1)[0], prefix = args.slice(0, 2).join('_');
// console.log(type , num , prefix , "+++=========="); //dc 2 dc_out
this.devicesList.push(
{
label: `支路${num}${typeMap[type]}) 电压`,
key: `${prefix}_voltage_${num}`,
text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 3
},
{
label: '电流',
key: `${prefix}_electricity_${num}`,
text: deviceInfo.formatValue[key],
gridColumn: 2,
state: deviceInfo.value[key] > 0
}
);
}
const type = args[0], num = args.slice(-1)[0], prefix = args.slice(0, 2).join('_');
// console.log(type , num , prefix , "+++=========="); //dc 2 dc_out
this.devicesList.push(
{
label: `支路${num}${typeMap[type]}) 电压`,
key: `${prefix}_voltage_${num}`,
text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 3
},
{
label: '电流',
key: `${prefix}_electricity_${num}`,
text: deviceInfo.formatValue[key],
gridColumn: 2,
state: deviceInfo.value[key] > 0
}
);
}
this.devicesList.push(
{
label: '风扇',
key: `fan_status`,
// key: `aa_electricity_1`,
text: { 0: '正常', 1: '开' }[deviceInfo.formatValue['fan_status']] || '-',
gridColumn: 2,
state: (deviceInfo.formatValue['fan_status']==='0')
},
}
this.devicesList.push(
{
label: '风扇',
key: `fan_status`,
// key: `aa_electricity_1`,
text: { 0: '正常', 1: '开' }[deviceInfo.formatValue['fan_status']] || '-',
gridColumn: 2,
state: (deviceInfo.formatValue['fan_status'] === '0')
},
{
label: '温度',
key: `temperature`,
text: deviceInfo.formatValue['temperature'] ? `${deviceInfo.formatValue['temperature']} °C` : '-',
gridColumn: 2
},
{
{
label: '温度',
key: `temperature`,
text: deviceInfo.formatValue['temperature'] ? `${deviceInfo.formatValue['temperature']} °C` : '-',
gridColumn: 2
},
{
label: '箱门',
key: `door_status`,
text: { 0: '关闭', 1: '打开' }[deviceInfo.formatValue['door_status']] || '-',
gridColumn: 1
},
{
label: '湿度',
key: `humidity`,
text: deviceInfo.formatValue['humidity'] ? `${deviceInfo.formatValue['humidity']} %` : '-',
gridColumn: 2
},
{
label: '市电掉电',
key: `power_status`,
text: { 0: '正常', 1: '掉电' }[deviceInfo.formatValue['power_status']] || '-',
gridColumn: 2
},
)
// this.data = result.rows;
// this.total = result.total;
})
{
label: '湿度',
key: `humidity`,
text: deviceInfo.formatValue['humidity'] ? `${deviceInfo.formatValue['humidity']} %` : '-',
gridColumn: 2
},
{
label: '市电掉电',
key: `power_status`,
text: { 0: '正常', 1: '掉电' }[deviceInfo.formatValue['power_status']] || '-',
gridColumn: 2
},
)
// this.data = result.rows;
// this.total = result.total;
})
.finally(() => {
this.secondLoading = false
})
},
methods: {
getAc(){
getAc() {
return request({
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId || '10.0.36.143-1883'}/1ac`,
method: "get",
params: {}
})
},
getDc(){
getDc() {
return request({
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId || '10.0.36.143-1883'}/1dc`,
method: "get",
@ -145,17 +147,16 @@ export default {
async handleSwitcherChange(value, data) {
let str = data.state ? "关闭" : "开启";
let deviceName = "";
if(data.key.includes("fan")){
if (data.key.includes("fan")) {
str += "风扇?";
deviceName = "fan_out_en";
}else{
} else {
str += "该支路?"
deviceName = data.key.match(/^[a-z]+_out|[0-9]+/g).join("_") + "_en"; //dc_out_2_en ac_out_2_en;
}
data.state = value;
const isContinue = await confirm({ message: `${str}` })
.catch(() => {
console.log(data.state,value,333)
data.state = !value;
});

207
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/SmartDevice/components/DeviceParamsMulti.vue

@ -2,8 +2,8 @@
<div class='DeviceParams'>
<div class="no-data" v-if="!devicesList.length" v-loading="secondLoading">暂无设备参数</div>
<Descriptions :list="devicesList" style="gap: 18px;" column="5">
<template v-for="item in devicesList.slice(0, -1)" #[`content-${getSlotKey(item.key)}`]="{ data }">
<span>{{ data.text }}</span>
<template v-for="item in devicesList" #[`content-${item.key}`]="{ data }">
<span style="font-size: 15px;font-weight: 400;color: #3de8ff;">{{ data.text }}</span>
<Switcher v-if="!disabled" class="switcher" :activeOption="activeOption" :value="data.state"
@change="(value) => handleSwitcherChange(value, data)" />
<ElTag style="margin-left: 20px;" v-else effect="dark" :type="data.state ? '' : 'info'">{{ data.state ? '开' :
@ -17,10 +17,12 @@
<script>
import Descriptions from '@screen/components/Descriptions.vue';
import Switcher from '@screen/pages/service/PublishingChannelManagement/components/Switcher.vue';
import { cloneDeep } from 'lodash';
import request from "@/utils/request";
import { Message } from 'element-ui';
import { confirm } from "@screen/utils/common";
import { batchFunctions } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js";
import { multiResultShow } from "@screen/utils/common";
export default {
name: 'DeviceParams',
@ -34,12 +36,57 @@ export default {
default: () => ({})
},
disabled: Boolean,
isMultiControl: Boolean
isMultiControl: Boolean,
selectItems: {
type: Array,
default: () => []
}
},
data() {
return {
secondLoading: true,
devicesList: [],
devicesList: [
{
labelHidden: true,
text: `支路1 (220v): `,
key: `ac_out_1_en`,
// text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 1,
state: 0
},
{
labelHidden: true,
text: `支路2 (220v): `,
key: `ac_out_2_en`,
// text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 1,
state: 0
},
{
labelHidden: true,
text: `支路1 (12v): `,
key: `dc_out_1_en`,
// text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 1,
state: 0
},
{
labelHidden: true,
text: `支路2 (12v): `,
key: `dc_out_2_en`,
// text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 1,
state: 0
},
{
labelHidden: true,
text: '风扇:',
key: `fan_out_en`,
// text: { 0: '', 1: '' }[deviceInfo.formatValue['fan_status']] || '-',
gridColumn: 1,
state: 0
},
],
activeOption: {
active: {
text: "开"
@ -52,135 +99,50 @@ export default {
},
created() {
Promise.all([this.getAc(), this.getDc()]).then(res => {
// if (result.code != 200) return;
let ac = res[0].data;
let dc = res[1].data;
let deviceInfo = _.merge({}, ac, dc);
console.log(deviceInfo, "deviceInfo11")
const typeMap = {
ac: '220v',
dc: '12v',
}
for (const key in deviceInfo.formatValue) {
// electricity
// voltage
if (key.includes('electricity')) {
const args = key.match(/[a-z]+|[0-9]+$/g);
const type = args[0], num = args.slice(-1)[0], prefix = args.slice(0, 2).join('_');
// console.log(type , num , prefix , "+++=========="); //dc 2 dc_out
this.devicesList.push(
{
label: `支路${num}${typeMap[type]}) 电压`,
key: `${prefix}_voltage_${num}`,
text: deviceInfo.formatValue[`${prefix}_voltage_${num}`],
gridColumn: 3
},
{
label: '电流',
key: `${prefix}_electricity_${num}`,
text: deviceInfo.formatValue[key],
gridColumn: 2,
state: deviceInfo.value[key] > 0
}
);
}
}
this.devicesList.push(
{
label: '风扇',
key: `fan_status`,
// key: `aa_electricity_1`,
text: { 0: '正常', 1: '开' }[deviceInfo.formatValue['fan_status']] || '-',
gridColumn: 2,
state: (deviceInfo.formatValue['fan_status'] === '0')
},
{
label: '温度',
key: `temperature`,
text: deviceInfo.formatValue['temperature'] ? `${deviceInfo.formatValue['temperature']} °C` : '-',
gridColumn: 2
},
{
label: '箱门',
key: `door_status`,
text: { 0: '关闭', 1: '打开' }[deviceInfo.formatValue['door_status']] || '-',
gridColumn: 1
},
{
label: '湿度',
key: `humidity`,
text: deviceInfo.formatValue['humidity'] ? `${deviceInfo.formatValue['humidity']} %` : '-',
gridColumn: 2
},
{
label: '市电掉电',
key: `power_status`,
text: { 0: '正常', 1: '掉电' }[deviceInfo.formatValue['power_status']] || '-',
gridColumn: 2
},
)
// this.data = result.rows;
// this.total = result.total;
})
.finally(() => {
this.secondLoading = false
})
},
methods: {
getAc() {
return request({
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId || '10.0.36.143-1883'}/1ac`,
method: "get",
params: {}
})
},
getDc() {
return request({
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId || '10.0.36.143-1883'}/1dc`,
method: "get",
params: {}
})
},
async handleSwitcherChange(value, data) {
let str = data.state ? "关闭" : "开启";
let deviceName = "";
if (data.key.includes("fan")) {
str += "风扇?";
deviceName = "fan_out_en";
} else {
str += "该支路?"
deviceName = data.key.match(/^[a-z]+_out|[0-9]+/g).join("_") + "_en"; //dc_out_2_en ac_out_2_en;
}
let deviceName = data.key;
str += `${data.text.replace(":", "")}?`;
// if (data.key.includes("fan")) {
// str += "?";
// deviceName = "fan_out_en";
// } else {
// str += "?"
// deviceName = data.key.match(/^[a-z]+_out|[0-9]+/g).join("_") + "_en"; //dc_out_2_en ac_out_2_en;
// }
data.state = value;
if (!this.selectItems.length) {
setTimeout(() => { data.state = !value; }, 10);
return Message.error("请至少选择一个设备!");
}
const selectItems = this.selectItems.map(item => JSON.parse(item));
const isContinue = await confirm({ message: `${str}` })
.catch(() => {
console.log(data.state, value, 333)
data.state = !value;
});
if (!isContinue) return;
// https://www.yuque.com/dayuanzhong-ovjwn/gkht0m/ww776d5kzs72ilzh?singleDoc=
request({
url: `/business/device/functions/${this.dialogData.iotDeviceId}/${102}`,
method: "POST",
data: {
deviceName,
// 1=0=
value: value ? 1 : 0
}
})
batchFunctions(
{
"devices": selectItems,
"functions": [
{
"functionId": "102",
"params": {
deviceName,
// 1=0=
value: value ? 1 : 0
}
}
]
})
.then(result => {
if (result.code != 200) {
Message.error("操作失败");
data.state = !value;
return;
};
Message.success("操作成功");
multiResultShow(result.data, item => item.result.code == 200, "操作");
})
.catch(() => {
data.state = !value;
@ -197,5 +159,8 @@ export default {
<style lang='scss' scoped>
.DeviceParams {
height: 100%;
padding-right: 9px;
padding-left: 14px;
margin-top: 15px;
}
</style>

42
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/HomeFrameControl/index.vue

@ -13,10 +13,11 @@
<i class="el-icon-close" />
</span>
<Form v-model="data" labelWidth="90px" column="2" class="form" ref="FormConfigRef" :formList="formList" />
<component :is="componentMap[DeviceTopics[data.deviceType]]" :isMultiControl="true"></component>
<!-- -->
<div class="footer">
<Button @click.native="">
<component ref="ControlComponent" :is="componentMap[DeviceTopics[data.deviceType]]" :isMultiControl="true"
:selectItems="data.childType" @update:activeIcon="(val) => { this.activeIcon = val }"
@update:submitting="(val) => { submitting = val }"></component>
<div v-if="hiddenDevices.indexOf(componentMap[DeviceTopics[data.deviceType]]) == -1" class="footer">
<Button @click.native="submitClick" :loading="submitting">
确认
</Button>
<Button style="background-color: rgba(0, 179, 204, 0.3)" @click.native="cancelClick"> 取消 </Button>
@ -37,27 +38,29 @@ import { ChildTypes } from "@screen/utils/enum.js"
import { getDeviceList } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js";
import { delay } from "@screen/utils/common";
import { initSearch } from "@screen/utils/enum/common.js"
import DeviceParams from "@screen/pages/Home/components/Dialogs/SmartDevice/components/DeviceParams.vue";
import BroadcastParam from "@screen/pages/Home/components/Dialogs/Broadcast/components/BroadcastParam.vue";
import SmartDeviceParams from "@screen/pages/Home/components/Dialogs/SmartDevice/components/DeviceParamsMulti.vue";
import BroadcastParam from "@screen/pages/Home/components/Dialogs/Broadcast/components/BroadcastParamMulti.vue";
import FatigueWakesUpParam from "@screen/pages/Home/components/Dialogs/FatigueWakesUp/components/DeviceParam.vue";
import Vue from "vue";
import { DeviceForMap } from "@screen/pages/Home/components/RoadAndEvents/utils/buttonEvent";
import { DeviceForMap } from "@screen/pages/Home/components/RoadAndEvents/utils/buttonEvent"
const componentMap = { "语音广播": "BroadcastParam" } //DeviceTopics[deviceType]
//"": undefined, "": undefined, "": undefined, "": undefined,"": "DeviceParams",
const componentMap = { "设备箱": "SmartDeviceParams", "语音广播": "BroadcastParam", "疲劳唤醒": "FatigueWakesUpParam" } //DeviceTopics[deviceType]
//"": undefined, "": undefined, , "": undefined,
const hiddenDevices = ["SmartDeviceParams"];
const controlMulti = Object.keys(componentMap);//6
const DeviceTopics = {};//6 {key:label}
Object.keys(DeviceForMap).forEach(DeviceLabel => {
controlMulti.indexOf(DeviceLabel) !== -1 && (DeviceTopics[DeviceForMap[DeviceLabel].deviceType] = DeviceLabel);
});
const deviceTypeDefault = Object.keys(DeviceTopics)[0];
async function setDeviceOptions(config, filterData, formList) {
const data = await getDeviceList(config.deviceType, filterData).then(async (data) => {
await delay(600);
return data;
});
formList[4].options.options = data.map(item => {
return { label: `${item.deviceName}`, value: JSON.stringify({ id: item.id, iotDeviceId: item.iotDeviceId }), disabled: item.deviceState != 1 }
return { label: `${item.deviceName}`, value: JSON.stringify({ id: item.id, iotDeviceId: item.iotDeviceId, deviceType: item.deviceType, otherConfig: item.otherConfig }), disabled: item.deviceState != 1 }
})
};
function changeHandle(data, formList) {
@ -73,18 +76,22 @@ export default {
components: {
Button,
Form,
DeviceParams,
BroadcastParam
SmartDeviceParams,
BroadcastParam,
FatigueWakesUpParam,
},
data() {
return {
activeIcon: null,
data: {},
hiddenDevices,
submitting: false,
formList: [
{
label: "设备类型:",
key: "deviceType",
type: "select",
default: deviceTypeDefault,
options: {
clearable: true,
options: Object.keys(DeviceTopics).map(key => { return { label: DeviceTopics[key], value: key } }),
@ -92,7 +99,6 @@ export default {
ons: { //on element
change(value, ...args) {
const { data, formList } = args.slice(-1)[0]; //data formList
console.log(Vue, this)
if (data.deviceType) changeHandle(data, formList);
else data.childType = undefined;
}
@ -274,14 +280,18 @@ export default {
// deep: true
// }
// },
mounted() {
changeHandle(this.data, this.formList);
},
methods: {
submitClick() {
this.$refs.ControlComponent?.handleSubmit();
},
cancelClick() {
this.activeIcon = null;
},
handleClick(type) {
console.log("type: ", type);
this.activeIcon = this.activeIcon === type ? null : type;
console.log("this.activeIcon", this.activeIcon);
},
filterEnd(data) {
this.activeIcon = null;

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

@ -3,6 +3,14 @@ import { Message } from "element-ui";
import moment from "moment";
import request from "@/utils/request";
export function batchFunctions(data) {
return request({
url: `/business/device/batchFunctions`,
method: "post",
data: data,
});
}
/**
*
* @param {string} camId 相机 ID

2
ruoyi-ui/src/views/JiHeExpressway/pages/Home/index.vue

@ -22,7 +22,7 @@
<HomeVector class="item" />
<HomeWord class="item" />
<!-- <HomeVectorControl class="item" /> -->
<!-- <HomeFrameControl class="item" /> -->
<HomeFrameControl class="item" />
</div>
<ConditionStatistics class="right card-menu" />
</div>

41
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/CrowdnessIndicatorRankings/index.vue

@ -1,7 +1,11 @@
<template>
<Card class="CrowdnessIndicatorRankings border" title="拥挤度指标排名情况">
<div class="map">
<AMapContainer ref="AMapContainerRef" v-if="delayLoad" style="z-index: 9" />
<AMapContainer
ref="AMapContainerRef"
v-if="delayLoad"
style="z-index: 9"
/>
</div>
<div class="right border">
<div
@ -11,16 +15,21 @@
@click="handleClick(item)"
>
<div
v-if="item.key === 'bar'"
class="label"
slot="reference"
:style="{
backgroundImage: `url(${require(`./images/${item.key}${
isActive(item) ? '-active' : ''
}.svg`)})`,
}"
v-if="item.key === 'bar'"
class="label"
slot="reference"
:style="{
backgroundImage: `url(${require(`./images/${item.key}${
isActive(item) ? '-active' : ''
}.svg`)})`,
}"
/>
<ElPopover v-else trigger="manual" :value="isActive(item)" placement="left">
<ElPopover
v-else
trigger="manual"
:value="isActive(item)"
placement="left"
>
<div v-if="item.key === 'weather'" class="weather">
<span>天气{{ weatherData.text }}</span>
<span>能见度{{ weatherData.vis }}公里</span>
@ -51,7 +60,7 @@
import Card from "@screen/components/Card2/Card.vue";
import AMapContainer from "@screen/pages/Home/components/AMapContainer/index.vue";
import { provideMixin } from "./../../mixin";
import { WeatherForecast } from "@/api/commandDispatch";
import { getWeatherForecast } from "@/api/commandDispatch";
import * as echarts from "echarts";
import { StatChartOption } from "./charts";
@ -106,7 +115,7 @@ export default {
if (findIndex === -1) this.active.push(item.key);
else this.active.splice(findIndex, 1);
if (item.key === "weather") {
this.getWeatherForecast();
this.getWeather();
} else if (item.key === "pie") {
this.$nextTick(() => {
const statChart = echarts.init(
@ -114,12 +123,12 @@ export default {
);
statChart.setOption(StatChartOption);
});
} else if (item.key === 'bar'){
this.$refs.AMapContainerRef.showRoadConditions(findIndex === -1)
} else if (item.key === "bar") {
this.$refs.AMapContainerRef.showRoadConditions(findIndex === -1);
}
},
getWeatherForecast() {
WeatherForecast(117.2, 36.65).then((res) => {
getWeather() {
getWeatherForecast(117.2, 36.65).then((res) => {
this.weatherData =
res.data.weatherInTheAreaWhereTheIncidentOccurred.now;
console.log("气象", res);

55
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/DispatchLiaison/index.vue

@ -9,22 +9,23 @@
<div class="dispatch-item">
<span class="label">业务单位</span>
<span class="value">{{
dispatchData.organizationName ? dispatchData.organizationName : "-"
dispatchData.deptName ? dispatchData.deptName : "-"
}}</span>
</div>
<div class="dispatch-item">
<div>
<span class="label">值班领导</span>
<span class="value">{{
dispatchData.shiftsName ? dispatchData.shiftsName : "-"
}}</span>
</div>
<div>
<span class="label">值班领导</span>
<span class="value" v-for="item in dispatchData.shifts">
姓名{{ item.shiftsName ? item.shiftsName : "-" }} 电话{{
item.shiftsNumber ? item.shiftsNumber : "-"
}}</span
>
<!-- <div>
<span class="label">手机号</span>
<span class="value">{{
dispatchData.shiftsNumber ? dispatchData.shiftsNumber : "-"
}}</span>
</div>
</div> -->
</div>
<div class="dispatch-item">
<span class="label">调度人员</span>
@ -68,7 +69,7 @@ import Card from "@screen/components/Card2/Card.vue";
import ButtonGradient from "@screen/components/Buttons/ButtonGradient.vue";
import Descriptions from "@screen/components/Descriptions.vue";
import { provideMixin } from "./../../mixin";
import { commandDispatch } from "@/api/commandDispatch";
import { postCommandDispatch } from "@/api/commandDispatch";
import StatsDialogVisible from "./StatsDialogVisible/index.vue";
import request from "@/utils/request";
@ -99,29 +100,31 @@ export default {
},
getCommandDispatch() {
let data = {
stakeMark: "K099+750",
stakeMark: "K100+100",
id: "96b9918efc01488cb22fa1d9d3236dfd",
};
commandDispatch(data).then((res) => {
res.data.forEach((element) => {
if (element.vehiclesMap.length > 0) {
element.vehiclesMap.forEach((item) => {
this.vehicleTypeList.forEach((i) => {
if (item.vehicleType == i.dictValue) {
item.vehicleText = "(" + i.dictLabel + ")";
}
});
});
}
});
this.dispatchList = res.data;
this.dispatchData = res.data[0];
postCommandDispatch(data).then((res) => {
// res.data.forEach((element) => {
// if (element.vehiclesMap.length > 0) {
// element.vehiclesMap.forEach((item) => {
// this.vehicleTypeList.forEach((i) => {
// if (item.vehicleType == i.dictValue) {
// item.vehicleText = "" + i.dictLabel + "";
// }
// });
// });
// }
// });
// this.dispatchList = res.data;
this.dispatchData = res.data.resource;
console.log(" this.dispatchData", this.dispatchData);
});
},
getVehicleTypeList() {
if (this.vehicleTypeList.length) return;
request({
url: `/system/dict/data/type/sys_vehicle_type`,
url: `/system/dict/data/type/vehicle_type`,
method: "GET",
params: {},
})

356
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/DisposalProcess/DialogVisible/index.vue

@ -0,0 +1,356 @@
<template>
<Dialog v-model="modelVisible" title="收费站管制统计" style="width: 100%">
</Dialog>
</template>
<script>
import Dialog from "@screen/components/Dialog/index";
import InputSearch from "@screen/components/InputSearch/index.vue";
import Table from "@screen/components/Table.vue";
import { selectTollStation } from "@/api/event/governanceAnalysis";
import request from "@/utils/request";
export default {
name: "StatsDetail",
components: {
Dialog,
InputSearch,
Table,
},
model: {
prop: "visible",
event: "update:value",
},
props: {
visible: Boolean,
},
data() {
return {
num: 0,
tableData: [],
weatherNum: [],
startTime: "",
endTime: "",
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
},
searchType: 1,
controlType: 1,
facilityIds: [],
facilityTableData: [],
searchFormList: [
{
label: "查询条件:",
key: "searchType",
required: true,
isAlone: true,
type: "RadioGroup",
default: 1,
options: {
type: "circle",
options: [
{
key: 1,
label: "站点",
},
{
key: 2,
label: "原因",
},
],
},
},
{
label: "事件类型:",
key: "controlType",
required: true,
isAlone: true,
type: "RadioGroup",
visible: (data) => {
if (data.searchType == 2) {
return true;
}
},
default: 1,
options: {
type: "circle",
options: [
{
key: 1,
label: "收费站封闭",
},
{
key: 2,
label: "收费站限行",
},
],
},
},
{
label: "选择站点:",
key: "facilityId",
required: true,
type: "Select",
options: {
multiple: true,
options: [],
},
default: [],
visible: (data) => {
if (data.searchType == 1) {
return true;
}
},
},
{
label: "日期:",
key: "date",
required: true,
type: "datePicker",
default: "",
options: {
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
},
valueFormat: "yyyy-MM-dd",
type: "daterange",
},
},
],
queryParams: {},
};
},
computed: {
modelVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:value", val);
},
},
},
methods: {
getFacilityList() {
Promise.allSettled([
//
request({
url: `/business/facility/query`,
method: "get",
}),
]).then((res) => {
if (res[0].status === "fulfilled" && res[0].value.code == 200) {
// this.searchFormList[2].options.options = res[0].value.data.map(
// (item) => ({
// key: item.id,
// label: item.facilityName,
// })
// );
let dataList = [];
res[0].value.data.forEach((item) => {
if (item.facilityType == 1) {
dataList.push({
key: item.id,
label: item.facilityName,
});
}
});
this.searchFormList[2].options.options = dataList;
this.facilityIds = res[0].value.data.map((item) => item.id);
this.searchFormList[2].default = dataList.map((item) => item.key);
console.log(56, this.searchFormList[2].default);
let currentMonth = moment().format("YYYY-MM");
let currentDate = moment().format("YYYY-MM-DD");
this.queryParams = {
searchType: 1,
facilityId: this.facilityIds,
date: [currentMonth + "-01", currentDate],
};
this.searchFormList[3].default = [currentMonth + "-01", currentDate];
this.getSelectTollStation(this.queryParams);
}
});
},
// handleResetForm(data) {
// this.getSelectTollStation(data);
// },
handleSearch(data, value) {
console.log(888, data, value);
if (value == "reset") {
data = this.queryParams;
}
this.getSelectTollStation(data);
},
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (this.searchType == 2) {
if (!row.causeTypeName) {
if (columnIndex === 0) {
return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
if (row.controlCauseName === "恶劣天气") {
if (columnIndex === 0) {
console.log(this.weatherNum.length);
if (rowIndex === 0) {
return [this.weatherNum.length, 1];
} else if (rowIndex <= this.weatherNum.length) {
return [0, 0];
}
// if (rowIndex === 2) {
// return [7, 1];
// }
// else if (rowIndex === 3) {
// return [0, 0];
// } else if (rowIndex === 4) {
// return [0, 0];
// }
// else if (rowIndex === 5) {
// return [0, 0];
// }
// else if (rowIndex === 6) {
// return [0, 0];
// }
// else if (rowIndex === 7) {
// return [0, 0];
// }
// else if (rowIndex === 8) {
// return [0, 0];
// }
}
// this.weatherNum = 0
}
}
},
getSelectTollStation(data) {
let startTime = "";
let endTime = "";
if (data) {
startTime = data.date[0] + " 00:00:00";
endTime = data.date[1] + " 23:59:59";
} else {
startTime = new Date("2024-01-01 11:12:21");
startTime = new Date("2024-01-26 11:12:36");
}
var formData = new FormData();
this.searchType = data.searchType;
this.controlType = data.controlType;
if (data.searchType == 1) {
formData.append("facilityId", data.facilityId);
} else {
formData.append("controlType", data.controlType);
}
formData.append("searchType", data.searchType);
formData.append("startTime", startTime);
formData.append("endTime", endTime);
let weatherData = [];
let otherData = [];
selectTollStation(formData).then((res) => {
if (data.searchType == 2) {
this.weatherNum = [];
res.data.forEach((item) => {
if (item.causeTypeName) {
this.weatherNum.push(item.causeTypeName);
weatherData.push(item);
} else {
otherData.push(item);
}
});
this.tableData = weatherData.concat(otherData);
} else {
res.data.forEach((item) => {
item.total =
item.facilityClose +
item.facilityRestriction +
item.facilityInterval;
});
this.facilityTableData = res.data;
}
});
},
},
mounted() {
this.getFacilityList();
},
};
</script>
<style lang="scss" scoped>
.dialog {
min-height: 800px;
}
.search {
display: flex;
flex-direction: row-reverse;
}
::v-deep .is-scrolling-none {
background: #0b6581;
}
::v-deep .el-table__empty-text {
color: #3ae0f8;
}
.StatsDetail {
// height: 770px;
margin: 20px 0;
width: 100%;
display: flex;
gap: 5px;
}
.el-table {
border: 1px solid #07aec6;
background: #0b6581;
}
::v-deep .el-table .el-table__header-wrapper th,
.el-table .el-table__fixed-header-wrapper th {
background: #0b6581;
border: 1px solid #07aec6;
}
::v-deep .el-table th.el-table__cell > .cell {
color: #3de8ff;
}
::v-deep .el-table thead.is-group th.el-table__cell {
background: #0b6581;
border: 1px solid #07aec6;
}
// ::v-deep .el-table th.el-table__cell.is-leaf,
::v-deep .el-table td.el-table__cell {
border: 1px solid #07aec6;
background: #1b586d;
color: #fff;
}
::v-deep .el-table tr {
border: 1px solid #07aec6;
background-color: #0b6581;
}
::v-deep
.el-table--enable-row-hover
.el-table__body
tr:hover
> td.el-table__cell {
background: #1b586d;
border: 1px solid #07aec6;
}
::v-deep .el-table::before,
.el-table--group::after,
.el-table--border::after {
background: none;
}
</style>

194
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/DisposalProcess/index.vue

@ -1,9 +1,14 @@
<template>
<div>
<Card class="DisposalProcess" title="处置过程">
<template #title-suffix>
<ButtonGradient class="title-button" @click=""> 事件解除 </ButtonGradient>
<ButtonGradient class="title-button" @click="handleEventRelieve">
事件解除
</ButtonGradient>
<!-- <ButtonGradient class="title-button"> 协同调度 </ButtonGradient> -->
<ButtonGradient class="title-button" @click=""> 无需清障 </ButtonGradient>
<ButtonGradient class="title-button" @click="handleNoWrecker">
无需清障
</ButtonGradient>
<ButtonGradient class="title-button"> 重要事件上报 </ButtonGradient>
<!-- <ButtonGradient class="title-button"> 路赔 </ButtonGradient> -->
<ButtonGradient
@ -71,6 +76,12 @@
</ButtonGradient> -->
</div>
</Card>
<DialogVisible
:visible="dialogVisible"
:data="dispatchList"
@update:value="handleClose"
/>
</div>
</template>
<script>
@ -80,6 +91,14 @@ import RadioGroup from "@screen/components/FormConfig/components/RadioGroup/inde
import { getToken } from "@/utils/auth";
import TimeLine1 from "@screen/components/TimeLine/TimeLine1/index";
import TimeLine2 from "@screen/components/TimeLine/TimeLine2/index";
import DialogVisible from "./DialogVisible/index.vue";
import {
getProcessNode,
getProcessList,
postProcess,
postCompleteEvent,
postNoSkipClear,
} from "@/api/commandDispatch";
import { provideMixin } from "./../../mixin";
import { timeLine2List } from "./data";
@ -95,21 +114,16 @@ export default {
TimeLine1,
TimeLine2,
RadioGroup,
DialogVisible,
},
emit: ["fullHeight"],
data() {
return {
dialogVisible: true,
eventId: "1a91d65cc31f4a9d90122888edb31043",
test: null,
testRadio: "input",
timeLine1List: [],
// timeLine2List: Array.from({ length: 6 }).map(() => ({
// title: "",
// time: "2023-12-21 16:35:44",
// name: "",
// desc: "",
// posts: ''
// })),
timeLine2List: [],
isFullHeight: false,
options: [],
@ -133,108 +147,114 @@ export default {
this.$emit("fullHeight", "CrowdnessIndicatorRankings");
},
//
getProcess(eventId) {
getProcessNode(this.eventId).then((result) => {
console.log("处置过程节点", result);
if (result.code != 200) return [];
this.timeLine1List = result.data.map((item) => {
return {
time: item.operationTime,
label: item.processNode,
isActive: item.status == 1 ? true : false,
};
});
this.options = result.data.filter((item) => {
item.status == 0;
return item;
});
});
},
//
async detailChange(id) {
const timelineData = await this.getDetail(id);
let processIdMap = {};
getProcessList(id).then((result) => {
console.log("处置过程记录", result);
this.timeLine2List = result.map((item) => {
processIdMap[item.processId] = new Date(
item.operationTime
).toLocaleTimeString();
this.timeLine2List = timelineData.map((item) => {
processIdMap[item.processId] = new Date(
item.operationTime
).toLocaleTimeString();
return {
// title: "",
time: item.operationTime
? new Date(item.operationTime).toLocaleString()
: null,
name: item.operator,
desc: item.context,
// posts: ''
};
return {
// title: "",
time: item.operationTime
? new Date(item.operationTime).toLocaleString()
: null,
name: item.operator,
desc: item.context,
// posts: ''
};
});
});
// this.timeLine1List = data.processConfigList.map((item) => {
// return {
// time: processIdMap[item.nodeNode],
// label: item.processNode,
// isActive: !!processIdMap[item.nodeNode],
// };
// });
},
getDetail(id) {
return request({
url: `/system/process/list`,
method: "GET",
params: {
eventId: id,
},
})
.then((result) => {
return result || [];
})
.catch((err) => []);
},
//
getProcessNode(eventId) {
return request({
url:
`/dc/system/event/getProcessNode/` +
"1a91d65cc31f4a9d90122888edb31043",
method: "GET",
})
.then((result) => {
if (result.code != 200) return [];
this.timeLine1List = result.data.map((item) => {
return {
time: item.operationTime,
label: item.processNode,
isActive: item.status == 1 ? true : false,
};
});
this.options = result.data.filter((item) => {
item.status == 0;
return item;
});
})
.catch((err) => []);
},
//
handleUploadSuccess(res, file) {
this.$message.success("上传成功");
this.imageUrl = res.url;
},
//
handleUploadError() {
this.$message.error("上传失败");
},
containsArrayElement(str, arr) {
return arr.filter((element) => str.includes(element));
},
//
onSubmit() {
let type = this.containsArrayElement(this.imageUrl, this.fileType);
console.log(type);
request({
url: `/system/process`,
method: "POST",
data: {
eventId: "1a91d65cc31f4a9d90122888edb31043",
if (this.context || this.imageUrl) {
let type = this.containsArrayElement(this.imageUrl, this.fileType);
let data = {
eventId: this.eventId,
processId: this.processId,
context: this.context,
file: this.imageUrl,
type: type.join(","),
},
})
.then((result) => {
source: 1,
};
postProcess(data).then((result) => {
if (result.code != 200) return [];
this.getProcessNode();
this.detailChange("1a91d65cc31f4a9d90122888edb31043");
})
.catch((err) => []);
this.getProcess();
this.detailChange(this.eventId);
});
} else {
this.$message.warning("调度指令不能为空");
}
},
//
handleEventRelieve() {
let data = new FormData();
data.append("eventId", this.eventId);
postCompleteEvent(data).then((result) => {
if (result.code != 200) return [];
this.$message.success("事件解除成功");
});
},
//
handleNoWrecker() {
let data = new FormData();
data.append("eventId", this.eventId);
postNoSkipClear(data).then((result) => {
if (result.code != 200) return [];
this.$message.success("操作成功");
});
},
handleClick() {
this.dialogVisible = true;
},
handleClose() {
this.dialogVisible = false;
},
},
async mounted() {
this.getProcessNode();
await this.detailChange("1a91d65cc31f4a9d90122888edb31043");
this.getProcess();
await this.detailChange(this.eventId);
},
};
</script>
@ -261,7 +281,7 @@ export default {
.bottom {
display: grid;
grid-template-columns: 0.5fr auto 1fr 90px 90px;
grid-template-columns: 0.5fr auto 1fr 90px;
width: 100%;
gap: 6px;
}

2566
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/EventInformation/components/EditEventInformationDialog/data.js

File diff suppressed because it is too large

200
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/EventInformation/components/EditEventInformationDialog/index.vue

@ -1,11 +1,11 @@
<template>
<Dialog v-model="modelVisible" title="修改事件信息" width="550px">
<Dialog v-model="modelVisible" title="修改事件信息" width="1100px" top="10%">
<div class="EditEventInformationDialog">
<Form class="form" :formList="formConfigList" labelWidth="120px" />
<Form class="form" :formList="formConfigList" v-model="fData" labelWidth="120px" />
<div class="footer">
<Button>保存</Button>
<Button style="background: #c9c9c9">关闭</Button>
<Button @click.native="onSubmit">保存</Button>
<Button style="background: #c9c9c9" @click.native="modelVisible = false">关闭</Button>
</div>
</div>
</Dialog>
@ -15,8 +15,106 @@
import Dialog from "@screen/components/Dialog/index";
import Form from "@screen/components/FormConfig";
import Button from "@screen/components/Buttons/Button.vue";
import request from "@/utils/request";
import { tabConfigList } from "./data.js";
import { formConfigList } from "./data.js";
const eventInfo = {
id: "60f022d95a7c4b6cada2d780246543d8",
deptId: null,
deptName: null,
stakeMark: "k103+900",
endStakeMark: null,
direction: "菏泽方向",
userId: 1,
startTime: null,
endTime: null,
estimatedEndTime: "2024-02-22 10:44:27",
eventLevel: 1,
eventType: 1,
stringEventType: "交通事故",
eventSubclass: "其他事故",
eventCause: "其他事故",
description: "其他事故",
eventState: 0,
eventSource: null,
stringEventSource: "96659",
eventNature: null,
eventSourceTips: null,
inTunnel: null,
roadId: null,
occurrenceTime: "2024-02-22 10:44:18",
isPerceived: 0,
lang: "2,3",
roadName: "济菏高速",
organizationName: "研发部门",
processConfigList: [
{
"id": 8,
"eventType": 1,
"nodeNode": "1",
"processNode": "接警记录",
"commonPhrases": ""
},
],
eventTitle: "发生其他事故事故",
dimension: null,
longitude: null,
dcEventMap: null,
dcEventAbnormalWeather: null,
dcEventAccident: {
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
id: "60f022d95a7c4b6cada2d780246543d8",
reporterName: "王兴琳",
reporterPhoneNumber: "19806119906",
locationType: 1,
trafficJam: 100,
weatherCondition: 1,
impactLevel: 2,
isReverseCargo: 1,
isMaintenance: 1,
policeContact: "96659",
towingServiceContact: "19806119906",
congestionAhead: 0,
atIntersection: 0,
onCurve: 1,
spillageItem: "抛洒物",
vehicleOwnerPhone: "19806119906",
smallCar: 10,
trucks: 0,
buses: 0,
tankers: 0,
minorInjuries: 1,
seriousInjuries: null,
fatalities: null,
isPrivate: null,
facilityId: null,
rampId: null,
location: null,
dcEvent: null
},
dcEventConstruction: null,
dcEventServiceArea: null,
dcEventTrafficCongestion: null,
dcEventVehicleAccident: null,
dcEventTrafficControl: null,
nickName: "管理员",
stringEventState: "待确认",
commonPhrases: null,
nodeNode: null,
eventName: "交通事故",
processNode: null,
updateTime: null,
createTime: "2024-02-22 10:49:34",
remark: null,
subclass: "1-5",
linkId: null
};
export default {
name: "EditEventInformationDialog",
@ -34,19 +132,107 @@ export default {
},
data() {
return {
formConfigList,
formConfigList: {},
// tabConfigList,
fData: {},
eventId: '1a91d65cc31f4a9d90122888edb31043',
roads: [],
direction: [],
lwss: []
};
},
computed: {
modelVisible: {
get() {
if (this.visible) {
this.initData()
}
return this.visible;
},
set(val) {
console.log('val', val)
this.$emit("close", val);
},
},
},
mounted() {
},
methods: {
initData() {
let configList = tabConfigList.find(item => item.label == '交通事故')
this.formConfigList = configList.formConfig.list
let info = eventInfo;
if (info.stakeMark instanceof Array) {
let numbers = info.stakeMark.match(/\d+/g).map(Number);
info.stakeMark = numbers;
}
this.fData = info;
// Promise.all([
// //
// request({
// url: `/business/road/query`,
// method: "get",
// })
// .then((result) => {
// if (result.code != 200) return Message.error(result?.msg);
// result.data.forEach((it) => {
// this.roads.push({ key: it.id, label: it.roadName });
// });
// })
// .catch((err) => {
// Message.error("4", err);
// }),
// //
// request({
// url: `/system/dict/data/type/iot_event_direction`,
// method: "get",
// })
// .then((result) => {
// if (result.code != 200) return Message.error(result?.msg);
// result.data.forEach((it) => {
// this.direction.push({ key: it.dictValue, label: it.dictLabel });
// });
// })
// .catch((err) => {
// Message.error("5", err);
// }),
// // 1 2 3 4 5 6
// request({
// url: `/business/facility/query`,
// method: "get",
// })
// .then((result) => {
// if (result.code != 200) return Message.error(result?.msg);
// result.data.forEach((it) =>
// this.lwss.push({
// key: it.id,
// label: it.facilityName,
// type: it.facilityType,
// })
// );
// })
// .catch((err) => {
// console.log("err", err);
// Message.error("6", err);
// }),
// ]);
// request({
// url: `/dc/system/event/eventSubclass/1/60f022d95a7c4b6cada2d780246543d8`,//
// method: "get",
// }).then(async (result) => {
// if (result.code != 200) return Message.error(result?.msg);
// // this.formData = result.data;
// })
},
onSubmit() {
this.modelVisible = false;
}
}
};
</script>
@ -54,7 +240,7 @@ export default {
.EditEventInformationDialog {
gap: 9px;
width: 1050px;
height: 810px;
height: 850px;
display: flex;
flex-direction: column;

7
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/commandDispatch/Cards/EventInformation/index.vue

@ -22,7 +22,7 @@
<div class="tag" >{{ detailData.eventLevel?`${detailData.eventCause+['','一','二','三','四','五'][detailData.eventLevel]}级事件` : '暂无事件等级' }}</div>
</div>
<EditEventInformationDialog v-model="editEventInformationDialogVisible" />
<EditEventInformationDialog v-model="editEventInformationDialogVisible" @close="closeDialog"/>
</Card>
</template>
@ -80,6 +80,11 @@ export default {
],
editEventInformationDialogVisible: false
}
},
methods: {
closeDialog(){
this.editEventInformationDialogVisible = false;
}
}
}
</script>

29
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/EventDetailDialog/index.vue

@ -136,9 +136,10 @@ export default {
url: `/system/process/list`,
method: "get",
params: { eventId: this.formData.id },
}).then((result) => {
if (result.code != 200) return Message.error(result?.msg);
const rows = result.rows;
}).then((rows) => {
console.log('rows',rows)
// if (result.code != 200) return Message.error(result?.msg);
// const rows = result.rows;
this.timeLine1List = [];
this.timeLine2List = [];
@ -171,6 +172,28 @@ export default {
});
});
},
getProcessNode() {
return request({
url:
`/dc/system/event/getProcessNode/${this.formData.id}`,
method: "GET",
})
.then((result) => {
if (result.code != 200) return [];
// this.timeLine1List = result.data.map((item) => {
// return {
// time: item.operationTime,
// label: item.processNode,
// isActive: item.status == 1 ? true : false,
// };
// });
// this.options = result.data.filter((item) => {
// item.status == 0;
// return item;
// });
})
.catch((err) => []);
},
onCloseAddNew() {
this.isShowDialog = false;
},

18
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/FormEvent/PresetFormItems.js

@ -731,10 +731,10 @@ export const locationMode = {
default: "1",
options: {
options: [
{ key: "1", label: "高速主线" },
{ key: "2", label: "服务区" },
{ key: "3", label: "立交桥" },
{ key: "4", label: "收费站" },
{ key: 1, label: "高速主线" },
{ key: 2, label: "服务区" },
{ key: 3, label: "立交桥" },
{ key: 4, label: "收费站" },
],
},
ons: {
@ -907,11 +907,11 @@ export const effect = {
type: "select",
options: {
options: [
{ key: "1", label: "无" },
{ key: "2", label: "危化品泄漏" },
{ key: "3", label: "整车自燃" },
{ key: "4", label: "车辆复燃" },
{ key: "5", label: "散装人工倒货" },
{ key: 1, label: "无" },
{ key: 2, label: "危化品泄漏" },
{ key: 3, label: "整车自燃" },
{ key: 4, label: "车辆复燃" },
{ key: 5, label: "散装人工倒货" },
],
},
};

4
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/FormEvent/data.js

@ -945,7 +945,7 @@ export const tabConfigList = [
},
{
label: "限制类型:",
key: "dcEventAccident.limitedType",
key: "dcEventTrafficControl.limitedType",
required: true,
type: "select",
options: {
@ -963,7 +963,7 @@ export const tabConfigList = [
},
{
label: "车辆类型:",
key: "dcEventAccident.vehicleType",
key: "dcEventTrafficControl.vehicleType",
required: true,
type: "select",
options: {

2
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/event/FormEvent/index.vue

@ -162,7 +162,7 @@ export default {
formData.lang = "";
}
if (this.index == 2 && formData.dcEventTrafficControl.facilityId instanceof Array) {
let ids = formData.dcEventTrafficControl.facilityId.join(',');
let ids = formData.dcEventTrafficControl.facilityId;
formData.dcEventTrafficControl.facilityIds = ids
formData.dcEventTrafficControl.facilityId = ''
}

6
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/plan/addAndEditDialog/ScopeTable.vue

@ -155,7 +155,7 @@
<el-option label="智能发布" :value="2"></el-option>
</el-select>
</el-col> -->
<el-col v-if="tableInfo.deviceType == 5 && tableInfo.hf_operationType == 1" :span="4">
<el-col v-if="tableInfo.deviceType == 5" :span="4">
<el-input v-model="tableInfo.hf_content" placeholder="请输入发布内容"></el-input>
</el-col>
</el-row>
@ -213,10 +213,6 @@ export default {
},
{
value: 3,
label: '事发下游最近'
},
{
value: 4,
label: '最近公里数'
},
],

4
ruoyi-ui/src/views/JiHeExpressway/pages/control/event/plan/addAndEditDialog/index.vue

@ -273,7 +273,7 @@ export default {
let dcArr = [];
this.tableData.forEach(item => {
let dcData = {
id: item.id || '',
id: null,
deviceType: item.deviceType,
searchRule: item.searchRule,
number: item.number
@ -346,13 +346,13 @@ export default {
if (result.code != 200) return Message.error(result?.msg);
Message.success("提交成功");
this.modelVisible = false;
this.$emit("reInitData", true);
})
.catch(() => {
Message.error("提交失败");
})
.finally(() => {
this.submitting = false;
this.$emit("reInitData", true);
});
}
}

29
ruoyi-ui/src/views/JiHeExpressway/pages/maintenanceOperations/statisticalAnalysis/index.vue

@ -290,24 +290,25 @@ export default {
initDevice() {
//线线
if (process.env.NODE_ENV == "development") {
this.equipments = [];
this.equipSeries.forEach((item) => {
this.equipments.push({
title: item,
total: Math.floor(Math.random() * 600) + 800,
pctOnl: Math.floor(100 * Math.random()) + "%",
pctOffl: "25%",
pctLose: "15%",
sumUseState: "90%",
});
});
return;
}
// if (process.env.NODE_ENV == "development") {
// this.equipments = [];
// this.equipSeries.forEach((item) => {
// this.equipments.push({
// title: item,
// total: Math.floor(Math.random() * 600) + 800,
// pctOnl: Math.floor(100 * Math.random()) + "%",
// pctOffl: "25%",
// pctLose: "15%",
// sumUseState: "90%",
// });
// });
// return;
// }
getSystemStatusType().then((res) => {
let allList = [];
let sort = res.data["排序规则"].rule.split(",");
console.log("sort", sort);
sort.forEach((i) => {
for (let key in res.data) {
let val = res.data[key];

19
ruoyi-ui/src/views/JiHeExpressway/utils/common.js

@ -1,6 +1,25 @@
import request from "@/utils/request";
import { Message, MessageBox } from "element-ui";
/**
*
* @param {*} result 结果数组
* @param {*} predicate 断言函数
* @param {*} operationName 操作名称
*/
export const multiResultShow = (allItems, predicate, operationName) => {
const successItems = allItems.filter(predicate);
if (successItems.length == allItems.length) {
Message.success(`${operationName}成功!`);
} else {
Message.error(
`${operationName}成功${successItems.length}个, 失败${
allItems.length - successItems.length
}!`
);
}
};
export function delay(ms = 240) {
return new Promise((resolve) => setTimeout(() => resolve(void 0), ms));
}

4
ruoyi-ui/vue.config.js

@ -52,8 +52,8 @@ module.exports = {
// target: `http://10.0.81.204:8087`, //现场后台 刘文阁
// target: `http://10.168.69.255:8087`, //正晨后台 连现场物联 刘文阁
// target: `http://10.168.78.135:8087`, //王钦
target: `http://10.168.66.196:8087`, //正晨后台 连现场物联 刘文阁2
// target: `http://10.168.68.42:8087`, //王思祥
// target: `http://10.168.66.196:8087`, //正晨后台 连现场物联 刘文阁2
target: `http://10.168.68.42:8087`, //王思祥
// target: `http://10.168.65.194:8087`, //赵祥龙
// target: `http://10.168.65.156:8097`, //孟
// target: `http://10.168.56.165:8087`, //王家宝

Loading…
Cancel
Save