Commit 1b471b784586e802a1a8f662567e6544699f0cdf
Merge branch 'main_dev' of http://git.yunteng.com/yunteng/thingskit-front into f…
…ix/board-style-issues
Showing
39 changed files
with
263 additions
and
106 deletions
@@ -8,6 +8,7 @@ export interface BigScreenCenterItemsModel { | @@ -8,6 +8,7 @@ export interface BigScreenCenterItemsModel { | ||
8 | remark: string; | 8 | remark: string; |
9 | state: number; | 9 | state: number; |
10 | publicId: string; | 10 | publicId: string; |
11 | + organizationId?: string; | ||
11 | } | 12 | } |
12 | export type queryPageParams = BasicPageParams & { | 13 | export type queryPageParams = BasicPageParams & { |
13 | name?: Nullable<string>; | 14 | name?: Nullable<string>; |
@@ -7,6 +7,7 @@ export interface ConfigurationCenterItemsModal { | @@ -7,6 +7,7 @@ export interface ConfigurationCenterItemsModal { | ||
7 | creator: string; | 7 | creator: string; |
8 | remark: string; | 8 | remark: string; |
9 | publicId?: string; | 9 | publicId?: string; |
10 | + organizationId?: string; | ||
10 | } | 11 | } |
11 | export type queryPageParams = BasicPageParams & { | 12 | export type queryPageParams = BasicPageParams & { |
12 | name?: Nullable<string>; | 13 | name?: Nullable<string>; |
@@ -85,7 +85,7 @@ interface TrendParamsType { | @@ -85,7 +85,7 @@ interface TrendParamsType { | ||
85 | } | 85 | } |
86 | // 获取租户趋势或者客户趋势数据 | 86 | // 获取租户趋势或者客户趋势数据 |
87 | export const getTrendData = (params: TrendParamsType) => { | 87 | export const getTrendData = (params: TrendParamsType) => { |
88 | - return defHttp.get({ | 88 | + return defHttp.get<Record<'date' | 'value', string>[]>({ |
89 | url: HomeEnum.TrendAPI, | 89 | url: HomeEnum.TrendAPI, |
90 | params, | 90 | params, |
91 | }); | 91 | }); |
@@ -30,6 +30,8 @@ enum DeviceManagerApi { | @@ -30,6 +30,8 @@ enum DeviceManagerApi { | ||
30 | 30 | ||
31 | ALARM_BATCH_ACK = '/alarm/batch/ack', | 31 | ALARM_BATCH_ACK = '/alarm/batch/ack', |
32 | 32 | ||
33 | + ALARM_BATCH_CLEAR = '/alarm/batch/clear', | ||
34 | + | ||
33 | DEVICE_CREDENTIALS = '/device/credentials', | 35 | DEVICE_CREDENTIALS = '/device/credentials', |
34 | 36 | ||
35 | COMMAND_ISSUANCE = '/rpc', | 37 | COMMAND_ISSUANCE = '/rpc', |
@@ -358,3 +360,13 @@ export const doBatchAckAlarm = (ids: string[]) => { | @@ -358,3 +360,13 @@ export const doBatchAckAlarm = (ids: string[]) => { | ||
358 | { joinPrefix: false } | 360 | { joinPrefix: false } |
359 | ); | 361 | ); |
360 | }; | 362 | }; |
363 | + | ||
364 | +export const doBatchClearAlarm = (ids: string[]) => { | ||
365 | + return defHttp.post( | ||
366 | + { | ||
367 | + url: DeviceManagerApi.ALARM_BATCH_CLEAR, | ||
368 | + data: { alarmIds: ids }, | ||
369 | + }, | ||
370 | + { joinPrefix: false } | ||
371 | + ); | ||
372 | +}; |
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | import { useMessage } from '/@/hooks/web/useMessage'; | 9 | import { useMessage } from '/@/hooks/web/useMessage'; |
10 | import { computed, ref, unref } from 'vue'; | 10 | import { computed, ref, unref } from 'vue'; |
11 | import { cloneDeep } from 'lodash-es'; | 11 | import { cloneDeep } from 'lodash-es'; |
12 | - import { isFunction, isNumber, isObject } from '/@/utils/is'; | 12 | + import { isFunction, isNumber, isObject, isString } from '/@/utils/is'; |
13 | import { useDesign } from '/@/hooks/web/useDesign'; | 13 | import { useDesign } from '/@/hooks/web/useDesign'; |
14 | 14 | ||
15 | export interface FileItem { | 15 | export interface FileItem { |
@@ -59,10 +59,19 @@ | @@ -59,10 +59,19 @@ | ||
59 | ); | 59 | ); |
60 | 60 | ||
61 | const handleBeforeUpload = (file: File, fileList: File[]) => { | 61 | const handleBeforeUpload = (file: File, fileList: File[]) => { |
62 | - const { beforeUpload } = props; | 62 | + const { beforeUpload, accept } = props; |
63 | 63 | ||
64 | if (beforeUpload && isFunction(beforeUpload)) return beforeUpload?.(file, fileList); | 64 | if (beforeUpload && isFunction(beforeUpload)) return beforeUpload?.(file, fileList); |
65 | 65 | ||
66 | + if (accept && isString(accept)) { | ||
67 | + const limitFileSuffix = accept.split(','); | ||
68 | + | ||
69 | + if (limitFileSuffix.length && !limitFileSuffix.some((suffix) => file.name.includes(suffix))) { | ||
70 | + createMessage.warning(`允许上传的文件类型包括${accept}`); | ||
71 | + return false; | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
66 | if (file.size > props.maxSize) { | 75 | if (file.size > props.maxSize) { |
67 | createMessage.warning(`文件大小超过${Math.floor(props.maxSize / 1024 / 1024)}mb`); | 76 | createMessage.warning(`文件大小超过${Math.floor(props.maxSize / 1024 / 1024)}mb`); |
68 | return false; | 77 | return false; |
@@ -2,7 +2,7 @@ import { RouteLocationNormalizedLoaded } from 'vue-router'; | @@ -2,7 +2,7 @@ import { RouteLocationNormalizedLoaded } from 'vue-router'; | ||
2 | 2 | ||
3 | const menuMap = new Map(); | 3 | const menuMap = new Map(); |
4 | 4 | ||
5 | -menuMap.set('/visual/board/detail/:boardId/:boardName?', '/visual/board'); | 5 | +menuMap.set('/visual/board/detail/:boardId/:boardName/:organizationId?', '/visual/board'); |
6 | menuMap.set('/rule/chain/:id', '/rule/chain'); | 6 | menuMap.set('/rule/chain/:id', '/rule/chain'); |
7 | 7 | ||
8 | export const useMenuActiveFix = (route: RouteLocationNormalizedLoaded) => { | 8 | export const useMenuActiveFix = (route: RouteLocationNormalizedLoaded) => { |
@@ -37,7 +37,7 @@ | @@ -37,7 +37,7 @@ | ||
37 | </a-button> | 37 | </a-button> |
38 | </template> | 38 | </template> |
39 | <template #status="{ record }"> | 39 | <template #status="{ record }"> |
40 | - <Authority value="api:yt:alarm:profile:status"> | 40 | + <Authority value="api:yt:alarm:profile:update"> |
41 | <Switch | 41 | <Switch |
42 | :checked="record.status === 1" | 42 | :checked="record.status === 1" |
43 | :loading="record.pendingStatus" | 43 | :loading="record.pendingStatus" |
@@ -47,7 +47,7 @@ | @@ -47,7 +47,7 @@ | ||
47 | /> | 47 | /> |
48 | </Authority> | 48 | </Authority> |
49 | <Tag | 49 | <Tag |
50 | - v-if="!hasPermission('api:yt:alarm:profile:status')" | 50 | + v-if="!hasPermission('api:yt:alarm:profile:update')" |
51 | :color="record.status ? 'green' : 'red'" | 51 | :color="record.status ? 'green' : 'red'" |
52 | > | 52 | > |
53 | {{ record.status ? '启用' : '禁用' }} | 53 | {{ record.status ? '启用' : '禁用' }} |
@@ -19,7 +19,30 @@ | @@ -19,7 +19,30 @@ | ||
19 | </a-button> | 19 | </a-button> |
20 | </template> | 20 | </template> |
21 | <template #toolbar> | 21 | <template #toolbar> |
22 | - <Button @click="handleBatchAck" type="primary" :disabled="getCanBatchAck">批量处理</Button> | 22 | + <Tooltip> |
23 | + <template #title> | ||
24 | + <div>激活未确认: 可以处理,清除</div> | ||
25 | + <div>激活已确认: 只可清除,已经处理</div> | ||
26 | + <div>清除未确认: 只可处理,已经清除</div> | ||
27 | + <div>清除已确认: 不需要做处理和清除</div> | ||
28 | + </template> | ||
29 | + <Button @click="handleBatchClear" type="primary" :disabled="getCanBatchClear"> | ||
30 | + <QuestionCircleOutlined class="cursor-pointer" /> | ||
31 | + <span>批量清除</span> | ||
32 | + </Button> | ||
33 | + </Tooltip> | ||
34 | + <Tooltip> | ||
35 | + <template #title> | ||
36 | + <div>激活未确认: 可以处理,清除</div> | ||
37 | + <div>激活已确认: 只可清除,已经处理</div> | ||
38 | + <div>清除未确认: 只可处理,已经清除</div> | ||
39 | + <div>清除已确认: 不需要做处理和清除</div> | ||
40 | + </template> | ||
41 | + <Button @click="handleBatchAck" type="primary" :disabled="getCanBatchAck"> | ||
42 | + <QuestionCircleOutlined class="cursor-pointer" /> | ||
43 | + <span>批量处理</span> | ||
44 | + </Button> | ||
45 | + </Tooltip> | ||
23 | </template> | 46 | </template> |
24 | </BasicTable> | 47 | </BasicTable> |
25 | <AlarmDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" /> | 48 | <AlarmDetailDrawer @register="registerDetailDrawer" @success="handleSuccess" /> |
@@ -29,10 +52,10 @@ | @@ -29,10 +52,10 @@ | ||
29 | import { defineComponent, nextTick, h, computed } from 'vue'; | 52 | import { defineComponent, nextTick, h, computed } from 'vue'; |
30 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 53 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
31 | import { alarmColumns, alarmSearchSchemas } from './config/detail.config'; | 54 | import { alarmColumns, alarmSearchSchemas } from './config/detail.config'; |
32 | - import { doBatchAckAlarm, getDeviceAlarm } from '/@/api/device/deviceManager'; | 55 | + import { doBatchAckAlarm, doBatchClearAlarm, getDeviceAlarm } from '/@/api/device/deviceManager'; |
33 | import { useDrawer } from '/@/components/Drawer'; | 56 | import { useDrawer } from '/@/components/Drawer'; |
34 | import AlarmDetailDrawer from './cpns/AlarmDetailDrawer.vue'; | 57 | import AlarmDetailDrawer from './cpns/AlarmDetailDrawer.vue'; |
35 | - import { Modal, Button } from 'ant-design-vue'; | 58 | + import { Modal, Button, Tooltip } from 'ant-design-vue'; |
36 | import { JsonPreview } from '/@/components/CodeEditor'; | 59 | import { JsonPreview } from '/@/components/CodeEditor'; |
37 | import { getDeviceDetail } from '/@/api/device/deviceManager'; | 60 | import { getDeviceDetail } from '/@/api/device/deviceManager'; |
38 | import { getAttribute } from '/@/api/ruleengine/ruleengineApi'; | 61 | import { getAttribute } from '/@/api/ruleengine/ruleengineApi'; |
@@ -44,6 +67,7 @@ | @@ -44,6 +67,7 @@ | ||
44 | import { AlarmLogItem } from '/@/api/device/model/deviceConfigModel'; | 67 | import { AlarmLogItem } from '/@/api/device/model/deviceConfigModel'; |
45 | import { AlarmStatus } from '/@/enums/alarmEnum'; | 68 | import { AlarmStatus } from '/@/enums/alarmEnum'; |
46 | import { useMessage } from '/@/hooks/web/useMessage'; | 69 | import { useMessage } from '/@/hooks/web/useMessage'; |
70 | + import { QuestionCircleOutlined } from '@ant-design/icons-vue'; | ||
47 | 71 | ||
48 | export default defineComponent({ | 72 | export default defineComponent({ |
49 | name: 'AlarmCenter', | 73 | name: 'AlarmCenter', |
@@ -52,6 +76,8 @@ | @@ -52,6 +76,8 @@ | ||
52 | BasicTable, | 76 | BasicTable, |
53 | TableAction, | 77 | TableAction, |
54 | AlarmDetailDrawer, | 78 | AlarmDetailDrawer, |
79 | + QuestionCircleOutlined, | ||
80 | + Tooltip, | ||
55 | }, | 81 | }, |
56 | 82 | ||
57 | setup() { | 83 | setup() { |
@@ -60,6 +86,7 @@ | @@ -60,6 +86,7 @@ | ||
60 | title: '告警记录列表', | 86 | title: '告警记录列表', |
61 | api: getDeviceAlarm, | 87 | api: getDeviceAlarm, |
62 | columns: alarmColumns, | 88 | columns: alarmColumns, |
89 | + rowKey: 'id', | ||
63 | useSearchForm: true, | 90 | useSearchForm: true, |
64 | formConfig: { | 91 | formConfig: { |
65 | labelWidth: 120, | 92 | labelWidth: 120, |
@@ -168,9 +195,30 @@ | @@ -168,9 +195,30 @@ | ||
168 | }; | 195 | }; |
169 | }; | 196 | }; |
170 | 197 | ||
198 | + const getCanBatchClear = computed(() => { | ||
199 | + const rowSelection = getRowSelection(); | ||
200 | + const getRows: AlarmLogItem[] = getSelectRows(); | ||
201 | + | ||
202 | + return ( | ||
203 | + !rowSelection.selectedRowKeys?.length || | ||
204 | + getRows.some( | ||
205 | + (item) => | ||
206 | + item.status === AlarmStatus.CLEARED_ACK || item.status === AlarmStatus.CLEARED_UN_ACK | ||
207 | + ) | ||
208 | + ); | ||
209 | + }); | ||
210 | + | ||
171 | const getCanBatchAck = computed(() => { | 211 | const getCanBatchAck = computed(() => { |
172 | const rowSelection = getRowSelection(); | 212 | const rowSelection = getRowSelection(); |
173 | - return !rowSelection.selectedRowKeys?.length; | 213 | + const getRows: AlarmLogItem[] = getSelectRows(); |
214 | + | ||
215 | + return ( | ||
216 | + !rowSelection.selectedRowKeys?.length || | ||
217 | + getRows.some( | ||
218 | + (item) => | ||
219 | + item.status === AlarmStatus.CLEARED_ACK || item.status === AlarmStatus.ACTIVE_ACK | ||
220 | + ) | ||
221 | + ); | ||
174 | }); | 222 | }); |
175 | 223 | ||
176 | const { createMessage } = useMessage(); | 224 | const { createMessage } = useMessage(); |
@@ -183,6 +231,15 @@ | @@ -183,6 +231,15 @@ | ||
183 | reload(); | 231 | reload(); |
184 | }; | 232 | }; |
185 | 233 | ||
234 | + const handleBatchClear = async () => { | ||
235 | + const ids = getSelectRows<AlarmLogItem>().map((item) => item.id); | ||
236 | + if (!ids.length) return; | ||
237 | + await doBatchClearAlarm(ids); | ||
238 | + createMessage.success('操作成功'); | ||
239 | + clearSelectedRowKeys(); | ||
240 | + reload(); | ||
241 | + }; | ||
242 | + | ||
186 | return { | 243 | return { |
187 | registerTable, | 244 | registerTable, |
188 | registerDetailDrawer, | 245 | registerDetailDrawer, |
@@ -190,7 +247,9 @@ | @@ -190,7 +247,9 @@ | ||
190 | handleSuccess, | 247 | handleSuccess, |
191 | handleViewAlarmDetails, | 248 | handleViewAlarmDetails, |
192 | handleBatchAck, | 249 | handleBatchAck, |
250 | + handleBatchClear, | ||
193 | getCanBatchAck, | 251 | getCanBatchAck, |
252 | + getCanBatchClear, | ||
194 | }; | 253 | }; |
195 | }, | 254 | }, |
196 | }); | 255 | }); |
@@ -56,7 +56,10 @@ | @@ -56,7 +56,10 @@ | ||
56 | return unref(orgList); | 56 | return unref(orgList); |
57 | } | 57 | } |
58 | }, | 58 | }, |
59 | - params: { ...params, _t: unref(timespan) }, | 59 | + params: { |
60 | + ...params, | ||
61 | + _t: unref(timespan), | ||
62 | + }, | ||
60 | onChange: (...args: any[]) => { | 63 | onChange: (...args: any[]) => { |
61 | emit('change', ...args); | 64 | emit('change', ...args); |
62 | }, | 65 | }, |
@@ -136,13 +136,19 @@ | @@ -136,13 +136,19 @@ | ||
136 | const handlePreview = (record: ConfigurationCenterItemsModal) => { | 136 | const handlePreview = (record: ConfigurationCenterItemsModal) => { |
137 | if (!unref(getPreviewFlag)) return; | 137 | if (!unref(getPreviewFlag)) return; |
138 | window.open( | 138 | window.open( |
139 | - `${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}&lightbox=1` | 139 | + `${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${ |
140 | + record!.id | ||
141 | + }&lightbox=1&organizationId=${record.organizationId}` | ||
140 | ); | 142 | ); |
141 | }; | 143 | }; |
142 | 144 | ||
143 | const handleDesign = (record: ConfigurationCenterItemsModal) => { | 145 | const handleDesign = (record: ConfigurationCenterItemsModal) => { |
144 | if (!unref(getDesignFlag)) return; | 146 | if (!unref(getDesignFlag)) return; |
145 | - window.open(`${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}`); | 147 | + window.open( |
148 | + `${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${ | ||
149 | + record!.id | ||
150 | + }&organizationId=${record.organizationId}` | ||
151 | + ); | ||
146 | }; | 152 | }; |
147 | 153 | ||
148 | const handleDelete = async (record: ConfigurationCenterItemsModal) => { | 154 | const handleDelete = async (record: ConfigurationCenterItemsModal) => { |
@@ -165,6 +171,7 @@ | @@ -165,6 +171,7 @@ | ||
165 | searchParams.set('configurationId', record.id); | 171 | searchParams.set('configurationId', record.id); |
166 | searchParams.set('publicId', record.publicId || ''); | 172 | searchParams.set('publicId', record.publicId || ''); |
167 | searchParams.set('lightbox', '1'); | 173 | searchParams.set('lightbox', '1'); |
174 | + searchParams.set('organizationId', record!.organizationId || ''); | ||
168 | return `${origin}${configurationPrefix}/?${searchParams.toString()}`; | 175 | return `${origin}${configurationPrefix}/?${searchParams.toString()}`; |
169 | }; | 176 | }; |
170 | 177 |
@@ -132,6 +132,9 @@ | @@ -132,6 +132,9 @@ | ||
132 | @calendarChange="handleCalendarChange" | 132 | @calendarChange="handleCalendarChange" |
133 | size="small" | 133 | size="small" |
134 | v-model:value="customerDateValue" | 134 | v-model:value="customerDateValue" |
135 | + :showTime="{ | ||
136 | + defaultValue: [dateUtil('00:00:00', 'HH:mm:ss'), dateUtil('23:59:59', 'HH:mm:ss')], | ||
137 | + }" | ||
135 | > | 138 | > |
136 | <Button | 139 | <Button |
137 | type="link" | 140 | type="link" |
@@ -165,7 +168,7 @@ | @@ -165,7 +168,7 @@ | ||
165 | import { useWebSocket } from '@vueuse/core'; | 168 | import { useWebSocket } from '@vueuse/core'; |
166 | import { getAuthCache } from '/@/utils/auth'; | 169 | import { getAuthCache } from '/@/utils/auth'; |
167 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; | 170 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; |
168 | - import { formatToDateTime } from '/@/utils/dateUtil'; | 171 | + import { dateUtil, formatToDateTime } from '/@/utils/dateUtil'; |
169 | import CustomerTrend from './CustomerTrend.vue'; | 172 | import CustomerTrend from './CustomerTrend.vue'; |
170 | // import TenantTrend from './TenantTrend.vue'; | 173 | // import TenantTrend from './TenantTrend.vue'; |
171 | import CustomerAlarmMessage from './CustomerAlarmMessage.vue'; | 174 | import CustomerAlarmMessage from './CustomerAlarmMessage.vue'; |
@@ -530,6 +533,7 @@ | @@ -530,6 +533,7 @@ | ||
530 | }; | 533 | }; |
531 | 534 | ||
532 | const handleDisableDate = (current: moment.Moment) => { | 535 | const handleDisableDate = (current: moment.Moment) => { |
536 | + if (!current) return true; | ||
533 | if (!unref(customerDateValue) || unref(customerDateValue).length === 0) { | 537 | if (!unref(customerDateValue) || unref(customerDateValue).length === 0) { |
534 | return false; | 538 | return false; |
535 | } | 539 | } |
@@ -117,6 +117,9 @@ | @@ -117,6 +117,9 @@ | ||
117 | @calendarChange="handleCalendarChange" | 117 | @calendarChange="handleCalendarChange" |
118 | :disabledDate="handleDisableDate" | 118 | :disabledDate="handleDisableDate" |
119 | v-model:value="tenantDateValue" | 119 | v-model:value="tenantDateValue" |
120 | + :showTime="{ | ||
121 | + defaultValue: [dateUtil('00:00:00', 'HH:mm:ss'), dateUtil('23:59:59', 'HH:mm:ss')], | ||
122 | + }" | ||
120 | > | 123 | > |
121 | <Button | 124 | <Button |
122 | type="link" | 125 | type="link" |
@@ -175,7 +178,7 @@ | @@ -175,7 +178,7 @@ | ||
175 | import { useWebSocket } from '@vueuse/core'; | 178 | import { useWebSocket } from '@vueuse/core'; |
176 | import { getAuthCache } from '/@/utils/auth'; | 179 | import { getAuthCache } from '/@/utils/auth'; |
177 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; | 180 | import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; |
178 | - import { formatToDateTime } from '/@/utils/dateUtil'; | 181 | + import { dateUtil, formatToDateTime } from '/@/utils/dateUtil'; |
179 | // import CustomerTrend from './CustomerTrend.vue'; | 182 | // import CustomerTrend from './CustomerTrend.vue'; |
180 | import TenantTrend from './TenantTrend.vue'; | 183 | import TenantTrend from './TenantTrend.vue'; |
181 | import CustomerAlarmMessage from './CustomerAlarmMessage.vue'; | 184 | import CustomerAlarmMessage from './CustomerAlarmMessage.vue'; |
@@ -548,6 +551,7 @@ | @@ -548,6 +551,7 @@ | ||
548 | }; | 551 | }; |
549 | 552 | ||
550 | const handleDisableDate = (current: moment.Moment) => { | 553 | const handleDisableDate = (current: moment.Moment) => { |
554 | + if (!current) return true; | ||
551 | if (!unref(tenantDateValue) || unref(tenantDateValue).length === 0) { | 555 | if (!unref(tenantDateValue) || unref(tenantDateValue).length === 0) { |
552 | return false; | 556 | return false; |
553 | } | 557 | } |
1 | -import { dateUtil, formatToDateTime } from '/@/utils/dateUtil'; | ||
2 | -import { ref } from 'vue'; | 1 | +import { dateUtil } from '/@/utils/dateUtil'; |
2 | +import { Ref, ref } from 'vue'; | ||
3 | import { getTrendData } from '/@/api/dashboard'; | 3 | import { getTrendData } from '/@/api/dashboard'; |
4 | import { RangePickerValue } from 'ant-design-vue/lib/date-picker/interface'; | 4 | import { RangePickerValue } from 'ant-design-vue/lib/date-picker/interface'; |
5 | +import moment from 'moment'; | ||
5 | 6 | ||
6 | export enum ShortcutQueryKeyEnum { | 7 | export enum ShortcutQueryKeyEnum { |
7 | LATEST_1_MONTH = 'LATEST_1_MONTH', | 8 | LATEST_1_MONTH = 'LATEST_1_MONTH', |
@@ -42,8 +43,8 @@ export function getDateByShortcutQueryKey(value: ShortcutQueryKeyEnum) { | @@ -42,8 +43,8 @@ export function getDateByShortcutQueryKey(value: ShortcutQueryKeyEnum) { | ||
42 | export function useDate() { | 43 | export function useDate() { |
43 | const tenantDateValue = ref([]); | 44 | const tenantDateValue = ref([]); |
44 | const customerDateValue = ref<RangePickerValue>([]); | 45 | const customerDateValue = ref<RangePickerValue>([]); |
45 | - const tenantTrendList = ref([]); | ||
46 | - const customerTrendList = ref([]); | 46 | + const tenantTrendList = ref<[string, string][]>([]); |
47 | + const customerTrendList = ref<[string, string][]>([]); | ||
47 | const activeTenantIndex = ref(0); | 48 | const activeTenantIndex = ref(0); |
48 | const activeCustomerIndex = ref(0); | 49 | const activeCustomerIndex = ref(0); |
49 | const TenantOrCustomerDateList = ref([ | 50 | const TenantOrCustomerDateList = ref([ |
@@ -80,52 +81,39 @@ export function useDate() { | @@ -80,52 +81,39 @@ export function useDate() { | ||
80 | } | 81 | } |
81 | 82 | ||
82 | // 获取选中的时间范围内的数据 | 83 | // 获取选中的时间范围内的数据 |
83 | - async function getDateData(startTs, endTs, trend: 'CUSTOMER_TREND' | 'TENANT_TREND', list) { | ||
84 | - // 计算时间间隔 | ||
85 | - function computedInterval(startTs: number, endTs: number) { | ||
86 | - /** | ||
87 | - * 选择的时间间隔 | ||
88 | - * <=1 2h | ||
89 | - * <=30 1day | ||
90 | - * >30<90 2day | ||
91 | - * >90 1month | ||
92 | - */ | ||
93 | - let interval = 86400000; | ||
94 | - if (endTs - startTs <= 86400000) { | ||
95 | - interval = 7200000; | ||
96 | - } else if (endTs - startTs <= 2592000000) { | ||
97 | - interval = 86400000; | ||
98 | - } else if (endTs - startTs > 2592000000 && endTs - startTs < 7776000000) { | ||
99 | - interval = 172800000; | ||
100 | - } else if (endTs - startTs > 7776000000) { | ||
101 | - interval = 2592000000; | ||
102 | - } | ||
103 | - return interval; | ||
104 | - } | ||
105 | - startTs = parseInt(formatToDateTime(startTs, 'x')) - 86400000; | ||
106 | - endTs = parseInt(formatToDateTime(endTs, 'x')); | 84 | + async function getDateData( |
85 | + startTs: moment.Moment, | ||
86 | + endTs: moment.Moment, | ||
87 | + trend: 'CUSTOMER_TREND' | 'TENANT_TREND', | ||
88 | + list: Ref<[string, string][]> | ||
89 | + ) { | ||
107 | const res = await getTrendData({ | 90 | const res = await getTrendData({ |
108 | - startTs, | ||
109 | - endTs, | ||
110 | - interval: computedInterval(startTs, endTs), | 91 | + startTs: startTs.valueOf(), |
92 | + endTs: endTs.valueOf(), | ||
93 | + interval: 24 * 60 * 60 * 1000, | ||
111 | trend, | 94 | trend, |
112 | }); | 95 | }); |
113 | - list.value = res.map((item) => [item.ts, item.value]); | 96 | + list.value = res.map((item) => [item.date, item.value]); |
114 | } | 97 | } |
115 | 98 | ||
116 | // 租户选择日期 | 99 | // 租户选择日期 |
117 | - function onDateTenantChange(_, dateString) { | ||
118 | - if (!_.length) return; | ||
119 | - const [startTs, endTs] = dateString; | 100 | + function onDateTenantChange(range: RangePickerValue) { |
101 | + if (!range.length) return; | ||
102 | + const [startTs, endTs] = range; | ||
120 | activeTenantIndex.value = -1; | 103 | activeTenantIndex.value = -1; |
121 | - getDateData(startTs, endTs, 'TENANT_TREND', tenantTrendList); | 104 | + getDateData(startTs as moment.Moment, endTs as moment.Moment, 'TENANT_TREND', tenantTrendList); |
122 | } | 105 | } |
123 | // 客户趋势选择日期 | 106 | // 客户趋势选择日期 |
124 | - function onDateCustomerChange(_, dateString) { | ||
125 | - if (!_.length) return; | ||
126 | - const [startTs, endTs] = dateString; | 107 | + function onDateCustomerChange(range: RangePickerValue) { |
108 | + if (!range.length) return; | ||
109 | + const [startTs, endTs] = range; | ||
127 | activeCustomerIndex.value = -1; | 110 | activeCustomerIndex.value = -1; |
128 | - getDateData(startTs, endTs, 'CUSTOMER_TREND', customerTrendList); | 111 | + getDateData( |
112 | + startTs as moment.Moment, | ||
113 | + endTs as moment.Moment, | ||
114 | + 'CUSTOMER_TREND', | ||
115 | + customerTrendList | ||
116 | + ); | ||
129 | } | 117 | } |
130 | return { | 118 | return { |
131 | tenantDateValue, | 119 | tenantDateValue, |
@@ -124,12 +124,16 @@ | @@ -124,12 +124,16 @@ | ||
124 | const { largeDesignerPrefix } = useGlobSetting(); | 124 | const { largeDesignerPrefix } = useGlobSetting(); |
125 | 125 | ||
126 | const handlePreview = (record: BigScreenCenterItemsModel) => { | 126 | const handlePreview = (record: BigScreenCenterItemsModel) => { |
127 | - window.open(`${largeDesignerPrefix}/#/chart/preview/${record.id}`); | 127 | + window.open( |
128 | + `${largeDesignerPrefix}/#/chart/preview/${record.id}?organizationId=${record.organizationId}` | ||
129 | + ); | ||
128 | }; | 130 | }; |
129 | 131 | ||
130 | const handleDesign = (record: BigScreenCenterItemsModel) => { | 132 | const handleDesign = (record: BigScreenCenterItemsModel) => { |
131 | if (record.state === 1) return; | 133 | if (record.state === 1) return; |
132 | - window.open(`${largeDesignerPrefix}/#/chart/home/${record.id}`); | 134 | + window.open( |
135 | + `${largeDesignerPrefix}/#/chart/home/${record.id}?organizationId=${record.organizationId}` | ||
136 | + ); | ||
133 | }; | 137 | }; |
134 | 138 | ||
135 | const handleDelete = async (record: BigScreenCenterItemsModel) => { | 139 | const handleDelete = async (record: BigScreenCenterItemsModel) => { |
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | </div> | 10 | </div> |
11 | </template> | 11 | </template> |
12 | <script lang="ts"> | 12 | <script lang="ts"> |
13 | - import { defineComponent, ref } from 'vue'; | 13 | + import { defineComponent, nextTick, ref } from 'vue'; |
14 | import { BasicForm, useForm } from '/@/components/Form'; | 14 | import { BasicForm, useForm } from '/@/components/Form'; |
15 | import { CommandFieldsEnum, CommandSchemas, CommandType, ValueType } from '../../config/data'; | 15 | import { CommandFieldsEnum, CommandSchemas, CommandType, ValueType } from '../../config/data'; |
16 | import { commandIssuanceApi } from '/@/api/device/deviceManager'; | 16 | import { commandIssuanceApi } from '/@/api/device/deviceManager'; |
@@ -35,7 +35,7 @@ | @@ -35,7 +35,7 @@ | ||
35 | const { createMessage } = useMessage(); | 35 | const { createMessage } = useMessage(); |
36 | const loading = ref(false); | 36 | const loading = ref(false); |
37 | 37 | ||
38 | - const [registerForm, { getFieldsValue, validate, resetFields }] = useForm({ | 38 | + const [registerForm, { getFieldsValue, validate, resetFields, clearValidate }] = useForm({ |
39 | labelWidth: 120, | 39 | labelWidth: 120, |
40 | schemas: CommandSchemas( | 40 | schemas: CommandSchemas( |
41 | props.deviceDetail.deviceProfile.transportType as TransportTypeEnum, | 41 | props.deviceDetail.deviceProfile.transportType as TransportTypeEnum, |
@@ -47,8 +47,10 @@ | @@ -47,8 +47,10 @@ | ||
47 | showResetButton: false, | 47 | showResetButton: false, |
48 | }); | 48 | }); |
49 | 49 | ||
50 | - const handleCancel = () => { | ||
51 | - resetFields(); | 50 | + const handleCancel = async () => { |
51 | + await resetFields(); | ||
52 | + await nextTick(); | ||
53 | + await clearValidate(); | ||
52 | }; | 54 | }; |
53 | 55 | ||
54 | const handleOk = async () => { | 56 | const handleOk = async () => { |
@@ -36,6 +36,7 @@ | @@ -36,6 +36,7 @@ | ||
36 | <Authority value="api:yt:things_model:import"> | 36 | <Authority value="api:yt:things_model:import"> |
37 | <Upload | 37 | <Upload |
38 | v-if="isShowBtn" | 38 | v-if="isShowBtn" |
39 | + accept=".json," | ||
39 | :show-upload-list="false" | 40 | :show-upload-list="false" |
40 | :customRequest="handleImportModel" | 41 | :customRequest="handleImportModel" |
41 | > | 42 | > |
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | </Authority> | 22 | </Authority> |
23 | </template> | 23 | </template> |
24 | <template #status="{ record }"> | 24 | <template #status="{ record }"> |
25 | - <Authority value="api:yt:message:status"> | 25 | + <Authority value="api:yt:message:update"> |
26 | <Switch | 26 | <Switch |
27 | :checked="record.status === 1" | 27 | :checked="record.status === 1" |
28 | :loading="record.pendingStatus" | 28 | :loading="record.pendingStatus" |
@@ -32,7 +32,7 @@ | @@ -32,7 +32,7 @@ | ||
32 | /> | 32 | /> |
33 | </Authority> | 33 | </Authority> |
34 | <Tag | 34 | <Tag |
35 | - v-if="!hasPermission('api:yt:message:status')" | 35 | + v-if="!hasPermission('api:yt:message:update')" |
36 | :color="record.status ? 'green' : 'red'" | 36 | :color="record.status ? 'green' : 'red'" |
37 | > | 37 | > |
38 | {{ record.status ? '启用' : '禁用' }} | 38 | {{ record.status ? '启用' : '禁用' }} |
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | </a-button> | 22 | </a-button> |
23 | </template> | 23 | </template> |
24 | <template #status="{ record }"> | 24 | <template #status="{ record }"> |
25 | - <Authority value="api:yt:template:status"> | 25 | + <Authority value="api:yt:template:update"> |
26 | <Switch | 26 | <Switch |
27 | :checked="record.status === 1" | 27 | :checked="record.status === 1" |
28 | :loading="record.pendingStatus" | 28 | :loading="record.pendingStatus" |
@@ -32,7 +32,7 @@ | @@ -32,7 +32,7 @@ | ||
32 | /> | 32 | /> |
33 | </Authority> | 33 | </Authority> |
34 | <Tag | 34 | <Tag |
35 | - v-if="!hasPermission('api:yt:template:status')" | 35 | + v-if="!hasPermission('api:yt:template:update')" |
36 | :color="record.status ? 'green' : 'red'" | 36 | :color="record.status ? 'green' : 'red'" |
37 | > | 37 | > |
38 | {{ record.status ? '启用' : '禁用' }} | 38 | {{ record.status ? '启用' : '禁用' }} |
@@ -4,12 +4,12 @@ | @@ -4,12 +4,12 @@ | ||
4 | <div style="height: 30px"></div> | 4 | <div style="height: 30px"></div> |
5 | <BasicForm @register="registerForm" /> | 5 | <BasicForm @register="registerForm" /> |
6 | <div class="flex flex-end" style="float: right"> | 6 | <div class="flex flex-end" style="float: right"> |
7 | - <a-button type="primary" @click="handleDeviceState">处理</a-button> | 7 | + <a-button v-if="!isHandler" type="primary" @click="handleDeviceState">处理</a-button> |
8 | </div> | 8 | </div> |
9 | </BasicDrawer> | 9 | </BasicDrawer> |
10 | </template> | 10 | </template> |
11 | <script lang="ts" setup> | 11 | <script lang="ts" setup> |
12 | - import { reactive } from 'vue'; | 12 | + import { reactive, ref } from 'vue'; |
13 | import { BasicForm, useForm } from '/@/components/Form'; | 13 | import { BasicForm, useForm } from '/@/components/Form'; |
14 | import { formHandleSchema, formDetailSchema } from './config.data'; | 14 | import { formHandleSchema, formDetailSchema } from './config.data'; |
15 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | 15 | import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; |
@@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
26 | obj: {}, | 26 | obj: {}, |
27 | }); | 27 | }); |
28 | 28 | ||
29 | - const [registerForm, { resetFields, getFieldsValue }] = useForm({ | 29 | + const [registerForm, { resetFields, getFieldsValue, setFieldsValue }] = useForm({ |
30 | schemas: formHandleSchema, | 30 | schemas: formHandleSchema, |
31 | showActionButtonGroup: false, | 31 | showActionButtonGroup: false, |
32 | }); | 32 | }); |
@@ -37,11 +37,15 @@ | @@ -37,11 +37,15 @@ | ||
37 | layout: 'vertical', | 37 | layout: 'vertical', |
38 | }); | 38 | }); |
39 | 39 | ||
40 | + const isHandler = ref(false); | ||
41 | + | ||
40 | const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { | 42 | const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { |
41 | await resetFields(); | 43 | await resetFields(); |
42 | setDrawerProps({ confirmLoading: false }); | 44 | setDrawerProps({ confirmLoading: false }); |
43 | record.obj = data.record; | 45 | record.obj = data.record; |
44 | setDescProps({ data: data.record }); | 46 | setDescProps({ data: data.record }); |
47 | + isHandler.value = data?.record?.remark; | ||
48 | + setFieldsValue(data.record); | ||
45 | }); | 49 | }); |
46 | 50 | ||
47 | const handleDeviceState = async () => { | 51 | const handleDeviceState = async () => { |
@@ -194,6 +194,10 @@ export const formSchema: DescItem[] = [ | @@ -194,6 +194,10 @@ export const formSchema: DescItem[] = [ | ||
194 | field: 'createTime', | 194 | field: 'createTime', |
195 | label: '时间', | 195 | label: '时间', |
196 | }, | 196 | }, |
197 | + { | ||
198 | + field: 'remark', | ||
199 | + label: '备注', | ||
200 | + }, | ||
197 | ]; | 201 | ]; |
198 | 202 | ||
199 | export const formDetailSchema: DescItem[] = [ | 203 | export const formDetailSchema: DescItem[] = [ |
@@ -221,7 +225,7 @@ export const formDetailSchema: DescItem[] = [ | @@ -221,7 +225,7 @@ export const formDetailSchema: DescItem[] = [ | ||
221 | //处理表单 | 225 | //处理表单 |
222 | export const formHandleSchema: FormSchema[] = [ | 226 | export const formHandleSchema: FormSchema[] = [ |
223 | { | 227 | { |
224 | - field: 'description', | 228 | + field: 'remark', |
225 | label: '备注', | 229 | label: '备注', |
226 | colProps: { span: 24 }, | 230 | colProps: { span: 24 }, |
227 | component: 'InputTextArea', | 231 | component: 'InputTextArea', |
@@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
20 | label: '处理', | 20 | label: '处理', |
21 | auth: 'api:yt:device:state:log::post', | 21 | auth: 'api:yt:device:state:log::post', |
22 | icon: 'clarity:note-edit-line', | 22 | icon: 'clarity:note-edit-line', |
23 | + ifShow: () => !record?.remark, | ||
23 | onClick: handleView.bind(null, record), | 24 | onClick: handleView.bind(null, record), |
24 | }, | 25 | }, |
25 | { | 26 | { |
@@ -74,7 +74,7 @@ | @@ -74,7 +74,7 @@ | ||
74 | /> | 74 | /> |
75 | </template> | 75 | </template> |
76 | <template #configStatus="{ record }"> | 76 | <template #configStatus="{ record }"> |
77 | - <Authority :value="PermissionReportConfigEnum.PERMISSION_STATUS"> | 77 | + <Authority :value="PermissionReportConfigEnum.PERMISSION_UPDATE"> |
78 | <Switch | 78 | <Switch |
79 | :disabled="disabledSwitch" | 79 | :disabled="disabledSwitch" |
80 | :checked="record.status === 1" | 80 | :checked="record.status === 1" |
@@ -85,7 +85,7 @@ | @@ -85,7 +85,7 @@ | ||
85 | /> | 85 | /> |
86 | </Authority> | 86 | </Authority> |
87 | <Tag | 87 | <Tag |
88 | - v-if="!hasPermission(PermissionReportConfigEnum.PERMISSION_STATUS)" | 88 | + v-if="!hasPermission(PermissionReportConfigEnum.PERMISSION_UPDATE)" |
89 | :color="record.status ? 'green' : 'red'" | 89 | :color="record.status ? 'green' : 'red'" |
90 | > | 90 | > |
91 | {{ record.status ? '启用' : '禁用' }} | 91 | {{ record.status ? '启用' : '禁用' }} |
@@ -31,9 +31,9 @@ | @@ -31,9 +31,9 @@ | ||
31 | import { CredentialsEnum } from '../mqtt/enum'; | 31 | import { CredentialsEnum } from '../mqtt/enum'; |
32 | 32 | ||
33 | const credentialsFile = reactive({ | 33 | const credentialsFile = reactive({ |
34 | - caCertFileName: '', | ||
35 | - certFileName: '', | ||
36 | - privateKeyFileName: '', | 34 | + caCertFileName: undefined, |
35 | + certFileName: undefined, | ||
36 | + privateKeyFileName: undefined, | ||
37 | }); | 37 | }); |
38 | 38 | ||
39 | const [register, { validateFields, setFieldsValue, resetFields }] = useForm({ | 39 | const [register, { validateFields, setFieldsValue, resetFields }] = useForm({ |
@@ -50,6 +50,11 @@ | @@ -50,6 +50,11 @@ | ||
50 | const getValue = async () => { | 50 | const getValue = async () => { |
51 | const values = await validateFields(); | 51 | const values = await validateFields(); |
52 | if (!values) return; | 52 | if (!values) return; |
53 | + // if (values.type == 'anonymous' || values.type == 'basic') { | ||
54 | + // credentialsFile.caCertFileName = undefined; | ||
55 | + // credentialsFile.certFileName = undefined; | ||
56 | + // credentialsFile.privateKeyFileName = undefined; | ||
57 | + // } | ||
53 | const credentials = { | 58 | const credentials = { |
54 | type: values['type'], | 59 | type: values['type'], |
55 | ...credentialsFile, | 60 | ...credentialsFile, |
@@ -51,10 +51,16 @@ | @@ -51,10 +51,16 @@ | ||
51 | const getValue = async () => { | 51 | const getValue = async () => { |
52 | const values = await validateFields(); | 52 | const values = await validateFields(); |
53 | if (!values) return; | 53 | if (!values) return; |
54 | + if (values.type == 'anonymous' || values.type == 'basic') { | ||
55 | + credentialsFile.caCertFileName = undefined; | ||
56 | + credentialsFile.certFileName = undefined; | ||
57 | + credentialsFile.privateKeyFileName = undefined; | ||
58 | + } | ||
54 | const credentials = { | 59 | const credentials = { |
55 | type: values['type'], | 60 | type: values['type'], |
56 | ...credentialsFile, | 61 | ...credentialsFile, |
57 | }; | 62 | }; |
63 | + | ||
58 | const mergeValues = { | 64 | const mergeValues = { |
59 | ...values, | 65 | ...values, |
60 | ...{ credentials }, | 66 | ...{ credentials }, |
@@ -67,7 +73,12 @@ | @@ -67,7 +73,12 @@ | ||
67 | if (credentials) { | 73 | if (credentials) { |
68 | for (let i in credentials) Reflect.set(credentialsFile, i, credentials[i]); | 74 | for (let i in credentials) Reflect.set(credentialsFile, i, credentials[i]); |
69 | } | 75 | } |
70 | - setFieldsValue({ ...value, type: credentials.type }); | 76 | + setFieldsValue({ |
77 | + ...value, | ||
78 | + type: credentials.type, | ||
79 | + username: credentials.username, | ||
80 | + password: credentials.password, | ||
81 | + }); | ||
71 | }; | 82 | }; |
72 | 83 | ||
73 | const resetValue = () => resetFields(); | 84 | const resetValue = () => resetFields(); |
@@ -18,7 +18,7 @@ class MqttFormPartialConfig { | @@ -18,7 +18,7 @@ class MqttFormPartialConfig { | ||
18 | return [ | 18 | return [ |
19 | { label: 'Anonymous', value: 'anonymous' }, | 19 | { label: 'Anonymous', value: 'anonymous' }, |
20 | { label: 'Basic', value: 'basic' }, | 20 | { label: 'Basic', value: 'basic' }, |
21 | - { label: 'PEM', value: 'pem' }, | 21 | + { label: 'PEM', value: 'cert.PEM' }, |
22 | ]; | 22 | ]; |
23 | } | 23 | } |
24 | } | 24 | } |
@@ -138,9 +138,21 @@ export const modeMqttForm: FormSchema[] = [ | @@ -138,9 +138,21 @@ export const modeMqttForm: FormSchema[] = [ | ||
138 | label: '凭据类型', | 138 | label: '凭据类型', |
139 | colProps: { span: 12 }, | 139 | colProps: { span: 12 }, |
140 | defaultValue: MqttFormPartialConfig.type, | 140 | defaultValue: MqttFormPartialConfig.type, |
141 | - componentProps: { | ||
142 | - placeholder: '请选择Credentials', | ||
143 | - options: MqttFormPartialConfig.getType(), | 141 | + componentProps: ({ formActionType }) => { |
142 | + const { setFieldsValue } = formActionType; | ||
143 | + return { | ||
144 | + placeholder: '请选择Credentials', | ||
145 | + options: MqttFormPartialConfig.getType(), | ||
146 | + onChange(e) { | ||
147 | + if (e) { | ||
148 | + console.log('执行'); | ||
149 | + setFieldsValue({ | ||
150 | + password: undefined, | ||
151 | + username: undefined, | ||
152 | + }); | ||
153 | + } | ||
154 | + }, | ||
155 | + }; | ||
144 | }, | 156 | }, |
145 | }, | 157 | }, |
146 | { | 158 | { |
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | export enum CredentialsEnum { | 6 | export enum CredentialsEnum { |
7 | IS_ANONYMOUS = 'anonymous', | 7 | IS_ANONYMOUS = 'anonymous', |
8 | IS_BASIC = 'basic', | 8 | IS_BASIC = 'basic', |
9 | - IS_PEM = 'pem', | 9 | + IS_PEM = 'cert.PEM', |
10 | } | 10 | } |
11 | 11 | ||
12 | export const isBasic = (type: string) => { | 12 | export const isBasic = (type: string) => { |
@@ -128,8 +128,9 @@ | @@ -128,8 +128,9 @@ | ||
128 | : undefined, | 128 | : undefined, |
129 | appendClientIdSuffix: getDataFlowParams.appendClientIdSuffix || undefined, | 129 | appendClientIdSuffix: getDataFlowParams.appendClientIdSuffix || undefined, |
130 | type: undefined, | 130 | type: undefined, |
131 | + username: undefined, | ||
132 | + password: undefined, | ||
131 | }; | 133 | }; |
132 | - | ||
133 | const rest = isRabbitmq(getDataFlowMethod?.type) | 134 | const rest = isRabbitmq(getDataFlowMethod?.type) |
134 | ? await postAddConvertApi({ ...restData.data, ...data }) | 135 | ? await postAddConvertApi({ ...restData.data, ...data }) |
135 | : await postAddConvertApi({ ...restData.data, ...data, configuration }); | 136 | : await postAddConvertApi({ ...restData.data, ...data, configuration }); |
@@ -79,7 +79,7 @@ | @@ -79,7 +79,7 @@ | ||
79 | /> | 79 | /> |
80 | </template> | 80 | </template> |
81 | <template #status="{ record }"> | 81 | <template #status="{ record }"> |
82 | - <Authority :value="PermissionDataFlowEnum.PERMISSION_STATUS"> | 82 | + <Authority :value="PermissionDataFlowEnum.PERMISSION_UPDATE"> |
83 | <Switch | 83 | <Switch |
84 | :checked="record.status === 1" | 84 | :checked="record.status === 1" |
85 | :loading="record.pendingStatus" | 85 | :loading="record.pendingStatus" |
@@ -89,7 +89,7 @@ | @@ -89,7 +89,7 @@ | ||
89 | /> | 89 | /> |
90 | </Authority> | 90 | </Authority> |
91 | <Tag | 91 | <Tag |
92 | - v-if="!hasPermission(PermissionDataFlowEnum.PERMISSION_STATUS)" | 92 | + v-if="!hasPermission(PermissionDataFlowEnum.PERMISSION_UPDATE)" |
93 | :color="record.status ? 'green' : 'red'" | 93 | :color="record.status ? 'green' : 'red'" |
94 | > | 94 | > |
95 | {{ record.status ? '启用' : '禁用' }} | 95 | {{ record.status ? '启用' : '禁用' }} |
@@ -755,6 +755,18 @@ export const actionSchema: FormSchema[] = [ | @@ -755,6 +755,18 @@ export const actionSchema: FormSchema[] = [ | ||
755 | component: 'Select', | 755 | component: 'Select', |
756 | label: '', | 756 | label: '', |
757 | show: ({ values }) => isAlarmOut(values.outTarget), | 757 | show: ({ values }) => isAlarmOut(values.outTarget), |
758 | + // dynamicRules: (params) => { | ||
759 | + // const { outTarget } = params.values; | ||
760 | + // return [ | ||
761 | + // { | ||
762 | + // required: outTarget == 'MSG_NOTIFY' ? true : false, | ||
763 | + // validator: (_, value) => { | ||
764 | + // if (!value) return Promise.reject('请选择告警配置'); | ||
765 | + // Promise.resolve(); | ||
766 | + // }, | ||
767 | + // }, | ||
768 | + // ]; | ||
769 | + // }, | ||
758 | componentProps: { | 770 | componentProps: { |
759 | placeholder: '请选择告警等级', | 771 | placeholder: '请选择告警等级', |
760 | options: [ | 772 | options: [ |
@@ -273,6 +273,10 @@ | @@ -273,6 +273,10 @@ | ||
273 | if (validate.device == 'PART' && validate.deviceId == undefined) | 273 | if (validate.device == 'PART' && validate.deviceId == undefined) |
274 | return createMessage.error('请选择设备'); | 274 | return createMessage.error('请选择设备'); |
275 | } | 275 | } |
276 | + if (type === 'MSG_NOTIFY') { | ||
277 | + if (!validate.alarm_config) return createMessage.error('请选择告警配置'); | ||
278 | + if (!validate.alarm_level) return createMessage.error('请选择告警等级'); | ||
279 | + } | ||
276 | //ft-add-2022-11-22 | 280 | //ft-add-2022-11-22 |
277 | //TODO-fengtao-设备验证 | 281 | //TODO-fengtao-设备验证 |
278 | const value = getFieldsValue(); | 282 | const value = getFieldsValue(); |
@@ -50,7 +50,7 @@ | @@ -50,7 +50,7 @@ | ||
50 | </template> | 50 | </template> |
51 | 51 | ||
52 | <template #status="{ record }"> | 52 | <template #status="{ record }"> |
53 | - <Authority value="api:yt:sceneLinkage:status"> | 53 | + <Authority value="api:yt:sceneLinkage:update"> |
54 | <Switch | 54 | <Switch |
55 | :checked="record.status === 1" | 55 | :checked="record.status === 1" |
56 | :loading="record.pendingStatus" | 56 | :loading="record.pendingStatus" |
@@ -60,7 +60,7 @@ | @@ -60,7 +60,7 @@ | ||
60 | /> | 60 | /> |
61 | </Authority> | 61 | </Authority> |
62 | <Tag | 62 | <Tag |
63 | - v-if="!hasPermission('api:yt:sceneLinkage:status')" | 63 | + v-if="!hasPermission('api:yt:sceneLinkage:update')" |
64 | :color="record.status ? 'green' : 'red'" | 64 | :color="record.status ? 'green' : 'red'" |
65 | > | 65 | > |
66 | {{ record.status ? '启用' : '禁用' }} | 66 | {{ record.status ? '启用' : '禁用' }} |
@@ -17,7 +17,7 @@ | @@ -17,7 +17,7 @@ | ||
17 | </Authority> | 17 | </Authority> |
18 | </template> | 18 | </template> |
19 | <template #status="{ record }"> | 19 | <template #status="{ record }"> |
20 | - <Authority value="api:yt:convert:js:status"> | 20 | + <Authority value="api:yt:convert:js:update"> |
21 | <Switch | 21 | <Switch |
22 | :checked="record.status === 1" | 22 | :checked="record.status === 1" |
23 | :loading="record.pendingStatus" | 23 | :loading="record.pendingStatus" |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | /> | 27 | /> |
28 | </Authority> | 28 | </Authority> |
29 | <Tag | 29 | <Tag |
30 | - v-if="!hasPermission('api:yt:convert:js:status')" | 30 | + v-if="!hasPermission('api:yt:convert:js:update')" |
31 | :color="record.status ? 'green' : 'red'" | 31 | :color="record.status ? 'green' : 'red'" |
32 | > | 32 | > |
33 | {{ record.status ? '启用' : '禁用' }} | 33 | {{ record.status ? '启用' : '禁用' }} |
@@ -71,7 +71,7 @@ | @@ -71,7 +71,7 @@ | ||
71 | /> | 71 | /> |
72 | </template> | 72 | </template> |
73 | <template #status="{ record }"> | 73 | <template #status="{ record }"> |
74 | - <Authority :value="PermissionConvertScriptEnum.PERMISSION_UPDATE_STATUS"> | 74 | + <Authority :value="PermissionConvertScriptEnum.PERMISSION_UPDATE"> |
75 | <Switch | 75 | <Switch |
76 | :checked="record.status === 1" | 76 | :checked="record.status === 1" |
77 | :loading="record.pendingStatus" | 77 | :loading="record.pendingStatus" |
@@ -81,7 +81,7 @@ | @@ -81,7 +81,7 @@ | ||
81 | /> | 81 | /> |
82 | </Authority> | 82 | </Authority> |
83 | <Tag | 83 | <Tag |
84 | - v-if="!hasPermission(PermissionConvertScriptEnum.PERMISSION_UPDATE_STATUS)" | 84 | + v-if="!hasPermission(PermissionConvertScriptEnum.PERMISSION_UPDATE)" |
85 | :color="record.status ? 'green' : 'red'" | 85 | :color="record.status ? 'green' : 'red'" |
86 | > | 86 | > |
87 | {{ record.status ? '启用' : '禁用' }} | 87 | {{ record.status ? '启用' : '禁用' }} |
@@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
21 | </Authority> | 21 | </Authority> |
22 | </template> | 22 | </template> |
23 | <template #status="{ record }"> | 23 | <template #status="{ record }"> |
24 | - <Authority value="api:yt:role:status"> | 24 | + <Authority value="api:yt:role:saveOrUpdateRoleInfoWithMenu:update"> |
25 | <Switch | 25 | <Switch |
26 | :checked="record.status === 1" | 26 | :checked="record.status === 1" |
27 | :loading="record.pendingStatus" | 27 | :loading="record.pendingStatus" |
@@ -30,7 +30,10 @@ | @@ -30,7 +30,10 @@ | ||
30 | @change="(checked:boolean)=>statusChange(checked,record)" | 30 | @change="(checked:boolean)=>statusChange(checked,record)" |
31 | /> | 31 | /> |
32 | </Authority> | 32 | </Authority> |
33 | - <Tag v-if="!hasPermission('api:yt:role:status')" :color="record.status ? 'green' : 'red'"> | 33 | + <Tag |
34 | + v-if="!hasPermission('api:yt:role:saveOrUpdateRoleInfoWithMenu:update')" | ||
35 | + :color="record.status ? 'green' : 'red'" | ||
36 | + > | ||
34 | {{ record.status ? '启用' : '禁用' }} | 37 | {{ record.status ? '启用' : '禁用' }} |
35 | </Tag> | 38 | </Tag> |
36 | </template> | 39 | </template> |
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | import { BasicForm, useForm } from '/@/components/Form'; | 2 | import { BasicForm, useForm } from '/@/components/Form'; |
3 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 3 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
4 | import { formSchemas } from './config'; | 4 | import { formSchemas } from './config'; |
5 | - import { ref } from 'vue'; | 5 | + import { nextTick, ref } from 'vue'; |
6 | import { composeData, parseData } from './util'; | 6 | import { composeData, parseData } from './util'; |
7 | import { createTask, updateTask } from '/@/api/task'; | 7 | import { createTask, updateTask } from '/@/api/task'; |
8 | import { ModalParamsType } from '/#/utils'; | 8 | import { ModalParamsType } from '/#/utils'; |
@@ -33,7 +33,10 @@ | @@ -33,7 +33,10 @@ | ||
33 | modalMode.value = mode; | 33 | modalMode.value = mode; |
34 | dataSource.value = record; | 34 | dataSource.value = record; |
35 | formMode.value = mode; | 35 | formMode.value = mode; |
36 | - resetFields(); | 36 | + resetFields().then(async () => { |
37 | + await nextTick(); | ||
38 | + clearValidate(); | ||
39 | + }); | ||
37 | if (record && mode === DataActionModeEnum.UPDATE) { | 40 | if (record && mode === DataActionModeEnum.UPDATE) { |
38 | const res = parseData(record); | 41 | const res = parseData(record); |
39 | setFieldsValue({ ...res }); | 42 | setFieldsValue({ ...res }); |
@@ -41,13 +44,14 @@ | @@ -41,13 +44,14 @@ | ||
41 | } | 44 | } |
42 | ); | 45 | ); |
43 | 46 | ||
44 | - const [registerForm, { getFieldsValue, validate, setFieldsValue, resetFields }] = useForm({ | ||
45 | - schemas: formSchemas, | ||
46 | - showActionButtonGroup: false, | ||
47 | - layout: 'inline', | ||
48 | - baseColProps: { span: 24 }, | ||
49 | - labelWidth: 140, | ||
50 | - }); | 47 | + const [registerForm, { getFieldsValue, validate, setFieldsValue, resetFields, clearValidate }] = |
48 | + useForm({ | ||
49 | + schemas: formSchemas, | ||
50 | + showActionButtonGroup: false, | ||
51 | + layout: 'inline', | ||
52 | + baseColProps: { span: 24 }, | ||
53 | + labelWidth: 140, | ||
54 | + }); | ||
51 | 55 | ||
52 | const loading = ref(false); | 56 | const loading = ref(false); |
53 | const { createMessage } = useMessage(); | 57 | const { createMessage } = useMessage(); |
@@ -124,7 +124,6 @@ export const parseData = (result: TaskRecordType): Required<FormValueType> => { | @@ -124,7 +124,6 @@ export const parseData = (result: TaskRecordType): Required<FormValueType> => { | ||
124 | TaskRecordType['executeTarget'] | 124 | TaskRecordType['executeTarget'] |
125 | >; | 125 | >; |
126 | const { type: executeTimeType, period, periodType, time, pollUnit } = executeTime; | 126 | const { type: executeTimeType, period, periodType, time, pollUnit } = executeTime; |
127 | - console.log(pushWay === PushWayEnum.MQTT ? JSON.stringify(rpcCommand, null, 2) : rpcCommand); | ||
128 | return { | 127 | return { |
129 | name, | 128 | name, |
130 | targetType, | 129 | targetType, |
@@ -188,7 +188,9 @@ | @@ -188,7 +188,9 @@ | ||
188 | if (hasDetailPermission) { | 188 | if (hasDetailPermission) { |
189 | const boardId = encode(record.id); | 189 | const boardId = encode(record.id); |
190 | const boardName = encode(record.name); | 190 | const boardName = encode(record.name); |
191 | - router.push(`/visual/board/detail/${boardId}/${boardName}`); | 191 | + const organizationId = encode(record?.organizationId); |
192 | + | ||
193 | + router.push(`/visual/board/detail/${boardId}/${boardName}/${organizationId}`); | ||
192 | } else createMessage.warning('没有权限'); | 194 | } else createMessage.warning('没有权限'); |
193 | }; | 195 | }; |
194 | 196 |
@@ -12,10 +12,6 @@ | @@ -12,10 +12,6 @@ | ||
12 | [PackagesCategoryEnum.MAP]: [ | 12 | [PackagesCategoryEnum.MAP]: [ |
13 | '地图组件,需绑定两个数据源,且数据源为同一设备。第一数据源为经度,第二数据源为纬度,否则地图组件不能正常显示。', | 13 | '地图组件,需绑定两个数据源,且数据源为同一设备。第一数据源为经度,第二数据源为纬度,否则地图组件不能正常显示。', |
14 | ], | 14 | ], |
15 | - [PackagesCategoryEnum.CONTROL]: [ | ||
16 | - '控制组件数据源为TCP产品,则其控制命令下发为TCP产品 物模型=>服务,且不具备状态显示功能.', | ||
17 | - '控制组件数据源为非TCP产品,则其控制命令下发为产品 物模型=>属性,且具备状态显示功能.', | ||
18 | - ], | ||
19 | }; | 15 | }; |
20 | 16 | ||
21 | const getMessage = computed(() => { | 17 | const getMessage = computed(() => { |
@@ -90,6 +90,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => { | @@ -90,6 +90,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => { | ||
90 | const isUpdate = unref(mode) === DataActionModeEnum.UPDATE; | 90 | const isUpdate = unref(mode) === DataActionModeEnum.UPDATE; |
91 | const selectWidgetKeys = useSelectWidgetKeys(); | 91 | const selectWidgetKeys = useSelectWidgetKeys(); |
92 | const category = unref(selectWidgetKeys).categoryKey; | 92 | const category = unref(selectWidgetKeys).categoryKey; |
93 | + | ||
93 | return [ | 94 | return [ |
94 | { | 95 | { |
95 | field: DataSourceField.IS_GATEWAY_DEVICE, | 96 | field: DataSourceField.IS_GATEWAY_DEVICE, |
@@ -191,6 +192,9 @@ export const commonDataSourceSchemas = (): FormSchema[] => { | @@ -191,6 +192,9 @@ export const commonDataSourceSchemas = (): FormSchema[] => { | ||
191 | }); | 192 | }); |
192 | }, | 193 | }, |
193 | showCreate: false, | 194 | showCreate: false, |
195 | + apiTreeSelectProps: { | ||
196 | + params: { organizationId: location?.pathname?.split('/')?.pop() || '' }, | ||
197 | + }, | ||
194 | getPopupContainer: () => document.body, | 198 | getPopupContainer: () => document.body, |
195 | }; | 199 | }; |
196 | }, | 200 | }, |