Commit 13280e0a2586f311eb7bdf18ecad2cb4bc6b8f3c

Authored by fengistao
2 parents ac20103a ff6045b5

Merge branch 'main' into ft-dev

... ... @@ -2,10 +2,17 @@
2 2 <div class="md:flex justify-between">
3 3 <template v-for="(item, index) in growCardList" :key="item.title">
4 4 <div
5   - class="growCardItem md:w-1/3 w-full !md:mt-0 !mt-4"
  5 + class="growCardItem md:w-1/3 w-full !md:mt-0 !mt-4 bg-white"
6 6 :class="index === 0 ? '!md:ml-0' : '!md:ml-4'"
7 7 >
8   - <div class="growCardItem-top">
  8 + <div
  9 + class="
  10 + growCardItem-top
  11 + border border-solid border-t-0 border-r-0 border-l-0 border-b-1
  12 + dark:border-#ccc
  13 + light:border-#F2F2F5
  14 + "
  15 + >
9 16 <img :src="item.imgUrl" style="width: 90px; height: 90px" />
10 17 <div class="growCardItem-right">
11 18 <div class="flex justify-between ml-3">
... ... @@ -50,12 +57,10 @@
50 57 <style scoped lang="less">
51 58 .growCardItem {
52 59 height: 179px;
53   - background-color: #fff;
54 60 color: #666;
55 61 .growCardItem-top {
56 62 display: flex;
57 63 margin: 20px;
58   - border-bottom: 1px solid #f2f2f5;
59 64 padding-bottom: 10px;
60 65 .growCardItem-right {
61 66 width: 300px;
... ...
... ... @@ -102,3 +102,152 @@ export const step1Schemas: FormSchema[] = [
102 102 show: false,
103 103 },
104 104 ];
  105 +
  106 +// 第二步的表单
  107 +export const step2Schemas: FormSchema[] = [
  108 + {
  109 + label: '',
  110 + component: 'Checkbox',
  111 + field: 'addAgree',
  112 + slot: 'addAgree',
  113 + },
  114 + {
  115 + label: '凭据类型',
  116 + component: 'Select',
  117 + field: 'creaentialsType',
  118 + componentProps({ formActionType }) {
  119 + const { updateSchema, setFieldsValue } = formActionType;
  120 + return {
  121 + options: [
  122 + {
  123 + value: 'Access token',
  124 + label: 'Access token',
  125 + },
  126 +
  127 + {
  128 + value: 'X.509',
  129 + label: 'X.509',
  130 + },
  131 + {
  132 + value: 'MQTT Basic',
  133 + label: 'MQTT Basic',
  134 + },
  135 + ],
  136 + onChange(value) {
  137 + setFieldsValue({
  138 + publicKey: '',
  139 + token: '',
  140 + clientId: '',
  141 + username: '',
  142 + password: '',
  143 + });
  144 + if (value === 'Access token') {
  145 + updateSchema([
  146 + {
  147 + field: 'token',
  148 + ifShow: true,
  149 + },
  150 + {
  151 + field: 'clientId',
  152 + ifShow: false,
  153 + },
  154 + {
  155 + field: 'username',
  156 + ifShow: false,
  157 + },
  158 + {
  159 + field: 'password',
  160 + ifShow: false,
  161 + },
  162 + {
  163 + field: 'publicKey',
  164 + ifShow: false,
  165 + },
  166 + ]);
  167 + } else if (value === 'X.509') {
  168 + updateSchema([
  169 + {
  170 + field: 'publicKey',
  171 + ifShow: true,
  172 + },
  173 + {
  174 + field: 'token',
  175 + ifShow: false,
  176 + },
  177 + {
  178 + field: 'clientId',
  179 + ifShow: false,
  180 + },
  181 + {
  182 + field: 'username',
  183 + ifShow: false,
  184 + },
  185 + {
  186 + field: 'password',
  187 + ifShow: false,
  188 + },
  189 + ]);
  190 + } else {
  191 + updateSchema([
  192 + {
  193 + field: 'clientId',
  194 + ifShow: true,
  195 + },
  196 + {
  197 + field: 'username',
  198 + ifShow: true,
  199 + },
  200 + {
  201 + field: 'password',
  202 + ifShow: true,
  203 + },
  204 + {
  205 + field: 'publicKey',
  206 + ifShow: false,
  207 + },
  208 + {
  209 + field: 'token',
  210 + ifShow: false,
  211 + },
  212 + ]);
  213 + }
  214 + },
  215 + };
  216 + },
  217 + ifShow: ({ values }) => values.addAgree,
  218 + },
  219 + {
  220 + label: '访问令牌',
  221 + component: 'Input',
  222 + field: 'token',
  223 + required: true,
  224 + ifShow: false,
  225 + },
  226 + {
  227 + label: 'RSA公钥',
  228 + component: 'Input',
  229 + field: 'publicKey',
  230 + required: true,
  231 + ifShow: false,
  232 + },
  233 + {
  234 + label: '客户端ID',
  235 + component: 'Input',
  236 + field: 'clientId',
  237 + required: true,
  238 + ifShow: false,
  239 + },
  240 + {
  241 + label: '用户名',
  242 + component: 'Input',
  243 + field: 'username',
  244 + required: true,
  245 + ifShow: false,
  246 + },
  247 + {
  248 + label: '密码',
  249 + component: 'Input',
  250 + field: 'password',
  251 + ifShow: false,
  252 + },
  253 +];
... ...
... ... @@ -14,7 +14,7 @@
14 14 <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'"
15 15 ><RealTimeData
16 16 /></TabPane>
17   - <TabPane key="3" tab="告警"><Alarm :id="deviceId" /></TabPane>
  17 + <TabPane key="3" tab="告警"><Alarm :id="tbDeviceId" /></TabPane>
18 18 <TabPane key="4" tab="子设备" v-if="deviceDetail?.deviceType === 'GATEWAY'"
19 19 ><ChildDevice
20 20 /></TabPane>
... ... @@ -49,14 +49,13 @@
49 49 const size = ref('small');
50 50 const deviceDetailRef = ref();
51 51 const deviceDetail: any = ref({});
52   - const deviceId = ref('');
  52 + const tbDeviceId = ref('');
53 53 // 详情回显
54 54 const [register] = useDrawerInner(async (data) => {
55   - const { id } = data;
  55 + const { id, tbDeviceId: tbId } = data;
56 56 const res = await getDeviceDetail(id);
57 57 deviceDetail.value = res;
58   - deviceId.value = id;
59   - console.log(deviceId.value);
  58 + tbDeviceId.value = tbId;
60 59 const { latitude, longitude, address } = res.deviceInfo;
61 60 if (latitude) {
62 61 deviceDetailRef.value.initMap(longitude, latitude, address);
... ... @@ -73,7 +72,7 @@
73 72 closeDrawer,
74 73 deviceDetail,
75 74 deviceDetailRef,
76   - deviceId,
  75 + tbDeviceId,
77 76 };
78 77 },
79 78 });
... ...
... ... @@ -17,9 +17,9 @@
17 17 <div class="mt-5">
18 18 <DeviceStep1
19 19 @next="handleStep1Next"
20   - v-show="current === 0"
21 20 ref="DeviceStep1Ref"
22 21 :deviceInfo="deviceInfo"
  22 + v-show="current === 0"
23 23 />
24 24 <DeviceStep2
25 25 ref="DeviceStep2Ref"
... ... @@ -56,7 +56,7 @@
56 56 const DeviceStep1Ref = ref<InstanceType<typeof DeviceStep1>>();
57 57 const DeviceStep2Ref = ref<InstanceType<typeof DeviceStep2>>();
58 58 const { createMessage } = useMessage();
59   - const current = ref(0);
  59 + const current = ref(1);
60 60 const isUpdate = ref<Boolean>();
61 61 const deviceInfo = ref({});
62 62 const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备'));
... ... @@ -98,7 +98,7 @@
98 98 }
99 99 current.value = 0;
100 100 DeviceStep1Ref?.value?.resetFields();
101   - DeviceStep2Ref?.value?.resetFields();
  101 + DeviceStep2Ref?.value?.resetFieldsValueAndStatus();
