Commit 7a32d197ddd88f9f3a406dfba314fe080af613d4

Authored by xp.Huang
2 parents 07534f38 9677fae5

Merge branch 'f-dev' into 'main'

fix:修复Teambition上的问题,

See merge request huang/yun-teng-iot-front!240
... ... @@ -21,6 +21,7 @@ enum DeviceManagerApi {
21 21 DEVICE_ALARM_URL = '/alarm',
22 22
23 23 DEVICE_CREDENTIALS = '/device/credentials',
  24 + COMMAND_ISSUANCE = '/rpc',
24 25 }
25 26
26 27 export const devicePage = (params: DeviceQueryParam) => {
... ... @@ -207,3 +208,17 @@ export const generateSNCode = () => {
207 208 url: '/device/sn',
208 209 });
209 210 };
  211 +
  212 +//命令下发
  213 +export const commandIssuanceApi = (type, tbDeviceId, data) => {
  214 + const T = type === 'OneWay' ? 'oneway' : 'twoway';
  215 + return defHttp.post(
  216 + {
  217 + url: DeviceManagerApi.COMMAND_ISSUANCE + '/' + T + '/' + tbDeviceId,
  218 + data,
  219 + },
  220 + {
  221 + joinPrefix: false,
  222 + }
  223 + );
  224 +};
... ...
... ... @@ -31,6 +31,7 @@
31 31 import { CreateContextOptions } from '/@/components/ContextMenu';
32 32
33 33 import { CheckEvent } from './typing';
  34 + import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
