Browse Source

首页弹窗功能修改

wangqin
Joe 10 months ago
parent
commit
a21c9ee8c9
  1. 115
      ruoyi-ui/src/views/JiHeExpressway/components/CustomControlVideo/index.vue
  2. 7
      ruoyi-ui/src/views/JiHeExpressway/components/Descriptions.vue
  3. 64
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/components/RadioGroup/RadioCircle.vue
  4. 21
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/components/RadioGroup/index.vue
  5. 1
      ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/index.vue
  6. 2
      ruoyi-ui/src/views/JiHeExpressway/components/InputSearch/index.vue
  7. 111
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/DrivingGuidance/components/DeviceControlDialog.vue
  8. 129
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/DrivingGuidance/index.vue
  9. 15
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/index.vue
  10. 105
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/buttonEvent.js
  11. 71
      ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/RoadAndEvents/utils/map.js
  12. 11
      ruoyi-ui/src/views/JiHeExpressway/utils/axios/auth.js

115
ruoyi-ui/src/views/JiHeExpressway/components/CustomControlVideo/index.vue

@ -0,0 +1,115 @@
<template>
<div class='CustomControlVideo'>
<div class="control-btns">
<div class="left">
<div class="radio">
<span>图像</span>
<span class="active">视频</span>
</div>
</div>
<div class="right">
<div class="btn">2X</div>
<div class="btn">全屏</div>
</div>
</div>
<Video controls class="videoStream" :camId="camId" />
</div>
</template>
<script>
import Video from "@screen/components/Video"
export default {
name: 'CustomControlVideo',
components: {
Video
},
props: {
camId: {
type: String,
default: null
}
}
}
</script>
<style lang='scss' scoped>
.CustomControlVideo {
position: relative;
flex: 1;
// background-color: #19E1B1;
.videoStream {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.control-btns {
z-index: 1;
position: absolute;
padding: 6px 9px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left,
.right {
display: flex;
align-items: center;
gap: 9px;
}
.radio {
background: #265A70;
border-radius: 41px 41px 41px 41px;
overflow: hidden;
opacity: 1;
border: 1px solid #3DE8FF;
font-size: 12px;
// font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 14px;
height: fit-content;
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
.active {
background-color: rgba(61, 232, 255, 1);
}
span {
background-color: rgba(38, 90, 112, 1);
padding: 4px 9px;
display: inline-block;
cursor: pointer;
&:hover {
background-color: rgba(61, 232, 255, 1);
}
}
}
.btn {
background: #265A70;
border-radius: 6px 6px 6px 6px;
opacity: 1;
border: 1px solid #3DE8FF;
font-size: 12px;
// font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 14px;
padding: 3px 9px;
cursor: pointer;
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
}
}
}
</style>

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

@ -9,7 +9,7 @@
</div>
<div class="content text" :style="resolveStyle(contentStyle)">
<slot :name="`content-${item.key || item.label}`" :data="item">
{{ item.text || '-' }}
{{ data[item.key] || '-' }}
</slot>
</div>
</div>
@ -20,11 +20,14 @@
export default {
name: 'Descriptions',
props: {
data: {
type: Object,
default: () => ({})
},
/**
* {
* key: string;
* label: string;
* text: string;
* gridRow: number;
* gridColumn: number;
* }[]

64
ruoyi-ui/src/views/JiHeExpressway/components/FormConfig/components/RadioGroup/RadioCircle.vue

@ -0,0 +1,64 @@
<template>
<ElRadio v-bind="getBind" v-on="$listeners" class="Radio">
<slot />
</ElRadio>
</template>
<script>
export default {
name: 'Radio',
props: {},
computed: {
getBind() {
return {
border: true,
...this.$attrs
}
}
}
}
</script>
<style lang='scss' scoped>
label.Radio {
border-color: rgba(96, 223, 254, .5);
border: 0;
// padding: 0;
// display: inline-flex;
// align-items: center;
// justify-content: center;
// height: 27px;
// padding: 0 6px;
// margin: 0 3px !important;
&.is-checked {
border-color: rgba(0, 0, 0, 0);
// background: var(--active-color);
}
::v-deep {
.el-radio__input {
.el-radio__inner {
background-color: rgba(0, 0, 0, 0);
border: 1px solid #3DE8FF;
width: 15px;
height: 15px;
&::after {
background-color: #3DE8FF;
width: 9px;
height: 9px;
}
}
}
.el-radio__label {
font-size: 14px;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
padding-left: 3px;
}
}
}
</style>

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

@ -1,7 +1,6 @@
<template>
<ElRadioGroup class='RadioGroup' v-bind="$attrs" v-on="$listeners">
<component :activeColor="activeColor" :is="type === 'button' ? 'RadioButton' : 'Radio'" v-for="item in options"
:key="item.key" :label="item.key">
<component :activeColor="activeColor" :is="getComponents()" v-for="item in options" :key="item.key" :label="item.key">
{{ item.label }}
</component>
</ElRadioGroup>
@ -10,17 +9,19 @@
<script>
import Radio from "./Radio.vue"
import RadioButton from "./RadioButton.vue"
import RadioCircle from "./RadioCircle.vue"
export default {
name: 'RadioGroup',
components: {
Radio,
RadioButton
RadioButton,
RadioCircle
},
props: {
type: {
type: String,
// button | normal
// button | normal | circle
default: "normal"
},
activeColor: {
@ -36,6 +37,18 @@ export default {
type: Array,
default: () => []
}
},
methods: {
getComponents() {
switch (this.type) {
case "button":
return 'RadioButton';
case "circle":
return 'RadioCircle';
default:
return 'Radio'
}
}
}
}
</script>

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

@ -144,6 +144,7 @@ export default {
&:first-child {
.el-form-item__label-wrap {
// padding-top: 9px;
margin: 0 !important;
}
}

2
ruoyi-ui/src/views/JiHeExpressway/components/InputSearch/index.vue

@ -8,7 +8,7 @@
<div style="width: 100%">
<slot>
<Form v-if="formList && formList.length" class="form" ref="FormConfigRef" :formList="formList"
<Form v-if="formList && formList.length" labelWidth="120px" class="form" ref="FormConfigRef" :formList="formList"
v-bind="getFormConfigOptions" />
<ElEmpty v-else description="暂无搜索内容"></ElEmpty>
</slot>

111
ruoyi-ui/src/views/JiHeExpressway/pages/Home/components/Dialogs/DrivingGuidance/components/DeviceControlDialog.vue

@ -0,0 +1,111 @@
<template>
<Dialog v-model="modelVisible" title="设备操作">
<div class='DeviceControlDialog'>
<Form class="form" ref="FormConfigRef" :formList="formList" column="1" style="flex: 1;" labelWidth="90px" />
<div class="footer">
<Button style="background-color: rgba(0, 179, 204, .3);" @click.native="modelVisible = false">
取消
</Button>
<Button @click.native="handleSearch">
确定
</Button>
</div>
</div>
</Dialog>
</template>
<script>
import Dialog from "@screen/components/Dialog/index.vue";
import Button from "@screen/components/Buttons/Button.vue"
import Form from '@screen/components/FormConfig';
import { cloneDeep } from "lodash"
export default {
name: 'DeviceControlDialog',
components: {
Dialog,
Button,
Form
},
model: {
prop: 'visible',
event: "update:value"
},
props: {
visible: Boolean
},
data() {
return {
formList: [
{
label: "类型:",
key: "key291",
type: "RadioGroup",
isAlone: true,
required: true,
options: {
type: 'circle',
options: [
{
key: "手动控制",
label: "手动控制",
},
{
key: "自动控制",
label: "自动控制",
}
],
},
},
{
label: "工作状态:",
key: "key999",
type: "select",
},
{
label: "选择时间:",
key: "key009",
type: "datePicker",
options: {
type: "daterange",
},
},
]
}
},
computed: {
modelVisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:value', val)
}
}
},
methods: {
handleSearch() {
const result = cloneDeep(this.$refs.FormConfigRef?.formData);
}
},
}
</script>
<style lang='scss' scoped>
.DeviceControlDialog {
width: 360px;
height: 150px;
display: flex;
flex-direction: column;
gap: 15px;
.footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 9px;
}
}
</style>

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

@ -0,0 +1,129 @@
<template>
<Dialog v-model="obverseVisible" title="行车诱导">
<div class="DrivingGuidance">
<CustomControlVideo class="camera-video" />
<ElTabs v-model="activeName" @tab-click="handleClickTabs" class="tabs">
<ElTabPane label="详细设计" name="first">
<Descriptions :list="list" :data="data" style="gap: 18px" />
</ElTabPane>
<ElTabPane label="设备参数" name="second">摄相机参数</ElTabPane>
</ElTabs>
<div class="bottom">
<Button @click.native="deviceControlVisible = true">设备操作</Button>
</div>
</div>
<DeviceControlDialog v-model="deviceControlVisible" />
</Dialog>
</template>
<script>
import Dialog from "@screen/components/Dialog/index.vue";
import Button from "@screen/components/Buttons/Button.vue"
import Descriptions from '@screen/components/Descriptions.vue';
import CustomControlVideo from '@screen/components/CustomControlVideo/index.vue';
import DeviceControlDialog from "./components/DeviceControlDialog.vue"
import { dialogDelayVisible } from "./../mixin"
// G35 K094+079
export default {
name: 'DrivingGuidance',
mixins: [dialogDelayVisible],
components: {
Dialog,
Button,
Descriptions,
CustomControlVideo,
DeviceControlDialog
},
data() {
return {
activeName: 'first',
deviceControlVisible: true,
data: {
deviceType: "行车诱导",
deviceStation: "k094+079",
roadName: "G35济泽高速",
deviceDirection: "济南方向",
deviceStatus: "在线",
deviceVendors: "XXX厂家",
},
list: [
{
label: '设备类型',
key: "deviceType",
},
{
label: '设备桩号',
key: "deviceStation",
},
{
label: '道路名称',
key: "roadName",
},
{
label: '设备方向',
key: "deviceDirection",
},
{
label: '设备状态',
key: "deviceStatus",
},
{
label: '设备厂商',
key: "deviceVendors",
},
]
}
},
methods: {
handleClickTabs() { }
}
}
</script>
<style lang='scss' scoped>
.DrivingGuidance {
width: 600px;
height: 510px;
color: #fff;
display: flex;
flex-direction: column;
.camera-video {
flex: 1.5;
}
.tabs {
flex: 1;
display: flex;
flex-direction: column;
::v-deep {
.el-tabs__content {
flex: 1;
.el-tab-pane {
height: 100%;
}
}
}
}
.bottom {
margin-top: 12px;
display: flex;
gap: 9px;
align-items: center;
justify-content: end;
>div {
font-size: 16px;
padding: 6px 12px;
}
}
}
</style>

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

@ -37,8 +37,9 @@ import { getLayerData } from "./utils/layerImages";
import { debounce } from "lodash";
import { eventMap, cacheRemoveFunc } from "./utils/buttonEvent";
import ControlCamera from "./../Dialogs/ControlCamera/index.vue"
import Bg1 from "@screen/components/Decorations/bg-1.vue"
import ControlCamera from "./../Dialogs/ControlCamera/index.vue"
import DrivingGuidance from "./../Dialogs/DrivingGuidance/index.vue"
import Camera from "./../Dialogs/Camera/index.vue";
export default {
@ -46,6 +47,7 @@ export default {
components: {
ControlCamera,
Camera,
DrivingGuidance,
Bg1
},
data() {
@ -59,7 +61,7 @@ export default {
// 0 ControlCamera | 1 Camera
component: void 0,
data: void 0,
// component: ControlCamera,
// component: DrivingGuidance,
// data: {
// camId: "57937",
// }
@ -97,12 +99,17 @@ export default {
this.tabContentData = item.children;
},
handleDevice: debounce(function (item) {
this.$emit("onClickItem", item);
const key = `${this.active}/${item.title}`;
eventMap[`${key}${item.status ? "_close" : ""}`]?.call(this, item);
const status = item.status;
item.status = item.status ? "" : "_active";
console.log("%c [ key ]-102-「index.vue」", "font-size:15px; background:#9d63e9; color:#e1a7ff;", key);
if (!eventMap[`${key}${status ? "_close" : ""}`]) return this.$emit("onClickItem", item);
eventMap[`${key}${status ? "_close" : ""}`]?.call(this, item);
}, 360),
handleCleared() {
const { mapIns } = this.getMap();

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

@ -3,7 +3,7 @@ import { Message } from "element-ui";
const PilePointJSON = require(`@screen/pages/Home/components/AMapContainer/data/lcz.json`);
import { setMarkerCluster } from "./map";
import { setMarkToMap } from "./map";
// 0 有 可控(球机)ControlCamera | 1 ⽆ 不可控(枪机)Camera
const cameraCtrlMap = {
@ -18,9 +18,6 @@ export const cacheRemoveFunc = {
export const eventMap = {
async "路测设备/摄像机"(item) {
// https://lbs.amap.com/demo/javascript-api-v2/example/mass-markers/labelmarker-mass
const { AMap, mapIns } = this.getMap();
if (!mapIns) return Message.error("地图加载失败!");
// {
// camId: "57937",
@ -43,73 +40,67 @@ export const eventMap = {
.get("/system/camera/camList")
// .get("/system/dept/camTreeselect")
.catch(() => ({}));
// const { code, data } = { code: 200 };
// const { code, data } = { code: 200, data: [] };
if (code != 200) return Message.error("摄像机加载失败!");
cacheRemoveFunc.DriveTestEquipment_Camera_Remove?.();
const normal = require(`@screen/images/layer${item.id.replace(
/^\.|[^/]+(?=.svg$)/g,
(data) => (data === "." ? "" : `${data}_active`)
)}`);
const fault = require(`@screen/images/layer${item.id.replace(
/^\.|[^/]+(?=.svg$)/g,
(data) => (data === "." ? "" : `${data}_fault`)
)}`);
const faultBg = require(`@screen/images/mapBg/fault.svg`);
const normalBg = require(`@screen/images/mapBg/active.svg`);
cacheRemoveFunc.DriveTestEquipment_Camera_Remove = setMarkToMap.call(
this,
item,
data,
() => {
const { lng, lat } = PilePointJSON[item.pileNum] || {};
const markerClick = (e) => {
const extData = e.target.getExtData();
return {
lnglat: [lng, lat],
};
},
(extData) => {
this.dialogConfig = {
// 0 有(球机) 1 ⽆(枪机)
component: cameraCtrlMap[extData.ptzCtrl],
data: extData,
};
}
);
},
async "路测设备/摄像机_close"() {
cacheRemoveFunc.DriveTestEquipment_Camera_Remove?.();
},
async "路测设备/行车诱导_close"() {
cacheRemoveFunc.Driving_Guidance_Remove?.();
},
async "路测设备/行车诱导"(item) {
const { code, data } = await axiosIns
.get("/system/camera/camList")
// .get("/system/dept/camTreeselect")
.catch(() => ({}));
// const { code, data } = { code: 200, data: [] };
this.dialogConfig = {
// 0 有(球机) 1 ⽆(枪机)
component: cameraCtrlMap[extData.ptzCtrl],
data: extData,
};
if (code != 200) return Message.error("摄像机加载失败!");
console.log(this.dialogConfig);
};
cacheRemoveFunc.Driving_Guidance_Remove?.();
const markerCluster = await setMarkerCluster(
mapIns,
data.map((item) => {
cacheRemoveFunc.Driving_Guidance_Remove = setMarkToMap.call(
this,
item,
data,
() => {
const { lng, lat } = PilePointJSON[item.pileNum] || {};
return {
weight: 1,
lnglat: [lng, lat],
name: "",
extData: item,
content: `<div style="
background-image: url(${item.status !== "0" ? faultBg : normalBg});
background-size: 100% 100%;
background-repeat: no-repeat;
width: 42px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
">
<img style="
width: 18px;
height: 18px;
margin-left: 3px;
margin-bottom: 6px;
" src='${item.status !== "0" ? fault : normal}'>
</div>`,
};
}),
markerClick
},
(extData) => {
this.dialogConfig = {
component: "DrivingGuidance",
data: extData,
};
}
);
cacheRemoveFunc.DriveTestEquipment_Camera_Remove = () =>
markerCluster.setMap(null);
mapIns.setFitView(markerCluster.U, false, [360, 360, 360, 360]);
},
async "路测设备/摄像机_close"() {
cacheRemoveFunc.DriveTestEquipment_Camera_Remove?.();
// cacheRemoveFunc.DriveTestEquipment_Camera_Remove?.();
},
};

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

@ -86,3 +86,74 @@ export async function setMarkerCluster(map, points, markerFun) {
return markerCluster;
}
/**
*
* @param {*} item
* @param {*} resolveMarker 处理数据 返回 { lnglat: [lng, lat], content: '' }
* @param {*} _markerClick marker 点击
* @returns
*/
export function setMarkToMap(item, data, resolveMarker, _markerClick) {
const { mapIns } = this.getMap();
if (!mapIns) return Message.error("地图加载失败!");
const normal = require(`@screen/images/layer${item.id.replace(
/^\.|[^/]+(?=.svg$)/g,
(data) => (data === "." ? "" : `${data}_active`)
)}`);
const fault = require(`@screen/images/layer${item.id.replace(
/^\.|[^/]+(?=.svg$)/g,
(data) => (data === "." ? "" : `${data}_fault`)
)}`);
const faultBg = require(`@screen/images/mapBg/fault.svg`);
const normalBg = require(`@screen/images/mapBg/active.svg`);
const markerClick = (e) => {
const extData = e.target.getExtData();
_markerClick(extData, e);
};
const markerCluster = setMarkerCluster(
mapIns,
data.map((item) => {
const { lnglat, content } = resolveMarker(item);
// const { lng, lat } = PilePointJSON[item.pileNum] || {};
return {
weight: 1,
lnglat,
name: "",
extData: item,
content:
content ||
`<div style="
background-image: url(${item.status !== "0" ? faultBg : normalBg});
background-size: 100% 100%;
background-repeat: no-repeat;
width: 42px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
">
<img style="
width: 18px;
height: 18px;
margin-left: 3px;
margin-bottom: 6px;
" src='${item.status !== "0" ? fault : normal}'>
</div>`,
};
}),
markerClick
);
mapIns.setFitView(markerCluster.U, false, [360, 360, 360, 360]);
return () => markerCluster.setMap(null);
}

11
ruoyi-ui/src/views/JiHeExpressway/utils/axios/auth.js

@ -6,10 +6,10 @@ import axios from "axios";
// 后台
const RequestURL = `http://10.168.77.209:1024/dev-api`;
// const UN = "jhgskj",
// PD = "jhgskj@2023",
const UN = "admin",
PD = "admin123",
const UN = "jhgskj",
PD = "jhgskj@2023",
// const UN = "admin",
// PD = "admin123",
tokeKey = "LOCAL_TOKEN";
let continueRefreshToken = true;
@ -21,7 +21,8 @@ function getToken() {
return new Promise((resolve, reject) => {
axios
.post(`${RequestURL}/login`, {
// .post(`${RequestURL}/login`, {
.post(`${RequestURL}/apiLogin`, {
username: UN,
password: PD,
})

Loading…
Cancel
Save