Commit 1b471b784586e802a1a8f662567e6544699f0cdf

Authored by loveumiko
2 parents 95d8c567 4239e0ae

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 },