34 35
35 36 interface State {
36 37 expandedKeys: Keys;
... ... @@ -51,6 +52,14 @@
51 52 'update:searchValue',
52 53 ],
53 54 setup(props, { attrs, slots, emit, expose }) {
  55 + /**
  56 + * 作者自带Tree组件
  57 + * 新增显示隐藏
  58 + * ft
  59 + */
  60 + //ft
  61 + const isFlod = ref(false);
  62 + //ft
54 63 const state = reactive<State>({
55 64 checkStrictly: props.checkStrictly,
56 65 expandedKeys: props.expandedKeys || [],
... ... @@ -205,6 +214,7 @@
205 214 });
206 215
207 216 function handleSearch(searchValue: string) {
  217 + console.log('searchValue', searchValue);
208 218 if (searchValue !== searchText.value) searchText.value = searchValue;
209 219 emit('update:searchValue', searchValue);
210 220 if (!searchValue) {
... ... @@ -223,6 +233,11 @@
223 233 );
224 234 }
225 235
  236 + //ft
  237 + function handleFlodOrUnFoldFunc(v) {
  238 + isFlod.value = v;
  239 + }
  240 + //ft
226 241 function handleClickNode(key: string, children: TreeItem[]) {
227 242 if (!props.clickRowToExpand || !children || children.length === 0) return;
228 243 if (!state.expandedKeys.includes(key)) {
... ... @@ -388,9 +403,10 @@
388 403 const showTitle = title || toolbar || search || slots.headerTitle;
389 404 const scrollStyle: CSSProperties = { height: 'calc(100% - 38px)' };
390 405 return (
391   - <div class={[prefixCls, 'h-full', attrs.class]}>
  406 + <div style={isFlod.value ? '' : 'width:0vw'} class={[prefixCls, 'h-full', attrs.class]}>
392 407 {showTitle && (
393 408 <TreeHeader
  409 + style={'position:relative'}
394 410 checkable={checkable}
395 411 checkAll={checkAll}
396 412 expandAll={expandAll}
... ... @@ -416,6 +432,28 @@
416 432 </ScrollContainer>
417 433
418 434 <Empty v-show={unref(getNotFound)} image={Empty.PRESENTED_IMAGE_SIMPLE} class="!mt-4" />
  435 + <span
  436 + v-show={unref(isFlod)}
  437 + onClick={() => handleFlodOrUnFoldFunc(false)}
  438 + style={
  439 + isFlod.value
  440 + ? 'z-index:9999;cursor:pointer;position:absolute;top:40vh;left:17.5vw'
  441 + : 'z-index:9999;cursor:pointer;position:absolute;top:40vh;left:0.5vw'
  442 + }
  443 + >
  444 + <RightOutlined />
  445 + </span>
  446 + <span
  447 + v-show={!unref(isFlod) && unref(treeDataRef).length != 0}
  448 + onClick={() => handleFlodOrUnFoldFunc(true)}
  449 + style={
  450 + isFlod.value
  451 + ? 'z-index:9999;cursor:pointer;position:absolute;top:40vh;left:17.5vw'
  452 + : 'z-index:9999;cursor:pointer;position:absolute;top:40vh;left:0.5vw'
  453 + }
  454 + >
  455 + <LeftOutlined />
  456 + </span>
419 457 </div>
420 458 );
421 459 };
... ...
... ... @@ -6,28 +6,13 @@
6 6 @select="handleSelect"
7 7 style="position: relative"
8 8 ref="organizationIdTreeRef"
9   - :style="[{ width: !isFold ? '0rem' : '20rem' }]"
10   - :class="[!isFold ? 'w-1/4 xl:w-1/1' : 'w-1/4 xl:w-1/5']"
11 9 />
12   - <div
13   - style="position: absolute; top: 1.48rem; left: 6.5rem; cursor: pointer"
14   - :style="[{ left: !isFold ? '0.5rem' : '6.5rem' }, { top: !isFold ? '0.8rem' : '1.48rem' }]"
15   - >
16   - <Tooltip v-if="isFold">
17   - <template #title>隐藏组织</template>
18   - <MenuFoldOutlined @click="changeWidth(true)" />
19   - </Tooltip>
20   - <Tooltip v-else>
21   - <template #title>打开组织</template>
22   - <MenuUnfoldOutlined @click="changeWidth(false)" />
23   - </Tooltip>
24   - </div>
25 10 <BasicTable
  11 + style="flex: auto"
26 12 @register="registerTable"
27 13 :searchInfo="searchInfo"
28 14 class="w-3/4 xl:w-4/5"
29 15 :clickToRowSelect="false"
30   - :class="[!isFold ? 'w-3/4 xl:w-7/7' : 'w-3/4 xl:w-4/5']"
31 16 >
32 17 <template #toolbar>
33 18 <Authority value="api:yt:alarm:profile:post">
... ... @@ -98,7 +83,7 @@
98 83 </template>
99 84
100 85 <script lang="ts">
101   - import { defineComponent, reactive, h, nextTick, ref } from 'vue';
  86 + import { defineComponent, reactive, h, nextTick } from 'vue';
102 87 import { BasicTable, useTable, TableAction } from '/@/components/Table';
103 88 import { PageWrapper } from '/@/components/Page';
104 89 import { useDrawer } from '/@/components/Drawer';
... ... @@ -106,7 +91,7 @@
106 91 import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
107 92 import { deleteAlarmConfig, queryAlarmConfig } from '/@/api/alarm/config/alarmConfig';
108 93 import { searchFormSchema, columns } from './config.data';
109   - import { Modal, Tooltip } from 'ant-design-vue';
  94 + import { Modal } from 'ant-design-vue';
110 95 import { JsonPreview } from '/@/components/CodeEditor';
111 96 import { findDictItemByCode } from '/@/api/system/dict';
112 97 import { alarmContactGetPage } from '/@/api/device/deviceConfigApi';
... ... @@ -115,7 +100,6 @@
115 100 import { putAlarmConfigStatus } from '/@/api/alarm/config/alarmConfig';
116 101 import { useMessage } from '/@/hooks/web/useMessage';
117 102 import { Authority } from '/@/components/Authority';
118   - import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
119 103
120 104 export default defineComponent({
121 105 components: {
... ... @@ -126,13 +110,8 @@
126 110 ContactDrawer,
127 111 Switch,
128 112 Authority,
129   - MenuFoldOutlined,
130   - MenuUnfoldOutlined,
131   - Tooltip,
132 113 },
133 114 setup() {
134   - const isFold = ref(true);
135   -
136 115 const searchInfo = reactive<Recordable>({});
137 116 const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
138 117 // 刷新
... ... @@ -260,13 +239,6 @@
260 239 reload();
261 240 }
262 241 };
263   - const changeWidth = (e) => {
264   - if (e) {
265   - isFold.value = false;
266   - } else {
267   - isFold.value = true;
268   - }
269   - };
270 242 return {
271 243 searchInfo,
272 244 hasBatchDelete,
... ... @@ -280,8 +252,6 @@
280 252 showAlarmContact,
281 253 showMessageMode,
282 254 statusChange,
283   - changeWidth,
284   - isFold,
285 255 };
286 256 },
287 257 });
... ...
... ... @@ -2,31 +2,15 @@
2 2 <div>
3 3 <PageWrapper dense contentFullHeight contentClass="flex">
4 4 <OrganizationIdTree
5   - style="position: relative"
6 5 class="w-1/4 xl:w-1/5"
7   - :style="[{ width: !isFold ? '0rem' : '20rem' }]"
8   - :class="[!isFold ? 'w-1/4 xl:w-1/1' : 'w-1/4 xl:w-1/5']"
9 6 @select="handleSelect"
10 7 ref="organizationIdTreeRef"
11 8 />
12   - <div
13   - style="position: absolute; top: 1.48rem; left: 6.5rem; cursor: pointer"
14   - :style="[{ left: !isFold ? '0.5rem' : '6.5rem' }, { top: !isFold ? '0.8rem' : '1.48rem' }]"
15   - >
16   - <Tooltip v-if="isFold">
17   - <template #title>隐藏组织</template>
18   - <MenuFoldOutlined @click="changeWidth(true)" />
19   - </Tooltip>
20   - <Tooltip v-else>
21   - <template #title>打开组织</template>
22   - <MenuUnfoldOutlined @click="changeWidth(false)" />
23   - </Tooltip>
24   - </div>
25 9 <BasicTable
  10 + style="flex: auto"
26 11 @register="registerTable"
27 12 :searchInfo="searchInfo"
28 13 class="w-3/4 xl:w-4/5"
29   - :class="[!isFold ? 'w-3/4 xl:w-7/7' : 'w-3/4 xl:w-4/5']"
30 14 >
31 15 <template #toolbar>
32 16 <Authority value="api:yt:alarmContact:post">
... ... @@ -82,8 +66,6 @@
82 66 import { getAlarmContact, deleteAlarmContact } from '/@/api/alarm/contact/alarmContact';
83 67 import { searchFormSchema, columns } from './config.data';
84 68 import { Authority } from '/@/components/Authority';
85   - import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
86   - import { Tooltip } from 'ant-design-vue';
87 69
88 70 export default defineComponent({
89 71 components: {
... ... @@ -93,12 +75,8 @@
93 75 TableAction,
94 76 ContactDrawer,
95 77 Authority,
96   - MenuFoldOutlined,
97   - MenuUnfoldOutlined,
98   - Tooltip,
99 78 },
100 79 setup() {
101   - const isFold = ref(true);
102 80 const searchInfo = reactive<Recordable>({});
103 81 const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
104 82 // 表格hooks
... ... @@ -157,13 +135,6 @@
157 135 searchInfo.organizationId = organizationId;
158 136 handleSuccess();
159 137 };
160   - const changeWidth = (e) => {
161   - if (e) {
162   - isFold.value = false;
163   - } else {
164   - isFold.value = true;
165   - }
166   - };
167 138 return {
168 139 searchInfo,
169 140 hasBatchDelete,
... ... @@ -174,8 +145,6 @@
174 145 registerTable,
175 146 registerDrawer,
176 147 organizationIdTreeRef,
177   - changeWidth,
178   - isFold,
179 148 };
180 149 },
181 150 });
... ...
... ... @@ -6,28 +6,13 @@
6 6 @select="handleSelect"
7 7 ref="organizationIdTreeRef"
8 8 style="position: relative"
9   - :style="[{ width: !isFold ? '0rem' : '20rem' }]"
10   - :class="[!isFold ? 'w-1/4 xl:w-1/1' : 'w-1/4 xl:w-1/5']"
11 9 />
12   - <div
13   - style="position: absolute; top: 1.48rem; left: 6.5rem; cursor: pointer"
14   - :style="[{ left: !isFold ? '0.5rem' : '6.5rem' }, { top: !isFold ? '0.8rem' : '1.48rem' }]"
15   - >
16   - <Tooltip v-if="isFold">
17   - <template #title>隐藏组织</template>
18   - <MenuFoldOutlined @click="changeWidth(true)" />
19   - </Tooltip>
20   - <Tooltip v-else>
21   - <template #title>打开组织</template>
22   - <MenuUnfoldOutlined @click="changeWidth(false)" />
23   - </Tooltip>
24   - </div>
25 10 <BasicTable
  11 + style="flex: auto"
26 12 :clickToRowSelect="false"
27 13 @register="registerTable"
28 14 :searchInfo="searchInfo"
29 15 class="w-3/4 xl:w-4/5"
30   - :class="[!isFold ? 'w-3/4 xl:w-7/7' : 'w-3/4 xl:w-4/5']"
31 16 >
32 17 <template #toolbar>
33 18 <Authority value="api:yt:video:post">
... ... @@ -92,7 +77,7 @@
92 77 </template>
93 78
94 79 <script lang="ts">
95   - import { defineComponent, reactive, nextTick, ref } from 'vue';
  80 + import { defineComponent, reactive, nextTick } from 'vue';
96 81 import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table';
97 82 import { PageWrapper } from '/@/components/Page';
98 83 import { useDrawer } from '/@/components/Drawer';
... ... @@ -104,8 +89,6 @@
104 89 import { useModal } from '/@/components/Modal';
105 90 import { Authority } from '/@/components/Authority';
106 91 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
107   - import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
108   - import { Tooltip } from 'ant-design-vue';
109 92
110 93 export default defineComponent({
111 94 components: {
... ... @@ -117,12 +100,8 @@
117 100 VideoPreviewModal,
118 101 TableImg,
119 102 Authority,
120   - MenuFoldOutlined,
121   - MenuUnfoldOutlined,
122   - Tooltip,
123 103 },
124 104 setup() {
125   - const isFold = ref(true);
126 105 const searchInfo = reactive<Recordable>({});
127 106 const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
128 107 const [registerModal, { openModal }] = useModal();
... ... @@ -191,13 +170,6 @@
191 170 record,
192 171 });
193 172 };
194   - const changeWidth = (e) => {
195   - if (e) {
196   - isFold.value = false;
197   - } else {
198   - isFold.value = true;
199   - }
200   - };
201 173 return {
202 174 searchInfo,
203 175 hasBatchDelete,
... ... @@ -210,8 +182,6 @@
210 182 organizationIdTreeRef,
211 183 handleViewVideo,
212 184 registerModal,
213   - changeWidth,
214   - isFold,
215 185 };
216 186 },
217 187 });
... ...
1 1 <template>
  2 + <div style="position: absolute"> </div>
