|
|
@@ -28,6 +28,8 @@ export function useTopology() {
|
|
|
/** 测风装置显示名映射(rawId → devicePos/deviceCode/id,取自全量 windrectList):
|
|
|
* 已绑定设备不再绘制节点,其名称由该映射写入巷道连线 edgeLabel 及解绑确认文案 */
|
|
|
let deviceNameMap: Record<string, string> = {};
|
|
|
+ /** 瓦斯装置显示名映射(rawId → devicePos/deviceCode/id,取自全量 gasList),用途同上 */
|
|
|
+ let gasNameMap: Record<string, string> = {};
|
|
|
let resizeObserver: ResizeObserver | null = null;
|
|
|
|
|
|
// —— 模式状态 ——
|
|
|
@@ -35,10 +37,12 @@ export function useTopology() {
|
|
|
const mode = ref<TopoMode>('relation');
|
|
|
/** 绑定模式选中的关联源节点(双击节点选中,再单击另一节点建立关系;红色描边高亮) */
|
|
|
const armedSource = ref<TopoNodeData | null>(null);
|
|
|
- /** 布点模式绑定弹窗:双击未绑定布点的连线后弹出选择测风装置 */
|
|
|
+ /** 布点模式绑定弹窗:双击巷道连线后弹出,同时处理测风装置与瓦斯装置的绑定/解绑 */
|
|
|
const bindVisible = ref(false);
|
|
|
const bindPoint = ref<TopoNodeData | null>(null);
|
|
|
- const bindDeviceId = ref<string | undefined>(undefined);
|
|
|
+ /** 本次新选的测风装置 / 瓦斯装置 id(已绑定的设备只读展示,不在此处回填) */
|
|
|
+ const bindWindrectId = ref<string | undefined>(undefined);
|
|
|
+ const bindGasId = ref<string | undefined>(undefined);
|
|
|
/** 操作栏部门选择:选中任意层级部门后过滤部门树(该部门及其后代)并按该部门查询数据;空=全局 */
|
|
|
const selectedDeptId = ref('');
|
|
|
|
|
|
@@ -96,6 +100,11 @@ export function useTopology() {
|
|
|
for (const d of bundle.windrectList) {
|
|
|
if (d.id) deviceNameMap[String(d.id)] = d.devicePos || d.deviceCode || String(d.id);
|
|
|
}
|
|
|
+ // 瓦斯装置显示名映射(同上)
|
|
|
+ gasNameMap = {};
|
|
|
+ for (const g of bundle.gasList) {
|
|
|
+ if (g.id) gasNameMap[String(g.id)] = g.devicePos || g.deviceCode || String(g.id);
|
|
|
+ }
|
|
|
renderTopology(bundle.topology);
|
|
|
// 数据为空时给出诊断信息(总进地面节点仍会渲染)
|
|
|
if (!bundle.topology.nodes.some((n) => n.category !== 0)) {
|
|
|
@@ -214,15 +223,19 @@ export function useTopology() {
|
|
|
if (l.kind === 'roadway') {
|
|
|
// 巷道连线:直线(无曲率)+ 按主要数据点位 level 用 levelColorMap 着色 + 风流方向箭头;
|
|
|
// 疑似隐蔽工作面巷道(主要数据点位 judgeAreaList 字段有内容 → 节点 suspected)标红加粗;
|
|
|
- // 中点标注(edgeLabel rich 富文本):第一行主要数据点位名称、第二行风量、第三行圆点 + 已绑定设备名;
|
|
|
- // 未绑定时第三行输出浅灰占位圆点(dotEmpty),保证标签高度恒定
|
|
|
+ // 中点标注(edgeLabel rich 富文本):第一行主要数据点位名称、第二行为测风装置(绿点)、第三行为瓦斯装置(蓝点);
|
|
|
+ // 未绑定的设备行输出浅灰占位圆点(dotEmpty),保证标签恒为 3 行、高度稳定
|
|
|
const point = l.mainPointId ? pointById.get(l.mainPointId) : undefined;
|
|
|
const lv = point ? Number(point.level) : NaN;
|
|
|
const deviceName = point?.windrectId ? deviceNameMap[point.windrectId] : '';
|
|
|
+ const gasName = point?.gasId ? gasNameMap[point.gasId] : '';
|
|
|
const suspected = point?.suspected;
|
|
|
- // 常态标注:仅名称;高亮标注:名称 + 圆点与已绑定布点名(未绑定输出浅灰占位圆点)
|
|
|
+ // 设备行:已绑定输出设备名,未绑定输出浅灰占位圆点
|
|
|
+ const windrectLine = deviceName ? `{dot|● }{device|${deviceName}}` : '{dotEmpty|● }';
|
|
|
+ const gasLine = gasName ? `{dotGas|● }{device|${gasName}}` : '{dotEmpty|● }';
|
|
|
+ // 常态标注:仅名称;高亮标注:名称 + 测风装置行 + 瓦斯装置行
|
|
|
link.midLabel = point ? `{name|${point.name}}` : '';
|
|
|
- link.midLabelFull = point ? `{name|${point.name}}\n${deviceName ? `{dot|● }{device|${deviceName}}` : '{dotEmpty|● }'}` : '';
|
|
|
+ link.midLabelFull = point ? `{name|${point.name}}\n${windrectLine}\n${gasLine}` : '';
|
|
|
link.lineStyle = {
|
|
|
color: suspected ? JUDGE_COLOR : levelColorMap[lv] || POINT_COLOR,
|
|
|
width: suspected ? JUDGE_WIDTH : 3,
|
|
|
@@ -287,7 +300,7 @@ export function useTopology() {
|
|
|
// 绑定模式:双击连线 → 解除巷道关系(传关系 id)
|
|
|
handleRemoveRelation(params.data);
|
|
|
} else {
|
|
|
- // 布点模式:双击连线 → 对其主要数据点位解绑/绑定测风装置
|
|
|
+ // 布点模式:双击连线 → 打开其主数据点位的设备绑定弹窗(测风装置 / 瓦斯装置)
|
|
|
const mainId = params.data.mainPointId || params.data.pointId;
|
|
|
const point = mainId ? topologyData.nodes.find((n) => n.id === mainId) : undefined;
|
|
|
if (point) handleDeviceAction(point);
|
|
|
@@ -394,15 +407,21 @@ export function useTopology() {
|
|
|
return (rawId && deviceNameMap[rawId]) || rawId || '';
|
|
|
}
|
|
|
|
|
|
- /** 布点模式:双击连线 → 已有测风装置则解绑,否则弹窗选择绑定 */
|
|
|
+ /** 按瓦斯装置原始 id 解析其显示名(同上) */
|
|
|
+ function gasNameOf(rawId?: string) {
|
|
|
+ return (rawId && gasNameMap[rawId]) || rawId || '';
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 布点模式:双击连线 → 打开设备绑定弹窗。
|
|
|
+ * 弹窗内已绑定的设备只读展示(附解绑按钮),未绑定的设备用下拉(NoUsed 列表)新选,
|
|
|
+ * 因此「未绑定→绑定」「已绑定→解绑」两种场景共用同一个弹窗。
|
|
|
+ */
|
|
|
function handleDeviceAction(point: TopoNodeData) {
|
|
|
- if (point.windrectId) {
|
|
|
- confirmUnbindDevice(point);
|
|
|
- } else {
|
|
|
- bindPoint.value = point;
|
|
|
- bindDeviceId.value = undefined;
|
|
|
- bindVisible.value = true;
|
|
|
- }
|
|
|
+ bindPoint.value = point;
|
|
|
+ bindWindrectId.value = undefined;
|
|
|
+ bindGasId.value = undefined;
|
|
|
+ bindVisible.value = true;
|
|
|
}
|
|
|
|
|
|
/** 关闭布点绑定弹窗(index.vue 取消/关闭时同步,成功关闭由 confirmBind 内部调用) */
|
|
|
@@ -410,19 +429,24 @@ export function useTopology() {
|
|
|
bindVisible.value = false;
|
|
|
}
|
|
|
|
|
|
- /** 布点模式:弹窗选择测风装置后调用(updateMineArea 更新 windrectId 字段) */
|
|
|
- async function confirmBind(deviceId?: string) {
|
|
|
+ /**
|
|
|
+ * 布点模式:弹窗确认 → 仅提交「本次新选」的设备字段(updateMineArea 更新 windrectId / gasId),
|
|
|
+ * 避免把另一设备的既有绑定覆盖为空。
|
|
|
+ */
|
|
|
+ async function confirmBind() {
|
|
|
const point = bindPoint.value;
|
|
|
if (!point?.rawId) {
|
|
|
message.warning('缺少测风地点原始 id,无法绑定');
|
|
|
return;
|
|
|
}
|
|
|
- if (!deviceId) {
|
|
|
- message.warning('请选择数据点位');
|
|
|
+ const windrectId = bindWindrectId.value;
|
|
|
+ const gasId = bindGasId.value;
|
|
|
+ if (!windrectId && !gasId) {
|
|
|
+ message.warning('请选择要绑定的测风装置或瓦斯装置');
|
|
|
return;
|
|
|
}
|
|
|
try {
|
|
|
- await updateArea({ id: point.rawId, windrectId: deviceId });
|
|
|
+ await updateArea({ id: point.rawId, ...(windrectId ? { windrectId } : {}), ...(gasId ? { gasId } : {}) });
|
|
|
closeBindDialog();
|
|
|
await loadTopology();
|
|
|
message.success('绑定成功');
|
|
|
@@ -432,20 +456,31 @@ export function useTopology() {
|
|
|
}
|
|
|
|
|
|
/** 布点模式:解绑测风装置(清空 windrectId 字段,updateMineArea) */
|
|
|
- function confirmUnbindDevice(point: TopoNodeData) {
|
|
|
- const deviceName = deviceNameOf(point.windrectId);
|
|
|
+ function unbindWindrect(point: TopoNodeData) {
|
|
|
+ confirmUnbind('测风装置', deviceNameOf(point.windrectId), { id: point.rawId, windrectId: '' }, point.name);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 布点模式:解绑瓦斯装置(清空 gasId 字段,updateMineArea) */
|
|
|
+ function unbindGas(point: TopoNodeData) {
|
|
|
+ confirmUnbind('瓦斯装置', gasNameOf(point.gasId), { id: point.rawId, gasId: '' }, point.name);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 解绑确认弹窗(测风装置 / 瓦斯装置共用;field 为提交的字段负载,空串表示解绑) */
|
|
|
+ function confirmUnbind(deviceLabel: string, deviceName: string, payload: Record<string, any>, pointName: string) {
|
|
|
Modal.confirm({
|
|
|
title: '确认解绑',
|
|
|
- content: `确定解除"${point.name}"与测风装置"${deviceName}"的绑定关系?`,
|
|
|
+ content: `确定解除"${pointName}"与${deviceLabel}"${deviceName}"的绑定关系?`,
|
|
|
okText: '确认解绑',
|
|
|
cancelText: '取消',
|
|
|
onOk: async () => {
|
|
|
- if (!point.rawId) {
|
|
|
+ if (!payload.id) {
|
|
|
message.warning('缺少测风地点原始 id,无法解绑');
|
|
|
return;
|
|
|
}
|
|
|
try {
|
|
|
- await updateArea({ id: point.rawId, windrectId: '' });
|
|
|
+ await updateArea(payload);
|
|
|
+ // 解绑后关闭绑定弹窗:bindPoint 引用的是重载前的节点快照,避免弹窗仍显示旧的绑定态
|
|
|
+ closeBindDialog();
|
|
|
await loadTopology();
|
|
|
message.success('解绑成功');
|
|
|
} catch {
|
|
|
@@ -549,6 +584,13 @@ export function useTopology() {
|
|
|
label: f.label,
|
|
|
value: (node as any)[f.key] ?? '-',
|
|
|
}));
|
|
|
+ // 测风地点:追加已绑定的测风装置 / 瓦斯装置显示名(原始 id → 设备位置名,未绑定显示「未绑定」)
|
|
|
+ if (node.category === 1) {
|
|
|
+ detailFields.value.push(
|
|
|
+ { label: '测风装置', value: deviceNameOf(node.windrectId) || '未绑定' },
|
|
|
+ { label: '瓦斯装置', value: gasNameOf(node.gasId) || '未绑定' }
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function clearSelection() {
|
|
|
@@ -587,7 +629,7 @@ export function useTopology() {
|
|
|
if (m === 'relation') {
|
|
|
message.info('双击连线解除关系;双击节点并选中另一节点以建立关系');
|
|
|
} else {
|
|
|
- message.info('双击连线解绑或绑定测风装置');
|
|
|
+ message.info('双击连线绑定或解绑测风装置、瓦斯装置');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -611,8 +653,13 @@ export function useTopology() {
|
|
|
setMode,
|
|
|
bindVisible,
|
|
|
bindPoint,
|
|
|
- bindDeviceId,
|
|
|
+ bindWindrectId,
|
|
|
+ bindGasId,
|
|
|
confirmBind,
|
|
|
+ unbindWindrect,
|
|
|
+ unbindGas,
|
|
|
+ deviceNameOf,
|
|
|
+ gasNameOf,
|
|
|
closeBindDialog,
|
|
|
selectedNode,
|
|
|
detailFields,
|