Commit b0714d21c87829f08c2f4cb6c44f67cc17b76055

Authored by 史婷婷
1 parent 7be7525e

feat: 设备-详情-三个设备类型(燃气、水表、电表)增加上报功能

... ... @@ -6,12 +6,12 @@ VITE_GLOB_PUBLIC_PATH = /
6 6
7 7 # Cross-domain proxy, you can configure multiple
8 8 # Please note that no line breaks
9   -
  9 +# https://iot.hzzlyun.com 线上生产地址
10 10 # 本地
11   -VITE_PROXY = [["/api","http://10.9.0.205:8080/api"],["/thingskit-scada","http://localhost:5173/thingskit-scada"],["/large-designer", "http://localhost:5555/large-designer/"]]
  11 +VITE_PROXY = [["/api","https://iot.hzzlyun.com/api"],["/thingskit-scada","http://localhost:5173/thingskit-scada"],["/large-designer", "http://localhost:5555/large-designer/"]]
12 12
13 13 # 实时数据的ws地址
14   -VITE_GLOB_WEB_SOCKET = ws://10.9.0.205:8080/api/ws/plugins/telemetry?token=
  14 +VITE_GLOB_WEB_SOCKET = wss://iot.hzzlyun.com/api/ws/plugins/telemetry?token=
15 15
16 16 # Delete console
17 17 VITE_GLOB_DROP_CONSOLE = true
... ...
... ... @@ -28,5 +28,6 @@ export default {
28 28 historyTrendText: 'History trend',
29 29 commandDeliveryText: 'Command delivery',
30 30 serviceText: 'Service',
  31 + reportText: 'Report',
31 32 dateRangeText: 'Date range',
32 33 };
... ...
... ... @@ -30,6 +30,7 @@ export default {
30 30 historyTrendText: '历史趋势',
31 31 commandDeliveryText: '命令下发',
32 32 serviceText: '服务',
  33 + reportText: '上报',
33 34 dateRangeText: '时间范围',
34 35 directorName: '负责人',
35 36 };
... ...
1 1 <script lang="ts" setup>
2 2 import { nextTick, onMounted, onUnmounted, reactive, ref, unref, computed } from 'vue';
3   - import { List, Card, Tooltip, Space, PaginationProps } from 'ant-design-vue';
  3 + import { List, Card, Tooltip, Space, PaginationProps, InputNumber } from 'ant-design-vue';
4 4 import { PageWrapper } from '/@/components/Page';
5 5 import { BasicTable, useTable } from '/@/components/Table';
6 6 import { realTimeDataColumns } from '../../config/detail.config';
... ... @@ -12,7 +12,7 @@
12 12 import { BasicForm, useForm } from '/@/components/Form';
13 13 import HistoryData from './HistoryData.vue';
14 14 import { BasicModal, useModal } from '/@/components/Modal';
15   - import { getDeviceAttrs } from '/@/api/device/deviceManager';
  15 + import { getDeviceAttrs, getDeviceToken } from '/@/api/device/deviceManager';
16 16 import { DeviceRecord } from '/@/api/device/model/deviceModel';
17 17 import { isArray, isNull, isNullOrUnDef, isObject } from '/@/utils/is';
18 18 import { useGlobSetting } from '/@/hooks/setting';
... ... @@ -37,6 +37,8 @@
37 37 } from './ModelOfMatter.config';
38 38 import { useJsonParse } from '/@/hooks/business/useJsonParse';
39 39 import { useI18n } from '/@/hooks/web/useI18n';
  40 + import { defHttp } from '/@/utils/http/axios';
  41 +