2 3 <div class="bg-white m-4 mr-0 overflow-hidden">
3 4 <BasicTree
4   - v-if="treeData.length > 0"
5 5 title="组织列表"
6 6 toolbar
7 7 search
... ...
... ... @@ -6,28 +6,13 @@
6 6 @select="handleSelect"
7 7 ref="organizationIdTreeRef"
8 8 style="position: relative"
9   - :style="[{ width: !isFold ? '0rem' : '20rem' }]"
10   - :class="[!isFold ? 'w-1/4 xl:w-1/1' : 'w-1/4 xl:w-1/5']"
11 9 />
12   - <div
13   - style="position: absolute; top: 1.48rem; left: 6.5rem; cursor: pointer"
14   - :style="[{ left: !isFold ? '0.5rem' : '6.5rem' }, { top: !isFold ? '0.8rem' : '1.48rem' }]"
15   - >
16   - <Tooltip v-if="isFold">
17   - <template #title>隐藏组织</template>
18   - <MenuFoldOutlined @click="changeWidth(true)" />
19   - </Tooltip>
20   - <Tooltip v-else>
21   - <template #title>打开组织</template>
22   - <MenuUnfoldOutlined @click="changeWidth(false)" />
23   - </Tooltip>
24   - </div>
25 10 <BasicTable
  11 + style="flex: auto"
