index.vue
5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<script lang="ts" setup>
  import { ComponentMode, ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
  import { DEFAULT_VALUE, option, SwitchItemType } from './config';
  import { SvgIcon } from '/@/components/Icon';
  import { Switch } from 'ant-design-vue';
  import { computed, ref, toRaw } from 'vue';
  import { useComponentScale } from '../../../hook/useComponentScale';
  import { unref } from 'vue';
  import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  import { MultipleDataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
  import { useMultipleDataFetch } from '../../../hook/socket/useSocket';
  import { useReceiveMessage } from '../../../hook/useReceiveMessage';
  import { useReceiveValue } from '../../../hook/useReceiveValue';
  import { useModal } from '/@/components/Modal';
  import PasswordModal from '../component/PasswordModal.vue';
  import { useDeviceProfileQueryContext } from '/@/views/visual/palette/hooks/useDeviceProfileQueryContext';
  import {
    DoCommandDeliverDataSourceType,
    useControlComand,
  } from '../../../hook/useControlCommand';
  const props = defineProps<{
    config: ComponentPropsConfigType<typeof option>;
  }>();
  const { getDeviceProfileTslByIdWithIdentifier } = useDeviceProfileQueryContext();
  const getDesign = computed(() => {
    const { persetOption = {}, option } = props.config;
    const { dataSource = [] } = option || {};
    const {
      unit: persetUnit,
      fontColor: persetFontColor,
      icon: persetIcon,
      iconColor: persetIconColor,
      fontSize: persetFontSize,
      password: persetPassword,
    } = persetOption || {};
    return {
      dataSource: dataSource.map((item) => {
        const { fontColor, icon, iconColor, unit, showDeviceName, password, fontSize } =
          item.componentInfo;
        const {
          attribute,
          attributeRename,
          deviceId,
          deviceName,
          deviceRename,
          commandType,
          deviceProfileId,
          openCommand,
          closeCommand,
          openService,
          closeService,
        } = item;
        const tsl = getDeviceProfileTslByIdWithIdentifier?.(deviceProfileId, attribute);
        return {
          unit: unit ?? persetUnit,
          deviceProfileId,
          deviceId,
          fontColor: fontColor ?? persetFontColor,
          icon: icon ?? persetIcon,
          iconColor: iconColor ?? persetIconColor,
          attribute: attribute,
          attributeName: attributeRename || tsl?.functionName || attribute,
          showDeviceName,
          deviceName: deviceRename || deviceName,
          id: deviceId,
          commandType,
          fontSize: fontSize || persetFontSize || 14,
          password: password || persetPassword,
          checked: false,
          openCommand,
          closeCommand,
          openService,
          closeService,
        } as SwitchItemType;
      }),
    };
  });
  const handleChange = async (item) => {
    if (item.password) {
      openModal(true, { password: item.password });
      return;
    }
    handleSendCommand(item);
  };
  const { forEachGroupMessage } = useReceiveMessage();
  const { getNumberValue } = useReceiveValue();
  const controlList = ref(
    props.config.option.dataSource ? unref(getDesign).dataSource : DEFAULT_VALUE
  );
  const { loading, doControlSendCommand } = useControlComand();
  const handleSendCommand = async (modalData: SwitchItemType) => {
    if (props.config.option.mode === ComponentMode.SELECT_PREVIEW) return;
    await doControlSendCommand(
      toRaw(unref(modalData)) as DoCommandDeliverDataSourceType,
      Number(unref(modalData).checked)
    );
  };
  const updateFn: MultipleDataFetchUpdateFn = async (message, deviceId, attribute) => {
    forEachGroupMessage(message, deviceId, attribute, (attribute, value) => {
      controlList.value.forEach((item) => {
        if (item.id === deviceId && item.attribute === attribute && value) {
          item.checked = Boolean(getNumberValue(value));
        }
      });
    });
  };
  useMultipleDataFetch(props, updateFn);
  const { getRatio } = useComponentScale(props);
  const [registerModal, { openModal }] = useModal();
</script>
<template>
  <main class="w-full h-full flex flex-col justify-evenly items-center">
    <DeviceName :config="config" />
    <div
      v-for="item in controlList"
      :key="item.id"
      class="flex justify-between items-center w-full px-4"
    >
      <SvgIcon
        :name="item.icon!"
        prefix="iconfont"
        :size="getRatio ? 30 * getRatio : 30"
        :style="{ color: item.iconColor }"
      />
      <div
        class="text-gray-500 truncate mx-2"
        :style="{ fontSize: (getRatio ? getRatio * item.fontSize : item.fontSize) + 'px' }"
      >
        {{ `${item.deviceName} - ${item.attributeName}` }}
      </div>
      <Switch
        v-model:checked="item.checked"
        :loading="loading"
        @change="handleChange(item)"
        :style="{ transform: `scale(${getRatio || 1})` }"
      />
    </div>
    <PasswordModal @register="registerModal" @success="handleSendCommand" />
  </main>
</template>