This commit is contained in:
fan 2024-01-29 13:09:26 +08:00
commit 6ddc51ecd7
5 changed files with 357 additions and 43 deletions

View File

@ -0,0 +1,216 @@
<template>
<draggable-dialog seamless title="驱采状态" :width="1165" :height="500">
<q-tabs
v-model="tab"
dense
active-color="primary"
indicator-color="primary"
align="justify"
narrow-indicator
>
<q-tab
v-for="(item, index) in tabList"
:key="index"
:name="item.value"
:label="item.label"
/>
</q-tabs>
<q-separator />
<q-tab-panels v-model="tab" animated keep-alive>
<template v-for="tabInfo in tabList" :key="tabInfo.label">
<q-tab-panel :name="tabInfo.value">
<div
class="row no-wrap"
v-for="row in showSetCellMessage.rows"
:key="row"
>
<div
class="ceil"
:class="{
heightLight:
row > 1 &&
col > 1 &&
ciCjList?.cjList[col - 2].bitList[row - 2].refRelays.length,
changeCellSize: col == 1,
}"
v-for="col in showSetCellMessage.cols"
:key="col"
@click="handleCellClick(row, col)"
>
<span v-if="row == 1 && col == 1"> 位置</span>
<span v-else-if="row == 1 || col == 1">
{{ row == 1 ? col - 1 : row - 1 }}</span
>
<div
v-else
@mouseover="onMouseOver"
@mouseleave="showTooltip = false"
>
{{ tabInfo.ListMap.get(`${row - 1}-${col - 1}`) }}
<q-tooltip
anchor="bottom middle"
self="bottom middle"
v-if="showTooltip"
>
{{ tabInfo.ListMap.get(`${row - 1}-${col - 1}`) }}
</q-tooltip>
</div>
</div>
</div>
</q-tab-panel>
</template>
</q-tab-panels>
</draggable-dialog>
</template>
<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import { useLineStore } from 'src/stores/line-store';
import DraggableDialog from 'src/components/common/DraggableDialog.vue';
import { relayCabinetGraphicData } from 'src/protos/relayCabinetLayoutGraphics';
import {
loadSceneCiCjList,
loadSceneCiQdList,
refRelaysListMap,
} from 'src/drawApp/relayScene';
import { Relay } from 'src/graphics/relay/Relay';
import { JlGraphic } from 'jl-graphic';
const lineStore = useLineStore();
const tab = ref('CiCj');
const tabList = ref([
{
label: '采集状态',
value: 'CiCj',
ListMap: new Map<string, string>(),
},
{
label: '驱动状态',
value: 'CiQd',
ListMap: new Map<string, string>(),
},
]);
const setCellMessage = ref<{ rows: number; cols: number }>({
rows: 32,
cols: 8,
});
const showSetCellMessage = computed(() => {
return {
rows: setCellMessage.value.rows + 1,
cols: setCellMessage.value.cols + 1,
};
});
let ciCjList: relayCabinetGraphicData.CiCj;
let ciQdList: relayCabinetGraphicData.CiQd;
watch(tab, (newVal) => {
if (newVal == 'CiQd') {
updateCiQdListMap();
} else {
}
});
onMounted(() => {
ciCjList = loadSceneCiCjList();
ciQdList = loadSceneCiQdList();
setCellMessage.value.rows = ciCjList.dsCount;
setCellMessage.value.cols = ciCjList.cjList.length;
tabList.value[0].ListMap = updateCiCjListMap();
tabList.value[1].ListMap = updateCiQdListMap();
});
function updateCiCjListMap() {
const showCiCjListMap = new Map<string, string>();
ciCjList?.cjList.forEach((cjDataSet, i) => {
cjDataSet.bitList.forEach((cjData, j) => {
const ref = cjData.refRelays.map((refRelay) => {
const refDeviceData = refRelaysListMap.get(refRelay.relayId);
const relay = lineStore
.getLineApp()
.getScene(lineStore.sceneName)
.queryStore.queryById<Relay>(refRelay.relayId);
const pos =
refRelay.position == relayCabinetGraphicData.CjDataItem.PostionType.Q
? 'Q'
: 'H';
if (refDeviceData?.device) {
return `${refDeviceData.device}_${refDeviceData?.combinationtype}_${relay.datas.code}_${pos}`;
} else {
return `${refDeviceData?.combinationtype}_${relay.datas.code}_${pos}`;
}
});
showCiCjListMap.set(`${j + 1}-${i + 1}`, ref.join('/'));
});
});
return showCiCjListMap;
}
function updateCiQdListMap() {
const showCiQdListMap = new Map<string, string>();
ciQdList?.qdList.forEach((cjDataSet, i) => {
cjDataSet.bitList.forEach((cjData, j) => {
const ref = cjData.refRelays.map((refRelay) => {
const refDeviceData = refRelaysListMap.get(refRelay);
const relay = lineStore
.getLineApp()
.getScene(lineStore.sceneName)
.queryStore.queryById<Relay>(refRelay);
if (refDeviceData?.device) {
return `${refDeviceData.device}_${refDeviceData.combinationtype}_${relay.datas.code}`;
} else {
return `${refDeviceData?.combinationtype}_${relay.datas.code}`;
}
});
showCiQdListMap.set(`${j + 1}-${i + 1}`, ref.join('/'));
});
});
return showCiQdListMap;
}
function handleCellClick(row: number, col: number) {
if (row == 1 || col == 1) return;
const app = lineStore.getLineApp().getScene(lineStore.sceneName);
app.updateSelected();
const select: JlGraphic[] = [];
if (tab.value == 'CiCj') {
ciCjList.cjList[col - 2].bitList[row - 2].refRelays.forEach((relay) => {
const g = app.queryStore.queryById(relay.relayId) as Relay;
select.push(g);
});
} else {
ciQdList.qdList[col].bitList[row].refRelays.forEach((relayId) => {
const g = app.queryStore.queryById(relayId) as Relay;
select.push(g);
});
}
app.updateSelected(...select);
app.makeGraphicCenterShow(...select);
}
const showTooltip = ref(false);
function onMouseOver(e: MouseEvent) {
if ((e.target as HTMLElement).clientHeight > 30) {
showTooltip.value = true;
}
}
</script>
<style scoped>
.ceil {
width: 120px;
height: 30px;
border: solid 1px red;
margin: 7px;
cursor: pointer;
text-align: center;
line-height: 30px;
word-break: break-all;
overflow: hidden;
}
.changeCellSize {
width: 40px;
}
.heightLight {
background-color: orange;
}
</style>