26 12 :clickToRowSelect="false"
27 13 @register="registerTable"
28 14 :searchInfo="searchInfo"
29 15 class="w-3/4 xl:w-4/5"
30   - :class="[!isFold ? 'w-3/4 xl:w-7/7' : 'w-3/4 xl:w-4/5']"
31 16 >
32 17 <template #toolbar>
33 18 <Authority value="api:yt:admin:addConfiguration">
... ... @@ -85,7 +70,7 @@
85 70 </template>
86 71
87 72 <script lang="ts">
88   - import { defineComponent, reactive, nextTick, ref } from 'vue';
  73 + import { defineComponent, reactive, nextTick } from 'vue';
89 74 import { BasicTable, useTable, TableAction } from '/@/components/Table';
90 75 import { PageWrapper } from '/@/components/Page';
91 76 import { useDrawer } from '/@/components/Drawer';
... ... @@ -99,8 +84,6 @@
99 84 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
100 85 import { getAppEnvConfig, isDevMode } from '/@/utils/env';
101 86 import { Authority } from '/@/components/Authority';
102   - import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
103   - import { Tooltip } from 'ant-design-vue';
104 87
105 88 export default defineComponent({
106 89 components: {
... ... @@ -110,12 +93,8 @@
110 93 TableAction,
111 94 ContactDrawer,
112 95 Authority,
113   - MenuFoldOutlined,
114   - MenuUnfoldOutlined,
115   - Tooltip,
116 96 },
117 97 setup() {
118   - const isFold = ref(true);
119 98 const { VITE_GLOB_CONFIGURATION } = getAppEnvConfig();
120 99 const isDev = isDevMode();
121 100 const searchInfo = reactive<Recordable>({});
... ... @@ -191,13 +170,7 @@
191 170 `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}`
192 171 );
193 172 };
194   - const changeWidth = (e) => {
195   - if (e) {
196   - isFold.value = false;
197   - } else {
198   - isFold.value = true;
199   - }
200   - };
  173 +
201 174 return {
202 175 searchInfo,
203 176 hasBatchDelete,
... ... @@ -210,8 +183,6 @@
210 183 registerTable,
211 184 registerDrawer,
212 185 organizationIdTreeRef,
213   - changeWidth,
214   - isFold,
215 186 };
216 187 },
217 188 });
... ...
... ... @@ -629,3 +629,33 @@ export const TokenSchemas: FormSchema[] = [
629 629 },
630 630 },
631 631 ];
  632 +
  633 +export const CommandSchemas: FormSchema[] = [
  634 + {
  635 + field: 'commandType',
  636 + component: 'RadioGroup',
  637 + label: '下发类型',
  638 + colProps: {
  639 + span: 8,
  640 + },
  641 + defaultValue: 'OneWay',
  642 + componentProps: {
  643 + options: [
  644 + {
  645 + label: 'OneWay',
  646 + value: 'OneWay',
  647 + },
  648 + {
  649 + label: 'TwoWay',
  650 + value: 'TwoWay',
  651 + },
  652 + ],
  653 + },
  654 + },
  655 + {
  656 + field: 'commandValue',
  657 + label: '请输入命令内容',
  658 + slot: 'commandSlot',
  659 + component: 'InputTextArea',
  660 + },
  661 +];
