Showing
27 changed files
with
417 additions
and
118 deletions
| @@ -69,6 +69,7 @@ export interface ComponentInfo { | @@ -69,6 +69,7 @@ export interface ComponentInfo { | ||
| 69 | icon: string; | 69 | icon: string; |
| 70 | value?: string | number; | 70 | value?: string | number; |
| 71 | updateTime?: number; | 71 | updateTime?: number; |
| 72 | + showDeviceName: boolean; | ||
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | export interface DataSource { | 75 | export interface DataSource { |
| @@ -14,7 +14,7 @@ enum Api { | @@ -14,7 +14,7 @@ enum Api { | ||
| 14 | * @description: Get user menu based on id | 14 | * @description: Get user menu based on id |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | -export const getMenuList = (args) => { | 17 | +export const getMenuList = (args?: number) => { |
| 18 | const userStore = useUserStore(); | 18 | const userStore = useUserStore(); |
| 19 | let url = Api.GetMenuList; | 19 | let url = Api.GetMenuList; |
| 20 | try { | 20 | try { |
| @@ -94,3 +94,9 @@ export function forgetPasswordApi(data) { | @@ -94,3 +94,9 @@ export function forgetPasswordApi(data) { | ||
| 94 | data, | 94 | data, |
| 95 | }); | 95 | }); |
| 96 | } | 96 | } |
| 97 | + | ||
| 98 | +export const getUserToken = (id: string) => { | ||
| 99 | + return defHttp.get<Record<'token' | 'refreshToken', string>>({ | ||
| 100 | + url: `/third/login/id/${id}`, | ||
| 101 | + }); | ||
| 102 | +}; |
src/assets/icons/location.svg
0 → 100644
| 1 | +<svg t="1671693733059" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25398" width="200" height="200"><path d="M585.290213 343.524914c0-37.136805-33.106002-67.357084-73.789587-67.357084-40.684608 0-73.78754 30.220279-73.78754 67.357084 0 37.120432 33.102932 67.329455 73.78754 67.329455C552.184211 410.854369 585.290213 380.645346 585.290213 343.524914zM467.227284 343.524914c0-22.289656 19.860327-40.417525 44.273343-40.417525 24.415063 0 44.273343 18.127869 44.273343 40.417525 0 22.271236-19.85828 40.389896-44.273343 40.389896C487.087611 383.91481 467.227284 365.79615 467.227284 343.524914zM511.141446 741.92667l11.455913-12.768815c8.013511-8.92937 204.344015-220.213447 203.697285-358.458021-0.506537-111.529119-101.375875-208.420867-214.795041-208.420867-113.923656 0-215.816301 96.907097-215.816301 208.483288 0 138.182153 196.101283 349.432461 204.055442 358.356714L511.141446 741.92667zM511.500627 189.219549c97.206926 0 184.830589 84.850503 185.278797 181.601034 0.517793 109.87034-144.55121 279.638885-185.553043 328.016709-40.799218-48.428989-186.026834-218.179115-186.026834-328.072991C325.199547 274.042423 413.845493 189.219549 511.500627 189.219549zM946.101839 789.395798 832.104505 600.221274c-10.316973-17.114796-30.019711-27.752064-51.421136-27.752064L673.835875 572.46921c-8.156774 0-14.759145 6.03239-14.759145 13.472849 0 7.436366 6.601348 13.46671 14.759145 13.46671l106.848517 0c10.636245 0 20.437471 5.287423 25.566282 13.795191L920.250054 802.37746c5.013177 8.337899 4.856611 18.201547-0.448208 26.380834-5.303796 8.190543-14.699794 13.077853-25.120121 13.077853L128.318504 841.836147c-10.41828 0-19.814278-4.88731-25.119097-13.077853-5.302773-8.179286-5.462408-18.042935-0.446162-26.380834l113.997334-189.174524c5.130857-8.507768 14.930037-13.795191 25.566282-13.795191L349.166401 599.407746c8.15575 0 14.757099-6.030343 14.757099-13.46671 0-7.440459-6.601348-13.472849-14.757099-13.472849L242.317884 572.468187c-21.401426 0-41.10314 10.638291-51.42216 27.752064L76.898391 789.395798c-10.102079 16.758686-9.769504 36.600593 0.89437 53.073776 10.665921 16.476253 29.5582 26.307156 50.526767 26.307156L894.680702 868.776729c20.968567 0 39.862893-9.830903 50.528813-26.307156C955.87339 825.99639 956.204941 806.154483 946.101839 789.395798z" fill="#bfbfbf" p-id="25399"></path></svg> |
| 1 | -<script lang="ts" setup></script> | 1 | +<script lang="ts" setup> |
| 2 | + import { Dropdown, Menu, Popconfirm } from 'ant-design-vue'; | ||
| 3 | + import { computed, useSlots } from 'vue'; | ||
| 4 | + import Icon from '../Icon'; | ||
| 5 | + import { usePermission } from '/@/hooks/web/usePermission'; | ||
| 2 | 6 | ||
| 3 | -<template> <div></div></template> | 7 | + export interface AuthDropDownProps { |
| 8 | + dropMenuList: AuthDropMenuList[]; | ||
| 9 | + trigger?: ('contextmenu' | 'click' | 'hover')[]; | ||
| 10 | + } | ||
| 11 | + | ||
| 12 | + export interface AuthDropMenuList { | ||
| 13 | + icon?: string; | ||
| 14 | + event: string | number; | ||
| 15 | + text: string; | ||
| 16 | + disabled?: boolean; | ||
| 17 | + divider?: boolean; | ||
| 18 | + auth?: string; | ||
| 19 | + onClick?: Fn; | ||
| 20 | + popconfirm?: { | ||
| 21 | + cancelText?: string; | ||
| 22 | + okText?: string; | ||
| 23 | + okType?: string; | ||
| 24 | + title?: string; | ||
| 25 | + icon?: string; | ||
| 26 | + disabled?: boolean; | ||
| 27 | + onCancel?: Fn; | ||
| 28 | + onConfirm?: Fn; | ||
| 29 | + onVisibleChange?: Fn; | ||
| 30 | + }; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + const props = defineProps<AuthDropDownProps>(); | ||
| 34 | + | ||
| 35 | + const slot = useSlots(); | ||
| 36 | + | ||
| 37 | + const { hasPermission } = usePermission(); | ||
| 38 | + | ||
| 39 | + const getMenuList = computed(() => { | ||
| 40 | + const { dropMenuList } = props; | ||
| 41 | + return dropMenuList.filter((menu) => (menu.auth ? hasPermission(menu.auth) : true)); | ||
| 42 | + }); | ||
| 43 | + | ||
| 44 | + const hasDefaultSlot = computed(() => { | ||
| 45 | + return !!slot.default; | ||
| 46 | + }); | ||
| 47 | +</script> | ||
| 48 | + | ||
| 49 | +<template> | ||
| 50 | + <Dropdown :trigger="$props.trigger"> | ||
| 51 | + <template #overlay> | ||
| 52 | + <Menu v-if="getMenuList.length"> | ||
| 53 | + <template v-for="item in getMenuList" :key="item.event"> | ||
| 54 | + <Menu.Divider v-if="item.divider" /> | ||
| 55 | + <Menu.Item v-if="!item.popconfirm" @click="item.onClick"> | ||
| 56 | + <span class="flex justify-center items-center"> | ||
| 57 | + <Icon :icon="item.icon" /> | ||
| 58 | + <span class="ml-2">{{ item.text }}</span> | ||
| 59 | + </span> | ||
| 60 | + </Menu.Item> | ||
| 61 | + <Menu.Item v-if="item.popconfirm"> | ||
| 62 | + <Popconfirm v-bind="item.popconfirm"> | ||
| 63 | + <template v-if="item.popconfirm.icon" #icon> | ||
| 64 | + <Icon :icon="item.popconfirm.icon" /> | ||
| 65 | + </template> | ||
| 66 | + <span class="flex justify-center items-center"> | ||
| 67 | + <Icon :icon="item.icon" /> | ||
| 68 | + <span class="ml-2">{{ item.text }}</span> | ||
| 69 | + </span> | ||
| 70 | + </Popconfirm> | ||
| 71 | + </Menu.Item> | ||
| 72 | + </template> | ||
| 73 | + </Menu> | ||
| 74 | + </template> | ||
| 75 | + <Icon | ||
| 76 | + v-if="!hasDefaultSlot" | ||
| 77 | + class="items-center justify-center" | ||
| 78 | + icon="ant-design:ellipsis-outlined" | ||
| 79 | + :class="!getMenuList.length ? '!text-gray-200 !cursor-not-allowed' : ''" | ||
| 80 | + /> | ||
| 81 | + <slot name="default"></slot> | ||
| 82 | + </Dropdown> | ||
| 83 | +</template> |
| 1 | +<script lang="ts" setup> | ||
| 2 | + import { Icon } from '/@/components/Icon'; | ||
| 3 | + import { computed, ExtractPropTypes, unref } from 'vue'; | ||
| 4 | + import { usePermission } from '/@/hooks/web/usePermission'; | ||
| 5 | + | ||
| 6 | + interface AuthIconProps extends ExtractPropTypes<typeof Icon> { | ||
| 7 | + auth?: string; | ||
| 8 | + } | ||
| 9 | + | ||
| 10 | + const props = defineProps<AuthIconProps>(); | ||
| 11 | + | ||
| 12 | + const emit = defineEmits(['click']); | ||
| 13 | + | ||
| 14 | + const { hasPermission } = usePermission(); | ||
| 15 | + | ||
| 16 | + const getHasPermission = computed(() => { | ||
| 17 | + const { auth } = props; | ||
| 18 | + return auth ? hasPermission(auth) : true; | ||
| 19 | + }); | ||
| 20 | + | ||
| 21 | + const getBindProps = computed(() => { | ||
| 22 | + return { | ||
| 23 | + ...props, | ||
| 24 | + ...(unref(getHasPermission) ? { onClick: (event: Event) => emit('click', event) } : {}), | ||
| 25 | + }; | ||
| 26 | + }); | ||
| 27 | +</script> | ||
| 28 | + | ||
| 29 | +<template> | ||
| 30 | + <Icon | ||
| 31 | + v-bind="getBindProps" | ||
| 32 | + class="justify-center items-center" | ||
| 33 | + :class="getHasPermission ? '' : '!cursor-not-allowed !text-gray-200'" | ||
| 34 | + /> | ||
| 35 | +</template> |
| 1 | export { default as ModeSwitchButton } from './ModeSwitchButton.vue'; | 1 | export { default as ModeSwitchButton } from './ModeSwitchButton.vue'; |
| 2 | export { default as CardLayoutButton } from './CardLayoutButton.vue'; | 2 | export { default as CardLayoutButton } from './CardLayoutButton.vue'; |
| 3 | +export { default as AuthIcon } from './AuthIcon.vue'; | ||
| 3 | export { | 4 | export { |
| 4 | EnumTableCardMode, | 5 | EnumTableCardMode, |
| 5 | EnumTableChartMode, | 6 | EnumTableChartMode, |
| @@ -26,3 +26,26 @@ export function buildShortUUID(prefix = ''): string { | @@ -26,3 +26,26 @@ export function buildShortUUID(prefix = ''): string { | ||
| 26 | unique++; | 26 | unique++; |
| 27 | return prefix + '_' + random + unique + String(time); | 27 | return prefix + '_' + random + unique + String(time); |
| 28 | } | 28 | } |
| 29 | + | ||
| 30 | +export function getlowerCaseChars() { | ||
| 31 | + return Array.from({ length: 26 }).map((_, index) => String.fromCharCode(index + 97)); | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +export function getUpperCaseChars() { | ||
| 35 | + return Array.from({ length: 26 }).map((_, index) => String.fromCharCode(index + 65)); | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +export function randomString(length = 20) { | ||
| 39 | + const upperCaseChars = getUpperCaseChars(); | ||
| 40 | + const lowerCaseChars = getlowerCaseChars(); | ||
| 41 | + const numberChars = Array.from({ length: 10 }).map((_, index) => index); | ||
| 42 | + const allChars = [...numberChars, ...upperCaseChars, ...lowerCaseChars].sort( | ||
| 43 | + () => 0.5 - Math.random() | ||
| 44 | + ); | ||
| 45 | + | ||
| 46 | + const rangeFn = () => (Math.random() * 63) | 0; | ||
| 47 | + | ||
| 48 | + return Array.from({ length }) | ||
| 49 | + .map(() => allChars[rangeFn()]) | ||
| 50 | + .join(''); | ||
| 51 | +} |
| 1 | <script setup lang="ts"> | 1 | <script setup lang="ts"> |
| 2 | import { List, Card, Button, PaginationProps, Popover, Slider, Tooltip } from 'ant-design-vue'; | 2 | import { List, Card, Button, PaginationProps, Popover, Slider, Tooltip } from 'ant-design-vue'; |
| 3 | - import { | ||
| 4 | - ReloadOutlined, | ||
| 5 | - AppstoreOutlined, | ||
| 6 | - EyeOutlined, | ||
| 7 | - EditOutlined, | ||
| 8 | - EllipsisOutlined, | ||
| 9 | - } from '@ant-design/icons-vue'; | 3 | + import { ReloadOutlined, AppstoreOutlined } from '@ant-design/icons-vue'; |
| 10 | import { computed, onMounted, reactive, ref, unref } from 'vue'; | 4 | import { computed, onMounted, reactive, ref, unref } from 'vue'; |
| 11 | import { OrganizationIdTree, useResetOrganizationTree } from '../../common/organizationIdTree'; | 5 | import { OrganizationIdTree, useResetOrganizationTree } from '../../common/organizationIdTree'; |
| 12 | import { | 6 | import { |
| @@ -15,7 +9,6 @@ | @@ -15,7 +9,6 @@ | ||
| 15 | } from '/@/api/configuration/center/configurationCenter'; | 9 | } from '/@/api/configuration/center/configurationCenter'; |
| 16 | import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal'; | 10 | import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal'; |
| 17 | import { PageWrapper } from '/@/components/Page'; | 11 | import { PageWrapper } from '/@/components/Page'; |
| 18 | - import { Dropdown } from '/@/components/Dropdown'; | ||
| 19 | import { BasicForm, useForm } from '/@/components/Form'; | 12 | import { BasicForm, useForm } from '/@/components/Form'; |
| 20 | import { ConfigurationPermission, searchFormSchema } from './center.data'; | 13 | import { ConfigurationPermission, searchFormSchema } from './center.data'; |
| 21 | import { useMessage } from '/@/hooks/web/useMessage'; | 14 | import { useMessage } from '/@/hooks/web/useMessage'; |
| @@ -23,12 +16,13 @@ | @@ -23,12 +16,13 @@ | ||
| 23 | import { isDevMode } from '/@/utils/env'; | 16 | import { isDevMode } from '/@/utils/env'; |
| 24 | import ConfigurationCenterDrawer from './ConfigurationCenterDrawer.vue'; | 17 | import ConfigurationCenterDrawer from './ConfigurationCenterDrawer.vue'; |
| 25 | import { useDrawer } from '/@/components/Drawer'; | 18 | import { useDrawer } from '/@/components/Drawer'; |
| 26 | - import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm'; | ||
| 27 | import { getBoundingClientRect } from '/@/utils/domUtils'; | 19 | import { getBoundingClientRect } from '/@/utils/domUtils'; |
| 28 | import configurationSrc from '/@/assets/icons/configuration.svg'; | 20 | import configurationSrc from '/@/assets/icons/configuration.svg'; |
| 29 | import { cloneDeep } from 'lodash'; | 21 | import { cloneDeep } from 'lodash'; |
| 30 | import { usePermission } from '/@/hooks/web/usePermission'; | 22 | import { usePermission } from '/@/hooks/web/usePermission'; |
| 31 | import { useGlobSetting } from '/@/hooks/setting'; | 23 | import { useGlobSetting } from '/@/hooks/setting'; |
| 24 | + import { AuthIcon } from '/@/components/Widget'; | ||
| 25 | + import AuthDropDown from '/@/components/Widget/AuthDropDown.vue'; | ||
| 32 | 26 | ||
| 33 | const listColumn = ref(5); | 27 | const listColumn = ref(5); |
| 34 | 28 | ||
| @@ -136,10 +130,8 @@ | @@ -136,10 +130,8 @@ | ||
| 136 | window.open(`${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}`); | 130 | window.open(`${configurationPrefix}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}`); |
| 137 | }; | 131 | }; |
| 138 | 132 | ||
| 139 | - const { createSyncConfirm } = useSyncConfirm(); | ||
| 140 | const handleDelete = async (record: ConfigurationCenterItemsModal) => { | 133 | const handleDelete = async (record: ConfigurationCenterItemsModal) => { |
| 141 | try { | 134 | try { |
| 142 | - await createSyncConfirm({ iconType: 'warning', content: '是否确认删除操作?' }); | ||
| 143 | await deleteConfigurationCenter([record.id]); | 135 | await deleteConfigurationCenter([record.id]); |
| 144 | createMessage.success('删除成功'); | 136 | createMessage.success('删除成功'); |
| 145 | await getListData(); | 137 | await getListData(); |
| @@ -227,20 +219,44 @@ | @@ -227,20 +219,44 @@ | ||
| 227 | </template> | 219 | </template> |
| 228 | <template class="ant-card-actions" #actions> | 220 | <template class="ant-card-actions" #actions> |
| 229 | <Tooltip title="预览"> | 221 | <Tooltip title="预览"> |
| 230 | - <EyeOutlined | ||
| 231 | - :class="getPreviewFlag ? '' : '!cursor-not-allowed !text-gray-200'" | ||
| 232 | - key="setting" | 222 | + <AuthIcon |
| 223 | + :auth="ConfigurationPermission.PREVIEW" | ||
| 224 | + class="!text-lg" | ||
| 225 | + icon="ant-design:eye-outlined" | ||
| 233 | @click="handlePreview(item)" | 226 | @click="handlePreview(item)" |
| 234 | /> | 227 | /> |
| 235 | </Tooltip> | 228 | </Tooltip> |
| 236 | <Tooltip title="设计"> | 229 | <Tooltip title="设计"> |
| 237 | - <EditOutlined | ||
| 238 | - :class="getDesignFlag ? '' : '!cursor-not-allowed !text-gray-200'" | ||
| 239 | - key="edit" | 230 | + <AuthIcon |
| 231 | + :auth="ConfigurationPermission.DESIGN" | ||
| 232 | + class="!text-lg" | ||
| 233 | + icon="ant-design:edit-outlined" | ||
| 240 | @click="handleDesign(item)" | 234 | @click="handleDesign(item)" |
| 241 | /> | 235 | /> |
| 242 | </Tooltip> | 236 | </Tooltip> |
| 243 | - <Dropdown | 237 | + <AuthDropDown |
| 238 | + :dropMenuList="[ | ||
| 239 | + { | ||
| 240 | + text: '编辑', | ||
| 241 | + auth: ConfigurationPermission.UPDATE, | ||
| 242 | + icon: 'clarity:note-edit-line', | ||
| 243 | + event: '', | ||
| 244 | + onClick: handleCreateOrUpdate.bind(null, item), | ||
| 245 | + }, | ||
| 246 | + { | ||
| 247 | + text: '删除', | ||
| 248 | + auth: ConfigurationPermission.DELETE, | ||
| 249 | + icon: 'ant-design:delete-outlined', | ||
| 250 | + event: '', | ||
| 251 | + popconfirm: { | ||
| 252 | + title: '是否确认删除操作?', | ||
| 253 | + onConfirm: handleDelete.bind(null, item), | ||
| 254 | + }, | ||
| 255 | + }, | ||
| 256 | + ]" | ||
| 257 | + :trigger="['hover']" | ||
| 258 | + /> | ||
| 259 | + <!-- <Dropdown | ||
| 244 | :dropMenuList="[ | 260 | :dropMenuList="[ |
| 245 | { | 261 | { |
| 246 | text: '编辑', | 262 | text: '编辑', |
| @@ -261,7 +277,7 @@ | @@ -261,7 +277,7 @@ | ||
| 261 | :trigger="['hover']" | 277 | :trigger="['hover']" |
| 262 | > | 278 | > |
| 263 | <EllipsisOutlined key="ellipsis" /> | 279 | <EllipsisOutlined key="ellipsis" /> |
| 264 | - </Dropdown> | 280 | + </Dropdown> --> |
| 265 | </template> | 281 | </template> |
| 266 | <Card.Meta> | 282 | <Card.Meta> |
| 267 | <template #title> | 283 | <template #title> |
| @@ -80,6 +80,9 @@ export const step1Schemas: FormSchema[] = [ | @@ -80,6 +80,9 @@ export const step1Schemas: FormSchema[] = [ | ||
| 80 | gatewayId: null, | 80 | gatewayId: null, |
| 81 | }); | 81 | }); |
| 82 | }, | 82 | }, |
| 83 | + showSearch: true, | ||
| 84 | + filterOption: (inputValue: string, option: Record<'label' | 'value', string>) => | ||
| 85 | + option.label.includes(inputValue), | ||
| 83 | }; | 86 | }; |
| 84 | }, | 87 | }, |
| 85 | }, | 88 | }, |
| @@ -399,6 +402,7 @@ export const step2Schemas: FormSchema[] = [ | @@ -399,6 +402,7 @@ export const step2Schemas: FormSchema[] = [ | ||
| 399 | field: 'credentialsId', | 402 | field: 'credentialsId', |
| 400 | required: true, | 403 | required: true, |
| 401 | ifShow: false, | 404 | ifShow: false, |
| 405 | + slot: 'credentialsId', | ||
| 402 | componentProps: { | 406 | componentProps: { |
| 403 | maxLength: 36, | 407 | maxLength: 36, |
| 404 | placeholder: '请输入访问令牌', | 408 | placeholder: '请输入访问令牌', |
| @@ -421,6 +425,7 @@ export const step2Schemas: FormSchema[] = [ | @@ -421,6 +425,7 @@ export const step2Schemas: FormSchema[] = [ | ||
| 421 | field: 'clientId', | 425 | field: 'clientId', |
| 422 | required: true, | 426 | required: true, |
| 423 | ifShow: false, | 427 | ifShow: false, |
| 428 | + slot: 'clientId', | ||
| 424 | componentProps: { | 429 | componentProps: { |
| 425 | maxLength: 36, | 430 | maxLength: 36, |
| 426 | placeholder: '请输入客户端ID', | 431 | placeholder: '请输入客户端ID', |
| @@ -597,6 +602,7 @@ export const TokenSchemas: FormSchema[] = [ | @@ -597,6 +602,7 @@ export const TokenSchemas: FormSchema[] = [ | ||
| 597 | field: 'credentialsId', | 602 | field: 'credentialsId', |
| 598 | required: true, | 603 | required: true, |
| 599 | ifShow: false, | 604 | ifShow: false, |
| 605 | + slot: 'credentialsId', | ||
| 600 | componentProps: { | 606 | componentProps: { |
| 601 | maxLength: 36, | 607 | maxLength: 36, |
| 602 | placeholder: '请输入访问令牌', | 608 | placeholder: '请输入访问令牌', |
| @@ -90,6 +90,7 @@ export const searchFormSchema: FormSchema[] = [ | @@ -90,6 +90,7 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 90 | { label: '直连设备', value: DeviceTypeEnum.DIRECT_CONNECTION }, | 90 | { label: '直连设备', value: DeviceTypeEnum.DIRECT_CONNECTION }, |
| 91 | { label: '网关子设备', value: DeviceTypeEnum.SENSOR }, | 91 | { label: '网关子设备', value: DeviceTypeEnum.SENSOR }, |
| 92 | ], | 92 | ], |
| 93 | + placeholder: '请选择设备类型', | ||
| 93 | }, | 94 | }, |
| 94 | colProps: { span: 6 }, | 95 | colProps: { span: 6 }, |
| 95 | }, | 96 | }, |
| @@ -103,13 +104,14 @@ export const searchFormSchema: FormSchema[] = [ | @@ -103,13 +104,14 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 103 | { label: '在线', value: DeviceState.ONLINE }, | 104 | { label: '在线', value: DeviceState.ONLINE }, |
| 104 | { label: '离线', value: DeviceState.OFFLINE }, | 105 | { label: '离线', value: DeviceState.OFFLINE }, |
| 105 | ], | 106 | ], |
| 107 | + placeholder: '请选择设备状态', | ||
| 106 | }, | 108 | }, |
| 107 | colProps: { span: 6 }, | 109 | colProps: { span: 6 }, |
| 108 | }, | 110 | }, |
| 109 | { | 111 | { |
| 110 | field: 'deviceProfileId', | 112 | field: 'deviceProfileId', |
| 111 | label: '产品', | 113 | label: '产品', |
| 112 | - component: 'ApiSearchSelect', | 114 | + component: 'ApiSelect', |
| 113 | colProps: { span: 6 }, | 115 | colProps: { span: 6 }, |
| 114 | componentProps: () => { | 116 | componentProps: () => { |
| 115 | return { | 117 | return { |
| @@ -118,26 +120,9 @@ export const searchFormSchema: FormSchema[] = [ | @@ -118,26 +120,9 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 118 | valueField: 'id', | 120 | valueField: 'id', |
| 119 | resultField: 'data', | 121 | resultField: 'data', |
| 120 | placeholder: '请选择产品', | 122 | placeholder: '请选择产品', |
| 121 | - api: async () => { | ||
| 122 | - const data = await deviceProfile({ params: '' }); | ||
| 123 | - const returnData = data.map((m) => { | ||
| 124 | - return { | ||
| 125 | - name: m.name, | ||
| 126 | - id: m.id, | ||
| 127 | - }; | ||
| 128 | - }); | ||
| 129 | - return returnData; | ||
| 130 | - }, | ||
| 131 | - searchApi: async (params: Recordable) => { | ||
| 132 | - const data = await deviceProfile({ textSearch: params.text }); | ||
| 133 | - const returnData = data.map((m) => { | ||
| 134 | - return { | ||
| 135 | - name: m.name, | ||
| 136 | - id: m.id, | ||
| 137 | - }; | ||
| 138 | - }); | ||
| 139 | - return returnData; | ||
| 140 | - }, | 123 | + api: deviceProfile, |
| 124 | + filterOption: (inputValue: string, option: Record<'label' | 'value', string>) => | ||
| 125 | + option.label.includes(inputValue), | ||
| 141 | }; | 126 | }; |
| 142 | }, | 127 | }, |
| 143 | }, | 128 | }, |
| @@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
| 16 | @open-gateway-device="handleOpenGatewayDevice" | 16 | @open-gateway-device="handleOpenGatewayDevice" |
| 17 | /> | 17 | /> |
| 18 | </TabPane> | 18 | </TabPane> |
| 19 | - <TabPane key="modelOfMatter" tab="物模型"> | 19 | + <TabPane key="modelOfMatter" tab="物模型数据"> |
| 20 | <ModelOfMatter :deviceDetail="deviceDetail" /> | 20 | <ModelOfMatter :deviceDetail="deviceDetail" /> |
| 21 | </TabPane> | 21 | </TabPane> |
| 22 | <!-- <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'"> | 22 | <!-- <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'"> |
| @@ -12,7 +12,17 @@ | @@ -12,7 +12,17 @@ | ||
| 12 | <template #clientId="{ field, model }"> | 12 | <template #clientId="{ field, model }"> |
| 13 | <div class="flex items-center"> | 13 | <div class="flex items-center"> |
| 14 | <Input v-model:value="model[field]" placeholder="请输入客户端ID" /> | 14 | <Input v-model:value="model[field]" placeholder="请输入客户端ID" /> |
| 15 | - <ReloadOutlined class="ml-3 !text-blue-600" @click="handleCreateUUID" /> | 15 | + <Tooltip title="刷新客户端ID"> |
| 16 | + <ReloadOutlined class="ml-3 !text-blue-600" @click="handleCreateUUID" /> | ||
| 17 | + </Tooltip> | ||
| 18 | + </div> | ||
| 19 | + </template> | ||
| 20 | + <template #credentialsId="{ field, model }"> | ||
| 21 | + <div class="flex items-center"> | ||
| 22 | + <Input v-model:value="model[field]" placeholder="请输入访问令牌" /> | ||
| 23 | + <Tooltip title="刷新访问令牌"> | ||
| 24 | + <ReloadOutlined class="ml-3 !text-blue-600" @click="handleCreateCredentialsId" /> | ||
| 25 | + </Tooltip> | ||
| 16 | </div> | 26 | </div> |
| 17 | </template> | 27 | </template> |
| 18 | </BasicForm> | 28 | </BasicForm> |
| @@ -26,8 +36,8 @@ | @@ -26,8 +36,8 @@ | ||
| 26 | import { TokenSchemas, credentialTypeEnum } from '../../config/data'; | 36 | import { TokenSchemas, credentialTypeEnum } from '../../config/data'; |
| 27 | import { saveDeviceToken } from '/@/api/device/deviceManager'; | 37 | import { saveDeviceToken } from '/@/api/device/deviceManager'; |
| 28 | import { useMessage } from '/@/hooks/web/useMessage'; | 38 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 29 | - import { Input } from 'ant-design-vue'; | ||
| 30 | - import { buildUUID } from '/@/utils/uuid'; | 39 | + import { Input, Tooltip } from 'ant-design-vue'; |
| 40 | + import { buildUUID, randomString } from '/@/utils/uuid'; | ||
| 31 | import { ReloadOutlined } from '@ant-design/icons-vue'; | 41 | import { ReloadOutlined } from '@ant-design/icons-vue'; |
| 32 | export default defineComponent({ | 42 | export default defineComponent({ |
| 33 | components: { | 43 | components: { |
| @@ -35,6 +45,7 @@ | @@ -35,6 +45,7 @@ | ||
| 35 | BasicForm, | 45 | BasicForm, |
| 36 | Input, | 46 | Input, |
| 37 | ReloadOutlined, | 47 | ReloadOutlined, |
| 48 | + Tooltip, | ||
| 38 | }, | 49 | }, |
| 39 | emits: ['register'], | 50 | emits: ['register'], |
| 40 | setup() { | 51 | setup() { |
| @@ -224,6 +235,10 @@ | @@ -224,6 +235,10 @@ | ||
| 224 | const handleCreateUUID = () => { | 235 | const handleCreateUUID = () => { |
| 225 | setFieldsValue({ clientId: buildUUID() }); | 236 | setFieldsValue({ clientId: buildUUID() }); |
| 226 | }; | 237 | }; |
| 238 | + | ||
| 239 | + const handleCreateCredentialsId = () => { | ||
| 240 | + setFieldsValue({ credentialsId: randomString() }); | ||
| 241 | + }; | ||
| 227 | return { | 242 | return { |
| 228 | registerModal, | 243 | registerModal, |
| 229 | registerForm, | 244 | registerForm, |
| @@ -231,6 +246,7 @@ | @@ -231,6 +246,7 @@ | ||
| 231 | handleCancel, | 246 | handleCancel, |
| 232 | handleOk, | 247 | handleOk, |
| 233 | handleCreateUUID, | 248 | handleCreateUUID, |
| 249 | + handleCreateCredentialsId, | ||
| 234 | }; | 250 | }; |
| 235 | }, | 251 | }, |
| 236 | }); | 252 | }); |
| @@ -4,6 +4,30 @@ | @@ -4,6 +4,30 @@ | ||
| 4 | <template #addAgree="{ model, field }"> | 4 | <template #addAgree="{ model, field }"> |
| 5 | <Checkbox v-model:checked="model[field]" @change="checkedChange">添加协议</Checkbox> | 5 | <Checkbox v-model:checked="model[field]" @change="checkedChange">添加协议</Checkbox> |
| 6 | </template> | 6 | </template> |
| 7 | + <template #clientId="{ model, field }"> | ||
| 8 | + <div class="flex justify-center items-center"> | ||
| 9 | + <Input v-model:value="model[field]" placeholder="请输入客户端ID" /> | ||
| 10 | + <Tooltip title="刷新客户端ID"> | ||
| 11 | + <Icon | ||
| 12 | + class="ml-3 cursor-pointer !text-blue-600" | ||
| 13 | + icon="ant-design:reload-outlined" | ||
| 14 | + @click="handleGenerateClientId" | ||
| 15 | + /> | ||
| 16 | + </Tooltip> | ||
| 17 | + </div> | ||
| 18 | + </template> | ||
| 19 | + <template #credentialsId="{ model, field }"> | ||
| 20 | + <div class="flex justify-center items-center"> | ||
| 21 | + <Input v-model:value="model[field]" placeholder="请输入访问令牌" /> | ||
| 22 | + <Tooltip title="刷新访问令牌"> | ||
| 23 | + <Icon | ||
| 24 | + class="ml-3 cursor-pointer !text-blue-600" | ||
| 25 | + icon="ant-design:reload-outlined" | ||
| 26 | + @click="handleGenerateCredentialsId" | ||
| 27 | + /> | ||
| 28 | + </Tooltip> | ||
| 29 | + </div> | ||
| 30 | + </template> | ||
| 7 | </BasicForm> | 31 | </BasicForm> |
| 8 | <div> | 32 | <div> |
| 9 | <a-button @click="prevStep">上一步</a-button> | 33 | <a-button @click="prevStep">上一步</a-button> |
| @@ -13,13 +37,18 @@ | @@ -13,13 +37,18 @@ | ||
| 13 | <script lang="ts"> | 37 | <script lang="ts"> |
| 14 | import { defineComponent } from 'vue'; | 38 | import { defineComponent } from 'vue'; |
| 15 | 39 | ||
| 16 | - import { Checkbox } from 'ant-design-vue'; | 40 | + import { Checkbox, Input, Tooltip } from 'ant-design-vue'; |
| 17 | import { BasicForm, useForm } from '/@/components/Form'; | 41 | import { BasicForm, useForm } from '/@/components/Form'; |
| 18 | import { step2Schemas } from '../../config/data'; | 42 | import { step2Schemas } from '../../config/data'; |
| 43 | + import { Icon } from '/@/components/Icon'; | ||
| 44 | + import { buildUUID, randomString } from '/@/utils/uuid'; | ||
| 19 | export default defineComponent({ | 45 | export default defineComponent({ |
| 20 | components: { | 46 | components: { |
| 21 | BasicForm, | 47 | BasicForm, |
| 22 | Checkbox, | 48 | Checkbox, |
| 49 | + Input, | ||
| 50 | + Icon, | ||
| 51 | + Tooltip, | ||
| 23 | }, | 52 | }, |
| 24 | 53 | ||
| 25 | emits: ['prev', 'next'], | 54 | emits: ['prev', 'next'], |
| @@ -105,6 +134,14 @@ | @@ -105,6 +134,14 @@ | ||
| 105 | validate(); | 134 | validate(); |
| 106 | } | 135 | } |
| 107 | 136 | ||
| 137 | + const handleGenerateClientId = () => { | ||
| 138 | + setFieldsValue({ clientId: buildUUID() }); | ||
| 139 | + }; | ||
| 140 | + | ||
| 141 | + const handleGenerateCredentialsId = () => { | ||
| 142 | + setFieldsValue({ credentialsId: randomString() }); | ||
| 143 | + }; | ||
| 144 | + | ||
| 108 | return { | 145 | return { |
| 109 | prevStep, | 146 | prevStep, |
| 110 | registerForm, | 147 | registerForm, |
| @@ -113,6 +150,8 @@ | @@ -113,6 +150,8 @@ | ||
| 113 | validate, | 150 | validate, |
| 114 | resetFieldsValueAndStatus, | 151 | resetFieldsValueAndStatus, |
| 115 | validateStep2Method, | 152 | validateStep2Method, |
| 153 | + handleGenerateClientId, | ||
| 154 | + handleGenerateCredentialsId, | ||
| 116 | }; | 155 | }; |
| 117 | }, | 156 | }, |
| 118 | }); | 157 | }); |
| @@ -55,15 +55,23 @@ | @@ -55,15 +55,23 @@ | ||
| 55 | <a-button type="primary" class="mr-4" @click="manageDeviceToken">管理设备凭证</a-button> | 55 | <a-button type="primary" class="mr-4" @click="manageDeviceToken">管理设备凭证</a-button> |
| 56 | <ManageDeviceTokenModal @register="registerModal" /> | 56 | <ManageDeviceTokenModal @register="registerModal" /> |
| 57 | </div> | 57 | </div> |
| 58 | - <div v-if="deviceDetail?.deviceInfo?.address" class="mt-4"> | 58 | + <div class="mt-4"> |
| 59 | <p>设备位置</p> | 59 | <p>设备位置</p> |
| 60 | - <div ref="mapWrapRef" style="height: 550px; width: 100%"></div> | 60 | + <div v-if="deviceDetail?.deviceInfo?.address"> |
| 61 | + <div ref="mapWrapRef" style="height: 550px; width: 100%"></div> | ||
| 62 | + </div> | ||
| 63 | + <Empty | ||
| 64 | + v-if="!deviceDetail?.deviceInfo?.address" | ||
| 65 | + :image="locationImage" | ||
| 66 | + :imageStyle="{ display: 'flex', 'justify-content': 'center', height: '150px' }" | ||
| 67 | + description="请添加设备地理位置" | ||
| 68 | + /> | ||
| 61 | </div> | 69 | </div> |
| 62 | </div> | 70 | </div> |
| 63 | </template> | 71 | </template> |
| 64 | <script lang="ts"> | 72 | <script lang="ts"> |
| 65 | import { defineComponent, ref, unref, nextTick } from 'vue'; | 73 | import { defineComponent, ref, unref, nextTick } from 'vue'; |
| 66 | - import { Image, Tooltip } from 'ant-design-vue'; | 74 | + import { Empty, Image, Tooltip } from 'ant-design-vue'; |
| 67 | import { descSchema } from '../../config/detail.config'; | 75 | import { descSchema } from '../../config/detail.config'; |
| 68 | import { useAsyncScript } from '/@/hooks/web/useAsyncScript'; | 76 | import { useAsyncScript } from '/@/hooks/web/useAsyncScript'; |
| 69 | import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | 77 | import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; |
| @@ -78,6 +86,8 @@ | @@ -78,6 +86,8 @@ | ||
| 78 | 86 | ||
| 79 | import wz from '/@/assets/images/wz.png'; | 87 | import wz from '/@/assets/images/wz.png'; |
| 80 | import { useAsyncQueue } from '../../../localtion/useAsyncQueue'; | 88 | import { useAsyncQueue } from '../../../localtion/useAsyncQueue'; |
| 89 | + import locationImage from '/@/assets/icons/location.svg'; | ||
| 90 | + | ||
| 81 | export default defineComponent({ | 91 | export default defineComponent({ |
| 82 | components: { | 92 | components: { |
| 83 | Image, | 93 | Image, |
| @@ -86,6 +96,7 @@ | @@ -86,6 +96,7 @@ | ||
| 86 | QuestionCircleOutlined, | 96 | QuestionCircleOutlined, |
| 87 | BasicModal, | 97 | BasicModal, |
| 88 | Tooltip, | 98 | Tooltip, |
| 99 | + Empty, | ||
| 89 | }, | 100 | }, |
| 90 | props: { | 101 | props: { |
| 91 | deviceDetail: { | 102 | deviceDetail: { |
| @@ -197,6 +208,7 @@ | @@ -197,6 +208,7 @@ | ||
| 197 | DeviceTypeEnum, | 208 | DeviceTypeEnum, |
| 198 | copyTopic, | 209 | copyTopic, |
| 199 | remoteConnectiondGateway, | 210 | remoteConnectiondGateway, |
| 211 | + locationImage, | ||
| 200 | }; | 212 | }; |
| 201 | }, | 213 | }, |
| 202 | }); | 214 | }); |
| @@ -286,7 +286,7 @@ | @@ -286,7 +286,7 @@ | ||
| 286 | setTableData(items); | 286 | setTableData(items); |
| 287 | const { setFieldsValue, resetFields } = getForm(); | 287 | const { setFieldsValue, resetFields } = getForm(); |
| 288 | setFieldsValue({ | 288 | setFieldsValue({ |
| 289 | - deviceProfileId: deviceProfileId.value, | 289 | + deviceProfileId: deviceProfileId.value || null, |
| 290 | }); | 290 | }); |
| 291 | if (onCloseVal.value == 1) { | 291 | if (onCloseVal.value == 1) { |
| 292 | resetFields(); | 292 | resetFields(); |
| @@ -2,9 +2,14 @@ | @@ -2,9 +2,14 @@ | ||
| 2 | import { PageWrapper } from '/@/components/Page'; | 2 | import { PageWrapper } from '/@/components/Page'; |
| 3 | import { BasicForm, useForm } from '/@/components/Form'; | 3 | import { BasicForm, useForm } from '/@/components/Form'; |
| 4 | import { List, Button, Tooltip, Card, PaginationProps, Image } from 'ant-design-vue'; | 4 | import { List, Button, Tooltip, Card, PaginationProps, Image } from 'ant-design-vue'; |
| 5 | - import { ReloadOutlined, EyeOutlined, FormOutlined, MoreOutlined } from '@ant-design/icons-vue'; | 5 | + import { ReloadOutlined } from '@ant-design/icons-vue'; |
| 6 | import { computed, onMounted, reactive, ref, unref } from 'vue'; | 6 | import { computed, onMounted, reactive, ref, unref } from 'vue'; |
| 7 | - import { CardLayoutButton, EnumTableCardMode, ModeSwitchButton } from '/@/components/Widget'; | 7 | + import { |
| 8 | + AuthIcon, | ||
| 9 | + CardLayoutButton, | ||
| 10 | + EnumTableCardMode, | ||
| 11 | + ModeSwitchButton, | ||
| 12 | + } from '/@/components/Widget'; | ||
| 8 | import { Authority } from '/@/components/Authority'; | 13 | import { Authority } from '/@/components/Authority'; |
| 9 | import { | 14 | import { |
| 10 | deviceConfigDelete, | 15 | deviceConfigDelete, |
| @@ -12,7 +17,6 @@ | @@ -12,7 +17,6 @@ | ||
| 12 | setDeviceProfileIsDefaultApi, | 17 | setDeviceProfileIsDefaultApi, |
| 13 | } from '/@/api/device/deviceConfigApi'; | 18 | } from '/@/api/device/deviceConfigApi'; |
| 14 | import { ProfileRecord } from '/@/api/device/model/deviceConfigModel'; | 19 | import { ProfileRecord } from '/@/api/device/model/deviceConfigModel'; |
| 15 | - import { Dropdown } from '/@/components/Dropdown'; | ||
| 16 | import { | 20 | import { |
| 17 | defaultObj, | 21 | defaultObj, |
| 18 | searchFormSchema, | 22 | searchFormSchema, |
| @@ -20,14 +24,13 @@ | @@ -20,14 +24,13 @@ | ||
| 20 | ProductPermission, | 24 | ProductPermission, |
| 21 | } from './device.profile.data'; | 25 | } from './device.profile.data'; |
| 22 | import { useMessage } from '/@/hooks/web/useMessage'; | 26 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 23 | - import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm'; | ||
| 24 | import DeviceProfileModal from './DeviceProfileModal.vue'; | 27 | import DeviceProfileModal from './DeviceProfileModal.vue'; |
| 25 | import DeviceProfileDrawer from './DeviceProfileDrawer.vue'; | 28 | import DeviceProfileDrawer from './DeviceProfileDrawer.vue'; |
| 26 | import { useModal } from '/@/components/Modal'; | 29 | import { useModal } from '/@/components/Modal'; |
| 27 | import { useDrawer } from '/@/components/Drawer'; | 30 | import { useDrawer } from '/@/components/Drawer'; |
| 28 | import productDefault from '/@/assets/icons/product-default.svg'; | 31 | import productDefault from '/@/assets/icons/product-default.svg'; |
| 29 | - import { usePermission } from '/@/hooks/web/usePermission'; | ||
| 30 | import { useRoute } from 'vue-router'; | 32 | import { useRoute } from 'vue-router'; |
| 33 | + import AuthDropDown from '/@/components/Widget/AuthDropDown.vue'; | ||
| 31 | 34 | ||
| 32 | defineProps<{ | 35 | defineProps<{ |
| 33 | mode: EnumTableCardMode; | 36 | mode: EnumTableCardMode; |
| @@ -42,7 +45,6 @@ | @@ -42,7 +45,6 @@ | ||
| 42 | const IMAGE_FALLBACK = productDefault; | 45 | const IMAGE_FALLBACK = productDefault; |
| 43 | 46 | ||
| 44 | const { createMessage } = useMessage(); | 47 | const { createMessage } = useMessage(); |
| 45 | - const { createSyncConfirm } = useSyncConfirm(); | ||
| 46 | 48 | ||
| 47 | const [register, { getFieldsValue, setFieldsValue }] = useForm({ | 49 | const [register, { getFieldsValue, setFieldsValue }] = useForm({ |
| 48 | showAdvancedButton: true, | 50 | showAdvancedButton: true, |
| @@ -72,7 +74,7 @@ | @@ -72,7 +74,7 @@ | ||
| 72 | 74 | ||
| 73 | const dataSource = ref<ProfileRecord[]>([]); | 75 | const dataSource = ref<ProfileRecord[]>([]); |
| 74 | 76 | ||
| 75 | - const colNumber = ref(4); | 77 | + const colNumber = ref(5); |
| 76 | 78 | ||
| 77 | const getSelectAllFlag = computed(() => { | 79 | const getSelectAllFlag = computed(() => { |
| 78 | return unref(dataSource).every((item) => item.checked); | 80 | return unref(dataSource).every((item) => item.checked); |
| @@ -105,40 +107,6 @@ | @@ -105,40 +107,6 @@ | ||
| 105 | } | 107 | } |
| 106 | }; | 108 | }; |
| 107 | 109 | ||
| 108 | - const { hasPermission } = usePermission(); | ||
| 109 | - | ||
| 110 | - const getHasDeleteFlag = computed(() => { | ||
| 111 | - return hasPermission(ProductPermission.DELETE); | ||
| 112 | - }); | ||
| 113 | - | ||
| 114 | - const getHasDetailFlag = computed(() => { | ||
| 115 | - return hasPermission(ProductPermission.DETAIL); | ||
| 116 | - }); | ||
| 117 | - | ||
| 118 | - const getHasUpdateFlag = computed(() => { | ||
| 119 | - return hasPermission(ProductPermission.UPDATE); | ||
| 120 | - }); | ||
| 121 | - | ||
| 122 | - const getDropDownList = (record: ProfileRecord) => { | ||
| 123 | - const list = [ | ||
| 124 | - { | ||
| 125 | - text: '默认', | ||
| 126 | - event: DropMenuEvent.SET_DEFAULT, | ||
| 127 | - icon: 'ant-design:unordered-list-outlined', | ||
| 128 | - onClick: handleSetDefault.bind(null, record), | ||
| 129 | - }, | ||
| 130 | - ]; | ||
| 131 | - if (unref(getHasDeleteFlag)) { | ||
| 132 | - list.push({ | ||
| 133 | - text: '删除', | ||
| 134 | - event: DropMenuEvent.DELETE, | ||
| 135 | - icon: 'ant-design:delete-outlined', | ||
| 136 | - onClick: handleDelete.bind(null, [record.id]), | ||
| 137 | - }); | ||
| 138 | - } | ||
| 139 | - return list; | ||
| 140 | - }; | ||
| 141 | - | ||
| 142 | const handleModeChange = (mode: EnumTableCardMode) => { | 110 | const handleModeChange = (mode: EnumTableCardMode) => { |
| 143 | emit('changeMode', mode); | 111 | emit('changeMode', mode); |
| 144 | }; | 112 | }; |
| @@ -163,12 +131,10 @@ | @@ -163,12 +131,10 @@ | ||
| 163 | }; | 131 | }; |
| 164 | 132 | ||
| 165 | const handleShowDetail = (record: ProfileRecord) => { | 133 | const handleShowDetail = (record: ProfileRecord) => { |
| 166 | - if (!unref(getHasDetailFlag)) return; | ||
| 167 | openDrawer(true, { record }); | 134 | openDrawer(true, { record }); |
| 168 | }; | 135 | }; |
| 169 | 136 | ||
| 170 | const handleUpdate = (record: ProfileRecord) => { | 137 | const handleUpdate = (record: ProfileRecord) => { |
| 171 | - if (!unref(getHasUpdateFlag)) return; | ||
| 172 | openModal(true, { | 138 | openModal(true, { |
| 173 | record, | 139 | record, |
| 174 | isUpdate: true, | 140 | isUpdate: true, |
| @@ -177,7 +143,6 @@ | @@ -177,7 +143,6 @@ | ||
| 177 | 143 | ||
| 178 | const handleDelete = async (id: string[]) => { | 144 | const handleDelete = async (id: string[]) => { |
| 179 | try { | 145 | try { |
| 180 | - await createSyncConfirm({ iconType: 'warning', content: '是否确认删除操作?' }); | ||
| 181 | await deviceConfigDelete(id); | 146 | await deviceConfigDelete(id); |
| 182 | createMessage.success('删除成功'); | 147 | createMessage.success('删除成功'); |
| 183 | await getDataSource(); | 148 | await getDataSource(); |
| @@ -268,22 +233,43 @@ | @@ -268,22 +233,43 @@ | ||
| 268 | </template> | 233 | </template> |
| 269 | <template class="ant-card-actions" #actions> | 234 | <template class="ant-card-actions" #actions> |
| 270 | <Tooltip title="详情"> | 235 | <Tooltip title="详情"> |
| 271 | - <EyeOutlined | ||
| 272 | - :class="getHasDetailFlag ? '' : '!cursor-not-allowed !text-gray-200'" | ||
| 273 | - key="setting" | 236 | + <AuthIcon |
| 237 | + :auth="ProductPermission.DETAIL" | ||
| 238 | + class="!text-lg" | ||
| 239 | + icon="ant-design:eye-outlined" | ||
| 274 | @click.stop="handleShowDetail(item)" | 240 | @click.stop="handleShowDetail(item)" |
| 275 | /> | 241 | /> |
| 276 | </Tooltip> | 242 | </Tooltip> |
| 277 | <Tooltip title="编辑"> | 243 | <Tooltip title="编辑"> |
| 278 | - <FormOutlined | ||
| 279 | - :class="getHasUpdateFlag ? '' : '!cursor-not-allowed !text-gray-200'" | ||
| 280 | - key="edit" | 244 | + <AuthIcon |
| 245 | + :auth="ProductPermission.UPDATE" | ||
| 246 | + class="!text-lg" | ||
| 247 | + icon="ant-design:form-outlined" | ||
| 281 | @click.stop="handleUpdate(item)" | 248 | @click.stop="handleUpdate(item)" |
| 282 | /> | 249 | /> |
| 283 | </Tooltip> | 250 | </Tooltip> |
| 284 | - <Dropdown :trigger="['hover']" :drop-menu-list="getDropDownList(item)"> | ||
| 285 | - <MoreOutlined @click.stop class="transform rotate-90" /> | ||
| 286 | - </Dropdown> | 251 | + <AuthDropDown |
| 252 | + @click.stop | ||
| 253 | + :trigger="['hover']" | ||
| 254 | + :drop-menu-list="[ | ||
| 255 | + { | ||
| 256 | + text: '默认', | ||
| 257 | + event: DropMenuEvent.SET_DEFAULT, | ||
| 258 | + icon: 'ant-design:unordered-list-outlined', | ||
| 259 | + onClick: handleSetDefault.bind(null, item), | ||
| 260 | + }, | ||
| 261 | + { | ||
| 262 | + text: '删除', | ||
| 263 | + event: DropMenuEvent.DELETE, | ||
| 264 | + auth: ProductPermission.DELETE, | ||
| 265 | + icon: 'ant-design:delete-outlined', | ||
| 266 | + popconfirm: { | ||
| 267 | + title: '是否确认删除操作?', | ||
| 268 | + onConfirm: handleDelete.bind(null, [item.id]), | ||
| 269 | + }, | ||
| 270 | + }, | ||
| 271 | + ]" | ||
| 272 | + /> | ||
| 287 | </template> | 273 | </template> |
| 288 | <Card.Meta> | 274 | <Card.Meta> |
| 289 | <template #title> | 275 | <template #title> |
| @@ -308,7 +294,10 @@ | @@ -308,7 +294,10 @@ | ||
| 308 | 294 | ||
| 309 | <style lang="less" scoped> | 295 | <style lang="less" scoped> |
| 310 | .profile-list:deep(.ant-image-img) { | 296 | .profile-list:deep(.ant-image-img) { |
| 311 | - width: 100% !important; | ||
| 312 | - height: 100% !important; | 297 | + @apply !w-full !h-full; |
| 298 | + } | ||
| 299 | + | ||
| 300 | + .profile-list:deep(.ant-card-body) { | ||
| 301 | + @apply !p-4; | ||
| 313 | } | 302 | } |
| 314 | </style> | 303 | </style> |
| @@ -28,10 +28,13 @@ | @@ -28,10 +28,13 @@ | ||
| 28 | field: 'scriptName', | 28 | field: 'scriptName', |
| 29 | label: '转换脚本', | 29 | label: '转换脚本', |
| 30 | render: (value: string) => { | 30 | render: (value: string) => { |
| 31 | - return h('div', [ | ||
| 32 | - h(Tag, { color: 'blue' }, () => value), | ||
| 33 | - h(Button, { type: 'link', onClick: handleTestScript }, () => '测试脚本'), | ||
| 34 | - ]); | 31 | + return ( |
| 32 | + value && | ||
| 33 | + h('div', [ | ||
| 34 | + h(Tag, { color: 'blue' }, () => value), | ||
| 35 | + h(Button, { type: 'link', onClick: handleTestScript }, () => '测试脚本'), | ||
| 36 | + ]) | ||
| 37 | + ); | ||
| 35 | }, | 38 | }, |
| 36 | }, | 39 | }, |
| 37 | ], | 40 | ], |
| @@ -261,12 +261,14 @@ export const columns: BasicColumn[] = [ | @@ -261,12 +261,14 @@ export const columns: BasicColumn[] = [ | ||
| 261 | title: '默认配置', | 261 | title: '默认配置', |
| 262 | dataIndex: 'default', | 262 | dataIndex: 'default', |
| 263 | width: 80, | 263 | width: 80, |
| 264 | - format: (text) => (text ? '是' : '否'), | 264 | + customRender: ({ text }) => |
| 265 | + text ? h(Tag, { color: 'blue' }, () => '是') : h(Tag, { color: 'red' }, () => '否'), | ||
| 265 | }, | 266 | }, |
| 266 | { | 267 | { |
| 267 | title: '描述', | 268 | title: '描述', |
| 268 | dataIndex: 'description', | 269 | dataIndex: 'description', |
| 269 | width: 90, | 270 | width: 90, |
| 271 | + ellipsis: true, | ||
| 270 | }, | 272 | }, |
| 271 | { | 273 | { |
| 272 | title: '创建时间', | 274 | title: '创建时间', |
| @@ -8,7 +8,9 @@ | @@ -8,7 +8,9 @@ | ||
| 8 | placeholder="请选择转换脚本" | 8 | placeholder="请选择转换脚本" |
| 9 | v-model:value="selectScript.script" | 9 | v-model:value="selectScript.script" |
| 10 | style="width: 305px" | 10 | style="width: 305px" |
| 11 | + show-search | ||
| 11 | :options="selectOptions" | 12 | :options="selectOptions" |
| 13 | + :filter-option="handleSearch" | ||
| 12 | allowClear | 14 | allowClear |
| 13 | /> | 15 | /> |
| 14 | </div> | 16 | </div> |
| @@ -113,6 +115,11 @@ | @@ -113,6 +115,11 @@ | ||
| 113 | const setFormData = (v) => { | 115 | const setFormData = (v) => { |
| 114 | selectScript.script = v?.scriptId; | 116 | selectScript.script = v?.scriptId; |
| 115 | }; | 117 | }; |
| 118 | + | ||
| 119 | + const handleSearch = (inputValue: string, option: Record<'label' | 'value', string>) => { | ||
| 120 | + return option.label.includes(inputValue); | ||
| 121 | + }; | ||
| 122 | + | ||
| 116 | defineExpose({ | 123 | defineExpose({ |
| 117 | getFormData, | 124 | getFormData, |
| 118 | resetFormData, | 125 | resetFormData, |
| @@ -16,6 +16,14 @@ | @@ -16,6 +16,14 @@ | ||
| 16 | <TableAction | 16 | <TableAction |
| 17 | :actions="[ | 17 | :actions="[ |
| 18 | { | 18 | { |
| 19 | + label: '进入', | ||
| 20 | + icon: 'ant-design:login-outlined', | ||
| 21 | + tooltip: '以租户管理员身份登录', | ||
| 22 | + onClick: handleLoginTenantAdmin.bind(null, record), | ||
| 23 | + }, | ||
| 24 | + ]" | ||
| 25 | + :drop-down-actions="[ | ||
| 26 | + { | ||
| 19 | label: '短信通知', | 27 | label: '短信通知', |
| 20 | icon: 'ant-design:send-outlined', | 28 | icon: 'ant-design:send-outlined', |
| 21 | tooltip: '发送通知短信', | 29 | tooltip: '发送通知短信', |
| @@ -94,6 +102,12 @@ | @@ -94,6 +102,12 @@ | ||
| 94 | import { MessageTypeEnum, SendResetPasswordEmailMsg } from '/@/api/tenant/tenantInfo'; | 102 | import { MessageTypeEnum, SendResetPasswordEmailMsg } from '/@/api/tenant/tenantInfo'; |
| 95 | import { useMessage } from '/@/hooks/web/useMessage'; | 103 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 96 | import { Authority } from '/@/components/Authority'; | 104 | import { Authority } from '/@/components/Authority'; |
| 105 | + import { getMyInfo, getPermCode, getUserToken } from '/@/api/sys/user'; | ||
| 106 | + import { useUserStore } from '/@/store/modules/user'; | ||
| 107 | + import { usePermissionStore } from '/@/store/modules/permission'; | ||
| 108 | + import { RoleEnum } from '/@/enums/roleEnum'; | ||
| 109 | + import { useGo } from '/@/hooks/web/usePage'; | ||
| 110 | + import { PageEnum } from '/@/enums/pageEnum'; | ||
| 97 | 111 | ||
| 98 | export default defineComponent({ | 112 | export default defineComponent({ |
| 99 | name: 'TenantAdminDrawer', | 113 | name: 'TenantAdminDrawer', |
| @@ -198,10 +212,15 @@ | @@ -198,10 +212,15 @@ | ||
| 198 | fixed: 'right', | 212 | fixed: 'right', |
| 199 | }, | 213 | }, |
| 200 | }); | 214 | }); |
| 215 | + | ||
| 216 | + let firstEnterFlag = true; | ||
| 201 | //默认传递页面数据 | 217 | //默认传递页面数据 |
| 202 | const [tenantAdminDrawer, { closeDrawer }] = useDrawerInner(async (data) => { | 218 | const [tenantAdminDrawer, { closeDrawer }] = useDrawerInner(async (data) => { |
| 203 | tenantId.value = data.record.tenantId; | 219 | tenantId.value = data.record.tenantId; |
| 204 | - reload(); | 220 | + !firstEnterFlag && reload(); |
| 221 | + if (firstEnterFlag) { | ||
| 222 | + firstEnterFlag = false; | ||
| 223 | + } | ||
| 205 | }); | 224 | }); |
| 206 | 225 | ||
| 207 | //提交按钮 | 226 | //提交按钮 |
| @@ -213,6 +232,24 @@ | @@ -213,6 +232,24 @@ | ||
| 213 | reload(); | 232 | reload(); |
| 214 | } | 233 | } |
| 215 | 234 | ||
| 235 | + const userStore = useUserStore(); | ||
| 236 | + const permissionStore = usePermissionStore(); | ||
| 237 | + const go = useGo(); | ||
| 238 | + async function handleLoginTenantAdmin(record: { tbUser: string; id: string }) { | ||
| 239 | + try { | ||
| 240 | + const { token, refreshToken } = await getUserToken(record.id); | ||
| 241 | + userStore.storeToken(token, refreshToken); | ||
| 242 | + const userInfo = await getMyInfo(); | ||
| 243 | + const permissionList = await getPermCode(); | ||
| 244 | + permissionStore.setPermCodeList(permissionList); | ||
| 245 | + userStore.setUserInfo(userInfo); | ||
| 246 | + userStore.setRoleList(userInfo.roles as RoleEnum[]); | ||
| 247 | + go(PageEnum.BASE_HOME); | ||
| 248 | + } catch (error) { | ||
| 249 | + } finally { | ||
| 250 | + } | ||
| 251 | + } | ||
| 252 | + | ||
| 216 | return { | 253 | return { |
| 217 | tenantAdminDrawer, | 254 | tenantAdminDrawer, |
| 218 | handleCreateTenantAdmin, | 255 | handleCreateTenantAdmin, |
| @@ -225,6 +262,7 @@ | @@ -225,6 +262,7 @@ | ||
| 225 | handleDelete, | 262 | handleDelete, |
| 226 | handleResetPassword, | 263 | handleResetPassword, |
| 227 | handleSendMsg, | 264 | handleSendMsg, |
| 265 | + handleLoginTenantAdmin, | ||
| 228 | }; | 266 | }; |
| 229 | }, | 267 | }, |
| 230 | }); | 268 | }); |
| @@ -72,7 +72,9 @@ | @@ -72,7 +72,9 @@ | ||
| 72 | > | 72 | > |
| 73 | <Tooltip :title="item.deviceName" placement="topLeft"> | 73 | <Tooltip :title="item.deviceName" placement="topLeft"> |
| 74 | <div class="flex p-1"> | 74 | <div class="flex p-1"> |
| 75 | - <div class="truncate font-bold">{{ item.deviceRename || item.deviceName }}</div> | 75 | + <div v-if="item.componentInfo.showDeviceName" class="truncate font-bold"> |
| 76 | + {{ item.deviceRename || item.deviceName }} | ||
| 77 | + </div> | ||
| 76 | </div> | 78 | </div> |
| 77 | </Tooltip> | 79 | </Tooltip> |
| 78 | </div> | 80 | </div> |
| @@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
| 33 | return decode((ROUTE.params as DataComponentRouteParams).boardId as string); | 33 | return decode((ROUTE.params as DataComponentRouteParams).boardId as string); |
| 34 | }); | 34 | }); |
| 35 | 35 | ||
| 36 | - const frontId = ref(FrontComponent.TEXT_COMPONENT_1); | 36 | + const frontId = ref(); |
| 37 | 37 | ||
| 38 | const isEdit = ref(false); | 38 | const isEdit = ref(false); |
| 39 | 39 | ||
| @@ -48,6 +48,7 @@ | @@ -48,6 +48,7 @@ | ||
| 48 | const [register, { closeModal, changeOkLoading }] = useModalInner( | 48 | const [register, { closeModal, changeOkLoading }] = useModalInner( |
| 49 | (data: { isEdit: boolean; record?: DataBoardLayoutInfo }) => { | 49 | (data: { isEdit: boolean; record?: DataBoardLayoutInfo }) => { |
| 50 | componentRecord.value = data.record || ({} as unknown as DataBoardLayoutInfo); | 50 | componentRecord.value = data.record || ({} as unknown as DataBoardLayoutInfo); |
| 51 | + if (!unref(isEdit)) frontId.value = FrontComponent.TEXT_COMPONENT_1; | ||
| 51 | frontId.value = | 52 | frontId.value = |
| 52 | (data.record?.record?.frontId as FrontComponent) || FrontComponent.TEXT_COMPONENT_1; | 53 | (data.record?.record?.frontId as FrontComponent) || FrontComponent.TEXT_COMPONENT_1; |
| 53 | isEdit.value = data.isEdit || false; | 54 | isEdit.value = data.isEdit || false; |
| 1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
| 2 | - import { ref, onMounted, unref } from 'vue'; | 2 | + import { ref, onMounted, unref, computed } from 'vue'; |
| 3 | import { FrontComponent } from '../../../const/const'; | 3 | import { FrontComponent } from '../../../const/const'; |
| 4 | import { DataSourceField, dataSourceSchema } from '../../config/basicConfiguration'; | 4 | import { DataSourceField, dataSourceSchema } from '../../config/basicConfiguration'; |
| 5 | import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; | 5 | import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; |
| @@ -7,12 +7,18 @@ | @@ -7,12 +7,18 @@ | ||
| 7 | import BasicForm from '/@/components/Form/src/BasicForm.vue'; | 7 | import BasicForm from '/@/components/Form/src/BasicForm.vue'; |
| 8 | const formEl = ref<Nullable<FormActionType>>(null); | 8 | const formEl = ref<Nullable<FormActionType>>(null); |
| 9 | 9 | ||
| 10 | - defineProps<{ | 10 | + const props = defineProps<{ |
| 11 | frontId?: FrontComponent; | 11 | frontId?: FrontComponent; |
| 12 | }>(); | 12 | }>(); |
| 13 | 13 | ||
| 14 | defineExpose({ formActionType: formEl }); | 14 | defineExpose({ formActionType: formEl }); |
| 15 | 15 | ||
| 16 | + const getDataSchema = computed(() => { | ||
| 17 | + const { frontId } = props; | ||
| 18 | + if (!frontId) return []; | ||
| 19 | + return dataSourceSchema(frontId); | ||
| 20 | + }); | ||
| 21 | + | ||
| 16 | onMounted(() => { | 22 | onMounted(() => { |
| 17 | unref(formEl)?.setFieldsValue({ [DataSourceField.DEVICE_TYPE]: DeviceTypeEnum.SENSOR }); | 23 | unref(formEl)?.setFieldsValue({ [DataSourceField.DEVICE_TYPE]: DeviceTypeEnum.SENSOR }); |
| 18 | }); | 24 | }); |
| @@ -21,7 +27,7 @@ | @@ -21,7 +27,7 @@ | ||
| 21 | <template> | 27 | <template> |
| 22 | <BasicForm | 28 | <BasicForm |
| 23 | ref="formEl" | 29 | ref="formEl" |
| 24 | - :schemas="dataSourceSchema($props.frontId)" | 30 | + :schemas="getDataSchema" |
| 25 | class="w-full flex-1 data-source-form" | 31 | class="w-full flex-1 data-source-form" |
| 26 | :show-action-button-group="false" | 32 | :show-action-button-group="false" |
| 27 | :row-props="{ | 33 | :row-props="{ |
| @@ -61,6 +61,7 @@ | @@ -61,6 +61,7 @@ | ||
| 61 | icon: value.icon || null, | 61 | icon: value.icon || null, |
| 62 | iconColor: value.iconColor || null, | 62 | iconColor: value.iconColor || null, |
| 63 | unit: value.unit || null, | 63 | unit: value.unit || null, |
| 64 | + showDeviceName: value.showDeviceName, | ||
| 64 | gradientInfo: [ | 65 | gradientInfo: [ |
| 65 | { key: Gradient.FIRST, value: value.firstPhaseValue, color: value.firstPhaseColor }, | 66 | { key: Gradient.FIRST, value: value.firstPhaseValue, color: value.firstPhaseColor }, |
| 66 | { key: Gradient.SECOND, value: value.secondPhaseValue, color: value.secondPhaseColor }, | 67 | { key: Gradient.SECOND, value: value.secondPhaseValue, color: value.secondPhaseColor }, |
| @@ -149,6 +149,7 @@ export const dataSourceSchema = (frontId?: FrontComponent): FormSchema[] => { | @@ -149,6 +149,7 @@ export const dataSourceSchema = (frontId?: FrontComponent): FormSchema[] => { | ||
| 149 | const { setFieldsValue } = formActionType; | 149 | const { setFieldsValue } = formActionType; |
| 150 | const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID]; | 150 | const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID]; |
| 151 | const deviceType = formModel[DataSourceField.DEVICE_TYPE]; | 151 | const deviceType = formModel[DataSourceField.DEVICE_TYPE]; |
| 152 | + if (![deviceType, deviceProfileId].every(Boolean)) return {}; | ||
| 152 | return { | 153 | return { |
| 153 | api: async () => { | 154 | api: async () => { |
| 154 | if (!deviceType) return []; | 155 | if (!deviceType) return []; |
| @@ -253,6 +254,7 @@ export const dataSourceSchema = (frontId?: FrontComponent): FormSchema[] => { | @@ -253,6 +254,7 @@ export const dataSourceSchema = (frontId?: FrontComponent): FormSchema[] => { | ||
| 253 | componentProps({ formModel }) { | 254 | componentProps({ formModel }) { |
| 254 | const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID]; | 255 | const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID]; |
| 255 | const transportType = formModel[DataSourceField.TRANSPORT_TYPE]; | 256 | const transportType = formModel[DataSourceField.TRANSPORT_TYPE]; |
| 257 | + if (![deviceProfileId, transportType].every(Boolean)) return {}; | ||
| 256 | return { | 258 | return { |
| 257 | api: async () => { | 259 | api: async () => { |
| 258 | try { | 260 | try { |
| @@ -12,6 +12,7 @@ export interface VisualOptionParams { | @@ -12,6 +12,7 @@ export interface VisualOptionParams { | ||
| 12 | [visualOptionField.FIRST_PHASE_VALUE]: string; | 12 | [visualOptionField.FIRST_PHASE_VALUE]: string; |
| 13 | [visualOptionField.SECOND_PHASE_VALUE]: string; | 13 | [visualOptionField.SECOND_PHASE_VALUE]: string; |
| 14 | [visualOptionField.THIRD_PHASE_VALUE]: string; | 14 | [visualOptionField.THIRD_PHASE_VALUE]: string; |
| 15 | + [visualOptionField.SHOW_DEVICE_NAME]: string; | ||
| 15 | } | 16 | } |
| 16 | 17 | ||
| 17 | export enum visualOptionField { | 18 | export enum visualOptionField { |
| @@ -25,6 +26,7 @@ export enum visualOptionField { | @@ -25,6 +26,7 @@ export enum visualOptionField { | ||
| 25 | FIRST_PHASE_VALUE = 'firstPhaseValue', | 26 | FIRST_PHASE_VALUE = 'firstPhaseValue', |
| 26 | SECOND_PHASE_VALUE = 'secondPhaseValue', | 27 | SECOND_PHASE_VALUE = 'secondPhaseValue', |
| 27 | THIRD_PHASE_VALUE = 'thirdPhaseValue', | 28 | THIRD_PHASE_VALUE = 'thirdPhaseValue', |
| 29 | + SHOW_DEVICE_NAME = 'showDeviceName', | ||
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | export const modeOne: FormSchema[] = [ | 32 | export const modeOne: FormSchema[] = [ |
| @@ -37,6 +39,11 @@ export const modeOne: FormSchema[] = [ | @@ -37,6 +39,11 @@ export const modeOne: FormSchema[] = [ | ||
| 37 | defaultValue: '#000', | 39 | defaultValue: '#000', |
| 38 | }, | 40 | }, |
| 39 | }, | 41 | }, |
| 42 | + { | ||
| 43 | + field: visualOptionField.SHOW_DEVICE_NAME, | ||
| 44 | + label: '显示设备名称', | ||
| 45 | + component: 'Checkbox', | ||
| 46 | + }, | ||
| 40 | ]; | 47 | ]; |
| 41 | 48 | ||
| 42 | export const modeTwo: FormSchema[] = [ | 49 | export const modeTwo: FormSchema[] = [ |
| @@ -78,6 +85,11 @@ export const modeTwo: FormSchema[] = [ | @@ -78,6 +85,11 @@ export const modeTwo: FormSchema[] = [ | ||
| 78 | }; | 85 | }; |
| 79 | }, | 86 | }, |
| 80 | }, | 87 | }, |
| 88 | + { | ||
| 89 | + field: visualOptionField.SHOW_DEVICE_NAME, | ||
| 90 | + label: '显示设备名称', | ||
| 91 | + component: 'Checkbox', | ||
| 92 | + }, | ||
| 81 | ]; | 93 | ]; |
| 82 | 94 | ||
| 83 | export const modeThree: FormSchema[] = [ | 95 | export const modeThree: FormSchema[] = [ |
| @@ -156,6 +168,11 @@ export const modeThree: FormSchema[] = [ | @@ -156,6 +168,11 @@ export const modeThree: FormSchema[] = [ | ||
| 156 | }; | 168 | }; |
| 157 | }, | 169 | }, |
| 158 | }, | 170 | }, |
| 171 | + { | ||
| 172 | + field: visualOptionField.SHOW_DEVICE_NAME, | ||
| 173 | + label: '显示设备名称', | ||
| 174 | + component: 'Checkbox', | ||
| 175 | + }, | ||
| 159 | ]; | 176 | ]; |
| 160 | 177 | ||
| 161 | export const modeFour: FormSchema[] = [ | 178 | export const modeFour: FormSchema[] = [ |
| @@ -176,6 +193,11 @@ export const modeFour: FormSchema[] = [ | @@ -176,6 +193,11 @@ export const modeFour: FormSchema[] = [ | ||
| 176 | placeholder: '请输入数值单位', | 193 | placeholder: '请输入数值单位', |
| 177 | }, | 194 | }, |
| 178 | }, | 195 | }, |
| 196 | + { | ||
| 197 | + field: visualOptionField.SHOW_DEVICE_NAME, | ||
| 198 | + label: '显示设备名称', | ||
| 199 | + component: 'Checkbox', | ||
| 200 | + }, | ||
| 179 | ]; | 201 | ]; |
| 180 | 202 | ||
| 181 | export const modeFive: FormSchema[] = [ | 203 | export const modeFive: FormSchema[] = [ |
| @@ -209,6 +231,11 @@ export const modeFive: FormSchema[] = [ | @@ -209,6 +231,11 @@ export const modeFive: FormSchema[] = [ | ||
| 209 | }; | 231 | }; |
| 210 | }, | 232 | }, |
| 211 | }, | 233 | }, |
| 234 | + { | ||
| 235 | + field: visualOptionField.SHOW_DEVICE_NAME, | ||
| 236 | + label: '显示设备名称', | ||
| 237 | + component: 'Checkbox', | ||
| 238 | + }, | ||
| 212 | ]; | 239 | ]; |
| 213 | 240 | ||
| 214 | export const schemasMap = new Map<FrontComponent, FormSchema[]>(); | 241 | export const schemasMap = new Map<FrontComponent, FormSchema[]>(); |