View File

@ -1,5 +1,11 @@
<template>
<q-card flat bordered>
<q-card
flat
bordered
v-for="(item, index) in relayState"
:key="item.id"
style="margin-bottom: 10px"
>
<q-card-section class="flex justify-between">
<span class="text-h6">继电器状态</span>
<q-btn-dropdown color="primary" label="操作">
@ -9,7 +15,7 @@
:key="item.label"
clickable
v-close-popup
@click="changePosition(item.value)"
@click="changePosition(item.value, index)"
>
<q-item-section>{{ item.label }}</q-item-section>
</q-item>
@ -18,10 +24,15 @@
</q-card-section>
<q-separator inset />
<q-card-section class="q-gutter-sm">
<q-input outlined readonly v-model="relayState.id" label="id" />
<q-input outlined readonly v-model="relayState.code" label="名称" />
<q-checkbox disable v-model="relayState.xh" label="是否吸合" />
<q-checkbox disable v-model="relayState.force" label="是否强制" />
<q-input outlined readonly v-model="relayState[index].id" label="id" />
<q-input
outlined
readonly
v-model="relayState[index].code"
label="名称"
/>
<q-checkbox disable v-model="relayState[index].xh" label="是否吸合" />
<q-checkbox disable v-model="relayState[index].force" label="是否强制" />
</q-card-section>
</q-card>
</template>
@ -37,12 +48,21 @@ import { request } from 'src/protos/request';
const $q = useQuasar();
const lineStore = useLineStore();
const relayState = ref({
id: 0,
code: '',
xh: false,
force: false,
});
const relayState = ref<
{
id: number;
code: string;
xh: boolean;
force: boolean;
}[]
>([
{
id: 0,
code: '',
xh: false,
force: false,
},
]);
let operateOptions: {
label: string;
value: request.Relay.Operation;
@ -51,17 +71,17 @@ let operateOptions: {
{ label: ' 强制后接点位(落下)', value: request.Relay.Operation.ForceHw },
{ label: ' 取消强制', value: request.Relay.Operation.CancelForce },
];
let copySelectGraphic: Relay | null = null;
let copySelectGraphic: Relay[] | null = null;
watch(
() => lineStore.selectedGraphics,
(val, oldVal) => {
if (oldVal?.length == 1 && oldVal[0] instanceof Relay) {
unSubscribeState(oldVal[0]);
if (oldVal && oldVal.length >= 1) {
unSubscribeState(oldVal as Relay[]);
}
if (val?.length == 1 && val[0] instanceof Relay) {
copySelectGraphic = toRaw(val[0]);
initRelayState(val[0]);
if (val && val.length >= 1) {
copySelectGraphic = toRaw(val as Relay[]);
initRelayState(val as Relay[]);
} else {
copySelectGraphic = null;
}
@ -70,31 +90,38 @@ watch(
onMounted(() => {
if (lineStore.selectedGraphics) {
initRelayState(lineStore.selectedGraphics[0] as Relay);
initRelayState(lineStore.selectedGraphics as Relay[]);
}
});
function initRelayState(relay: Relay) {
copySelectGraphic = toRaw(relay);
relayState.value = {
id: relay.datas.id,
code: relay.datas.code,
xh: relay.states.xh || false,
force: relay.states.force || false,
};
subscribeState(relay);
function initRelayState(relays: Relay[]) {
copySelectGraphic = toRaw(relays);
relayState.value = [];
relays.forEach((relay) =>
relayState.value.push({
id: relay.datas.id,
code: relay.datas.code,
xh: relay.states.xh || false,
force: relay.states.force || false,
})
);
subscribeState(relays);
}
function updateState(newVal: RelayState) {
relayState.value.xh = newVal.states.xh || false;
for (let i = 0; i < relayState.value.length; i++) {
if (+newVal.code == relayState.value[i].id) {
relayState.value[i].xh = newVal.states.xh || false;
}
}
}
function changePosition(operation: request.Relay.Operation) {
function changePosition(operation: request.Relay.Operation, index: number) {
if (lineStore.simulationId) {
setRelayState({
simulationId: lineStore.simulationId,
mapId: lineStore.mapId as number,
deviceId: relayState.value.id,
deviceId: relayState.value[index].id,
operation,
})
.then(() => {
@ -110,12 +137,16 @@ function changePosition(operation: request.Relay.Operation) {
}
}
function subscribeState(g: Relay) {
g.on('stateupdate', updateState);
function subscribeState(g: Relay[]) {
g.forEach((item) => {
item.on('stateupdate', updateState);
});
}
function unSubscribeState(g: Relay) {
g.off('stateupdate', updateState);
function unSubscribeState(g: Relay[]) {
g.forEach((item) => {
item.off('stateupdate', updateState);
});
}
onUnmounted(() => {

View File

@ -1,10 +1,12 @@
import {
ContextMenu,
GraphicData,
GraphicQueryStore,
GraphicState,
IGraphicApp,
IGraphicScene,
IGraphicStorage,
MenuItemOptions,
} from 'jl-graphic';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { useLineStore } from 'src/stores/line-store';
@ -24,7 +26,26 @@ import {
} from 'src/graphics/phaseFailureProtector/PhaseFailureProtector';
import { PhaseFailureProtectorData } from './relayCabinetGraphics/PhaseFailureProtectorInteraction';
import { state } from 'src/protos/device_state';
import { Notify, QNotifyUpdateOptions } from 'quasar';
import { Dialog, Notify, QNotifyUpdateOptions } from 'quasar';
import CiCjQdListStateDialog from 'src/components/draw-app/dialogs/CiCjQdListStateDialog.vue';
const CiCjQdListState: MenuItemOptions = {
name: '驱采状态',
};
const canvasMenu = new ContextMenu({
name: '图层选择',
groups: [
{
items: [CiCjQdListState],
},
],
});
export const refRelaysListMap = new Map<
number,
{ combinationtype: string; device: string }
>();
export function initRelayScene(lineApp: IGraphicApp, sceneName: string) {
// 继电器
@ -46,28 +67,33 @@ export function initRelayScene(lineApp: IGraphicApp, sceneName: string) {
];
relayScene.registerGraphicTemplates(...relayGraphicTemplate);
RelayOperationPlugin.init(relayScene);
updataOnChangeScene(relayScene);
relayScene.on('postdataloaded', () => {
handleSubscribe(relayScene);
const map = new Map<number, string>();
refRelaysList.forEach((device) => {
device.combinationtypes.forEach((combinationtype) => {
combinationtype.refRelays.forEach((relayId) => {
map.set(relayId, device.code);
refRelaysListMap.set(relayId, {
combinationtype: combinationtype.code,
device: device.code,
});
});
});
});
const relays = relayScene.queryStore.queryByType<Relay>(Relay.Type);
relays.forEach((relay) => {
relay.refDevice.text = map.get(relay.id)?.replace(/_/g, '\n') as string;
relay.refDevice.text = refRelaysListMap
.get(relay.id)
?.device.replace(/_/g, '\n') as string;
});
const phaseFailureProtectors =
relayScene.queryStore.queryByType<PhaseFailureProtector>(
PhaseFailureProtector.Type
);
phaseFailureProtectors.forEach((phaseFailureProtector) => {
phaseFailureProtector.refDevice.text = map
.get(phaseFailureProtector.id)
?.replace(/_/g, '\n') as string;
phaseFailureProtector.refDevice.text = refRelaysListMap.get(
phaseFailureProtector.id
)?.device as string;
});
});
lineApp.on('destroy', () => {
@ -75,6 +101,24 @@ export function initRelayScene(lineApp: IGraphicApp, sceneName: string) {
});
}
export function updataOnChangeScene(relayScene: IGraphicScene) {
relayScene.registerMenu(canvasMenu);
relayScene.canvas.on('_rightclick', (e) => {
const lineStore = useLineStore();
CiCjQdListState.handler = async () => {
if (lineStore.deviceOpreratDialogInstance) return;
lineStore.deviceOpreratDialogInstance = Dialog.create({
component: CiCjQdListStateDialog,
cancel: true,
persistent: true,
}).onCancel(() => {
lineStore.deviceOpreratDialogInstance = null;
});
};
canvasMenu.open(e.global);
});
}
function handleSubscribe(relayScene: IGraphicScene) {
const lineStore = useLineStore();
const simulationId = lineStore.simulationId;
@ -123,7 +167,6 @@ function handleSubscribe(relayScene: IGraphicScene) {
});
}
let refRelaysList: relayCabinetGraphicData.DeviceRelateRelay[] = [];
async function loadRelayDatas(): Promise<IGraphicStorage> {
const lineStore = useLineStore();
const mapId = lineStore.mapId;
@ -148,6 +191,8 @@ async function loadRelayDatas(): Promise<IGraphicStorage> {
datas.push(new PhaseFailureProtectorData(phaseFailureProtector));
});
refRelaysList = storage.deviceRelateRelayList;
ciCjList = storage.ciCjList;
ciQdList = storage.ciQdList;
return Promise.resolve({
canvasProperty: storage.canvas,
datas: datas,
@ -158,3 +203,16 @@ async function loadRelayDatas(): Promise<IGraphicStorage> {
});
}
}
//关联继电器列表
let refRelaysList: relayCabinetGraphicData.DeviceRelateRelay[] = [];
//采集列表
let ciCjList: relayCabinetGraphicData.CiCj;
export function loadSceneCiCjList() {
return ciCjList;
}
//驱动列表
let ciQdList: relayCabinetGraphicData.CiQd;
export function loadSceneCiQdList() {
return ciQdList;
}

View File

@ -112,6 +112,7 @@ import { useIbpStore } from 'src/stores/ibp-store';
import { state } from 'src/protos/device_state';
import { PictureType } from 'src/protos/picture';
import ConnectInfoDialog from 'src/components/line-app/dialogs/ConnectInfoDialog.vue';
import { updataOnChangeScene } from 'src/drawApp/relayScene';
const $q = useQuasar();
const canvasWidth = ref(0);
@ -389,6 +390,9 @@ function switchScene(val: MapInfo) {
lineApp.switchScene(sceneName, dom);
scene = lineApp.getScene(sceneName);
scene.reload();
if (val.type == PictureType.RelayCabinetLayout) {
updataOnChangeScene(scene);
}
}
}

View File

@ -43,6 +43,11 @@ export const useLineStore = defineStore('line', {
if (state.selectedGraphics) {
if (state.selectedGraphics.length === 1) {
return state.selectedGraphics[0].type;
} else if (state.selectedGraphics.length > 1) {
for (let i = 0; i < state.selectedGraphics.length; i++) {
if (state.selectedGraphics[i].type !== 'Relay') return;
}
return state.selectedGraphics[0].type;
}
}
},