... ...
... ... @@ -15,6 +15,9 @@
15 15 <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'">
16 16 <RealTimeData :deviceDetail="deviceDetail" />
17 17 </TabPane>
  18 + <TabPane key="5" tab="命令下发" v-if="deviceDetail?.deviceType !== 'SENSOR'">
  19 + <CommandIssuance :deviceDetail="deviceDetail" />
  20 + </TabPane>
18 21 <TabPane key="3" tab="告警"><Alarm :id="deviceDetail.id" /></TabPane>
19 22 <TabPane key="4" tab="子设备" v-if="deviceDetail?.deviceType === 'GATEWAY'">
20 23 <ChildDevice :fromId="deviceDetail?.tbDeviceId" />
... ... @@ -31,6 +34,7 @@
31 34 import RealTimeData from '../tabs/RealTimeData.vue';
32 35 import Alarm from '../tabs/Alarm.vue';
33 36 import ChildDevice from '../tabs/ChildDevice.vue';
  37 + import CommandIssuance from '../tabs/CommandIssuance.vue';
34 38 import { getDeviceDetail } from '/@/api/device/deviceManager';
35 39 export default defineComponent({
36 40 name: 'DeviceModal',
... ... @@ -42,6 +46,7 @@
42 46 RealTimeData,
43 47 Alarm,
44 48 ChildDevice,
  49 + CommandIssuance,
45 50 },
46 51 emits: ['reload', 'register'],
47 52 setup() {
... ...
  1 +<template>
  2 + <div class="tabs-detail">
  3 + <div class="mt-4">
  4 + <BasicForm @register="registerForm">
  5 + <template #commandSlot>
  6 + <div class="flex">
  7 + <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div>
  8 + <Tooltip title='{"method":"setGpio","params":{"pin":7,"value":1}}' class="ml-2">
  9 + <QuestionCircleOutlined style="font-size: 1rem" />
  10 + </Tooltip>
  11 + </div>
  12 + </template>
  13 + </BasicForm>
  14 + <div>
  15 + <Button :disabled="disable" type="primary" @click="handleOk" class="mr-2">确定</Button>
  16 + <Button type="default" @click="handleCancel" class="mr-2">重置</Button>
  17 + </div>
  18 + </div>
  19 + </div>
  20 +</template>
  21 +<script lang="ts">
  22 + import { defineComponent, ref, onMounted, unref, nextTick } from 'vue';
  23 + import { BasicForm, useForm } from '/@/components/Form';
  24 + import { CommandSchemas } from '../../config/data';
  25 + import { commandIssuanceApi } from '/@/api/device/deviceManager';
  26 + import { useMessage } from '/@/hooks/web/useMessage';
  27 + import { Button } from '/@/components/Button';
  28 + import jsoneditor from 'jsoneditor';
  29 + import 'jsoneditor/dist/jsoneditor.min.css';
  30 + import { QuestionCircleOutlined } from '@ant-design/icons-vue';
  31 + import { Tooltip } from 'ant-design-vue';
  32 +
  33 + export default defineComponent({
  34 + components: { BasicForm, Button, QuestionCircleOutlined, Tooltip },
  35 + props: {
  36 + deviceDetail: {
  37 + type: Object,
  38 + required: true,
  39 + },
  40 + },
  41 + emits: ['register'],
  42 + setup(props) {
  43 + const { createMessage } = useMessage();
  44 + const jsonData: any = ref({});
  45 + const disable = ref(false);
  46 + const [registerForm, { getFieldsValue, validate, resetFields }] = useForm({
  47 + labelWidth: 100,
  48 + schemas: CommandSchemas,
  49 + labelAlign: 'right',
  50 + showSubmitButton: false,
  51 + showResetButton: false,
  52 + wrapperCol: {
  53 + span: 12,
  54 + },
  55 + });
  56 + // json 以及初始化JSON
  57 + const jsoneditorRef = ref();
  58 + const jsonValue = ref({});
  59 + const jsonInstance = ref();
  60 + onMounted(() => {
  61 + nextTick(() => {
  62 + let options = {
  63 + mode: 'code',
  64 + mainMenuBar: false,
  65 + statusBar: false,
  66 + };
  67 + let editor = new jsoneditor(jsoneditorRef.value, options);
  68 + editor.set(jsonValue.value);
  69 + jsonInstance.value = editor;
  70 + });
  71 + });
  72 +
  73 + const handleCancel = () => {
  74 + resetFields();
  75 + };
  76 + const handleOk = async () => {
  77 + disable.value = true;
  78 + // 验证
  79 + const valid = await validate();
  80 + if (!valid) return;
  81 + // 收集表单数据
  82 + const field = getFieldsValue();
  83 + jsonData.value = unref(jsonInstance).get();
  84 + jsonData.value.persistent = true;
  85 + jsonData.value.additionalInfo = {
  86 + cmdType: 'API',
  87 + };
  88 + commandIssuanceApi(field.commandType, props.deviceDetail.tbDeviceId, jsonData.value)
  89 + .then((res) => {
  90 + if (!res) return;
  91 + createMessage.success('命令下发成功');
  92 + disable.value = true;
  93 + // 请求
  94 + handleCancel();
  95 + })
  96 + .catch((e) => {
  97 + if (e?.message) {
  98 + createMessage.error(e?.message);
  99 + }
  100 + })
  101 + .finally(() => {
  102 + setTimeout(() => {
  103 + disable.value = false;
  104 + }, 300);
  105 + });
  106 + };
  107 + return {
  108 + registerForm,
  109 + handleCancel,
  110 + handleOk,
  111 + disable,
  112 + jsonData,
  113 + jsoneditorRef,
  114 + jsonValue,
  115 + jsonInstance,
  116 + };
  117 + },
  118 + });
  119 +</script>
  120 +<style scoped>
  121 + .jsoneditor-transform {
  122 + background-position: -144px -96px;
  123 + display: none !important;
  124 + }
  125 +</style>
... ...
... ... @@ -4,28 +4,9 @@
4 4 <OrganizationIdTree
5 5 class="w-1/6 xl:w-1/5"
6 6 @select="handleSelect"
7   - :style="[{ width: !isFold ? '0rem' : '20rem' }]"
8   - :class="[!isFold ? 'w-1/4 xl:w-1/1' : 'w-1/4 xl:w-1/5']"
9 7 ref="organizationIdTreeRef"
10 8 />
11   - <div
12   - style="position: absolute; top: 1.48rem; left: 6.5rem; cursor: pointer"
13   - :style="[{ left: !isFold ? '0.5rem' : '6.5rem' }, { top: !isFold ? '0.8rem' : '1.48rem' }]"
14   - >
15   - <Tooltip v-if="isFold">
16   - <template #title>隐藏组织</template>
17   - <MenuFoldOutlined @click="changeWidth(true)" />
18   - </Tooltip>
19   - <Tooltip v-else>
20   - <template #title>打开组织</template>
21   - <MenuUnfoldOutlined @click="changeWidth(false)" />
22   - </Tooltip>
23   - </div>
24   - <BasicTable
25   - @register="registerTable"
26   - class="w-5/6 xl:w-4/5"
27   - :class="[!isFold ? 'w-423 xl:w-423' : 'w-5/6 xl:w-4/5']"
28   - >
  9 + <BasicTable style="flex: auto" @register="registerTable" class="w-5/6 xl:w-4/5">
29 10 <template #toolbar>
30 11 <Authority value="api:yt:device:post">
31 12 <a-button type="primary" @click="handleCreate" v-if="authBtn(role)">
... ... @@ -201,11 +182,7 @@
201 182 import { authBtn } from '/@/enums/roleEnum';
202 183 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
203 184 import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
204   - import {
205   - QuestionCircleOutlined,
206   - MenuFoldOutlined,
207   - MenuUnfoldOutlined,
208   - } from '@ant-design/icons-vue';
  185 + import { QuestionCircleOutlined } from '@ant-design/icons-vue';
209 186 import { Authority } from '/@/components/Authority';
210 187
211 188 export default defineComponent({
... ... @@ -224,12 +201,8 @@
224 201 QuestionCircleOutlined,
225 202 Popover,
226 203 Authority,
227   - MenuFoldOutlined,
228   - MenuUnfoldOutlined,
229 204 },
230 205 setup(_) {
231   - const isFold = ref(true);
232   -
233 206 const { createMessage } = useMessage();
234 207 const go = useGo();
235 208 const searchInfo = reactive<Recordable>({});
... ... @@ -341,13 +314,6 @@
341 314 createMessage.success('复制成功~');
342 315 }
343 316 };
344   - const changeWidth = (e) => {
345   - if (e) {
346   - isFold.value = false;
347   - } else {
348   - isFold.value = true;
349   - }
350   - };
351 317
352 318 return {
353 319 registerTable,
... ... @@ -372,8 +338,6 @@
372 338 hasBatchDelete,
373 339 handleDeleteOrBatchDelete,
374 340 handleReload,
375   - changeWidth,
376   - isFold,
377 341 };
378 342 },
379 343 });
... ...
... ... @@ -105,6 +105,7 @@
105 105 //TODO-fengtao-设备、属性、条件筛选验证
106 106 const validate = getFieldsValue();
107 107 if (validate.triggerType == undefined) return createMessage.error('请选择设备触发方式');
  108 + if (validate.type1 == undefined) return createMessage.error('请选择属性触发方式');