102 102 }
103 103 // 提交
104 104 async function handleOk() {
... ... @@ -108,7 +108,7 @@
108 108 if (!valid) return;
109 109 stepState.value = DeviceStep1Ref?.value?.parentGetFieldsValue();
110 110 } else {
111   - if (!DeviceStep2Ref?.value?.creaentialsPassword.isCreaentials) {
  111 + if (DeviceStep2Ref?.value?.getFieldsValue().creaentialsType) {
112 112 const valid = await DeviceStep2Ref?.value?.validate();
113 113 // 第二页验证通过情况
114 114 if (!valid) return;
... ...
1 1 <template>
2 2 <div class="step2">
3   - <div
4   - ><input type="checkbox" v-model="creaentialsPassword.isCreaentials" @click="checked" />
5   - 添加凭证
6   - </div>
7   - <a-form
8   - ref="formRef"
9   - :rules="rules"
10   - :label-col="labelCol"
11   - :wrapper-col="wrapperCol"
12   - v-show="creaentialsPassword.isCreaentials"
13   - :model="creaentialsPassword"
14   - labelAlign="left"
15   - >
16   - <a-form-item label="凭据类型" name="creaentialsType">
17   - <a-select
18   - v-model:value="creaentialsPassword.creaentialsType"
19   - style="width: 200px"
20   - @change="handleChange"
21   - placeholder="请选择凭据类型"
22   - :options="options"
23   - />
24   - </a-form-item>
25   - <div v-if="creaentialsPassword.creaentialsType === 'Access token'">
26   - <a-form-item label="访问令牌" name="token">
27   - <a-input type="password" style="width: 200px" v-model:value="creaentialsPassword.token" />
28   - </a-form-item>
29   - </div>
30   - <div v-else-if="creaentialsPassword.creaentialsType === 'X.509'">
31   - <a-form-item label="RSA公钥" name="publicKey">
32   - <a-input
33   - type="password"
34   - style="width: 200px"
35   - v-model:value="creaentialsPassword.publicKey"
36   - />
37   - </a-form-item>
38   - </div>
39   - <div v-else>
40   - <a-form-item label="客户端ID" name="clientId">
41   - <a-input type="input" style="width: 200px" v-model:value="creaentialsPassword.clientId" />
42   - </a-form-item>
43   - <a-form-item label="用户名" name="username">
44   - <a-input type="input" style="width: 200px" v-model:value="creaentialsPassword.username" />
45   - </a-form-item>
46   - <a-form-item label="密码" name="password">
47   - <a-input
48   - type="password"
49   - style="width: 200px"
50   - v-model:value="creaentialsPassword.password"
51   - />
52   - </a-form-item>
53   - </div>
54   - </a-form>
55   - <div class="flex justify-start">
56   - <a-button class="mr-5" @click="prevStep">上一步</a-button>
  3 + <BasicForm @register="registerForm">
  4 + <template #addAgree="{ model, field }">
  5 + <Checkbox v-model:checked="model[field]" @change="checkedChange" />添加协议
  6 + </template>
  7 + </BasicForm>
  8 + <div>
  9 + <a-button @click="prevStep">上一步</a-button>
57 10 </div>
58 11 </div>
59 12 </template>
60 13 <script lang="ts">
61   - import { defineComponent, reactive, ref, watch } from 'vue';
  14 + import { defineComponent } from 'vue';
62 15
63   - import { Input, Form, Select, Button } from 'ant-design-vue';
  16 + import { Checkbox } from 'ant-design-vue';
  17 + import { BasicForm, useForm } from '/@/components/Form';
  18 + import { step2Schemas } from '../../config/data';
64 19 export default defineComponent({
65 20 components: {
66   - [Form.name]: Form,
67   - [Form.Item.name]: Form.Item,
68   - [Input.name]: Input,
69   - [Select.name]: Select,
70   - [Button.name]: Button,
  21 + BasicForm,
  22 + Checkbox,
71 23 },
72 24
73 25 emits: ['prev', 'next'],
74 26 setup(_, { emit }) {
75   - const formRef = ref();
76   - const creaentialsPassword = reactive({
77   - isCreaentials: false,
78   - creaentialsType: 'Access token',
79   - token: '',
80   - publicKey: '',
81   - clientId: '',
82   - username: '',
83   - password: '',
84   - });
85   - const rules = {
86   - token: [{ required: true, message: '请输入访问令牌', trigger: 'blur' }],
87   - publicKey: [{ required: true, message: '请输入RSA公钥', trigger: 'blur' }],
88   - clientId: [{ required: true, message: '请输入客户端ID', trigger: 'blur' }],
89   - username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
90   - };
91   - const options = ref([
92   - {
93   - value: 'Access token',
94   - label: 'Access token',
95   - },
96   -
97   - {
98   - value: 'X.509',
99   - label: 'X.509',
100   - },
101   - {
102   - value: 'MQTT Basic',
103   - label: 'MQTT Basic',
104   - },
105   - ]);
106   - // 切换是否添加凭证
107   - const checked = () => {
108   - creaentialsPassword.isCreaentials = !creaentialsPassword.isCreaentials;
109   - formRef.value.resetFields();
110   - creaentialsPassword.creaentialsType = 'Access token';
111   - };
112 27 const prevStep = () => {
113 28 emit('prev');
114 29 };
115   - watch(creaentialsPassword, (newValue) => {
116   - emit('next', newValue);
  30 + const [
  31 + registerForm,
  32 + { getFieldsValue, updateSchema, validate, resetFields, setFieldsValue },
  33 + ] = useForm({
  34 + labelWidth: 100,
  35 + schemas: step2Schemas,
  36 + actionColOptions: {
  37 + span: 14,
  38 + },
  39 + labelAlign: 'left',
  40 + showSubmitButton: false,
  41 + showResetButton: false,
  42 + wrapperCol: {
  43 + span: 12,
  44 + },
117 45 });
118   -
119   - // 切换凭证类型时,重置字段
120   - const handleChange = (value: string) => {
121   - if (value === 'Access token') {
122   - resetCreantialsType();
123   - } else if (value === 'X.509') {
124   - resetCreantialsType();
125   - } else {
126   - resetCreantialsType();
  46 + const checkedChange = async (e) => {
  47 + if (!e.target.checked) {
  48 + await updateSchema([
  49 + {
  50 + field: 'token',
  51 + ifShow: false,
  52 + },
  53 + {
  54 + field: 'clientId',
  55 + ifShow: false,
  56 + },
  57 + {
  58 + field: 'username',
  59 + ifShow: false,
  60 + },
  61 + {
  62 + field: 'password',
  63 + ifShow: false,
  64 + },
  65 + {
  66 + field: 'publicKey',
  67 + ifShow: false,
  68 + },
  69 + ]);
127 70 }
128 71 };
129   - // 切换凭证类型时,重置字段
130   - function resetCreantialsType() {
131   - creaentialsPassword.token = '';
132   - creaentialsPassword.publicKey = '';
133   - creaentialsPassword.clientId = '';
134   - creaentialsPassword.username = '';
135   - creaentialsPassword.password = '';
  72 + function resetFieldsValueAndStatus() {
  73 + resetFields();
  74 + setFieldsValue({
  75 + addAgree: false,
  76 + });
  77 + updateSchema([
  78 + {
  79 + field: 'publicKey',
  80 + ifShow: false,
  81 + },
  82 + {
  83 + field: 'token',
  84 + ifShow: false,
  85 + },
  86 + {
  87 + field: 'clientId',
  88 + ifShow: false,
  89 + },
  90 + {
  91 + field: 'username',
  92 + ifShow: false,
  93 + },
  94 + {
  95 + field: 'password',
  96 + ifShow: false,
  97 + },
  98 + ]);
136 99 }
137 100
138   - // 重置所有字段
139   - function resetFields() {
140   - creaentialsPassword.isCreaentials = false;
141   - creaentialsPassword.creaentialsType = 'Access token';
142   - creaentialsPassword.token = '';
143   - creaentialsPassword.publicKey = '';
144   - creaentialsPassword.clientId = '';
145   - creaentialsPassword.username = '';
146   - creaentialsPassword.password = '';
147   - formRef.value.resetFields();
148   - }
149   -
150   - // 表单验证
151   - function validate() {
152   - if (creaentialsPassword.isCreaentials) {
153   - return formRef.value.validate();
154   - }
155   - return true;
156   - }
157 101 return {
158   - options,
159   - formRef,
160   - creaentialsPassword,
161   - handleChange,
162 102 prevStep,
163   - checked,
164   - labelCol: { style: { width: '150px' } },
165   - wrapperCol: { span: 18 },
166   - resetFields,
  103 + registerForm,
  104 + checkedChange,
  105 + getFieldsValue,
167 106 validate,
168   - rules,
  107 + resetFieldsValueAndStatus,
169 108 };
170 109 },
171 110 });
... ...
... ... @@ -29,11 +29,8 @@
29 29 showTableSetting: true,
30 30 bordered: true,
31 31 showIndexColumn: false,
32   - beforeFetch: getDeviceId,
  32 + beforeFetch: (data) => Reflect.set(data, 'deviceId', props.id),
33 33 });
34   - function getDeviceId(data) {
35   - Reflect.set(data, 'deviceId', props.id);
36   - }
37 34
38 35 return {
39 36 registerTable,
... ...
... ... @@ -2,9 +2,12 @@
2 2 <BasicTable @register="registerTable" />
3 3 </template>
4 4 <script lang="ts">
5   - import { defineComponent } from 'vue';
  5 + import { defineComponent, reactive, onMounted, onUnmounted } from 'vue';
6 6 import { BasicTable, useTable } from '/@/components/Table';
7 7 import { realTimeDataColumns, realTimeDataSearchSchemas } from '../../config/detail.config';
  8 + import { useWebSocket } from '@vueuse/core';
  9 + import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
  10 + import { getAuthCache } from '/@/utils/auth';
8 11 export default defineComponent({
9 12 name: 'DeviceManagement',
10 13 components: {
... ... @@ -22,6 +25,45 @@
22 25 bordered: true,
23 26 showIndexColumn: false,
24 27 });
  28 + const token = getAuthCache(JWT_TOKEN_KEY);
  29 +
  30 + const state = reactive({
  31 + server: `ws://192.168.10.139:8080/api/ws/plugins/telemetry?token=${token}`,
  32 + sendValue: '',
  33 + recordList: [] as { id: number; time: number; res: string }[],
  34 + });
  35 + const { status, data, send, close, open } = useWebSocket(state.server, {
  36 + autoReconnect: false,
  37 + heartbeat: true,
  38 + });
  39 + onMounted(() => {
  40 + open();
  41 + send(
  42 + JSON.stringify({
  43 + attrSubCmds: [],
  44 + tsSubCmds: [
  45 + {
  46 + entityType: 'DEVICE',
  47 + entityId: '3199a500-6302-11ec-ba36-417bcc842c0a',
  48 + scope: 'LATEST_TELEMETRY',
  49 + cmdId: 1,
  50 + },
  51 + ],
  52 + historyCmds: [],
  53 + entityDataCmds: [],
  54 + entityDataUnsubscribeCmds: [],
  55 + alarmDataCmds: [],
  56 + alarmDataUnsubscribeCmds: [],
  57 + entityCountCmds: [],
  58 + entityCountUnsubscribeCmds: [],
  59 + })
  60 + );
  61 +
  62 + console.log(JSON.parse(data.value));
  63 + });
  64 + onUnmounted(() => {
  65 + close();
  66 + });
25 67
26 68 return {
27 69 registerTable,
... ...
... ... @@ -148,9 +148,10 @@
148 148 }
149 149
150 150 function handleDetail(record: Recordable) {
151   - const { id } = record;
  151 + const { id, tbDeviceId } = record;
152 152 openDrawer(true, {
153 153 id,
  154 + tbDeviceId,
154 155 });
155 156 }
156 157
... ...
... ... @@ -6,7 +6,7 @@
6 6 </template>
7 7 <template #config="{ record }">
8 8 <a-button type="link" class="ml-2" @click="goConfig">
9   - {{ record.messageConfig.configName }}
  9 + {{ record.messageConfig?.configName }}
10 10 </a-button>
11 11 </template>
12 12 <template #action="{ record }">
... ...
... ... @@ -45,12 +45,33 @@
45 45 ...data.record,
46 46 });
47 47 organizationId = Reflect.get(data.record, 'id');
  48 + console.log(organizationId);
  49 + let treeData: any = await getOrganizationList();
  50 +
  51 + // 过滤当前选中的组织,
  52 + function filterTransFun(treeData: any[]) {
  53 + treeData.forEach((item, index, arr) => {
  54 + if (item.id === organizationId) {
  55 + arr.splice(index, 1);
  56 + }
  57 + if (item.children.length) {
  58 + filterTransFun(item.children);
  59 + }
  60 + });
  61 + }
  62 + filterTransFun(treeData);
  63 + await updateSchema({
  64 + field: 'parentId',
  65 + componentProps: { treeData },
  66 + });
  67 + } else {
  68 + let treeData = await getOrganizationList();
  69 + console.log(treeData);
  70 + await updateSchema({
  71 + field: 'parentId',
  72 + componentProps: { treeData },
  73 + });
48 74 }
49   - let treeData = await getOrganizationList();
50   - await updateSchema({
51   - field: 'parentId',
52   - componentProps: { treeData },
53   - });
54 75 });
55 76
56 77 //得到页面标题
... ...