Browse Source

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

wangqin
zhangzhang 10 months ago
parent
commit
d381c669ac
  1. 45
      ruoyi-ui/src/views/JiHeExpressway/components/VideoMulti/index.vue
  2. 287
      ruoyi-ui/src/views/JiHeExpressway/mixins/InfoBoard.js
  3. 359
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/RoadNetworkFacilities/data.js
  4. 122
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/RoadNetworkFacilities/index.vue
  5. 12
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/HomeFrameControl/index.vue
  6. 1019
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/InfoBoard/InfoBoard.vue
  7. 1040
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/InfoBoard/index.vue
  8. 4
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/index.vue
  9. 73
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/buttonEvent.js
  10. 42
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/httpList.js
  11. 225
      ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/components/AddNEditDialog.vue
  12. 111
      ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/components/TaskItem.vue
  13. 345
      ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/components/taskEditDialog.vue
  14. 44
      ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/index.vue
  15. 11
      ruoyi-ui/src/views/JiHeExpressway/pages/control/qrCode/index.vue
  16. 32
      ruoyi-ui/src/views/JiHeExpressway/pages/service/board/index.vue
  17. 39
      ruoyi-ui/src/views/JiHeExpressway/utils/api/batch.js
  18. 117
      ruoyi-ui/src/views/JiHeExpressway/utils/enum.js
  19. 30
      ruoyi-ui/src/views/JiHeExpressway/utils/infoBoard.js
  20. 6
      ruoyi-ui/vue.config.js

45
ruoyi-ui/src/views/JiHeExpressway/components/VideoMulti/index.vue