108 109 if (validate.device == 'PART') {
109 110 if (validate.entityId == undefined) return createMessage.error('请选择设备');
110 111 }
... ...
... ... @@ -142,6 +142,7 @@
142 142 let predicateIsRequired = false;
143 143 let predicateDoubleIsRequired = false;
144 144 let triggerTypeIsRequired = false;
  145 + let type1IsRequired = false;
145 146 if (clearRule) {
146 147 clearRule.some((s) => {
147 148 if (s.device == 'PART') {
... ... @@ -152,6 +153,9 @@
152 153 if (s.type2 == '' || s.type2 == null) {
153 154 attrIsRequired = true;
154 155 }
  156 + if (s.type1 == '' || s.type1 == null) {
  157 + type1IsRequired = true;
  158 + }
155 159 if (s.triggerType == '' || s.triggerType == null || s.triggerType == undefined) {
156 160 triggerTypeIsRequired = true;
157 161 }
... ... @@ -179,6 +183,7 @@
179 183 if (predicateIsRequired) return createMessage.error('请填写条件筛选');
180 184 if (predicateDoubleIsRequired) return createMessage.error('请填写条件筛选');
181 185 if (triggerTypeIsRequired) return createMessage.error('请选择设备触发方式');
  186 + if (type1IsRequired) return createMessage.error('请选择属性触发方式');
182 187 //TODO-fengtao-清除告警验证
183 188 //TODO-fengtao-设备验证
184 189 const validate = getFieldsValue();
... ...
... ... @@ -5,28 +5,12 @@
5 5 class="w-1/4 xl:w-1/5"
6 6 @select="handleSelect"
7 7 ref="organizationIdTreeRef"
8   - style="position: relative"
9   - :style="[{ width: !isFold ? '0rem' : '20rem' }]"
10   - :class="[!isFold ? 'w-1/4 xl:w-1/1' : 'w-1/4 xl:w-1/5']"
11 8 />
12   - <div
13   - style="position: absolute; top: 1.48rem; left: 6.5rem; cursor: pointer"
14   - :style="[{ left: !isFold ? '0.5rem' : '6.5rem' }, { top: !isFold ? '0.8rem' : '1.48rem' }]"
15   - >
16   - <Tooltip v-if="isFold">
17   - <template #title>隐藏组织</template>
18   - <MenuFoldOutlined @click="changeWidth(true)" />
19   - </Tooltip>
20   - <Tooltip v-else>
21   - <template #title>打开组织</template>
22   - <MenuUnfoldOutlined @click="changeWidth(false)" />
23   - </Tooltip>
24   - </div>
25 9 <BasicTable
  10 + style="flex: auto"
26 11 :clickToRowSelect="false"
27 12 @register="registerTable"
28 13 class="w-3/4 xl:w-4/5"
29   - :class="[!isFold ? 'w-3/4 xl:w-7/7' : 'w-3/4 xl:w-4/5']"
30 14 >
31 15 <template #toolbar>
32 16 <Authority value="api:yt:user:post">
... ... @@ -101,7 +85,7 @@
101 85 </div>
102 86 </template>
103 87 <script lang="ts">
104   - import { defineComponent, reactive, nextTick, ref } from 'vue';
  88 + import { defineComponent, reactive, nextTick } from 'vue';
105 89 import { BasicTable, useTable, TableAction } from '/@/components/Table';
106 90 import { deleteUser, getAccountList } from '/@/api/system/system';
107 91 import { PageWrapper } from '/@/components/Page';
... ... @@ -113,8 +97,6 @@
113 97 import { useGo } from '/@/hooks/web/usePage';
114 98 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
115 99 import { Authority } from '/@/components/Authority';
116   - import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
117   - import { Tooltip } from 'ant-design-vue';
118 100
119 101 export default defineComponent({
120 102 name: 'AccountManagement',
... ... @@ -126,12 +108,8 @@
126 108 TableAction,
127 109 Tag,
128 110 Authority,
129   - MenuFoldOutlined,
130   - MenuUnfoldOutlined,
131   - Tooltip,
132 111 },
133 112 setup() {
134   - const isFold = ref(true);
135 113 const go = useGo();
136 114 const [registerModal, { openModal }] = useModal();
137 115 let searchInfo = reactive<Recordable>({});
... ... @@ -190,13 +168,6 @@
190 168 function handleView(record: Recordable) {
191 169 go('/system/account_detail/' + record.id);
192 170 }
193   - const changeWidth = (e) => {
194   - if (e) {
195   - isFold.value = false;
196   - } else {
197   - isFold.value = true;
198   - }
199   - };
200 171
201 172 return {
202 173 registerTable,
... ... @@ -209,8 +180,6 @@
209 180 organizationIdTreeRef,
210 181 hasBatchDelete,
211 182 handleDeleteOrBatchDelete,
212   - changeWidth,
213   - isFold,
214 183 };
215 184 },
216 185 });
... ...
... ... @@ -18,12 +18,6 @@ export const columns: BasicColumn[] = [
18 18 width: 120,
19 19 },
20 20 {
21   - title: '反馈方式',
22   - dataIndex: 'config',
23   - width: 180,
24   - slots: { customRender: 'config' },
25   - },
26   - {
27 21 title: '添加时间',
28 22 dataIndex: 'createTime',
29 23 width: 180,
... ... @@ -63,30 +57,6 @@ export const formSchema: FormSchema[] = [
63 57 },
64 58 },
65 59 {
66   - field: 'phone',
67   - label: '手机',
68   - component: 'Input',
69   - componentProps: {
70   - disabled: true,
71   - },
72   - },
73   - {
74   - field: 'qq',
75   - label: 'QQ',
76   - component: 'Input',
77   - componentProps: {
78   - disabled: true,
79   - },
80   - },
81   - {
82   - field: 'email',
83   - label: '邮箱',
84   - component: 'Input',
85   - componentProps: {
86   - disabled: true,
87   - },
88   - },
89   - {
90 60 field: 'message',
91 61 label: '反馈信息',
92 62 colProps: { span: 24 },
... ...
... ... @@ -13,9 +13,6 @@
13 13 </a-button>
14 14 </Authority>
15 15 </template>
16   - <template #config="{ record }">
17   - <a-button type="link" class="ml-2" @click="showData(record)"> 查看反馈方式 </a-button>
18   - </template>
19 16 <template #action="{ record }">
20 17 <TableAction
21 18 :actions="[
... ... @@ -44,15 +41,13 @@
44 41 </template>
45 42
46 43 <script lang="ts">
47   - import { defineComponent, reactive, h, nextTick } from 'vue';
  44 + import { defineComponent, reactive, nextTick } from 'vue';
48 45 import { BasicTable, useTable, TableAction } from '/@/components/Table';
49 46 import { useDrawer } from '/@/components/Drawer';
50 47 import FeedbackDrawer from './FeedbackDrawer.vue';
51 48 import { feedbackPage, deleteFeedbackManage } from '/@/api/feedback/feedbackManager';
52 49 import { searchFormSchema, columns } from './config.data';
53 50 import { useModal } from '/@/components/Modal';
54   - import { Modal } from 'ant-design-vue';
55   - import { JsonPreview } from '/@/components/CodeEditor';
56 51 import { Authority } from '/@/components/Authority';
57 52 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
58 53
... ... @@ -130,17 +125,6 @@
130 125 record,
131 126 });
132 127 };
133   - function showData(record: Recordable) {
134   - if (record.contact) {
135   - Modal.info({
136   - title: '当前反馈方式',
137   - width: 600,
138   - centered: true,
139   - maskClosable: true,
140   - content: h(JsonPreview, { data: JSON.parse(record.contact) }),
141   - });
142   - }
143   - }
144 128 return {
145 129 searchInfo,
146 130 hasBatchDelete,
... ... @@ -152,7 +136,6 @@
152 136 registerDrawer,
153 137 handleViewVideo,
154 138 registerModal,
155   - showData,
156 139 };
157 140 },
158 141 });
... ...