40 42
41 43 interface ReceiveMessage {
42 44 data: {
... ... @@ -46,6 +48,41 @@
46 48
47 49 const { t } = useI18n();
48 50
  51 + const reportDeviceKeyMap = {
  52 + GC: '燃气设备',
  53 + WU: '水表设备',
  54 + EC: '电表设备',
  55 + } as const;
  56 +
  57 + const reportDeviceKeys = Object.keys(reportDeviceKeyMap);
  58 +
  59 + type ReportDeviceKey = keyof typeof reportDeviceKeyMap;
  60 +
  61 + const reportFormModel = reactive<Record<ReportDeviceKey, number | undefined>>({
  62 + GC: undefined,
  63 + WU: undefined,
  64 + EC: undefined,
  65 + });
  66 +
  67 + const currentReportKey = ref<ReportDeviceKey | ''>('');
  68 +
  69 + const currentReportLabel = computed(() => {
  70 + const key = unref(currentReportKey);
  71 + return key ? reportDeviceKeyMap[key] : '';
  72 + });
  73 +
  74 + const currentReportValue = computed<number | undefined>({
  75 + get() {
  76 + const key = unref(currentReportKey);
  77 + return key ? reportFormModel[key] : undefined;
  78 + },
  79 + set(value) {
  80 + const key = unref(currentReportKey);
  81 + if (!key) return;
  82 + reportFormModel[key] = value;
  83 + },
  84 + });
  85 +
49 86 const props = defineProps<{
50 87 deviceDetail: DeviceRecord;
51 88 }>();
... ... @@ -197,6 +234,8 @@
197 234 }
198 235
199 236 const [registerModal, { openModal }] = useModal();
  237 + const [registerReportModal, { openModal: openReportModal, closeModal: closeReportModal }] =
  238 + useModal();
200 239
201 240 const mode = ref<EnumTableCardMode>(EnumTableCardMode.CARD);
202 241
... ... @@ -291,6 +330,40 @@
291 330 openModal(true);
292 331 };
293 332
  333 + const handleReport = (record: SocketInfoDataSourceItemType) => {
  334 + const { key } = record;
  335 + if (!reportDeviceKeys.includes(key)) return;
  336 + currentReportKey.value = key as ReportDeviceKey;
  337 + openReportModal(true);
  338 + };
  339 +
  340 + const handleReportSave = async () => {
  341 + const key = unref(currentReportKey);
  342 + if (!key) return;
  343 + const token = await getDeviceToken(props.deviceDetail.tbDeviceId);
  344 + console.log('token.credentialsId', token.credentialsId);
  345 + console.log('handleReportSave', { key, value: reportFormModel[key] });
  346 + // https://iot.hzzlyun.com/api/v1/HPlEWlrVPNlAbZ6WQpn2/telemetry
  347 + // 入参
  348 + const data = { [key]: reportFormModel[key] };
  349 + const credentialsId = token.credentialsId;
  350 + // 写一个接口请求,固定链接,不依赖token https://iot.hzzlyun.com/api/v1/${credentialsId}/telemetry
  351 + await defHttp.post(
  352 + {
  353 + url: `https://iot.hzzlyun.com/api/v1/${credentialsId}/telemetry`,
  354 + data,
  355 + },
  356 + {
  357 + joinPrefix: false,
  358 + apiUrl: '',
  359 + withToken: false,
  360 + }
  361 + );
  362 +
  363 + createMessage.success('保存成功');
  364 + closeReportModal();
  365 + };
  366 +
294 367 const getIsModbusDevice = computed(
295 368 () =>
296 369 props.deviceDetail.transportType === TransportTypeEnum.TCP &&
... ... @@ -307,21 +380,21 @@
307 380 open();
308 381 });
309 382
310   - const formatValue = (item: SocketInfoDataSourceItemType) => {
  383 + const formatValue = (item: SocketInfoDataSourceItemType): string => {
311 384 if (isNullOrUnDef(item) || isNullOrUnDef(item.value)) return '--';
312 385
313 386 if (unref(getIsModbusDevice) && item.type === DataTypeEnum.BOOL) {
314 387 const _result = Reflect.get(item.enum || {}, item.value as string);
315   - return isNullOrUnDef(_result) ? item.value : _result;
  388 + return isNullOrUnDef(_result) ? String(item.value) : String(_result);
316 389 }
317 390
318 391 switch (item.type) {
319 392 case DataTypeEnum.BOOL:
320   - return !!Number(item.value) ? item.boolOpen! : item.boolClose!;
  393 + return !!Number(item.value) ? (item.boolOpen ?? '--') : (item.boolClose ?? '--');
321 394 case DataTypeEnum.ENUM:
322   - return item.enum?.[item.value as string];
  395 + return item.enum?.[item.value as string] ?? '--';
323 396 default:
324   - return item.value || '--';
  397 + return String(item.value ?? '--');
325 398 }
326 399 };
327 400
... ... @@ -429,6 +502,22 @@
429 502 @click="handleShowDetail(item)"
430 503 />
431 504 </Tooltip>
  505 + <!-- 上报按钮 显示判断 -->
  506 + <!-- 燃气设备 GC-->
  507 + <!-- 水表设备 WU-->
  508 + <!-- 电表设备 EC-->
  509 + <Tooltip :title="t('business.reportText')"
  510 + v-if="reportDeviceKeys.includes(item.key)"
  511 + >
  512 + <SvgIcon
  513 + name="shuiwen"
  514 + prefix="iconfont"
  515 + class="cursor-pointer text-lg text-blue-500"
  516 + @click="handleReport(item)"
  517 + />
  518 + </Tooltip>
  519 +
  520 +
432 521 </Space>
433 522 </template>
434 523 <section class="min-h-16 flex flex-col justify-between">
... ... @@ -513,6 +602,21 @@
513 602 >
514 603 <HistoryData :deviceDetail="props.deviceDetail" :attr="socketInfo.attr" />
515 604 </BasicModal>
  605 + <BasicModal
  606 + @register="registerReportModal"
  607 + :title="`${t('business.reportText')}`"
  608 + width="40%"
  609 + :minHeight="0"
  610 + :bodyStyle="{ padding: '12px 16px' }"
  611 + destroy-on-close
  612 + okText="提交"
  613 + @ok="handleReportSave"
  614 + >
  615 + <div class="p-1 flex items-center gap-2">
  616 + <div class="w-20 text-right whitespace-nowrap">{{ currentReportLabel }}</div>
  617 + <InputNumber v-model:value="currentReportValue" class="flex-1 w-full" size="small" />
  618 + </div>
  619 + </BasicModal>
516 620 <ObjectModelCommandDeliveryModal
517 621 @register="register"
518 622 :deviceId="deviceDetail.tbDeviceId"
... ...