@ -1,28 +1,38 @@
<template>
<div class="video-container">
<div class="header">
<ElSelect @change="showVideo" v-model="cameraId">
<ElOption v-for="item in urls"
:key="item.id" :label="item.deviceName" :value="item.iotDeviceId">
<ElSelect @change="cameraChange" v-model="cameraId">
<ElOption v-for="item in urls" :key="item.id" :label="item.deviceName" :value="item.iotDeviceId">
</ElOption>
</ElSelect>
<img @click="controlDialogVisible = true" v-if="[0, '0'].includes(
dialogData.parseOtherConfig &&
dialogData.parseOtherConfig.ptzCtrl
)
" src="@screen/images/camera-control-icon.svg" width="18px" height="18px"
style="cursor: pointer;background-color: #0d5f79;" />
</div>
<Transition name="fade" mode="out-in">
<video controls autoplay muted class="video-stream" v-bind="$attrs" ref="videoContainerRef" />
</Transition>
<CameraControlDialog :deviceId="dialogData.iotDeviceId" :dialogData="dialogData" v-model="controlDialogVisible" />
</div>
</template>
<script>
import { HttpLivePlayer, openLiveVideo } from "./videoStream.js"
import { find } from "lodash"
import {
getNearCameraNew,
} from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js";
import CameraControlDialog from "@screen/pages/Home/components/Dialogs/Camera/components/CameraControlDialog.vue";
export default {
name: 'VideoControls',
components: {
CameraControlDialog,
},
props: {
//
@ -43,8 +53,10 @@ export default {
return {
active: "video",
player: null,
urls:[],
cameraId: null
urls: [],
cameraId: null,
controlDialogVisible: false,
dialogData: {},
}
},
async mounted() {
@ -52,11 +64,16 @@ export default {
this.$once("hook:beforeDestroy", () => this.player?.destroy());
},
methods: {
cameraChange() {
const changeItem = find(this.urls, { iotDeviceId: this.cameraId });
this.dialogData = { ...changeItem, parseOtherConfig: changeItem.otherConfig && JSON.parse(changeItem.otherConfig) };
console.log(this.cameraId, this.dialogData)
this.showVideo();
},
async playVideo() {
this.player?.destroy();
let {code,data} = await getNearCameraNew(this.pileNum).catch(() => ({}));
let { code, data } = await getNearCameraNew(this.pileNum).catch(() => ({}));
if (
code != 200 ||
(Array.isArray(data) ? !data?.length : !Object.keys(data || {}).length)
@ -64,14 +81,17 @@ export default {
Message.warning("未获取到附近的相机信息");
return;
}
if(data[this.rangeIndex]){
if (data[this.rangeIndex]) {
this.urls = data[this.rangeIndex]
this.cameraId = data[this.rangeIndex][0]['iotDeviceId']
console.log(data[this.rangeIndex][0], this.rangeIndex, 'xxxx');
const firstItem = data[this.rangeIndex]?.[0] || {};
this.cameraId = firstItem['iotDeviceId'];
this.dialogData = { ...firstItem, parseOtherConfig: firstItem.otherConfig && JSON.parse(firstItem.otherConfig) }
this.showVideo();
}
},
showVideo(){
this.player = new HttpLivePlayer(this.$refs.videoContainerRef, { camId: this.cameraId});
showVideo() {
this.player = new HttpLivePlayer(this.$refs.videoContainerRef, { camId: this.cameraId });
}
}
}
@ -102,6 +122,7 @@ export default {
z-index: 999;
display: flex;
justify-content: space-between;
.radio {
background: #265A70;
border-radius: 41px 41px 41px 41px;

287
ruoyi-ui/src/views/JiHeExpressway/mixins/InfoBoard.js

@ -1,152 +1,157 @@
import { publishToBoard, saveBoardReleaseLog } from '@/api/board/board'
import moment from 'moment/moment';
import store from '@/store'
export default{
data(){
return {
import { publishToBoard, saveBoardReleaseLog } from "@/api/board/board";
import moment from "moment/moment";
import store from "@/store";
import { Message } from "element-ui";
export default {
data() {
return {};
},
methods: {
// 新增待下发
____onAddDeviceItem() {
let arr = this.selectedSize.split("*");
}
},
methods:{
// 新增待下发
____onAddDeviceItem() {
let arr = this.selectedSize.split("*");
this.editDialog = {
visible: true,
mode: "add",
type: "device",
tpl: {
"textContent": "",
"origin": {
displayAreaWidth: +arr[0],
displayAreaHeight: +arr[1]
}
}
}
},
// 从模板新增待下发
____onTplToDevice(item, showDialog) {
// if(this.checkedDeviceIds.length<=0){
// this.$message.warning('未选择设备!');
// return;
// }
let arr = this.selectedSize.split("*");
item.origin = {
displayAreaWidth: +arr[0],
displayAreaHeight: +arr[1]
}
this.editDialog = {
visible: showDialog == false ? false : true,
mode: "toDevice",
type: "template",
tpl: item
}
this.editDialog = {
visible: true,
mode: "add",
type: "device",
tpl: {
textContent: "",
origin: {
displayAreaWidth: +arr[0],
displayAreaHeight: +arr[1],
},
},
// 发布信息
____publishInfo() {
let deviceList = [];
if (this.selectedDevice){
deviceList = [this.selectedDevice];
}else{
deviceList = this.selectedDevices;
}
this.$confirm('是否确定发布情报板?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
};
},
// 从模板新增待下发
____onTplToDevice(item, showDialog) {
// if(this.checkedDeviceIds.length<=0){
// this.$message.warning('未选择设备!');
// return;
// }
let content = [];
let arr = this.selectedSize.split("*");
item.origin = {
displayAreaWidth: +arr[0],
displayAreaHeight: +arr[1],
};
this.selectedBdMsg.forEach(item => {
content.push({
STAY: item.playbackDuration,
ACTION: item.screenEntryMethod,
SPEED: item.fontSpacing || 0,
COLOR: item.foregroundColor,
FONT: item.font,
FONT_SIZE: item.fontSize,
CONTENT: item.textContent.replaceAll(',', '\\,').replaceAll('=', '\\=').replaceAll('\n', '\\\\n'),
width: item.displayAreaWidth,
height: item.displayAreaHeight,
formatStyle: item.verticalAlignment
})
})
this.editDialog = {
visible: showDialog == false ? false : true,
mode: "toDevice",
type: "template",
tpl: item,
};
},
// 发布信息
____publishInfo() {
let deviceList = [];
if (this.isMultiControl && !this.selectItems.length) {
return Message.error("请至少选择一个设备!");
}
const selectItems = this.selectItems.map((item) => JSON.parse(item));
if (this.isMultiControl) deviceList = selectItems;
else {
if (this.selectedDevice) deviceList = [this.selectedDevice];
else deviceList = this.selectedDevices;
}
let data = { content: content, deviceList }
this.$confirm("是否确定发布情报板?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let loading = this.$loading({
lock: true,
text: "Loading",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
if (IS_TESTING) {
// this.saveLog(content);
this.____getDeviceInfo();
loading.close()
let content = [];
} else {
publishToBoard(data).then(res => {
// this.saveLog(content);
this.$message({
type:"success",
message:"发布成功!"
});
this.____getDeviceInfo();
}).catch(err=>{
this.selectedBdMsg.forEach((item) => {
content.push({
STAY: item.playbackDuration,
ACTION: item.screenEntryMethod,
SPEED: item.fontSpacing || 0,
COLOR: item.foregroundColor,
FONT: item.font,
FONT_SIZE: item.fontSize,
CONTENT: item.textContent
.replaceAll(",", "\\,")
.replaceAll("=", "\\=")
.replaceAll("\n", "\\\\n"),
width: item.displayAreaWidth,
height: item.displayAreaHeight,
formatStyle: item.verticalAlignment,
});
});
}).finally(()=>{
loading.close()
});
}
let data = { content: content, deviceList };
}).catch(() => {
if (IS_TESTING) {
// this.saveLog(content);
this.____getDeviceInfo();
loading.close();
} else {
publishToBoard(data)
.then((res) => {
// this.saveLog(content);
this.$message({
type: 'info',
message: '取消发布'
})
})
},
//
saveLog(content){
let time = moment().format("YYYY-MM-DD HH:mm:ss");
let device = this.selectedDevices;
let data = {
"createBy": store.getters.name,
"createTime": time,
"deviceId": device.id,
"deviceName": device.deviceName,
"direction": device.direction,
"params": {},
"platform": "",
"releaseContent": JSON.stringify(content),
"releaseDeptId": "",
"releaseDeptName": "",
"releaseIp": "",
"releaseStatus": "",
"releaseTime": time,
"releaseUserId": "",
"releaseUserName": "",
"remark": "",
"searchValue": "",
"stakeMark": device.stakeMark,
"updateBy": "",
"updateTime": time
}
saveBoardReleaseLog(data).then(res => {
if(res.code==200){
console.log("情报板日志已保存:::" , data);
}else{
console.log("情报板日志保存失败!");
}
})
type: "success",
message: "发布成功!",
});
!isMultiControl && this.____getDeviceInfo();
})
.catch((err) => {})
.finally(() => {
loading.close();
});
}
})
.catch(() => {
this.$message({
type: "info",
message: "取消发布",
});
});
},
//
saveLog(content) {
let time = moment().format("YYYY-MM-DD HH:mm:ss");
let device = this.selectedDevices;
let data = {
createBy: store.getters.name,
createTime: time,
deviceId: device.id,
deviceName: device.deviceName,
direction: device.direction,
params: {},
platform: "",
releaseContent: JSON.stringify(content),
releaseDeptId: "",
releaseDeptName: "",
releaseIp: "",
releaseStatus: "",
releaseTime: time,
releaseUserId: "",
releaseUserName: "",
remark: "",
searchValue: "",
stakeMark: device.stakeMark,
updateBy: "",
updateTime: time,
};
saveBoardReleaseLog(data).then((res) => {
if (res.code == 200) {
console.log("情报板日志已保存:::", data);
} else {
console.log("情报板日志保存失败!");
}
}
}
});
},
},
};

359
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/RoadNetworkFacilities/data.js

@ -0,0 +1,359 @@
export const tabList = {
1: [
{
name: "基本信息",
key: "first",
labelWidth: "70px",
list: [
{
label: "站点名称",
key: "facilityName",
gridColumn: "3",
},
{
label: "管制类型",
key: "controlType",
enum: "controlType",
gridColumn: "3",
},
{
label: "收费站总人数",
key: "stationTotal",
gridColumn: "3",
},
{
label: "所在城市",
key: "prefectureCity",
gridColumn: "3",
},
{
label: "所在桩号",
key: "stakeMark",
gridColumn: "3",
},
{
label: "收费站类型",
key: "stationType",
gridColumn: "3",
},
{
label: "经度",
key: "longitude",
gridColumn: "3",
},
{
label: "纬度",
key: "latitude",
gridColumn: "3",
},
],
},
{
name: "车道信息",
key: "second",
labelWidth: "142px",
list: [
{
label: "收费站总车道数",
key: "stationLaneNumber",
gridColumn: "3",
},
{
label: "收费广场数量",
key: "stationSquareNumber",
gridColumn: "3",
},
{
label: "mtc车道数(入口)",
key: "mtcEntrance",
gridColumn: "3",
},
{
label: "mtc车道专用(出口)",
key: "mtcExport",
gridColumn: "3",
},
{
label: "etc车道数(入口)",
key: "etcEntrance",
gridColumn: "3",
},
{
label: "etc车道专用(出口)",
key: "etcExport",
gridColumn: "3",
},
{
label: "小计(入口)总车道数",
key: "countEntrance",
gridColumn: "3",
},
{
label: "小计(出口)总车道数",
key: "countExport",
gridColumn: "3",
},
],
},
],
2: [
{
name: "基本信息",
key: "first",
labelWidth: "70px",
list: [
{
label: "桥梁名称",
key: "facilityName",
gridColumn: "3",
},
{
label: "桥梁桩号",
key: "stakeMark",
gridColumn: "3",
},
{
label: "路段名称",
key: "sectionName",
gridColumn: "3",
},
{
label: "路线编码",
key: "routeCode",
gridColumn: "3",
},
{
label: "跨径组合",
key: "spanCombination",
gridColumn: "3",
},
{
label: "技术等级",
key: "technicalLevel",
gridColumn: "3",
},
{
label: "桥梁长度",
key: "bridgeLength",
gridColumn: "3",
},
{
label: "桥梁宽度",
key: "bridgeWidth",
gridColumn: "3",
},
{
label: "集团公司",
key: "groupCompany",
gridColumn: "3",
},
{
label: "管养公司",
key: "maintenanceAndOperatingCompany",
gridColumn: "3",
},
{
label: "功能名称",
key: "functionName",
gridColumn: "3",
},
{
label: "桥梁方向",
key: "bridgeDirection",
gridColumn: "3",
},
{
label: "是否子桥",
key: "subBridge",
enum: "boolType",
gridColumn: "3",
},
{
label: "总跨径",
key: "totalSpan",
gridColumn: "3",
},
{
label: "经度",
key: "longitude",
gridColumn: "3",
},
{
label: "纬度",
key: "latitude",
gridColumn: "3",
},
{
label: "跨越类型",
key: "crossingType",
gridColumn: "3",
},
{
label: "最大跨径",
key: "maximumSpan",
gridColumn: "3",
},
{
label: "通车时间",
key: "openingTime",
gridColumn: "3",
},
{
label: "跨径类型名称",
key: "spanTypeName",
gridColumn: "3",
},
{
label: "跨域结构名称",
key: "crossDomainStructureName",
gridColumn: "3",
},
{
label: "上部结构名称",
key: "superstructureName",
gridColumn: "3",
},
{
label: "分中心全称",
key: "branchCenterFullName",
gridColumn: "3",
},
],
},
],
4: [
{
name: "基本信息",
key: "first",
labelWidth: "70px",
list: [
{
label: "立交名称",
key: "facilityName",
gridColumn: "3",
},
{
label: "方向数量",
key: "interchangeCount",
gridColumn: "3",
},
{
label: "北方方向",
key: "northDirection",
gridColumn: "3",
},
{
label: "北方道路",
key: "northernRoad",
gridColumn: "3",
},
{
label: "南方方向",
key: "southDirection",
gridColumn: "3",
},
{
label: "南方道路",
key: "southernRoad",
gridColumn: "3",
},
{
label: "东方方向",
key: "eastDirection",
gridColumn: "3",
},
{
label: "东方道路",
key: "eastRoad",
gridColumn: "3",
},
{
label: "西方方向",
key: "westDirection",
gridColumn: "3",
},
{
label: "西方道路",
key: "westRoad",
gridColumn: "3",
},
{
label: "经度",
key: "longitude",
gridColumn: "3",
},
{
label: "纬度",
key: "latitude",
gridColumn: "3",
},
{
label: "方向类型",
key: "directionType",
gridColumn: "3",
},
],
},
],
6: [
{
name: "简介",
key: "first",
labelWidth: "82px",
list: [
{
label: "服务区名称",
key: "facilityName",
gridColumn: "3",
},
{
label: "位置桩号",
key: "stakeMark",
gridColumn: "3",
},
{
label: "服务区状态",
key: "serviceState",
enum: "controlType",
gridColumn: "3",
},
{
label: "服务类别",
key: "serviceType",
gridColumn: "3",
},
{
label: "经度",
key: "longitude",
gridColumn: "3",
},
{
label: "纬度",
key: "latitude",
gridColumn: "3",
},
{
label: "所在城市",
key: "location",
gridColumn: "3",
},
{
label: "所在区县",
key: "districtName",
gridColumn: "3",
},
{
label: "方向名称",
key: "directionName",
gridColumn: "3",
},
{
label: "简介",
key: "introduction",
gridColumn: "6",
},
],
},
],
};

122
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/RoadNetworkFacilities/index.vue

@ -0,0 +1,122 @@
<template>
<Dialog v-model="obverseVisible" :title="dialogData._itemData && dialogData._itemData.title" width="500px" top="10%">
<div class="RoadNetworkFacilities">
<div class="header">
<Video class="video-stream" :pileNum="dialogData.stakeMark" :showHeader="false" />
</div>
<div class="SolarEnergy">
<ElTabs v-model="activeName" class="tabs">
<ElTabPane v-for="item in formList" :key="item.key" :label="item.name" :name="item.key">
<Descriptions :labelWidth="item.labelWidth" :list="item.list" :data="data" style="gap: 12px" column="6" />
</ElTabPane>
</ElTabs>
</div>
</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 Video from "@screen/components/VideoMulti";
import request from "@/utils/request";
import { dialogDelayVisible } from "./../mixin";
import { tabList } from './data'
//
export default {
name: "RoadNetworkFacilities",
mixins: [dialogDelayVisible],
components: {
Dialog,
Descriptions,
Video,
},
data() {
return {
tabList,
activeName: "first",
deviceControlVisible: false,
data: {
deviceType: "行车诱导",
deviceStation: "k094+079",
roadName: "G35济泽高速",
direction: "1",
deviceState: "0",
deviceVendors: "XXX厂家",
},
formList: []
};
},
async created() {
let dData = { ...this.dialogData };
this.formList = tabList[dData.facilityType]
if(dData.facilityType)
if (dData.otherConfig) {
let otherConfig = JSON.parse(dData.otherConfig);
dData.latitude = otherConfig.dimension
dData = { ...dData, ...otherConfig }
}
this.data = dData;
// console.log('this.data', this.data)
},
methods: {
},
};
</script>
<style lang="scss" scoped>
.RoadNetworkFacilities {
width: 456px;
color: #fff;
display: flex;
flex-direction: column;
gap: 12px;
.camera-video {
flex: 1.5;
}
.header {
display: flex;
justify-content: center;
>div.video-stream {
height: 255px;
}
}
.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>

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

@ -14,7 +14,7 @@
</span>
<Form v-model="data" labelWidth="90px" column="2" class="form" ref="FormConfigRef" :formList="formList" />
<component ref="ControlComponent" :is="componentMap[DeviceTopics[data.deviceType]]" :isMultiControl="true"
:selectItems="data.childType" @update:activeIcon="(val) => { this.activeIcon = val }"
:visible="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">
@ -42,23 +42,24 @@ import SmartDeviceParams from "@screen/pages/Home/components/Dialogs/SmartDevice
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 DrivingGuidanceParam from "@screen/pages/Home/components/Dialogs/DrivingGuidance/components/DeviceParam.vue";
import InfoBoardParam from "@screen/pages/Home/components/InfoBoard/InfoBoard.vue";
import { DeviceForMap } from "@screen/pages/Home/components/RoadAndEvents/utils/buttonEvent";
const componentMap = {
"设备箱": "SmartDeviceParams", "语音广播": "BroadcastParam", "疲劳唤醒": "FatigueWakesUpParam",
"行车诱导": "DrivingGuidanceParam"
"行车诱导": "DrivingGuidanceParam", "情报板": "InfoBoardParam",
} //DeviceTopics[deviceType]
//"": undefined, , , "": undefined,
const hiddenDevices = ["SmartDeviceParams"];
// , , "": undefined,
const hiddenDevices = ["SmartDeviceParams", "InfoBoardParam"];
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];
const deviceTypeDefault = Object.keys(DeviceTopics)[1];
async function setDeviceOptions(config, filterData, formList) {
const data = await getDeviceList(config.deviceType, filterData).then(async (data) => {
await delay(600);
@ -85,6 +86,7 @@ export default {
BroadcastParam,
FatigueWakesUpParam,
DrivingGuidanceParam,
InfoBoardParam
},
data() {
return {

1019
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/InfoBoard/InfoBoard.vue

File diff suppressed because it is too large

1040
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/InfoBoard/index.vue

File diff suppressed because it is too large

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

@ -45,6 +45,7 @@ import Camera from "./../Dialogs/Camera/index.vue";
import Broadcast from "./../Dialogs/Broadcast/index.vue";
import TrafficIncidents from "./../Dialogs/TrafficIncidents/index.vue";
import PerceiveEvent from "./../Dialogs/PerceiveEvent/index.vue";
import RoadNetworkFacilities from "./../Dialogs/RoadNetworkFacilities/index.vue";
import SmartDevice from "./../Dialogs/SmartDevice/index.vue";
import SolarEnergy from "./../Dialogs/SolarEnergy/index.vue";
import Intermodulation from "./../Dialogs/Intermodulation/index.vue";
@ -69,7 +70,8 @@ export default {
SolarEnergy,
Intermodulation,
GuardrailCollision,
FatigueWakesUp
FatigueWakesUp,
RoadNetworkFacilities
},
data() {
return {

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

@ -2,10 +2,11 @@ import {
getDeviceList,
getEventTopicList,
getPerceiveEventList,
getRoadNetworkFacilitiesList,
} from "./httpList";
import { delay } from "@screen/utils/common";
import { Message } from "element-ui";
import { EventTopics } from "@screen/utils/enum.js";
import { EventTopics, RoadNFTopics } from "@screen/utils/enum.js";
import { debounce, cloneDeep, find } from "lodash";
import Vue from "vue";
@ -84,6 +85,7 @@ export const lngLatMap = {}; //优化 缩略图 + 地图 复用lngLatmap
export function getHandleDeviceType(item) {
if (DeviceForMap[item.title]) return "地图路测设备/map";
if (EventTopics[item.title]) return "地图事件专题/map";
if (RoadNFTopics[item.title]) return "路网设施/map";
}
let debounceNoneLngLatMessage = debounce(() => {
@ -245,6 +247,75 @@ export const eventMap = {
cacheRemoveFunc[`地图事件专题/${item.title}`]?.();
},
// 路网设施 需要在地图显示的
async "路网设施/map"(item, filterData, isDefault, cb) {
const deviceType = RoadNFTopics[item.title];
let loadingMessage;
if (!isDefault) {
loadingMessage = Message.info({
message: `${item.title}路网设施位置加载中...`,
duration: 0,
customClass: "loading-message",
iconClass: "el-icon-loading",
});
}
console.log("deviceType", deviceType);
const data = await getRoadNetworkFacilitiesList(deviceType, filterData)
.then(async (data) => {
await delay(600);
data.forEach((item) => {
if (item.otherConfig) {
let otherConfig = JSON.parse(item.otherConfig);
item.latitude = otherConfig.dimension
item.longitude = otherConfig.longitude
}
});
return data;
})
.catch(() => {});
loadingMessage?.close();
if (!data) return this.emitter.emit("selectedCompleted", item);
if (!data.length && !isDefault) {
this.emitter.emit("selectedCompleted", item);
return Message.warning(`没有${item.title}路网设施数据!`);
}
eventMap[`路网设施/map_close`](item);
const cbCall = () => cb?.(item, { deviceType: `路网设施_${deviceType}` });
cbCall();
const options = {
stateCallback: () => true,
item,
};
let removeData = data.map((item) =>
resolveDataOptions.call(
this,
item,
options,
"RoadNetworkFacilities",
isDefault
)
);
addDataPreHandle(removeData);
markerClusterIns.addData(removeData, isDefault);
this.emitter.emit("selectedCompleted", item);
cacheRemoveFunc[`路网设施/${item.title}`] = () => {
cbCall();
removeDataPreHandle(removeData);
markerClusterIns.removeData(removeData);
};
},
"路网设施/map_close"(item) {
cacheRemoveFunc[`路网设施/${item.title}`]?.();
},
// 感知事件
async "事件专题/感知事件"(item, filterData, isDefault, cb) {
let loadingMessage;

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

@ -26,10 +26,10 @@ export async function getCameraStream(camId, media = 1) {
},
});
if (data.code == 200) {
/*if (data.code == 200) {
data.data.liveUrl =
"https://10.0.81.202/camera?target=" + data.data.liveUrl.substring(7);
}
}*/
return data;
}
@ -409,3 +409,41 @@ export function getPerceiveEventList(data = {}, options = {}) {
});
});
}
/**
* 路网设施 列表 根据类型获取
* @param {number} facilityType
*/
export function getRoadNetworkFacilitiesList(facilityType, options = {}) {
return new Promise((resolve, reject) => {
if (!facilityType) {
Message.error(`事件加载失败!`);
return reject();
}
const { stakeMark } = options;
let url = `/business/facility/query?facilityType=${facilityType}`;
if (stakeMark) {
let formatStartStakeMark = `K${padZero(stakeMark[0])}%2B${padZero(
stakeMark[1]
)}`;
url += `&stakeMark=${formatStartStakeMark}`;
}
request({
url: url,
method: "get",
})
.then(({ code, data }) => {
if (code != 200) {
reject();
return Message.error(`事件加载失败!`);
}
resolve(data);
})
.catch(() => {
Message.error(`事件加载失败!`);
reject();
});
});
}

225
ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/components/AddNEditDialog.vue

@ -1,37 +1,55 @@
<template>
<Dialog v-model="modelVisible" :title="data ? '修改' : '新增'" width="900px">
<Dialog v-model="modelVisible" :title="propData ? '修改' : '新增'" width="1400px">
{{ editData }}
<div class="AddNEditDialog">
<!-- <Form :value="formData" class="form" ref="FormConfigRef" :formList="formList" column="1" labelWidth="80px" /> -->
<el-form ref="form" :model="formStrategy" label-width="80px">
<el-form-item label="名称">
<el-input v-model="formData.groupName"></el-input>
<!-- <Form :value="propData" class="form" ref="basicInfoForm" :formList="formList" column="1" labelWidth="80px" /> -->
<el-form ref="basicInfoForm" :model="editData" label-width="80px" :rules="groupBasicRules">
<el-form-item label="名称" prop="groupName">
<el-input v-model="editData.groupName" placeholder="任务组名称"></el-input>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="formData.remark"></el-input>
<el-form-item label="描述" prop="remark">
<el-input v-model="editData.remark" placeholder="任务组描述"></el-input>
</el-form-item>
<div class="task" v-for="task,index in formStrategy">
<el-form-item label="状态" prop="status">
<el-switch v-model="editData.status" active-value="1" inactive-value="0"></el-switch>
</el-form-item>
<div style="display: flex; justify-content: flex-end;">
<el-button @click="(modelVisible = false), (submitting = false)">
取消
</el-button>
<el-button type="primary" @click="onSaveTaskGroup('basicInfoForm')" :loading="submitting"> 提交 </el-button>
</div>
</el-form>
{{ editData.id }}
<template v-if="editData.id">
<!-- 如果是新增的还没有保存的任务组不能添加任务 -->
<div class="fl-around task_op">
<el-button size="mini" type="primary" @click="onAddTaskGroup">新增</el-button>
</div>
<div class="task" v-for="taskGroup,index in taskGroupsEditing">
<div class="fl-around task_info">
<el-input v-model="task.time"></el-input>
<el-input v-model="taskGroup.time"></el-input>
<div class="fl-around task_op">
<el-button size="mini" type="primary">新增</el-button>
<el-button size="mini" type="primary" @click="onAddTaskItem(taskGroup)">新增子任务</el-button>
<el-button size="mini" type="primary">删除</el-button>
</div>
</div>
<div>
<TaskItem v-for="item, index in task.content" :data="item" @onModify="newV=>onModifyItem(newV, item)">
<TaskItem v-for="item, index1 in taskGroup.tasksEdit" :propData="item" :groupId="propData.id"
:time="taskGroup.time" @onModify="newV=>onModifyItem(newV, item)">
</TaskItem>
</div>
</div>
</el-form>
</template>
</div>
<template #footer>
<Button style="background-color: rgba(0, 179, 204, 0.3)"
@click.native="(modelVisible = false), (submitting = false)">
取消
</Button>
<Button @click.native="handleSubmit" :loading="submitting"> 确定 </Button>
</template>
<taskEditDialog v-model="isEditing" :groupId="propData.id" :time="selectedTaskGroup.time" :propData="{}"
@onSubmit="onSubmitTaskItem" />
</Dialog>
</template>
@ -43,8 +61,8 @@ import Form from "@screen/components/FormConfig";
import request from "@/utils/request";
import { Message } from "element-ui";
import { addEditFormList } from "./../data";
import { stakeMarkToArray, findPathIdByTreeId } from "@screen/utils/index.js";
import taskEditDialog from "./taskEditDialog.vue";
import TaskItem from "./TaskItem.vue";
export default {
@ -53,7 +71,8 @@ export default {
Dialog,
Button,
Form,
TaskItem
TaskItem,
taskEditDialog
},
model: {
prop: "visible",
@ -61,37 +80,33 @@ export default {
},
props: {
visible: Boolean,
data: Object,
dataAll: Array,
propData: {
type: Object,
default: ()=>{}
},
},
data() {
let gNameValidator = (rule, value, callback)=>{
return callback(new Error('请输入任务组名称'));
// if (value.trim().length<=0){
// return callback(new Error(''));
// }
};
return {
editData:{},
mode:"",
isEditing:false,
group:{},
submitting: false,
formData: {},
formList: addEditFormList,
formStrategy:[
{
time:"gdfsfds",
content:[
{
type:"5",
devices:[""],
options:{
}
},
{
type: "2",
devices: [""],
options: {
}
}
]
}
]
taskGroupsEditing:[],
selectedTaskGroup:{},
groupBasicRules:{
groupName: [
// { validator: gNameValidator, trigger: 'blur' }
{ required: true, message: '请输入活动名称', trigger: 'blur' },
],
}
};
},
computed: {
@ -110,12 +125,13 @@ export default {
handler(bool) {
if (!bool) return;
this.formData = !this.data
? {}
: {
...this.data,
};
this.testGetData();
// this.propData = !this.propData
// ? {}
// : {
// ...this.propData,
// };
this.initEditingData();
this.getTaskList();
},
},
},
@ -132,51 +148,102 @@ export default {
// });
},
methods: {
onSubmitTaskItem(){
this.getTaskList(); //task
},
onAddTaskGroup(){
this.taskGroupsEditing.push({time:"08:00:00",tasks:[1,2,3]});
},
onAddTaskItem(taskG){
this.selectedTaskGroup = taskG;
this.isEditing = true;
},
onModifyItem(newV , oldV){
console.log(newV, oldV , "修改条目》》》")
// oldV.devices
},
testGetData(){
initEditingData(){
if(this.propData?.id){
this.mode = "edit"
this.editData = {
id: this.propData.id,
groupName : this.propData.groupName,
status: this.propData.status,
remark: this.propData.remark,
detailedConfiguration: this.propData.detailedConfiguration
}
} else {
this.mode = "add"
this.editData = {
groupName: "",
status: "1",
remark: "",
detailedConfiguration: ""
}
}
},
getTaskList(){
// this.taskGroupsEditing = JSON.parse(this.propData.detailedConfiguration);
this.taskGroupsEditing = [{time:"08:00:00",tasks:[1],tasksEdit:[]}];
//
let rstData = [
{
id: 1,
callParameter: '{"deviceType":"2","direction":"1","devices":[{"id":904,"iotDeviceId":"81221 - 65535","deviceType":"2","direction":"1"},{"id":2116,"iotDeviceId":"26113 - 65535","deviceType":"2","direction":"1"}],"functions":[{"functionId":"11","params":{"size":"65535","fileName":"play012.lst"}},{"functionId":"13","params":{"STAY":90,"ACTION":"1","SPEED":"0","COLOR":"ffff00","FONT":"3","FONT_SIZE":"24","CONTENT":"长清收费站\\\\n出入口封闭","width":"160","height":"80","formatStyle":"2"}},{"functionId":"1B","params":{"fileId":"12"}}]}',
jobGroup: 1
}
]
this.taskGroupsEditing.forEach(item => {
let arr = _.filter(rstData, itm => { return item.tasks.includes(itm.id) });
item.tasksEdit = arr;
});
return
//
request({
url: `/business/dcBatchFunctionsJob/query`,
method: "GET",
params: {
jobGroup: 0
jobGroup: this.propData.id
},
})
.then((result) => {
if (result.code != 200) return;
console.log(result.data, "接口数据");
result.data = [
{
id:1,
callParameter: '{"deviceType":"2","devices":[{"id":904,"iotDeviceId":"81221 - 65535","deviceType":"2","direction":"1"},{"id":2116,"iotDeviceId":"26113 - 65535","deviceType":"2","direction":"1"}],"functions":[{"functionId":"11","params":{"size":"65535","fileName":"play012.lst"}},{"functionId":"13","params":{"STAY":90,"ACTION":"1","SPEED":"0","COLOR":"ffff00","FONT":"3","FONT_SIZE":"24","CONTENT":"长清收费站\\\\n出入口封闭","width":"160","height":"80","formatStyle":"2"}},{"functionId":"1B","params":{"fileId":"12"}}]}',
jobGroup:1
}
]
this.taskGroupsEditing.forEach(item=>{
let arr = _.filter(result.data, itm=>{ return item.tasks.includes(itm.id)});
item.tasksEdit = arr;
});
})
},
checkRepeat(word) {
let temp = _.find(this.dataAll, { word: word });
if (
temp &&
Object.keys(temp).length > 0 &&
!(this.data && this.data.id == temp.id)
) {
this.$message.error("该关键词已存在。");
return false;
} else {
return true;
}
},
handleSubmit() {
this.$refs.FormConfigRef.validate().then((data) => {
data.word = data.word.trim();
onSaveTaskGroup(formName) {
this.$refs[formName].validate(valid => {
if (!valid){
return ;
}
this.editData.groupName = this.editData.groupName.trim();
this.editData.remark = this.editData.remark.trim();
this.submitting = true;
if (this.data) data.id = this.data.id;
// if (!this.checkRepeat(data.word)) {
// return;
// }
//
// this.$set(this.editData, "id", 11);
// this.submitting = false;
// return
//
request({
url: `/business/dcInfoBoardVocabulary`,
method: this.data ? "PUT" : "POST",
data,
url: `/business/dcBatchFunctionsJobGroup`,
method: this.mode=="edit" ? "PUT" : "POST",
data: this.editData,
})
.then((result) => {
if (result.code != 200) return;
@ -184,7 +251,9 @@ export default {
Message.success(`提交成功!`);
this.$emit("onSuccess");
this.modelVisible = false;
this.editData = { ...result.data };
this.mode = "edit"
})
.catch((err) => {
console.log(

111
ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/components/TaskItem.vue

@ -1,41 +1,71 @@
<template>
<div class="task_editor_box">
<div class="task_editor_box" v-if="isCompReady">
<el-form>
<div class="flex" style="justify-content: space-between;">
<div>
设备类型:<span>{{ deviceTypeDic[editData.deviceType].label }}</span>
</div>
<div>
设备:
<!-- {{ deviceDic }} -->
<span v-for="item,index in editData.devices">
{{ deviceDic[item.id].deviceName }}
</span>{{ editData.devices.length }}个设备
</div>
<!-- <div>{{ editData.params }}</div> -->
<template v-if="editData.deviceType=='2'">
<BoardRecordPreview :tpl="editData.params" style="width:300px; height: 100%;"></BoardRecordPreview>
</template>
<template v-if="editData.deviceType == '5'">
<div class="flex">
<div>
任务内容
<!-- {{ data }} -->
</template>
<template v-if="editData.deviceType == '2'">
</template>
<template v-if="editData.deviceType == '2'">
</template>
<template v-if="editData.deviceType == '2'">
</template>
<el-form-item>
<el-button size="mini" type="primary" @click="onModify">修改</el-button>
<el-button size="mini" type="danger" @click="onDelete">删除</el-button>
</el-form-item>
</div>
<el-form-item>
<el-button size="mini" type="primary" @click="onModify">修改</el-button>
<el-button size="mini" type="danger" @click="onDelete">删除</el-button>
</el-form-item>
</div>
</el-form>
<taskEditDialog v-model="isEditing" :data="data" @onSubmit="onSubmit" />
<taskEditDialog v-model="isEditing" :groupId="groupId" :time="time" :deviceDic="deviceDic" :deviceList="deviceList"
:propData="editData" @onSubmit="onSubmit" />
</div>
</template>
<script>
import { deviceTypeOptions } from "@screen/utils/enum.js"
import { deviceTypeDic } from "@screen/utils/enum.js"
import { getDeviceList } from "@screen/utils/api/device.js"
import taskEditDialog from "./taskEditDialog.vue";
import BoardRecordPreview from '@screen/components/infoBoard/BoardRecordPreview.vue'
export default {
name: "TaskEditor",
name: "TaskItem",
components: {
taskEditDialog
taskEditDialog, BoardRecordPreview
},
props: {
data:Object
groupId:Number,
time:String,
propData:Object
},
data() {
return {
isCompReady:false,
editData:{},
isEditing: false,
selectedType:"",
deviceTypeOptions:"",
deviceOptions:""
deviceTypeDic:"",
deviceDic:{},
deviceList:[]
};
},
computed: {
@ -45,34 +75,51 @@ export default {
},
mounted() {
this.deviceTypeOptions = deviceTypeOptions;
this.deviceTypeDic = deviceTypeDic;
this.initBasicData().then(res=>{
console.log(this.deviceDic);
let temp = JSON.parse(this.propData.callParameter);
//BoardRecordPreview
temp.functions[1].params.CONTENT = temp.functions[1].params.CONTENT.replaceAll(/\\n/g, '\\\\n').replaceAll(/=/g, '\\=').replaceAll(/,/g, '\\,').replaceAll(/&nbsp/g, ' ');
this.editData = {
id: this.propData.id,
direction: temp.direction,
deviceType: temp.deviceType,
devices: temp.devices,
params: temp.functions[1].params,
screenSize: "160*80"
};
this.isCompReady = true;
})
},
methods: {
onModify(){
this.isEditing = true;
},
onSubmit(){
this.isEditing = false;
let devices = _.filter(this.deviceOptions, item=>{
this.editData.devices.includes(item.id);
})
console.log(devices, "选中的设备")
this.$emit("onModify", {devices});
// this.isEditing = false;
// let devices = _.filter(this.deviceOptions, item=>{
// this.editData.devices.includes(item.id);
// })
// console.log(devices, "")
// this.$emit("onModify", {devices});
},
onDelete(){
},
onChange(val){
initBasicData(){
this.deviceOptions = [];
getDeviceList({ deviceType :val}).then(res=>{
this.deviceDic = {};
return getDeviceList({ deviceType: this.editData.deviceType }).then(res=>{
this.deviceList = res.data;
res.data.forEach(item=>{
this.deviceOptions.push({
label: item.deviceName,
value: item.id
})
// this.deviceOptions.push({
item.screenSize = JSON.parse(item.otherConfig||'{}').screenSize;
this.$set(this.deviceDic, item.id, item);
})
}).catch(err=>{})
})
}
},
};

345
ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/components/taskEditDialog.vue

@ -1,114 +1,116 @@
<template>
<Dialog v-model="modelVisible" title="修改" width="600px">
<el-form-item label="设备类型">
<!-- <el-radio-group v-model="searchData.deviceType" @input="onChange">
<Dialog v-model="modelVisible" title="修改" width="600px" label-width="120px">
<el-form>
<el-form-item label="设备类型">
<!-- <el-radio-group v-model="searchData.deviceType" @input="onChange">
<el-radio-button v-for="item in deviceTypeOptions" :key="item.value" :label="item.label" :value="item.value"
v-if="item.timingControl"></el-radio-button>
</el-radio-group> -->
<el-select v-model="searchData.deviceType" placeholder="请选择设备类型" @change="onChange">
<el-option v-for="item in deviceTypeOptions" :key="item.value" :label="item.label" :value="item.value"
v-if="item.timingControl">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="方向">
<el-select v-model="searchData.direction" placeholder="请选择方向" @change="onChange" clearable>
<el-option v-for="item in directionOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="选择设备" v-if="searchData.deviceType != '2'">
<el-select v-model="editData.devices" multiple placeholder="请选择设备" filterable>
<el-option v-for="item in deviceOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<template v-if="searchData.deviceType=='2'">
<el-select v-model="searchData.deviceType" placeholder="请选择设备类型" @change="onChange">
<el-option v-for="item in deviceTypeOptions" :key="item.value" :label="item.label" :value="item.value+''"
v-if="item.timingControl">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="屏幕像素">
<el-select v-model="filterData.pixelSize" placeholder="请选择" clearable @change="resetEditData">
<el-option v-for="item in boardPixelOptions" :key="item.value" :label="item.label" :value="item.value">
<el-form-item label="方向">
<el-select v-model="searchData.direction" placeholder="请选择方向" @change="onChange" clearable>
<el-option v-for="item in directionOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="选择设备">
<el-form-item label="选择设备" v-if="searchData.deviceType != '2'">
<el-select v-model="editData.devices" multiple placeholder="请选择设备" filterable>
<el-option v-for="item in deviceOptions" :key="item.value" :label="item.label" :value="item.value"
v-if="item.pixelSize == filterData.pixelSize">
<el-option v-for="item in deviceArr" :key="item.id" :label="item.deviceName" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预览" v-if="filterData.pixelSize">
<div class="tplItem">
<!-- 模板内容 -->
<BoardPreview class="boardPreview" :boardWH="filterData.pixelSize" :tpl="editData.type2" />
<!-- 操作按钮 -->
<div class="infoBtnBox">
<el-tooltip content="编辑" placement="top">
<p @click="onEditBoard" class="btn btnEdit"></p>
</el-tooltip>
<template v-if="searchData.deviceType=='2'">
<el-form-item label="屏幕像素">
<el-select v-model="filterData.screenSize" placeholder="请选择" clearable @change="resetEditData">
<el-option v-for="item in boardPixelOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="选择设备">
<el-select v-model="editData.devices" multiple placeholder="请选择设备" filterable>
<el-option v-for="item in deviceArr" :key="item.id" :label="item.deviceName" :value="item.id"
v-if="item.screenSize == filterData.screenSize">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预览" v-if="filterData.screenSize">
<div class="tplItem">
<!-- 模板内容 -->
<BoardPreview class="boardPreview" :boardWH="filterData.screenSize" :tpl="editData.type2" />
<!-- 操作按钮 -->
<div class="infoBtnBox">
<el-tooltip content="编辑" placement="top">
<p @click="onEditBoard" class="btn btnEdit"></p>
</el-tooltip>
</div>
</div>
</div>
</el-form-item>
</template>
</el-form-item>
<template v-else-if="searchData.deviceType == '5'">
<!-- 语音广播 -->
<el-form-item label="广播内容">
<el-input type="textarea" v-model="editData.type5.content"></el-input>
</el-form-item>
</template>
</template>
<template v-else-if="searchData.deviceType == '10'">
<!-- 激光疲劳唤醒 -->
<el-form-item label="工作模式">
<el-select v-model="editData.type10.mode" placeholder="请选择">
<el-option v-for="key,value in gzmsMap" :key="key" :label="value" :value="key" />
</el-select>
</el-form-item>
<el-form-item label="工作时长">
<el-col :span="8">
<el-input-number v-model="editData.type10.timeLength" :min="1" :max="600" label="描述文字" />
</el-col>
<!-- <el-col :span="4" style="margin-left: 10px;">分钟</el-col> -->
</el-form-item>
</template>
<template v-else-if="searchData.deviceType == '5'">
<!-- 语音广播 -->
<el-form-item label="广播内容">
<el-input type="textarea" v-model="editData.type5.content"></el-input>
</el-form-item>
</template>
<template v-else-if="searchData.deviceType == '12'">
<!-- 行车诱导 -->
<el-form-item label="工作状态">
<el-select v-model="editData.type12.mode" placeholder="请选择">
<el-option v-for="key, value in gzztMap" :key="key" :label="value" :value="key" />
</el-select>
</el-form-item>
<el-form-item label="工作时长">
<el-col :span="8">
<el-input-number v-model="editData.type12.timeLength" :min="1" :max="600" label="描述文字" />
</el-col>
<!-- <el-col :span="4" style="margin-left: 10px;">分钟</el-col> -->
</el-form-item>
</template>
<template v-else-if="searchData.deviceType == '10'">
<!-- 激光疲劳唤醒 -->
<el-form-item label="工作模式">
<el-select v-model="editData.type10.mode" placeholder="请选择">
<el-option v-for="value,key in gzmsMap" :key="key" :label="value" :value="key" />
</el-select>
</el-form-item>
<el-form-item label="工作时长">
<el-col :span="8">
<el-input-number v-model="editData.type10.timeLength" :min="1" :max="600" label="描述文字" />
</el-col>
<!-- <el-col :span="4" style="margin-left: 10px;">分钟</el-col> -->
</el-form-item>
</template>
<template v-else-if="searchData.deviceType == '13'">
<!-- 智能设备箱 -->
<el-form-item label="开启">
<el-switch v-model="editData.type13.open">
<!-- active-color="#13ce66" inactive-color="#ff4949" -->
</el-switch>
</el-form-item>
</template>
<template v-else-if="searchData.deviceType == '12'">
<!-- 行车诱导 -->
<el-form-item label="工作状态">
<el-select v-model="editData.type12.mode" placeholder="请选择">
<el-option v-for="value, key in gzztMap" :key="key" :label="value" :value="key" />
</el-select>
</el-form-item>
<el-form-item label="工作时长">
<el-col :span="8">
<el-input-number v-model="editData.type12.timeLength" :min="1" :max="600" label="描述文字" />
</el-col>
<!-- <el-col :span="4" style="margin-left: 10px;">分钟</el-col> -->
</el-form-item>
</template>
<el-form-item>
<el-button size="mini" type="primary" @click="onSubmit">确定</el-button>
</el-form-item>
<template v-else-if="searchData.deviceType == '13'">
<!-- 智能设备箱 -->
<el-form-item label="开启">
<el-switch v-model="editData.type13.switch">
<!-- active-color="#13ce66" inactive-color="#ff4949" -->
</el-switch>
</el-form-item>
</template>
<el-form-item>
<el-button size="mini" type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
<BoardInfoEditor @afterSubmit="____onEditSubmit" :mode="editDialog.mode" :type="editDialog.type"
:visible.sync="editDialog.visible" :screenSize="'768*60'" :tpl="editDialog.tpl"></BoardInfoEditor>
:visible.sync="editDialog.visible" :screenSize="this.propData.screenSize" :tpl="editDialog.tpl"></BoardInfoEditor>
</Dialog>
</template>
@ -118,6 +120,8 @@ import { deviceTypeOptions, directionOptions, gzmsMap, gzztMap } from "@screen/u
import { getDeviceList } from "@screen/utils/api/device.js"
import BoardPreview from "@screen/components/infoBoard/BoardPreview.vue";
import BoardInfoEditor from "@screen/components/infoBoard/BoardInfoEditor";
import BoardUtils from "@screen/utils/infoBoard.js"
import { addTaskRequest } from "@screen/utils/api/batch.js"
export default {
name: "taskEditDialog",
components: {
@ -128,21 +132,27 @@ export default {
event: "update:value",
},
props: {
deviceDic:Object,
deviceList:Array,
groupId: Number,
time: String,
visible: Boolean,
data: Object
propData: Object
},
data() {
return {
mode:"add",
deviceTypeOptions,
directionOptions,
gzmsMap,
deviceOptions:[],
gzztMap,
deviceArr:[],
searchData: {
deviceType: "",
direction: ""
},
filterData:{
pixelSize:""
screenSize:""
},
editData:{
devices:[],
@ -170,6 +180,9 @@ export default {
immediate: true,
handler(bool) {
if (!bool) return;
this.propData?.id ? this.mode = 'edit' : this.mode = 'add';
this.transformData();
this.initBasicData();
},
},
},
@ -178,43 +191,62 @@ export default {
// this.directionOptions = directionOptions;
},
methods: {
initBasicData(){
if(this.mode=='edit'){
this.deviceArr = this.deviceList;
}
},
transformData(){
//props
if (this.mode == 'edit'){
this.searchData.deviceType = this.propData.deviceType;
this.searchData.direction = this.propData.direction;
this.filterData.screenSize = this.propData.screenSize;
this.editData.devices = _.map(this.propData.devices, "id");
// { "STAY": 90, "ACTION": "1", "SPEED": "0", "COLOR": "ffff00", "FONT": "3", "FONT_SIZE": "24", "CONTENT": "\\\\n", "width": "160", "height": "80", "formatStyle": "2" }
this.editData.type2 = BoardUtils.contentToDeviceItem(this.propData.params);
}else{
}
},
onEditBoard(){
this.editDialog = {
visible: true,
mode: "edit",
type: "device",
tpl: {
"residenceTime": "90",
"intonation": "0",
"fontSpacing": "0",
"screenEntryMethod": "1",
"screenOutputMethod": "1",
"lineSpacing": "0",
"yCoordinate": "0",
"whetherToSynchronizePlayback": "0",
"whetherToPlayText": "0",
"playbackCount": "1",
"flashingFrequency": "5",
"backgroundColor": "8",
"foregroundColor": "ffff00",
"textContent": "长清收费站\\\\n出入口封闭",
"fontStyle": "0",
"displayAreaWidth": "160",
"playbackDuration": "90",
"displayAreaHeight": "80",
"volume": "0",
"xCoordinate": "0",
"screenEntrySpeed": "1",
"horizontalAlignment": "2",
"playSpecialEffects": "0",
"setUpTheSpeaker": "0",
"flickerSpeed": "0",
"specialEffectsSpeed": "1",
"fontSize": "24",
"verticalAlignment": "2",
"speechSpeed": "0",
"font": "3"
},
tpl:this.editData.type2
// {
// "residenceTime": "90",
// "intonation": "0",
// "fontSpacing": "0",
// "screenEntryMethod": "1",
// "screenOutputMethod": "1",
// "lineSpacing": "0",
// "yCoordinate": "0",
// "whetherToSynchronizePlayback": "0",
// "whetherToPlayText": "0",
// "playbackCount": "1",
// "flashingFrequency": "5",
// "backgroundColor": "8",
// "foregroundColor": "ffff00",
// "textContent": "\\\\n",
// "fontStyle": "0",
// "displayAreaWidth": "160",
// "playbackDuration": "90",
// "displayAreaHeight": "80",
// "volume": "0",
// "xCoordinate": "0",
// "screenEntrySpeed": "1",
// "horizontalAlignment": "2",
// "playSpecialEffects": "0",
// "setUpTheSpeaker": "0",
// "flickerSpeed": "0",
// "specialEffectsSpeed": "1",
// "fontSize": "24",
// "verticalAlignment": "2",
// "speechSpeed": "0",
// "font": "3"
// },
};
},
____onEditSubmit(data){
@ -224,21 +256,66 @@ export default {
},
onSubmit(){
// this.boardDataTransform();
// let devices =
// let data = {devices, functions }
console.log(this.editData , "编辑出来的数据");
let devices = [];
this.deviceArr.forEach((item,index)=>{
if (this.editData.devices.includes(item.id)){
let temp = {
id: item.id,
iotDeviceId: item.iotDeviceId,
deviceType: item.deviceType,
direction: item.direction
}
if(item.type == '2'){
temp.screenSize = item.screenSize;
}
devices.push(temp);
}
});
let params = this.processParams();
if(this.mode == "add"){
}
addTaskRequest(devices, params, { jobGroup: this.groupId, time:this.time }).then(res=>{
console.log(res)
});
this.$emit("onSubmit")
},
processParams(){
if(this.searchData.deviceType == "2"){
return BoardUtils.deviceItemToContent(this.editData.type2);
}else if(this.searchData.deviceType == "5"){
return {
content : editData.type5.content
}
} else if (this.searchData.deviceType == "10") {
return {
mode: editData.type10.mode,
timeLength: editData.type10.timeLength
}
} else if (this.searchData.deviceType == "12") {
return {
mode: editData.type12.mode,
timeLength: editData.type12.timeLength
}
} else if (this.searchData.deviceType == "13") {
return {
switch: editData.type13.switch
}
}
},
onChange() {
this.resetEditData();
this.deviceOptions = [];
this.deviceArr = [];
getDeviceList(this.searchData).then(res => {
res.data.forEach(item => {
this.deviceOptions.push({
label: item.deviceName,
value: item.id,
pixelSize: JSON.parse(item.otherConfig).screenSize
if (this.searchData.deviceType == '2'){
res.data.forEach(item => {
item.screenSize = JSON.parse(item.otherConfig).screenSize;
// this.deviceArr.push(item);
})
})
}
this.deviceArr = res.data;
}).catch(err => { })
},
resetEditData(){

44
ruoyi-ui/src/views/JiHeExpressway/pages/control/device/strategy/index.vue

@ -3,7 +3,7 @@
element-loading-background="rgba(0, 0, 0, 0.3)">
<div class="filter">
<div>
<ButtonGradient @click.native="handleAddEdit(true)">
<ButtonGradient @click.native="onAddEdit()">
<template #prefix>
<img src="@screen/images/insert.svg" />
</template>
@ -40,10 +40,10 @@
<template #button>
<Switcher class="switcher" :activeOption="activeOption" :value="item.status!='0'"
@change="(value) => handleSwitcherChange(value, item) " />
<Button @click.native="() => handleAddEdit(true, item)">
<Button @click.native="() => onAddEdit(item)">
编辑
</Button>
<Button style="background-color: #ff5f5f" @click.native="handleDelete(item)">
<Button style="background-color: #ff5f5f" @click.native="onDelete(item)">
删除
</Button>
</template>
@ -59,7 +59,7 @@
@current-change="handleCurrentChange" />
</div>
<AddNEditDialog v-model="isShowDialog" :data="dialogData" @onSuccess="getData" :dataAll="data" />
<AddNEditDialog v-model="isShowDialog" :propData="dialogData" @onSuccess="getData" />
</div>
</template>
@ -120,7 +120,7 @@ export default {
},
],
data: [],
dialogData: null,
dialogData: {},
isShowDialog: false,
isFirst: true,
};
@ -145,11 +145,11 @@ export default {
// };
return params;
},
async handleDelete(data) {
await confirm({ message: "是否要删除该敏感词?" });
async onDelete(data) {
await confirm({ message: "删除该任务组?" });
request({
url: `/business/dcInfoBoardVocabulary/${data.id}`,
url: `/business/dcBatchFunctionsJobGroup/${data.id}`,
method: "DELETE",
data: {},
})
@ -162,9 +162,9 @@ export default {
Message.error("删除失败");
});
},
handleAddEdit(bool, data) {
this.isShowDialog = bool;
this.dialogData = data;
onAddEdit(data) {
this.isShowDialog = true;
this.dialogData = data||{};
},
handleExport() {
exportFile({
@ -190,12 +190,14 @@ export default {
await delay(100);
//
this.data = [{
groupName : "任务组一",
remark : "每天早7点关闭激光唤醒设备,晚7点打开激光唤醒设备。每天早7点关闭激光唤醒设备,晚7点打开激光唤醒设备。"
}]
this.isLoading = false;
return;
// this.data = [{
// id:1,
// groupName : "",
// remark : "7777",
// detailedConfiguration:"[{time:'08:00:00',tasks:[1]}]"
// }]
// this.isLoading = false;
// return;
//
request({
@ -204,12 +206,12 @@ export default {
params: this.getSearchData(),
})
.then((result) => {
this.searchText = this.searchData?.word || "请输入敏感词,回车搜索";
this.searchText = this.searchData?.word || "请输入关键词,回车搜索";
if (result.code != 200) return;
this.data = result.rows;
this.data.map(item=>{
item.remark = "每天早7点关闭激光唤醒设备,晚7点打开激光唤醒设备。每天早7点关闭激光唤醒设备,晚7点打开激光唤醒设备。"
});
// this.data.map(item=>{
// item.remark = "7777"
// });
this.numTotal = result.total;
// this.pageTotal = Math.ceil(result.total/this.pageSize);
})

11
ruoyi-ui/src/views/JiHeExpressway/pages/control/qrCode/index.vue

@ -1,11 +1,13 @@
<template>
<div class='comp_box'>
<iframe class="iframe" src="https://10.0.81.202:83/alarm-ui/single?u=pDo/guSkRP8=&p=u4johJJOFTyugiay04vYxQ==&t=za4NgrFfeTdF76uSUrhJuA==&route=/warning/QRCode" frameborder="0"></iframe>
<iframe class="iframe" :src="alarmUrl" frameborder="0"></iframe>
</div>
</template>
<script>
import { getConfigKey } from "@/api/system/config.js";
export default {
name: 'InDevelopment',
components: {
@ -14,9 +16,16 @@ export default {
text:{
type:String,
default:"暂无数据"
},
alarmUrl:{
type:String,
default:"",
}
},
mounted() {
getConfigKey("dc.alarmUrl").then((res) => {
this.alarmUrl = res.msg
});
}
}
</script>

32
ruoyi-ui/src/views/JiHeExpressway/pages/service/board/index.vue

@ -125,7 +125,8 @@
<div class="partCon">
<vuescroll :ops="scrollOptions" class="templateBox" v-if="selectedBdMsg.length > 0"
:class="{ hide: isHideCtt }">
<draggable tag="div" :list="selectedBdMsg" @end="____onDragend" ghostClass="ghost_class" dragClass="drag_class" chosenClass="chosen_class">
<draggable tag="div" :list="selectedBdMsg" @end="____onDragend" ghostClass="ghost_class"
dragClass="drag_class" chosenClass="chosen_class">
<div v-for="(itm, indx) in selectedBdMsg" :key="indx" class="tplItem">
<!-- 模板内容 -->
<BoardPreview class="boardPreview" :boardWH="selectedSize" :tpl="itm"></BoardPreview>
@ -492,6 +493,7 @@ export default {
if (!this.selectedSize) {
this.selectedSize = item.otherConfig.screenSize;
}
console.log(item, item.otherConfig.screenSize)
// if (!this.selectedDevices.deviceName) {
// this.selectedDevices = item;
// }
@ -548,7 +550,7 @@ export default {
tpl,
};
},
____onDragend(evt){
____onDragend(evt) {
// console.log(evt, this.selectedBdMsg , "+++=======")
},
____onEditBoardItem(tpl, index) {
@ -1049,7 +1051,8 @@ export default {
padding-bottom: 10px;
.boardPreview {
border: 2px solid #004c64; background-color: #133242;
border: 2px solid #004c64;
background-color: #133242;
// width: 560px;
// height:80px;
flex: 1;
@ -1061,7 +1064,8 @@ export default {
display: flex;
margin-left: 10px;
/* // border: solid 1px #05afe3; */
border: 2px solid #004c64; background-color: #133242;
border: 2px solid #004c64;
background-color: #133242;
display: flex;
justify-content: space-around;
align-items: center;
@ -1107,18 +1111,26 @@ export default {
}
.tplItem.ghost_class {
.boardPreview, .infoBtnBox{
border-color:#F00;
.boardPreview,
.infoBtnBox {
border-color: #F00;
}
}
.tplItem.chosen_class {
.boardPreview, .infoBtnBox{
border-color:#0A0;
.boardPreview,
.infoBtnBox {
border-color: #0A0;
}
}
.tplItem.drag_class {
.boardPreview, .infoBtnBox{
border-color:#FF0;
.boardPreview,
.infoBtnBox {
border-color: #FF0;
}
}

39
ruoyi-ui/src/views/JiHeExpressway/utils/api/batch.js

@ -0,0 +1,39 @@
import request from '@/utils/request'
export function addTaskRequest(devices, params, others) {
let data = {
...others,
devices: devices,
"functions": [
{
"functionId": "11",
"params": {
"size": "65535",
"fileName": "play012.lst"
}
},
{
"functionId": "13",
"params": params
},
{
"functionId": "1B",
"params": {
"fileId": "12"
}
}
]
}
// console.log(JSON.stringify(data));
return request({
// url: '/business/board/batch/publish',
url: `/business/dcBatchFunctionsJob`,
method: 'post',
// data: data
data
})
}

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

@ -109,6 +109,24 @@ export const EventTopics = {
其他事件: 11,
};
//路网设施类型
// 1-收费站
// 2-桥梁
// 3-互通立交
// 4-枢纽立交
// 5-隧道
// 6-服务区',
// 7-停车区,
// 8-清障驻点
// 9-边坡
export const RoadNFTopics = {
收费站: 1,
桥梁: 2,
枢纽立交: 4,
服务区: 6,
停车区: 7,
};
// 事件类型 eventType
export const EventType = {
0: {
@ -163,6 +181,13 @@ export const WarningType = {
99: "其他事件",
};
function arrayToDic(arr) {
let obj = {};
arr.map((item) => {
obj[item.value] = item;
});
return obj;
}
//设备Options
export const deviceTypeOptions = [
{
@ -172,7 +197,7 @@ export const deviceTypeOptions = [
{
value: 2,
label: "可变信息标志",
timingControl: true
timingControl: true,
},
{
value: 3,
@ -185,7 +210,7 @@ export const deviceTypeOptions = [
{
value: 5,
label: "路段语音广播",
timingControl: true
timingControl: true,
},
{
value: 6,
@ -206,7 +231,7 @@ export const deviceTypeOptions = [
{
value: 10,
label: "激光疲劳唤醒",
timingControl: true
timingControl: true,
},
{
value: 11,
@ -215,12 +240,12 @@ export const deviceTypeOptions = [
{
value: 12,
label: "行车诱导",
timingControl: true
timingControl: true,
},
{
value: 13,
label: "智能设备箱",
timingControl: true
timingControl: true,
},
{
value: 14,
@ -228,6 +253,8 @@ export const deviceTypeOptions = [
},
];
export const deviceTypeDic = arrayToDic(deviceTypeOptions);
export const WarningTypeList = Object.keys(WarningType).map((key) => {
return {
value: key * 1,
@ -352,49 +379,49 @@ export const eventSubClassMap = {
],
2: [
{
value: '1',
value: "1",
label: "高速主线",
},
{
value: '2',
value: "2",
label: "服务区",
},
{
value: '3',
value: "3",
label: "立交桥",
},
{
value: '4',
value: "4",
label: "收费站",
},
],
3: [
{
value: '1',
value: "1",
label: "主线关闭",
},
{
value: '2',
value: "2",
label: "主线限行",
},
{
value: '6',
value: "6",
label: "收费站关闭",
},
{
value: '7',
value: "7",
label: "收费站限行",
},
{
value: '10',
value: "10",
label: "匝道立交关闭",
},
{
value: '12',
value: "12",
label: "匝道立交限行",
},
{
value: '14',
value: "14",
label: "服务区关闭",
},
],
@ -458,43 +485,43 @@ export const eventSubClassMap = {
],
7: [
{
value: '1',
value: "1",
label: "道路养护施工",
},
{
value: '2',
value: "2",
label: "收费站养护施工",
},
{
value: '3',
value: "3",
label: "服务区养护施工",
},
{
value: '4',
value: "4",
label: "枢纽立交匝道养护施工",
},
{
value: '5',
value: "5",
label: "地方道路养护施工",
},
{
value: '6',
value: "6",
label: "道路工程建设施工",
},
{
value: '7',
value: "7",
label: "收费站工程建设施工",
},
{
value: '8',
value: "8",
label: "服务区工程建设施工",
},
{
value: '9',
value: "9",
label: "枢纽立交匝道工程建设施工",
},
{
value: '10',
value: "10",
label: "地方道路工程建设施工",
},
],
@ -514,27 +541,27 @@ export const eventSubClassMap = {
],
9: [
{
value: '1',
value: "1",
label: "摄像机",
},
{
value: '2',
value: "2",
label: "护栏",
},
{
value: '3',
value: "3",
label: "隔离栅",
},
{
value: '4',
value: "4",
label: "情报板",
},
{
value: '5',
value: "5",
label: "防炫板",
},
{
value: '6',
value: "6",
label: "其他",
},
],
@ -578,7 +605,7 @@ export const eventSubClassMap = {
],
11: [
{
value: '1',
value: "1",
label: "其他事件",
},
],
@ -973,9 +1000,9 @@ export const DirectionTypes = {
2: "双向",
};
export const directionOptions = [
{value : "1", label : "菏泽方向"},
{value : "3", label : "济南方向"},
{value : "2", label : "双向"}
{ value: "1", label: "菏泽方向" },
{ value: "3", label: "济南方向" },
{ value: "2", label: "双向" },
];
//行车诱导相关
@ -1041,3 +1068,21 @@ export const manualEarlyWarning = [
label: "逆行",
},
];
export const controlType = {
0: {
text: "正常",
},
1: {
text: "关闭",
},
};
export const boolType = {
0: {
text: "否",
},
1: {
text: "是",
},
};

30
ruoyi-ui/src/views/JiHeExpressway/utils/infoBoard.js

@ -70,5 +70,35 @@ export default {
data1 = _.merge(data.origin, temp);
}
return data1;
},
deviceItemToContent(item){
let temp = {
STAY: item.playbackDuration,
ACTION: item.screenEntryMethod,
SPEED: item.fontSpacing || 0,
COLOR: item.foregroundColor,
FONT: item.font,
FONT_SIZE: item.fontSize,
CONTENT: item.textContent.replaceAll(',', '\\,').replaceAll('=', '\\=').replaceAll('\n', '\\\\n'),
width: item.displayAreaWidth,
height: item.displayAreaHeight,
formatStyle: item.verticalAlignment
}
return temp
},
contentToDeviceItem(item){
let temp = {
playbackDuration : item.STAY,
screenEntryMethod : item.ACTION,
fontSpacing : item.SPEED,
foregroundColor : item.COLOR,
font : item.FONT,
fontSize : item.FONT_SIZE,
textContent: item.CONTENT.replaceAll('\\,', ',').replaceAll('\\=', '=').replaceAll('\\\\n', '\n'),
displayAreaWidth : item.width,
displayAreaHeight : item.height,
verticalAlignment : item.formatStyle
}
return temp
}
}

6
ruoyi-ui/vue.config.js

@ -31,7 +31,7 @@ module.exports = {
devServer: {
host: "0.0.0.0",
port: port,
https: true,
// https: true,
open: true,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
@ -52,9 +52,9 @@ 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.66.196:8087`, //正晨后台 连现场物联 刘文阁2
// target: `http://10.168.68.42:8087`, //王思祥
// target: `http://10.168.65.194:8087`, //赵祥龙
target: `http://10.168.72.174:8087`, //赵祥龙
// target: `http://10.168.65.156:8097`, //孟
// target: `http://10.168.56.165:8087`, //王家宝
// target: `http://10.168.77.128:8087`, //王兴琳

Loading…
Cancel
Save