Commit ea33b4b91bc25be8ad2b15a8b2825e7436c959d7
Merge branch 'ww' into 'main'
fix: BUG in teambition See merge request huang/yun-teng-iot-front!377
Showing
37 changed files
with
729 additions
and
289 deletions
1 | import { defHttp } from '/@/utils/http/axios'; | 1 | import { defHttp } from '/@/utils/http/axios'; |
2 | import type { | 2 | import type { |
3 | queryPageParams, | 3 | queryPageParams, |
4 | - ConfigurationModal, | ||
5 | ConfigurationCenterParams, | 4 | ConfigurationCenterParams, |
6 | ConfigurationCenterInfo, | 5 | ConfigurationCenterInfo, |
6 | + ConfigurationCenterItemsModal, | ||
7 | } from './model/configurationCenterModal'; | 7 | } from './model/configurationCenterModal'; |
8 | import { getPageData } from '../../base'; | 8 | import { getPageData } from '../../base'; |
9 | enum API { | 9 | enum API { |
@@ -11,7 +11,7 @@ enum API { | @@ -11,7 +11,7 @@ enum API { | ||
11 | } | 11 | } |
12 | 12 | ||
13 | export const getPage = (params: queryPageParams) => { | 13 | export const getPage = (params: queryPageParams) => { |
14 | - return getPageData<ConfigurationModal>(params, API.basicUrl); | 14 | + return getPageData<ConfigurationCenterItemsModal>(params, API.basicUrl); |
15 | }; | 15 | }; |
16 | 16 | ||
17 | export const saveConfigurationCenter = (params: ConfigurationCenterParams) => { | 17 | export const saveConfigurationCenter = (params: ConfigurationCenterParams) => { |
1 | import { BasicPageParams } from '/@/api/model/baseModel'; | 1 | import { BasicPageParams } from '/@/api/model/baseModel'; |
2 | -import { ContactParams } from '/@/api/alarm/contact/model/alarmContactModal'; | ||
3 | 2 | ||
4 | -interface ConfigurationCenterItemsModal { | 3 | +export interface ConfigurationCenterItemsModal { |
5 | id: string; | 4 | id: string; |
6 | name: string; | 5 | name: string; |
7 | createTime: string; | 6 | createTime: string; |
8 | creator: string; | 7 | creator: string; |
9 | remark: string; | 8 | remark: string; |
10 | } | 9 | } |
11 | -export type queryPageParams = BasicPageParams & { name: string; organizationId: string }; | 10 | +export type queryPageParams = BasicPageParams & { |
11 | + name?: Nullable<string>; | ||
12 | + organizationId?: Nullable<number>; | ||
13 | +}; | ||
12 | 14 | ||
13 | export interface ConfigurationModal { | 15 | export interface ConfigurationModal { |
14 | items: ConfigurationCenterItemsModal[]; | 16 | items: ConfigurationCenterItemsModal[]; |
@@ -47,8 +47,8 @@ export default defineComponent({ | @@ -47,8 +47,8 @@ export default defineComponent({ | ||
47 | const { | 47 | const { |
48 | getContentMode, | 48 | getContentMode, |
49 | getShowFooter, | 49 | getShowFooter, |
50 | - getShowBreadCrumb, | ||
51 | - getShowBreadCrumbIcon, | 50 | + // getShowBreadCrumb, |
51 | + // getShowBreadCrumbIcon, | ||
52 | getShowLogo, | 52 | getShowLogo, |
53 | getFullContent, | 53 | getFullContent, |
54 | getColorWeak, | 54 | getColorWeak, |
@@ -281,7 +281,7 @@ export default defineComponent({ | @@ -281,7 +281,7 @@ export default defineComponent({ | ||
281 | function renderContent() { | 281 | function renderContent() { |
282 | return ( | 282 | return ( |
283 | <> | 283 | <> |
284 | - <SwitchItem | 284 | + {/* <SwitchItem |
285 | title={t('layout.setting.breadcrumb')} | 285 | title={t('layout.setting.breadcrumb')} |
286 | event={HandlerEnum.SHOW_BREADCRUMB} | 286 | event={HandlerEnum.SHOW_BREADCRUMB} |
287 | def={unref(getShowBreadCrumb)} | 287 | def={unref(getShowBreadCrumb)} |
@@ -299,7 +299,7 @@ export default defineComponent({ | @@ -299,7 +299,7 @@ export default defineComponent({ | ||
299 | title={t('layout.setting.tabs')} | 299 | title={t('layout.setting.tabs')} |
300 | event={HandlerEnum.TABS_SHOW} | 300 | event={HandlerEnum.TABS_SHOW} |
301 | def={unref(getShowMultipleTab)} | 301 | def={unref(getShowMultipleTab)} |
302 | - /> | 302 | + /> */} |
303 | 303 | ||
304 | <SwitchItem | 304 | <SwitchItem |
305 | title={t('layout.setting.tabsRedoBtn')} | 305 | title={t('layout.setting.tabsRedoBtn')} |
@@ -250,7 +250,7 @@ export const DeviceProfileIdMaxLength: Rule[] = [ | @@ -250,7 +250,7 @@ export const DeviceProfileIdMaxLength: Rule[] = [ | ||
250 | required: true, | 250 | required: true, |
251 | validator: (_, value: string) => { | 251 | validator: (_, value: string) => { |
252 | if (String(value).length > 36) { | 252 | if (String(value).length > 36) { |
253 | - return Promise.reject('设备配置长度不超过36字'); | 253 | + return Promise.reject('所属产品长度不超过36字'); |
254 | } | 254 | } |
255 | return Promise.resolve(); | 255 | return Promise.resolve(); |
256 | }, | 256 | }, |
@@ -22,8 +22,8 @@ export enum AlarmPermissionKey { | @@ -22,8 +22,8 @@ export enum AlarmPermissionKey { | ||
22 | export function useAlarmNotify(params: UseAlarmNotifyParams = {}) { | 22 | export function useAlarmNotify(params: UseAlarmNotifyParams = {}) { |
23 | const { | 23 | const { |
24 | alarmNotifyStatus = AlarmStatus.ACTIVE_UN_ACK, | 24 | alarmNotifyStatus = AlarmStatus.ACTIVE_UN_ACK, |
25 | - interval = import.meta.env.VITE_ALARM_NOTIFY_POLLING_INTERVAL_TIME, | ||
26 | - duration = import.meta.env.VITE_ALARM_NOTIFY_DURATION, | 25 | + interval = import.meta.env.VITE_ALARM_NOTIFY_POLLING_INTERVAL_TIME || 60000, |
26 | + duration = import.meta.env.VITE_ALARM_NOTIFY_DURATION || 5, | ||
27 | color = 'orange', | 27 | color = 'orange', |
28 | } = params; | 28 | } = params; |
29 | const alarmNotifyStatusMean = AlarmStatusMean[alarmNotifyStatus]; | 29 | const alarmNotifyStatusMean = AlarmStatusMean[alarmNotifyStatus]; |
@@ -59,6 +59,8 @@ | @@ -59,6 +59,8 @@ | ||
59 | icon: 'clarity:note-edit-line', | 59 | icon: 'clarity:note-edit-line', |
60 | onClick: handleCreateOrEdit.bind(null, record), | 60 | onClick: handleCreateOrEdit.bind(null, record), |
61 | }, | 61 | }, |
62 | + ]" | ||
63 | + :drop-down-actions="[ | ||
62 | { | 64 | { |
63 | label: '删除', | 65 | label: '删除', |
64 | auth: 'api:yt:video:delete', | 66 | auth: 'api:yt:video:delete', |
1 | <script setup lang="ts"> | 1 | <script setup lang="ts"> |
2 | import { PageWrapper } from '/@/components/Page'; | 2 | import { PageWrapper } from '/@/components/Page'; |
3 | import OrganizationIdTree from '../../common/organizationIdTree/src/OrganizationIdTree.vue'; | 3 | import OrganizationIdTree from '../../common/organizationIdTree/src/OrganizationIdTree.vue'; |
4 | - import { computed, onMounted, reactive, ref, unref, watch } from 'vue'; | ||
5 | - import { Tabs, Row, Col, Spin, Button, Pagination, Empty } from 'ant-design-vue'; | 4 | + import { onMounted, reactive, ref, unref, watch } from 'vue'; |
5 | + import { Spin, Button, Pagination, Space, List } from 'ant-design-vue'; | ||
6 | import { cameraPage } from '/@/api/camera/cameraManager'; | 6 | import { cameraPage } from '/@/api/camera/cameraManager'; |
7 | import { CameraRecord } from '/@/api/camera/model/cameraModel'; | 7 | import { CameraRecord } from '/@/api/camera/model/cameraModel'; |
8 | import { videoPlay as VideoPlay } from 'vue3-video-play'; | 8 | import { videoPlay as VideoPlay } from 'vue3-video-play'; |
@@ -14,6 +14,7 @@ | @@ -14,6 +14,7 @@ | ||
14 | import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; | 14 | import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; |
15 | import { isDef } from '/@/utils/is'; | 15 | import { isDef } from '/@/utils/is'; |
16 | import { getStreamingPlayUrl } from '/@/api/camera/cameraManager'; | 16 | import { getStreamingPlayUrl } from '/@/api/camera/cameraManager'; |
17 | + import { buildUUID } from '/@/utils/uuid'; | ||
17 | 18 | ||
18 | type CameraRecordItem = CameraRecord & { | 19 | type CameraRecordItem = CameraRecord & { |
19 | canPlay?: boolean; | 20 | canPlay?: boolean; |
@@ -67,15 +68,11 @@ | @@ -67,15 +68,11 @@ | ||
67 | getCameraList(); | 68 | getCameraList(); |
68 | }; | 69 | }; |
69 | 70 | ||
70 | - const getColLayout = computed(() => { | ||
71 | - const totalSpan = 24; | ||
72 | - return totalSpan / pagination.colNumber; | ||
73 | - }); | ||
74 | - | ||
75 | const getCameraList = async () => { | 71 | const getCameraList = async () => { |
76 | try { | 72 | try { |
73 | + cameraList.value = []; | ||
77 | loading.value = true; | 74 | loading.value = true; |
78 | - const { items, total } = await cameraPage({ | 75 | + let { items, total } = await cameraPage({ |
79 | page: pagination.page, | 76 | page: pagination.page, |
80 | pageSize: pagination.pageSize, | 77 | pageSize: pagination.pageSize, |
81 | organizationId: unref(organizationId)!, | 78 | organizationId: unref(organizationId)!, |
@@ -87,6 +84,14 @@ | @@ -87,6 +84,14 @@ | ||
87 | (item as CameraRecordItem).isTransform = false; | 84 | (item as CameraRecordItem).isTransform = false; |
88 | beforeVideoPlay(item); | 85 | beforeVideoPlay(item); |
89 | } | 86 | } |
87 | + if (items.length < pagination.pageSize) { | ||
88 | + const fillArr: any = Array.from({ length: pagination.pageSize - items.length }).map(() => ({ | ||
89 | + id: buildUUID(), | ||
90 | + placeholder: true, | ||
91 | + })); | ||
92 | + items = [...items, ...fillArr]; | ||
93 | + console.log(fillArr); | ||
94 | + } | ||
90 | cameraList.value = items; | 95 | cameraList.value = items; |
91 | } catch (error) { | 96 | } catch (error) { |
92 | } finally { | 97 | } finally { |
@@ -128,7 +133,10 @@ | @@ -128,7 +133,10 @@ | ||
128 | } | 133 | } |
129 | }; | 134 | }; |
130 | 135 | ||
136 | + const gridLayout = ref({ gutter: 1, column: 2 }); | ||
137 | + | ||
131 | const handleSwitchLayoutWay = (pageSize: number, layout: number) => { | 138 | const handleSwitchLayoutWay = (pageSize: number, layout: number) => { |
139 | + gridLayout.value = { gutter: 1, column: Math.sqrt(pageSize) }; | ||
132 | pagination.colNumber = layout; | 140 | pagination.colNumber = layout; |
133 | pagination.pageSize = pageSize; | 141 | pagination.pageSize = pageSize; |
134 | pagination.page = 1; | 142 | pagination.page = 1; |
@@ -185,7 +193,7 @@ | @@ -185,7 +193,7 @@ | ||
185 | <PageWrapper dense contentFullHeight contentClass="flex"> | 193 | <PageWrapper dense contentFullHeight contentClass="flex"> |
186 | <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" /> | 194 | <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" /> |
187 | <section class="p-4 pl-9 split-screen-mode flex flex-col flex-auto w-3/4 xl:w-4/5"> | 195 | <section class="p-4 pl-9 split-screen-mode flex flex-col flex-auto w-3/4 xl:w-4/5"> |
188 | - <div class="p-3 bg-light-50 flex justify-between mb-4"> | 196 | + <div class="p-3 bg-light-50 flex justify-between mb-4 dark:bg-dark-900"> |
189 | <div class="flex gap-4 cursor-pointer items-center"> | 197 | <div class="flex gap-4 cursor-pointer items-center"> |
190 | <div | 198 | <div |
191 | class="w-8 h-8 flex justify-center items-center" | 199 | class="w-8 h-8 flex justify-center items-center" |
@@ -225,14 +233,67 @@ | @@ -225,14 +233,67 @@ | ||
225 | <div class="flex"> | 233 | <div class="flex"> |
226 | <Button type="primary" @click="handleAddCamera">新增视频</Button> | 234 | <Button type="primary" @click="handleAddCamera">新增视频</Button> |
227 | </div> | 235 | </div> |
228 | - <Tabs type="card" v-model:activeKey="activeKey" @change="handleChangeMode"> | ||
229 | - <Tabs.TabPane :key="PageMode.SPLIT_SCREEN_MODE" tab="分屏模式" /> | ||
230 | - <Tabs.TabPane :key="PageMode.LIST_MODE" tab="列表模式" /> | ||
231 | - <Tabs.TabPane :key="PageMode.FULL_SCREEN_MODE" tab="全屏" /> | ||
232 | - </Tabs> | 236 | + <Space> |
237 | + <Button type="primary" @click="handleChangeMode(PageMode.SPLIT_SCREEN_MODE)"> | ||
238 | + 分屏模式 | ||
239 | + </Button> | ||
240 | + <Button type="primary" @click="handleChangeMode(PageMode.LIST_MODE)"> | ||
241 | + 列表模式 | ||
242 | + </Button> | ||
243 | + <Button type="primary" @click="handleChangeMode(PageMode.FULL_SCREEN_MODE)"> | ||
244 | + 全屏 | ||
245 | + </Button> | ||
246 | + </Space> | ||
233 | </div> | 247 | </div> |
234 | </div> | 248 | </div> |
235 | - <section ref="videoContainer" class="bg-light-50 flex-auto"> | 249 | + <List |
250 | + :loading="loading" | ||
251 | + :data-source="cameraList" | ||
252 | + class="bg-light-50 flex-auto dark:bg-dark-900 split-mode-list" | ||
253 | + :grid="gridLayout" | ||
254 | + :style="{ '--height': `${100 / pagination.colNumber}%` }" | ||
255 | + > | ||
256 | + <template #renderItem="{ item }"> | ||
257 | + <List.Item> | ||
258 | + <div class="box-border w-full h-full p-1px"> | ||
259 | + <div | ||
260 | + v-if="item.placeholder" | ||
261 | + class="bg-black w-full h-full overflow-hidden relative" | ||
262 | + ></div> | ||
263 | + <div | ||
264 | + v-if="!item.placeholder" | ||
265 | + class="bg-black w-full h-full overflow-hidden relative video-container" | ||
266 | + > | ||
267 | + <Spin v-show="!item.isTransform" :spinning="!item.isTransform"> | ||
268 | + <div class="bg-black text-light-50"> </div> | ||
269 | + </Spin> | ||
270 | + <VideoPlay | ||
271 | + v-show="item.isTransform" | ||
272 | + @loadstart="handleLoadStart(item)" | ||
273 | + @loadeddata="handleLoadData(item)" | ||
274 | + v-bind="options" | ||
275 | + :src="item.videoUrl" | ||
276 | + :title="item.name" | ||
277 | + :type="item.type" | ||
278 | + /> | ||
279 | + <div | ||
280 | + v-if="item.isTransform && isDef(item.canPlay) && !item.canPlay" | ||
281 | + class="video-container-error-msk absolute top-0 left-0 text-lg w-full h-full text-light-50 flex justify-center items-center z-50 bg-black" | ||
282 | + > | ||
283 | + 视频加载出错了! | ||
284 | + </div> | ||
285 | + <div | ||
286 | + class="video-container-mask absolute top-0 left-0 z-50 text-lg w-full text-light-50 flex justify-center items-center" | ||
287 | + style="height: 100%; background-color: rgba(0, 0, 0, 0.5)" | ||
288 | + > | ||
289 | + <span>{{ item.name }}</span> | ||
290 | + </div> | ||
291 | + </div> | ||
292 | + </div> | ||
293 | + </List.Item> | ||
294 | + </template> | ||
295 | + </List> | ||
296 | + <!-- <section ref="videoContainer" class="bg-light-50 flex-auto dark:bg-dark-900"> | ||
236 | <Spin :spinning="loading" class="h-full"> | 297 | <Spin :spinning="loading" class="h-full"> |
237 | <Empty | 298 | <Empty |
238 | class="h-full flex flex-col justify-center items-center" | 299 | class="h-full flex flex-col justify-center items-center" |
@@ -277,7 +338,7 @@ | @@ -277,7 +338,7 @@ | ||
277 | </Col> | 338 | </Col> |
278 | </Row> | 339 | </Row> |
279 | </Spin> | 340 | </Spin> |
280 | - </section> | 341 | + </section> --> |
281 | </section> | 342 | </section> |
282 | </PageWrapper> | 343 | </PageWrapper> |
283 | <CameraDrawer @register="registerDrawer" @success="getCameraList" /> | 344 | <CameraDrawer @register="registerDrawer" @success="getCameraList" /> |
@@ -334,4 +395,20 @@ | @@ -334,4 +395,20 @@ | ||
334 | } | 395 | } |
335 | } | 396 | } |
336 | } | 397 | } |
398 | + | ||
399 | + .split-mode-list:deep(.ant-row) { | ||
400 | + width: 100%; | ||
401 | + height: 100%; | ||
402 | + } | ||
403 | + | ||
404 | + .split-mode-list:deep(.ant-list-item) { | ||
405 | + width: 100%; | ||
406 | + height: 100%; | ||
407 | + } | ||
408 | + | ||
409 | + .split-mode-list:deep(.ant-col) { | ||
410 | + width: 100%; | ||
411 | + // height: var(--height); | ||
412 | + height: 100%; | ||
413 | + } | ||
337 | </style> | 414 | </style> |
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | <div class="organization-tree flex relative"> | 2 | <div class="organization-tree flex relative"> |
3 | <div class="cursor-pointer flex py-4 fold-icon" :class="foldFlag ? 'absolute' : ''"> | 3 | <div class="cursor-pointer flex py-4 fold-icon" :class="foldFlag ? 'absolute' : ''"> |
4 | <div @click="handleFold"> | 4 | <div @click="handleFold"> |
5 | - <DoubleRightOutlined :class="[foldFlag ? '' : 'rotate-180']" class="text-xl transform" /> | 5 | + <CaretRightOutlined :class="[foldFlag ? '' : 'rotate-180']" class="text-xl transform" /> |
6 | </div> | 6 | </div> |
7 | </div> | 7 | </div> |
8 | <div | 8 | <div |
@@ -29,7 +29,7 @@ | @@ -29,7 +29,7 @@ | ||
29 | import { onMounted, ref, unref } from 'vue'; | 29 | import { onMounted, ref, unref } from 'vue'; |
30 | import { BasicTree, TreeItem } from '/@/components/Tree'; | 30 | import { BasicTree, TreeItem } from '/@/components/Tree'; |
31 | import { getOrganizationList } from '/@/api/system/system'; | 31 | import { getOrganizationList } from '/@/api/system/system'; |
32 | - import { DoubleRightOutlined } from '@ant-design/icons-vue'; | 32 | + import { CaretRightOutlined } from '@ant-design/icons-vue'; |
33 | 33 | ||
34 | const emit = defineEmits(['select']); | 34 | const emit = defineEmits(['select']); |
35 | const treeData = ref<TreeItem[]>([]); | 35 | const treeData = ref<TreeItem[]>([]); |
src/views/configuration/center/TableMode.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <PageWrapper dense contentFullHeight contentClass="flex"> | ||
4 | + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" /> | ||
5 | + <BasicTable | ||
6 | + style="flex: auto" | ||
7 | + :clickToRowSelect="false" | ||
8 | + @register="registerTable" | ||
9 | + :searchInfo="searchInfo" | ||
10 | + class="w-3/4 xl:w-4/5" | ||
11 | + > | ||
12 | + <template #platform="{ record }"> | ||
13 | + <Tag :color="record.platform === Platform.PHONE ? 'cyan' : 'blue'"> | ||
14 | + {{ record.platform === Platform.PHONE ? '移动端' : 'PC端' }} | ||
15 | + </Tag> | ||
16 | + </template> | ||
17 | + <template #toolbar> | ||
18 | + <Authority value="api:yt:configuration:center:post"> | ||
19 | + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增组态 </a-button> | ||
20 | + </Authority> | ||
21 | + <Authority value="api:yt:configuration:center:delete"> | ||
22 | + <Popconfirm | ||
23 | + title="您确定要批量删除数据" | ||
24 | + ok-text="确定" | ||
25 | + cancel-text="取消" | ||
26 | + @confirm="handleDeleteOrBatchDelete(null)" | ||
27 | + > | ||
28 | + <a-button type="primary" color="error" :disabled="hasBatchDelete"> | ||
29 | + 批量删除 | ||
30 | + </a-button> | ||
31 | + </Popconfirm> | ||
32 | + </Authority> | ||
33 | + </template> | ||
34 | + <template #action="{ record }"> | ||
35 | + <TableAction | ||
36 | + :actions="[ | ||
37 | + { | ||
38 | + label: '设计', | ||
39 | + auth: 'api:yt:configuration:center:get_configuration_info:get', | ||
40 | + icon: 'clarity:note-edit-line', | ||
41 | + onClick: handleDesign.bind(null, record), | ||
42 | + }, | ||
43 | + { | ||
44 | + label: '预览', | ||
45 | + auth: 'api:yt:configuration:center:get_configuration_info:get', | ||
46 | + icon: 'ant-design:eye-outlined', | ||
47 | + onClick: handlePreview.bind(null, record), | ||
48 | + }, | ||
49 | + { | ||
50 | + label: '编辑', | ||
51 | + auth: 'api:yt:configuration:center:update', | ||
52 | + icon: 'clarity:note-edit-line', | ||
53 | + onClick: handleCreateOrEdit.bind(null, record), | ||
54 | + }, | ||
55 | + { | ||
56 | + label: '删除', | ||
57 | + auth: 'api:yt:configuration:center:delete', | ||
58 | + icon: 'ant-design:delete-outlined', | ||
59 | + color: 'error', | ||
60 | + popConfirm: { | ||
61 | + title: '是否确认删除', | ||
62 | + confirm: handleDeleteOrBatchDelete.bind(null, record), | ||
63 | + }, | ||
64 | + }, | ||
65 | + ]" | ||
66 | + /> | ||
67 | + </template> | ||
68 | + </BasicTable> | ||
69 | + </PageWrapper> | ||
70 | + <ContactDrawer @register="registerDrawer" @success="handleSuccess" /> | ||
71 | + </div> | ||
72 | +</template> | ||
73 | + | ||
74 | +<script lang="ts"> | ||
75 | + import { defineComponent, reactive, nextTick } from 'vue'; | ||
76 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
77 | + import { PageWrapper } from '/@/components/Page'; | ||
78 | + import { useDrawer } from '/@/components/Drawer'; | ||
79 | + import ContactDrawer from './ConfigurationCenterDrawer.vue'; | ||
80 | + import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree'; | ||
81 | + import { searchFormSchema, columns, Platform } from './center.data'; | ||
82 | + import { | ||
83 | + getPage, | ||
84 | + deleteConfigurationCenter, | ||
85 | + } from '/@/api/configuration/center/configurationCenter'; | ||
86 | + import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | ||
87 | + import { getAppEnvConfig, isDevMode } from '/@/utils/env'; | ||
88 | + import { Authority } from '/@/components/Authority'; | ||
89 | + import { Popconfirm } from 'ant-design-vue'; | ||
90 | + import { Tag } from 'ant-design-vue'; | ||
91 | + export default defineComponent({ | ||
92 | + components: { | ||
93 | + PageWrapper, | ||
94 | + OrganizationIdTree, | ||
95 | + BasicTable, | ||
96 | + TableAction, | ||
97 | + ContactDrawer, | ||
98 | + Authority, | ||
99 | + Popconfirm, | ||
100 | + Tag, | ||
101 | + }, | ||
102 | + setup() { | ||
103 | + const { VITE_GLOB_CONFIGURATION } = getAppEnvConfig(); | ||
104 | + const isDev = isDevMode(); | ||
105 | + const searchInfo = reactive<Recordable>({}); | ||
106 | + const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); | ||
107 | + // 表格hooks | ||
108 | + const [registerTable, { reload, setProps }] = useTable({ | ||
109 | + title: '组态中心列表', | ||
110 | + api: getPage, | ||
111 | + columns, | ||
112 | + clickToRowSelect: false, | ||
113 | + formConfig: { | ||
114 | + labelWidth: 120, | ||
115 | + schemas: searchFormSchema, | ||
116 | + resetFunc: resetFn, | ||
117 | + }, | ||
118 | + showIndexColumn: false, | ||
119 | + useSearchForm: true, | ||
120 | + showTableSetting: true, | ||
121 | + bordered: true, | ||
122 | + rowKey: 'id', | ||
123 | + actionColumn: { | ||
124 | + width: 200, | ||
125 | + title: '操作', | ||
126 | + dataIndex: 'action', | ||
127 | + slots: { customRender: 'action' }, | ||
128 | + fixed: 'right', | ||
129 | + }, | ||
130 | + }); | ||
131 | + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete( | ||
132 | + deleteConfigurationCenter, | ||
133 | + handleSuccess, | ||
134 | + setProps | ||
135 | + ); | ||
136 | + nextTick(() => { | ||
137 | + setProps(selectionOptions); | ||
138 | + }); | ||
139 | + | ||
140 | + // 弹框 | ||
141 | + const [registerDrawer, { openDrawer }] = useDrawer(); | ||
142 | + | ||
143 | + // 刷新 | ||
144 | + function handleSuccess() { | ||
145 | + reload(); | ||
146 | + } | ||
147 | + // 新增或编辑 | ||
148 | + const handleCreateOrEdit = (record: Recordable | null) => { | ||
149 | + if (record) { | ||
150 | + openDrawer(true, { | ||
151 | + isUpdate: true, | ||
152 | + record, | ||
153 | + }); | ||
154 | + } else { | ||
155 | + openDrawer(true, { | ||
156 | + isUpdate: false, | ||
157 | + }); | ||
158 | + } | ||
159 | + }; | ||
160 | + // 树形选择器 | ||
161 | + const handleSelect = (organizationId: string) => { | ||
162 | + searchInfo.organizationId = organizationId; | ||
163 | + handleSuccess(); | ||
164 | + }; | ||
165 | + | ||
166 | + const handlePreview = (record: Recordable | null) => { | ||
167 | + window.open( | ||
168 | + `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${ | ||
169 | + record!.id | ||
170 | + }&lightbox=1` | ||
171 | + ); | ||
172 | + }; | ||
173 | + const handleDesign = (record: Recordable | null) => { | ||
174 | + window.open( | ||
175 | + `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}` | ||
176 | + ); | ||
177 | + }; | ||
178 | + | ||
179 | + return { | ||
180 | + Platform, | ||
181 | + searchInfo, | ||
182 | + hasBatchDelete, | ||
183 | + handleCreateOrEdit, | ||
184 | + handleDeleteOrBatchDelete, | ||
185 | + handleSelect, | ||
186 | + handleSuccess, | ||
187 | + handlePreview, | ||
188 | + handleDesign, | ||
189 | + registerTable, | ||
190 | + registerDrawer, | ||
191 | + organizationIdTreeRef, | ||
192 | + }; | ||
193 | + }, | ||
194 | + }); | ||
195 | +</script> |
1 | -<template> | ||
2 | - <div> | ||
3 | - <PageWrapper dense contentFullHeight contentClass="flex"> | ||
4 | - <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" /> | ||
5 | - <BasicTable | ||
6 | - style="flex: auto" | ||
7 | - :clickToRowSelect="false" | ||
8 | - @register="registerTable" | ||
9 | - :searchInfo="searchInfo" | ||
10 | - class="w-3/4 xl:w-4/5" | ||
11 | - > | ||
12 | - <template #platform="{ record }"> | ||
13 | - <Tag :color="record.platform === Platform.PHONE ? 'cyan' : 'blue'"> | ||
14 | - {{ record.platform === Platform.PHONE ? '移动端' : 'PC端' }} | ||
15 | - </Tag> | ||
16 | - </template> | ||
17 | - <template #toolbar> | ||
18 | - <Authority value="api:yt:configuration:center:post"> | ||
19 | - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增组态 </a-button> | ||
20 | - </Authority> | ||
21 | - <Authority value="api:yt:configuration:center:delete"> | ||
22 | - <Popconfirm | ||
23 | - title="您确定要批量删除数据" | ||
24 | - ok-text="确定" | ||
25 | - cancel-text="取消" | ||
26 | - @confirm="handleDeleteOrBatchDelete(null)" | ||
27 | - > | ||
28 | - <a-button type="primary" color="error" :disabled="hasBatchDelete"> | ||
29 | - 批量删除 | ||
30 | - </a-button> | ||
31 | - </Popconfirm> | ||
32 | - </Authority> | ||
33 | - </template> | ||
34 | - <template #action="{ record }"> | ||
35 | - <TableAction | ||
36 | - :actions="[ | ||
37 | - { | ||
38 | - label: '设计', | ||
39 | - auth: 'api:yt:configuration:center:get_configuration_info:get', | ||
40 | - icon: 'clarity:note-edit-line', | ||
41 | - onClick: handleDesign.bind(null, record), | ||
42 | - }, | ||
43 | - { | ||
44 | - label: '预览', | ||
45 | - auth: 'api:yt:configuration:center:get_configuration_info:get', | ||
46 | - icon: 'ant-design:eye-outlined', | ||
47 | - onClick: handlePreview.bind(null, record), | ||
48 | - }, | ||
49 | - { | ||
50 | - label: '编辑', | ||
51 | - auth: 'api:yt:configuration:center:update', | ||
52 | - icon: 'clarity:note-edit-line', | ||
53 | - onClick: handleCreateOrEdit.bind(null, record), | ||
54 | - }, | ||
55 | - { | ||
56 | - label: '删除', | ||
57 | - auth: 'api:yt:configuration:center:delete', | ||
58 | - icon: 'ant-design:delete-outlined', | ||
59 | - color: 'error', | ||
60 | - popConfirm: { | ||
61 | - title: '是否确认删除', | ||
62 | - confirm: handleDeleteOrBatchDelete.bind(null, record), | ||
63 | - }, | ||
64 | - }, | ||
65 | - ]" | ||
66 | - /> | ||
67 | - </template> | ||
68 | - </BasicTable> | ||
69 | - </PageWrapper> | ||
70 | - <ContactDrawer @register="registerDrawer" @success="handleSuccess" /> | ||
71 | - </div> | ||
72 | -</template> | ||
73 | - | ||
74 | -<script lang="ts"> | ||
75 | - import { defineComponent, reactive, nextTick } from 'vue'; | ||
76 | - import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
77 | - import { PageWrapper } from '/@/components/Page'; | ||
78 | - import { useDrawer } from '/@/components/Drawer'; | ||
79 | - import ContactDrawer from './ConfigurationCenterDrawer.vue'; | ||
80 | - import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree'; | ||
81 | - import { searchFormSchema, columns, Platform } from './center.data'; | 1 | +<script setup lang="ts"> |
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'; | ||
10 | + import { onMounted, reactive, ref, unref } from 'vue'; | ||
11 | + import { OrganizationIdTree, useResetOrganizationTree } from '../../common/organizationIdTree'; | ||
82 | import { | 12 | import { |
83 | - getPage, | ||
84 | deleteConfigurationCenter, | 13 | deleteConfigurationCenter, |
14 | + getPage, | ||
85 | } from '/@/api/configuration/center/configurationCenter'; | 15 | } from '/@/api/configuration/center/configurationCenter'; |
86 | - import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | ||
87 | - import { getAppEnvConfig, isDevMode } from '/@/utils/env'; | 16 | + import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal'; |
17 | + import { PageWrapper } from '/@/components/Page'; | ||
18 | + import { Dropdown } from '/@/components/Dropdown'; | ||
19 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
20 | + import { searchFormSchema } from './center.data'; | ||
21 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
88 | import { Authority } from '/@/components/Authority'; | 22 | import { Authority } from '/@/components/Authority'; |
89 | - import { Popconfirm } from 'ant-design-vue'; | ||
90 | - import { Tag } from 'ant-design-vue'; | ||
91 | - export default defineComponent({ | ||
92 | - components: { | ||
93 | - PageWrapper, | ||
94 | - OrganizationIdTree, | ||
95 | - BasicTable, | ||
96 | - TableAction, | ||
97 | - ContactDrawer, | ||
98 | - Authority, | ||
99 | - Popconfirm, | ||
100 | - Tag, | 23 | + import { isDevMode } from '/@/utils/env'; |
24 | + import ConfigurationCenterDrawer from './ConfigurationCenterDrawer.vue'; | ||
25 | + import { useDrawer } from '/@/components/Drawer'; | ||
26 | + import { useSyncConfirm } from '/@/hooks/component/useSyncConfirm'; | ||
27 | + import { getBoundingClientRect } from '/@/utils/domUtils'; | ||
28 | + | ||
29 | + const listColumn = ref(4); | ||
30 | + | ||
31 | + const { createMessage } = useMessage(); | ||
32 | + | ||
33 | + const organizationId = ref<Nullable<number>>(null); | ||
34 | + | ||
35 | + const pagination = reactive<PaginationProps>({ | ||
36 | + size: 'small', | ||
37 | + showTotal: (total: number) => `共 ${total} 条数据`, | ||
38 | + current: 1, | ||
39 | + onChange: (page: number) => { | ||
40 | + pagination.current = page; | ||
41 | + getListData(); | ||
42 | + }, | ||
43 | + }); | ||
44 | + | ||
45 | + const loading = ref(false); | ||
46 | + | ||
47 | + const dataSource = ref<ConfigurationCenterItemsModal[]>([]); | ||
48 | + | ||
49 | + const [registerForm, { getFieldsValue }] = useForm({ | ||
50 | + schemas: searchFormSchema, | ||
51 | + showAdvancedButton: true, | ||
52 | + labelWidth: 100, | ||
53 | + compact: true, | ||
54 | + resetFunc: () => { | ||
55 | + resetFn(); | ||
56 | + organizationId.value = null; | ||
57 | + return getListData(); | ||
101 | }, | 58 | }, |
102 | - setup() { | ||
103 | - const { VITE_GLOB_CONFIGURATION } = getAppEnvConfig(); | ||
104 | - const isDev = isDevMode(); | ||
105 | - const searchInfo = reactive<Recordable>({}); | ||
106 | - const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); | ||
107 | - // 表格hooks | ||
108 | - const [registerTable, { reload, setProps }] = useTable({ | ||
109 | - title: '组态中心列表', | ||
110 | - api: getPage, | ||
111 | - columns, | ||
112 | - clickToRowSelect: false, | ||
113 | - formConfig: { | ||
114 | - labelWidth: 120, | ||
115 | - schemas: searchFormSchema, | ||
116 | - resetFunc: resetFn, | ||
117 | - }, | ||
118 | - showIndexColumn: false, | ||
119 | - useSearchForm: true, | ||
120 | - showTableSetting: true, | ||
121 | - bordered: true, | ||
122 | - rowKey: 'id', | ||
123 | - actionColumn: { | ||
124 | - width: 200, | ||
125 | - title: '操作', | ||
126 | - dataIndex: 'action', | ||
127 | - slots: { customRender: 'action' }, | ||
128 | - fixed: 'right', | ||
129 | - }, | 59 | + submitFunc: async () => { |
60 | + const value = getFieldsValue(); | ||
61 | + getListData(value); | ||
62 | + }, | ||
63 | + }); | ||
64 | + | ||
65 | + async function getListData(value: Recordable = {}) { | ||
66 | + try { | ||
67 | + loading.value = true; | ||
68 | + const pageSize = 4 * unref(listColumn); | ||
69 | + const { items, total } = await getPage({ | ||
70 | + organizationId: unref(organizationId), | ||
71 | + ...value, | ||
72 | + page: pagination.current!, | ||
73 | + pageSize, | ||
74 | + }); | ||
75 | + dataSource.value = items; | ||
76 | + pagination.total = total; | ||
77 | + pagination.pageSize = pageSize; | ||
78 | + } catch (error) { | ||
79 | + } finally { | ||
80 | + loading.value = false; | ||
81 | + } | ||
82 | + } | ||
83 | + | ||
84 | + onMounted(() => { | ||
85 | + getListData(); | ||
86 | + }); | ||
87 | + | ||
88 | + const searchInfo = reactive<Recordable>({}); | ||
89 | + const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); | ||
90 | + const handleSelect = (orgId: number) => { | ||
91 | + organizationId.value = orgId; | ||
92 | + getListData(); | ||
93 | + }; | ||
94 | + | ||
95 | + const [registerDrawer, { openDrawer }] = useDrawer(); | ||
96 | + | ||
97 | + const handleCreateOrUpdate = (record?: ConfigurationCenterItemsModal) => { | ||
98 | + if (record) { | ||
99 | + openDrawer(true, { | ||
100 | + isUpdate: true, | ||
101 | + record, | ||
130 | }); | 102 | }); |
131 | - const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete( | ||
132 | - deleteConfigurationCenter, | ||
133 | - handleSuccess, | ||
134 | - setProps | ||
135 | - ); | ||
136 | - nextTick(() => { | ||
137 | - setProps(selectionOptions); | 103 | + } else { |
104 | + openDrawer(true, { | ||
105 | + isUpdate: false, | ||
138 | }); | 106 | }); |
107 | + } | ||
108 | + }; | ||
139 | 109 | ||
140 | - // 弹框 | ||
141 | - const [registerDrawer, { openDrawer }] = useDrawer(); | ||
142 | - | ||
143 | - // 刷新 | ||
144 | - function handleSuccess() { | ||
145 | - reload(); | ||
146 | - } | ||
147 | - // 新增或编辑 | ||
148 | - const handleCreateOrEdit = (record: Recordable | null) => { | ||
149 | - if (record) { | ||
150 | - openDrawer(true, { | ||
151 | - isUpdate: true, | ||
152 | - record, | ||
153 | - }); | ||
154 | - } else { | ||
155 | - openDrawer(true, { | ||
156 | - isUpdate: false, | ||
157 | - }); | ||
158 | - } | ||
159 | - }; | ||
160 | - // 树形选择器 | ||
161 | - const handleSelect = (organizationId: string) => { | ||
162 | - searchInfo.organizationId = organizationId; | ||
163 | - handleSuccess(); | ||
164 | - }; | ||
165 | - | ||
166 | - const handlePreview = (record: Recordable | null) => { | ||
167 | - window.open( | ||
168 | - `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${ | ||
169 | - record!.id | ||
170 | - }&lightbox=1` | ||
171 | - ); | ||
172 | - }; | ||
173 | - const handleDesign = (record: Recordable | null) => { | ||
174 | - window.open( | ||
175 | - `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}` | ||
176 | - ); | ||
177 | - }; | ||
178 | - | ||
179 | - return { | ||
180 | - Platform, | ||
181 | - searchInfo, | ||
182 | - hasBatchDelete, | ||
183 | - handleCreateOrEdit, | ||
184 | - handleDeleteOrBatchDelete, | ||
185 | - handleSelect, | ||
186 | - handleSuccess, | ||
187 | - handlePreview, | ||
188 | - handleDesign, | ||
189 | - registerTable, | ||
190 | - registerDrawer, | ||
191 | - organizationIdTreeRef, | ||
192 | - }; | ||
193 | - }, | 110 | + const { VITE_GLOB_CONFIGURATION } = import.meta.env; |
111 | + const isDev = isDevMode(); | ||
112 | + | ||
113 | + const handlePreview = (record: ConfigurationCenterItemsModal) => { | ||
114 | + console.log(record); | ||
115 | + window.open( | ||
116 | + `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${ | ||
117 | + record!.id | ||
118 | + }&lightbox=1` | ||
119 | + ); | ||
120 | + }; | ||
121 | + | ||
122 | + const handleDesign = (record: ConfigurationCenterItemsModal) => { | ||
123 | + window.open( | ||
124 | + `${VITE_GLOB_CONFIGURATION}/${isDev ? '?dev=1&' : '?'}configurationId=${record!.id}` | ||
125 | + ); | ||
126 | + }; | ||
127 | + | ||
128 | + const { createSyncConfirm } = useSyncConfirm(); | ||
129 | + const handleDelete = async (record: ConfigurationCenterItemsModal) => { | ||
130 | + try { | ||
131 | + await createSyncConfirm({ iconType: 'warning', content: '是否确认删除操作?' }); | ||
132 | + await deleteConfigurationCenter([record.id]); | ||
133 | + createMessage.success('删除成功'); | ||
134 | + await getListData(); | ||
135 | + } catch (error) {} | ||
136 | + }; | ||
137 | + | ||
138 | + const listEl = ref<Nullable<ComponentElRef>>(null); | ||
139 | + | ||
140 | + onMounted(() => { | ||
141 | + const clientHeight = document.documentElement.clientHeight; | ||
142 | + const rect = getBoundingClientRect(unref(listEl)!.$el!) as DOMRect; | ||
143 | + // margin-top 24 height 24 | ||
144 | + const paginationHeight = 24 + 24 + 8; | ||
145 | + // list pading top 8 maring-top 8 extra slot 56 | ||
146 | + const listContainerMarginBottom = 8 + 8 + 56; | ||
147 | + const listContainerHeight = | ||
148 | + clientHeight - rect.top - paginationHeight - listContainerMarginBottom; | ||
149 | + const listContainerEl = (unref(listEl)!.$el as HTMLElement).querySelector( | ||
150 | + '.ant-spin-container' | ||
151 | + ) as HTMLElement; | ||
152 | + listContainerEl && | ||
153 | + (listContainerEl.style.height = listContainerHeight + 'px') && | ||
154 | + (listContainerEl.style.overflowY = 'auto') && | ||
155 | + (listContainerEl.style.overflowX = 'hidden'); | ||
194 | }); | 156 | }); |
195 | </script> | 157 | </script> |
158 | + | ||
159 | +<template> | ||
160 | + <PageWrapper dense contentFullHeight contentClass="flex"> | ||
161 | + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" /> | ||
162 | + <section class="flex-auto pl-9 p-4 configuration-list"> | ||
163 | + <div class="flex-auto w-full bg-light-50 dark:bg-dark-900 p-4"> | ||
164 | + <BasicForm @register="registerForm" /> | ||
165 | + </div> | ||
166 | + <List | ||
167 | + ref="listEl" | ||
168 | + :loading="loading" | ||
169 | + class="flex-auto bg-light-50 dark:bg-dark-900 !p-2 !mt-4" | ||
170 | + position="bottom" | ||
171 | + :pagination="pagination" | ||
172 | + :data-source="dataSource" | ||
173 | + :grid="{ gutter: 4, column: listColumn }" | ||
174 | + > | ||
175 | + <template #header> | ||
176 | + <div class="flex gap-3 justify-end"> | ||
177 | + <Button type="primary" @click="handleCreateOrUpdate()">新增组态</Button> | ||
178 | + <Popover :trigger="['hover']"> | ||
179 | + <template #content> | ||
180 | + <div class="w-50"> | ||
181 | + <div>每行显示数量</div> | ||
182 | + <Slider | ||
183 | + v-model:value="listColumn" | ||
184 | + :max="12" | ||
185 | + :min="4" | ||
186 | + :marks="{ 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12 }" | ||
187 | + @change="getListData" | ||
188 | + /> | ||
189 | + </div> | ||
190 | + </template> | ||
191 | + <Button type="primary"> | ||
192 | + <AppstoreOutlined /> | ||
193 | + </Button> | ||
194 | + </Popover> | ||
195 | + <Tooltip title="刷新"> | ||
196 | + <Button type="primary" @click="getListData"> | ||
197 | + <ReloadOutlined @click="getListData" /> | ||
198 | + </Button> | ||
199 | + </Tooltip> | ||
200 | + </div> | ||
201 | + </template> | ||
202 | + <template #renderItem="{ item }"> | ||
203 | + <List.Item> | ||
204 | + <Card hoverable> | ||
205 | + <template #cover> | ||
206 | + <img | ||
207 | + alt="example" | ||
208 | + src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png" | ||
209 | + /> | ||
210 | + </template> | ||
211 | + <template class="ant-card-actions" #actions> | ||
212 | + <Authority value="api:yt:configuration:center:get_configuration_info:get"> | ||
213 | + <Tooltip title="预览"> | ||
214 | + <EyeOutlined key="setting" @click="handlePreview(item)" /> | ||
215 | + </Tooltip> | ||
216 | + </Authority> | ||
217 | + <Authority value="api:yt:configuration:center:update"> | ||
218 | + <Tooltip title="编辑"> | ||
219 | + <EditOutlined key="edit" @click="handleCreateOrUpdate(item)" /> | ||
220 | + </Tooltip> | ||
221 | + </Authority> | ||
222 | + <Dropdown | ||
223 | + :dropMenuList="[ | ||
224 | + { | ||
225 | + text: '设计', | ||
226 | + auth: 'api:yt:configuration:center:get_configuration_info:get', | ||
227 | + icon: 'clarity:note-edit-line', | ||
228 | + onClick: handleDesign.bind(null, item), | ||
229 | + }, | ||
230 | + { | ||
231 | + text: '删除', | ||
232 | + auth: 'api:yt:configuration:center:delete', | ||
233 | + icon: 'ant-design:delete-outlined', | ||
234 | + color: 'error', | ||
235 | + onClick: handleDelete.bind(null, item), | ||
236 | + }, | ||
237 | + ]" | ||
238 | + :trigger="['hover']" | ||
239 | + > | ||
240 | + <EllipsisOutlined key="ellipsis" /> | ||
241 | + </Dropdown> | ||
242 | + </template> | ||
243 | + <Card.Meta :title="item.name"> | ||
244 | + <template #description> | ||
245 | + <div class="truncate">{{ item.organizationDTO.name }}</div> | ||
246 | + <div class="truncate">{{ item.remark }} </div> | ||
247 | + </template> | ||
248 | + </Card.Meta> | ||
249 | + </Card> | ||
250 | + </List.Item> | ||
251 | + </template> | ||
252 | + </List> | ||
253 | + </section> | ||
254 | + <ConfigurationCenterDrawer @register="registerDrawer" @success="getListData" /> | ||
255 | + </PageWrapper> | ||
256 | +</template> | ||
257 | + | ||
258 | +<style lang="less" scoped> | ||
259 | + .configuration-list:deep(.ant-list-header) { | ||
260 | + border-bottom: none !important; | ||
261 | + } | ||
262 | + | ||
263 | + .configuration-list:deep(.ant-list-pagination) { | ||
264 | + height: 24px; | ||
265 | + } | ||
266 | +</style> |
@@ -206,7 +206,7 @@ | @@ -206,7 +206,7 @@ | ||
206 | target: '_blank ', | 206 | target: '_blank ', |
207 | }, | 207 | }, |
208 | { | 208 | { |
209 | - title: '什么是设备配置?', | 209 | + title: '什么是产品?', |
210 | href: 'https://docs.thingskit.com/thingskit-link/operation-guide/device-manage.html#%E8%AE%BE%E5%A4%87%E9%85%8D%E7%BD%AE', | 210 | href: 'https://docs.thingskit.com/thingskit-link/operation-guide/device-manage.html#%E8%AE%BE%E5%A4%87%E9%85%8D%E7%BD%AE', |
211 | target: '_blank ', | 211 | target: '_blank ', |
212 | }, | 212 | }, |
@@ -51,8 +51,8 @@ | @@ -51,8 +51,8 @@ | ||
51 | series: [ | 51 | series: [ |
52 | { | 52 | { |
53 | name: '告警数', | 53 | name: '告警数', |
54 | - barWidth: '10%', | ||
55 | - type: 'bar', | 54 | + // barWidth: '10%', |
55 | + type: 'line', | ||
56 | stack: 'Total', | 56 | stack: 'Total', |
57 | data: props.alarmList, | 57 | data: props.alarmList, |
58 | color: '#3C78FF', | 58 | color: '#3C78FF', |
@@ -63,6 +63,7 @@ | @@ -63,6 +63,7 @@ | ||
63 | watch( | 63 | watch( |
64 | () => props.alarmList, | 64 | () => props.alarmList, |
65 | (newValue) => { | 65 | (newValue) => { |
66 | + console.log({ newValue, props }); | ||
66 | let alarmTotal = 0; | 67 | let alarmTotal = 0; |
67 | for (const item of props.alarmList) { | 68 | for (const item of props.alarmList) { |
68 | alarmTotal += Number(item[1]); | 69 | alarmTotal += Number(item[1]); |
@@ -91,10 +92,10 @@ | @@ -91,10 +92,10 @@ | ||
91 | series: [ | 92 | series: [ |
92 | { | 93 | { |
93 | name: '告警数', | 94 | name: '告警数', |
94 | - type: 'bar', | 95 | + type: 'line', |
95 | stack: 'Total', | 96 | stack: 'Total', |
96 | color: '#3C78FF', | 97 | color: '#3C78FF', |
97 | - barWidth: '10%', | 98 | + // barWidth: '10%', |
98 | data: newValue, | 99 | data: newValue, |
99 | }, | 100 | }, |
100 | ], | 101 | ], |
@@ -63,17 +63,17 @@ | @@ -63,17 +63,17 @@ | ||
63 | series: [ | 63 | series: [ |
64 | { | 64 | { |
65 | name: '传输数据点', | 65 | name: '传输数据点', |
66 | - type: 'bar', | 66 | + type: 'line', |
67 | stack: 'total', | 67 | stack: 'total', |
68 | data: newValue, | 68 | data: newValue, |
69 | - barWidth: '10%', | 69 | + // barWidth: '10%', |
70 | color: '#5AEEED', | 70 | color: '#5AEEED', |
71 | }, | 71 | }, |
72 | { | 72 | { |
73 | name: '传输消息量', | 73 | name: '传输消息量', |
74 | - type: 'bar', | 74 | + type: 'line', |
75 | stack: 'total', | 75 | stack: 'total', |
76 | - barWidth: '10%', | 76 | + // barWidth: '10%', |
77 | data: newValue1, | 77 | data: newValue1, |
78 | color: '#3C78FF', | 78 | color: '#3C78FF', |
79 | }, | 79 | }, |
@@ -35,7 +35,7 @@ export const step1Schemas: FormSchema[] = [ | @@ -35,7 +35,7 @@ export const step1Schemas: FormSchema[] = [ | ||
35 | }, | 35 | }, |
36 | { | 36 | { |
37 | field: 'profileId', | 37 | field: 'profileId', |
38 | - label: '设备配置', | 38 | + label: '所属产品', |
39 | required: true, | 39 | required: true, |
40 | component: 'ApiSelect', | 40 | component: 'ApiSelect', |
41 | componentProps: ({ formActionType }) => { | 41 | componentProps: ({ formActionType }) => { |
@@ -57,7 +57,7 @@ export const step1Schemas: FormSchema[] = [ | @@ -57,7 +57,7 @@ export const step1Schemas: FormSchema[] = [ | ||
57 | required: true, | 57 | required: true, |
58 | component: 'ApiSelect', | 58 | component: 'ApiSelect', |
59 | dynamicDisabled: true, | 59 | dynamicDisabled: true, |
60 | - helpMessage: ['选择设备配置,自动关联设备类型'], | 60 | + helpMessage: ['选择所属产品,自动关联设备类型'], |
61 | componentProps: { | 61 | componentProps: { |
62 | placeholder: '设备类型', | 62 | placeholder: '设备类型', |
63 | api: findDictItemByCode, | 63 | api: findDictItemByCode, |
@@ -21,7 +21,7 @@ export const descSchema: DescItem[] = [ | @@ -21,7 +21,7 @@ export const descSchema: DescItem[] = [ | ||
21 | }, | 21 | }, |
22 | { | 22 | { |
23 | field: 'deviceProfile.name', | 23 | field: 'deviceProfile.name', |
24 | - label: '设备配置', | 24 | + label: '产品', |
25 | }, | 25 | }, |
26 | { | 26 | { |
27 | field: 'gatewayName', | 27 | field: 'gatewayName', |
@@ -32,7 +32,7 @@ export const columns: BasicColumn[] = [ | @@ -32,7 +32,7 @@ export const columns: BasicColumn[] = [ | ||
32 | slots: { customRender: 'deviceType' }, | 32 | slots: { customRender: 'deviceType' }, |
33 | }, | 33 | }, |
34 | { | 34 | { |
35 | - title: '设备配置', | 35 | + title: '所属产品', |
36 | dataIndex: 'deviceProfile.name', | 36 | dataIndex: 'deviceProfile.name', |
37 | width: 160, | 37 | width: 160, |
38 | slots: { customRender: 'deviceProfile' }, | 38 | slots: { customRender: 'deviceProfile' }, |
@@ -103,6 +103,21 @@ | @@ -103,6 +103,21 @@ | ||
103 | <template #action="{ record }"> | 103 | <template #action="{ record }"> |
104 | <TableAction | 104 | <TableAction |
105 | :actions="[ | 105 | :actions="[ |
106 | + { | ||
107 | + label: '详情', | ||
108 | + icon: 'ant-design:eye-outlined', | ||
109 | + auth: 'api:yt:device:get', | ||
110 | + onClick: handleDetail.bind(null, record), | ||
111 | + }, | ||
112 | + { | ||
113 | + label: '编辑', | ||
114 | + auth: 'api:yt:device:update', | ||
115 | + icon: 'clarity:note-edit-line', | ||
116 | + ifShow: authBtn(role) && record.customerId === undefined, | ||
117 | + onClick: handleEdit.bind(null, record), | ||
118 | + }, | ||
119 | + ]" | ||
120 | + :dropDownActions="[ | ||
106 | record.customerId | 121 | record.customerId |
107 | ? { | 122 | ? { |
108 | label: '取消分配', | 123 | label: '取消分配', |
@@ -119,20 +134,6 @@ | @@ -119,20 +134,6 @@ | ||
119 | ifShow: authBtn(role), | 134 | ifShow: authBtn(role), |
120 | onClick: handleDispatchCustomer.bind(null, record), | 135 | onClick: handleDispatchCustomer.bind(null, record), |
121 | }, | 136 | }, |
122 | - | ||
123 | - { | ||
124 | - label: '详情', | ||
125 | - icon: 'ant-design:eye-outlined', | ||
126 | - auth: 'api:yt:device:get', | ||
127 | - onClick: handleDetail.bind(null, record), | ||
128 | - }, | ||
129 | - { | ||
130 | - label: '编辑', | ||
131 | - auth: 'api:yt:device:update', | ||
132 | - icon: 'clarity:note-edit-line', | ||
133 | - ifShow: authBtn(role) && record.customerId === undefined, | ||
134 | - onClick: handleEdit.bind(null, record), | ||
135 | - }, | ||
136 | { | 137 | { |
137 | label: '删除', | 138 | label: '删除', |
138 | auth: 'api:yt:device:delete', | 139 | auth: 'api:yt:device:delete', |
@@ -235,7 +236,7 @@ | @@ -235,7 +236,7 @@ | ||
235 | searchInfo: searchInfo, | 236 | searchInfo: searchInfo, |
236 | clickToRowSelect: false, | 237 | clickToRowSelect: false, |
237 | actionColumn: { | 238 | actionColumn: { |
238 | - width: 300, | 239 | + width: 200, |
239 | title: '操作', | 240 | title: '操作', |
240 | slots: { customRender: 'action' }, | 241 | slots: { customRender: 'action' }, |
241 | fixed: 'right', | 242 | fixed: 'right', |
@@ -33,7 +33,7 @@ export const formSchema: FormSchema[] = [ | @@ -33,7 +33,7 @@ export const formSchema: FormSchema[] = [ | ||
33 | component: 'ApiSelect', | 33 | component: 'ApiSelect', |
34 | componentProps: { | 34 | componentProps: { |
35 | api: getDeviceProfile, | 35 | api: getDeviceProfile, |
36 | - placeholder: '请选择设备配置', | 36 | + placeholder: '请选择产品', |
37 | labelField: 'name', | 37 | labelField: 'name', |
38 | valueField: 'id', | 38 | valueField: 'id', |
39 | }, | 39 | }, |
1 | +<template> | ||
2 | + <BasicDrawer v-bind="$attrs" title="产品详情" @register="register" width="50%"> | ||
3 | + <Tabs :animated="true" v-model:activeKey="activeKey"> | ||
4 | + <TabPane forceRender key="1" tab="产品"> | ||
5 | + <div class="relative"> | ||
6 | + <DeviceConfigurationStep :ifShowBtn="false" ref="DevConStRef" /> | ||
7 | + <div class="absolute w-full h-full top-0 cursor-not-allowed"></div> | ||
8 | + </div> | ||
9 | + </TabPane> | ||
10 | + <TabPane forceRender key="2" tab="传输配置"> | ||
11 | + <div class="relative"> | ||
12 | + <TransportConfigurationStep :ifShowBtn="false" ref="TransConStRef" /> | ||
13 | + <div class="absolute w-full h-full top-0 cursor-not-allowed"></div> | ||
14 | + </div> | ||
15 | + </TabPane> | ||
16 | + <TabPane forceRender key="3" tab="物模型管理"> | ||
17 | + <PhysicalModelManagementStep /> | ||
18 | + </TabPane> | ||
19 | + </Tabs> | ||
20 | + </BasicDrawer> | ||
21 | +</template> | ||
22 | +<script lang="ts" setup> | ||
23 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
24 | + import { Tabs, TabPane } from 'ant-design-vue'; | ||
25 | + import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue'; | ||
26 | + import TransportConfigurationStep from './step/TransportConfigurationStep.vue'; | ||
27 | + import PhysicalModelManagementStep from './step/PhysicalModelManagementStep.vue'; | ||
28 | + import { ref, unref } from 'vue'; | ||
29 | + import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi'; | ||
30 | + | ||
31 | + defineEmits(['register']); | ||
32 | + | ||
33 | + const activeKey = ref('1'); | ||
34 | + | ||
35 | + const DevConStRef = ref<InstanceType<typeof DeviceConfigurationStep>>(); | ||
36 | + const TransConStRef = ref<InstanceType<typeof TransportConfigurationStep>>(); | ||
37 | + // const PhysicalModManRef = ref<InstanceType<typeof PhysicalModelManagementStep>>(); | ||
38 | + | ||
39 | + const setDeviceConfFormData = async (res: Recordable) => { | ||
40 | + unref(DevConStRef)?.setFormData(res); | ||
41 | + }; | ||
42 | + const setTransConfFormData = async (res: Recordable) => { | ||
43 | + unref(TransConStRef)?.setFormData(res); | ||
44 | + }; | ||
45 | + | ||
46 | + const [register, {}] = useDrawerInner(async (data: Recordable) => { | ||
47 | + activeKey.value = '1'; | ||
48 | + const res = await deviceConfigGetDetail(data.record.id); | ||
49 | + setDeviceConfFormData(res); | ||
50 | + setTransConfFormData(res); | ||
51 | + }); | ||
52 | +</script> | ||
53 | + | ||
54 | +<style lang="less" scope></style> |
@@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
33 | :size="size" | 33 | :size="size" |
34 | @change="handleChange" | 34 | @change="handleChange" |
35 | > | 35 | > |
36 | - <TabPane forceRender key="1" tab="设备配置"> | 36 | + <TabPane forceRender key="1" tab="产品"> |
37 | <div class="relative"> | 37 | <div class="relative"> |
38 | <DeviceConfigurationStep | 38 | <DeviceConfigurationStep |
39 | :ifShowBtn="isViewDetail ? false : true" | 39 | :ifShowBtn="isViewDetail ? false : true" |
@@ -109,7 +109,7 @@ | @@ -109,7 +109,7 @@ | ||
109 | isEditCreatTime.value = data.record !== undefined ? data.record.createTime : null; | 109 | isEditCreatTime.value = data.record !== undefined ? data.record.createTime : null; |
110 | if (!unref(isViewDetail)) { | 110 | if (!unref(isViewDetail)) { |
111 | dynamicWidth.value = 55 + 'rem'; | 111 | dynamicWidth.value = 55 + 'rem'; |
112 | - const title = !unref(isUpdate) ? '编辑设备配置' : '新增设备配置'; | 112 | + const title = !unref(isUpdate) ? '编辑产品' : '新增产品'; |
113 | setModalProps({ title, showOkBtn: true, showCancelBtn: true }); | 113 | setModalProps({ title, showOkBtn: true, showCancelBtn: true }); |
114 | if (!unref(isUpdate)) { | 114 | if (!unref(isUpdate)) { |
115 | await setDeviceConfEditFormData(res); | 115 | await setDeviceConfEditFormData(res); |
@@ -118,7 +118,7 @@ | @@ -118,7 +118,7 @@ | ||
118 | } | 118 | } |
119 | } else { | 119 | } else { |
120 | dynamicWidth.value = 60 + 'rem'; | 120 | dynamicWidth.value = 60 + 'rem'; |
121 | - setModalProps({ showOkBtn: false, showCancelBtn: false, title: '设备配置详情' }); | 121 | + setModalProps({ showOkBtn: false, showCancelBtn: false, title: '产品详情' }); |
122 | await setDeviceConfEditFormData(res); | 122 | await setDeviceConfEditFormData(res); |
123 | await setTransConfEditFormData(res); | 123 | await setTransConfEditFormData(res); |
124 | handleStepNext(false, res); | 124 | handleStepNext(false, res); |
@@ -10,7 +10,7 @@ import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; | @@ -10,7 +10,7 @@ import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; | ||
10 | 10 | ||
11 | export const steps = [ | 11 | export const steps = [ |
12 | { | 12 | { |
13 | - title: '设备配置', | 13 | + title: '产品', |
14 | content: 'First-content', | 14 | content: 'First-content', |
15 | }, | 15 | }, |
16 | { | 16 | { |
@@ -8,11 +8,11 @@ | @@ -8,11 +8,11 @@ | ||
8 | > | 8 | > |
9 | <template #toolbar> | 9 | <template #toolbar> |
10 | <Authority value="api:yt:deviceProfile:post"> | 10 | <Authority value="api:yt:deviceProfile:post"> |
11 | - <a-button type="primary" @click="handleCreate"> 新增设备配置 </a-button> | 11 | + <a-button type="primary" @click="handleCreate"> 新增产品 </a-button> |
12 | </Authority> | 12 | </Authority> |
13 | <Authority value="api:yt:deviceProfile:import"> | 13 | <Authority value="api:yt:deviceProfile:import"> |
14 | <ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD"> | 14 | <ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD"> |
15 | - <a-button @click="handleImport"> 导入设备配置 </a-button> | 15 | + <a-button @click="handleImport"> 导入产品 </a-button> |
16 | </ImpExcel> | 16 | </ImpExcel> |
17 | </Authority> | 17 | </Authority> |
18 | <Authority value="api:yt:deviceProfile:delete"> | 18 | <Authority value="api:yt:deviceProfile:delete"> |
@@ -42,14 +42,6 @@ | @@ -42,14 +42,6 @@ | ||
42 | <TableAction | 42 | <TableAction |
43 | :actions="[ | 43 | :actions="[ |
44 | { | 44 | { |
45 | - label: '默认', | ||
46 | - icon: 'ant-design:profile-outlined', | ||
47 | - onClick: handleSetDefault.bind(null, record), | ||
48 | - ifShow: () => { | ||
49 | - return record.default === false; | ||
50 | - }, | ||
51 | - }, | ||
52 | - { | ||
53 | label: '详情', | 45 | label: '详情', |
54 | auth: 'api:yt:deviceProfile:get', | 46 | auth: 'api:yt:deviceProfile:get', |
55 | icon: 'ant-design:eye-outlined', | 47 | icon: 'ant-design:eye-outlined', |
@@ -64,6 +56,16 @@ | @@ -64,6 +56,16 @@ | ||
64 | return record.name !== 'default' ? true : false; | 56 | return record.name !== 'default' ? true : false; |
65 | }, | 57 | }, |
66 | }, | 58 | }, |
59 | + ]" | ||
60 | + :drop-down-actions="[ | ||
61 | + { | ||
62 | + label: '默认', | ||
63 | + icon: 'ant-design:profile-outlined', | ||
64 | + onClick: handleSetDefault.bind(null, record), | ||
65 | + ifShow: () => { | ||
66 | + return record.default === false; | ||
67 | + }, | ||
68 | + }, | ||
67 | { | 69 | { |
68 | label: '导出', | 70 | label: '导出', |
69 | auth: 'api:yt:deviceProfile:export', | 71 | auth: 'api:yt:deviceProfile:export', |
@@ -88,6 +90,7 @@ | @@ -88,6 +90,7 @@ | ||
88 | </template> | 90 | </template> |
89 | </BasicTable> | 91 | </BasicTable> |
90 | <DeviceProfileModal @register="registerModal" @success="handleSuccess" /> | 92 | <DeviceProfileModal @register="registerModal" @success="handleSuccess" /> |
93 | + <DeviceProfileDrawer @register="registerDrawer" /> | ||
91 | <ExpExcelModal | 94 | <ExpExcelModal |
92 | ref="expExcelModalRef" | 95 | ref="expExcelModalRef" |
93 | @register="registerExportModal" | 96 | @register="registerExportModal" |
@@ -106,12 +109,14 @@ | @@ -106,12 +109,14 @@ | ||
106 | setDeviceProfileIsDefaultApi, | 109 | setDeviceProfileIsDefaultApi, |
107 | } from '/@/api/device/deviceConfigApi'; | 110 | } from '/@/api/device/deviceConfigApi'; |
108 | import { useModal } from '/@/components/Modal'; | 111 | import { useModal } from '/@/components/Modal'; |
112 | + import { useDrawer } from '/@/components/Drawer'; | ||
109 | import DeviceProfileModal from '/@/views/device/profiles/DeviceProfileModal.vue'; | 113 | import DeviceProfileModal from '/@/views/device/profiles/DeviceProfileModal.vue'; |
110 | import { ImpExcel, ExcelData } from '/@/components/Excel'; | 114 | import { ImpExcel, ExcelData } from '/@/components/Excel'; |
111 | import { jsonToSheetXlsx, ExpExcelModal, ExportModalResult } from '/@/components/Excel'; | 115 | import { jsonToSheetXlsx, ExpExcelModal, ExportModalResult } from '/@/components/Excel'; |
112 | import { Authority } from '/@/components/Authority'; | 116 | import { Authority } from '/@/components/Authority'; |
113 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | 117 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
114 | import { Popconfirm } from 'ant-design-vue'; | 118 | import { Popconfirm } from 'ant-design-vue'; |
119 | + import DeviceProfileDrawer from './DeviceProfileDrawer.vue'; | ||
115 | 120 | ||
116 | const exportData: any = ref([]); | 121 | const exportData: any = ref([]); |
117 | const expExcelModalRef: any = ref(null); | 122 | const expExcelModalRef: any = ref(null); |
@@ -124,7 +129,7 @@ | @@ -124,7 +129,7 @@ | ||
124 | const [registerModal, { openModal }] = useModal(); | 129 | const [registerModal, { openModal }] = useModal(); |
125 | const [registerExportModal, { openModal: openModalExcel }] = useModal(); | 130 | const [registerExportModal, { openModal: openModalExcel }] = useModal(); |
126 | const [registerTable, { setProps, reload, setTableData, getForm }] = useTable({ | 131 | const [registerTable, { setProps, reload, setTableData, getForm }] = useTable({ |
127 | - title: '设备配置列表', | 132 | + title: '产品列表', |
128 | clickToRowSelect: false, | 133 | clickToRowSelect: false, |
129 | api: deviceConfigGetQuery, | 134 | api: deviceConfigGetQuery, |
130 | immediate: immediateStatus.value, | 135 | immediate: immediateStatus.value, |
@@ -139,7 +144,7 @@ | @@ -139,7 +144,7 @@ | ||
139 | bordered: true, | 144 | bordered: true, |
140 | showIndexColumn: false, | 145 | showIndexColumn: false, |
141 | actionColumn: { | 146 | actionColumn: { |
142 | - width: 240, | 147 | + width: 200, |
143 | title: '操作', | 148 | title: '操作', |
144 | dataIndex: 'action', | 149 | dataIndex: 'action', |
145 | slots: { customRender: 'action' }, | 150 | slots: { customRender: 'action' }, |
@@ -251,13 +256,16 @@ | @@ -251,13 +256,16 @@ | ||
251 | isView: false, | 256 | isView: false, |
252 | }); | 257 | }); |
253 | } | 258 | } |
259 | + | ||
260 | + const [registerDrawer, { openDrawer }] = useDrawer(); | ||
254 | //详情 | 261 | //详情 |
255 | function handleDetailView(record: Recordable) { | 262 | function handleDetailView(record: Recordable) { |
256 | - openModal(true, { | ||
257 | - record, | ||
258 | - isUpdate: false, | ||
259 | - isView: true, | ||
260 | - }); | 263 | + openDrawer(true, { record }); |
264 | + // openModal(true, { | ||
265 | + // record, | ||
266 | + // isUpdate: false, | ||
267 | + // isView: true, | ||
268 | + // }); | ||
261 | } | 269 | } |
262 | 270 | ||
263 | function defaultHeader({ filename, bookType }: ExportModalResult) { | 271 | function defaultHeader({ filename, bookType }: ExportModalResult) { |
@@ -295,8 +303,8 @@ | @@ -295,8 +303,8 @@ | ||
295 | const handleSetDefault = async (record: Recordable) => { | 303 | const handleSetDefault = async (record: Recordable) => { |
296 | let id = record.tbProfileId; | 304 | let id = record.tbProfileId; |
297 | const data = await setDeviceProfileIsDefaultApi(id, 'default', defaultObj); | 305 | const data = await setDeviceProfileIsDefaultApi(id, 'default', defaultObj); |
298 | - if (!data) return createMessage.error('设置该设备配置为默认失败'); | ||
299 | - createMessage.success('设置该设备配置为默认成功'); | 306 | + if (!data) return createMessage.error('设置该产品为默认失败'); |
307 | + createMessage.success('设置该产品为默认成功'); | ||
300 | reload(); | 308 | reload(); |
301 | disabled.value = true; | 309 | disabled.value = true; |
302 | }; | 310 | }; |
@@ -151,7 +151,7 @@ | @@ -151,7 +151,7 @@ | ||
151 | showIndexColumn: false, | 151 | showIndexColumn: false, |
152 | clickToRowSelect: false, | 152 | clickToRowSelect: false, |
153 | useSearchForm: false, | 153 | useSearchForm: false, |
154 | - rowKey: 'id', | 154 | + // rowKey: 'id', |
155 | showTableSetting: true, | 155 | showTableSetting: true, |
156 | bordered: true, | 156 | bordered: true, |
157 | actionColumn: { | 157 | actionColumn: { |
1 | <template> | 1 | <template> |
2 | - <div style="background-color: #f0f2f5"> | ||
3 | - <BasicTable @register="registerTable"> | 2 | + <div style="background-color: #f0f2f5" class="dark:bg-dark-900"> |
3 | + <BasicTable @register="registerTable" class="dark:bg-dark-900"> | ||
4 | <template #toolbar> | 4 | <template #toolbar> |
5 | <Authority value="api:yt:smsLog:export"> | 5 | <Authority value="api:yt:smsLog:export"> |
6 | <a-button type="primary" @click="handleCreate"> 导出 </a-button> | 6 | <a-button type="primary" @click="handleCreate"> 导出 </a-button> |
1 | <template> | 1 | <template> |
2 | - <div style="background-color: #f0f2f5"> | ||
3 | - <BasicTable @register="registerTable"> | 2 | + <div style="background-color: #f0f2f5" class="dark:bg-dark-900"> |
3 | + <BasicTable @register="registerTable" class="dark:bg-dark-900"> | ||
4 | <template #toolbar> | 4 | <template #toolbar> |
5 | <Authority value="api:yt:smsLog:export"> | 5 | <Authority value="api:yt:smsLog:export"> |
6 | <a-button type="primary" @click="handleExport"> 导出 </a-button> | 6 | <a-button type="primary" @click="handleExport"> 导出 </a-button> |
@@ -103,15 +103,15 @@ export const formSchema: FormSchema[] = [ | @@ -103,15 +103,15 @@ export const formSchema: FormSchema[] = [ | ||
103 | }, | 103 | }, |
104 | { | 104 | { |
105 | field: PackageField.DEVICE_PROFILE_INFO, | 105 | field: PackageField.DEVICE_PROFILE_INFO, |
106 | - label: '设备配置', | 106 | + label: '所属产品', |
107 | component: 'ApiSearchSelect', | 107 | component: 'ApiSearchSelect', |
108 | helpMessage: ['上传的包仅适用于具有所选配置文件的设备'], | 108 | helpMessage: ['上传的包仅适用于具有所选配置文件的设备'], |
109 | defaultValue: 'default', | 109 | defaultValue: 'default', |
110 | - rules: [{ required: true, message: '设备配置为必填项' }], | 110 | + rules: [{ required: true, message: '所属产品为必填项' }], |
111 | componentProps: ({ formActionType }) => { | 111 | componentProps: ({ formActionType }) => { |
112 | const { setFieldsValue } = formActionType; | 112 | const { setFieldsValue } = formActionType; |
113 | return { | 113 | return { |
114 | - placeholder: '请选择设备配置', | 114 | + placeholder: '请选择所属产品', |
115 | showSearch: true, | 115 | showSearch: true, |
116 | resultField: 'data', | 116 | resultField: 'data', |
117 | labelField: 'name', | 117 | labelField: 'name', |
@@ -137,7 +137,7 @@ export const formSchema: FormSchema[] = [ | @@ -137,7 +137,7 @@ export const formSchema: FormSchema[] = [ | ||
137 | field: PackageField.PACKAGE_TYPE, | 137 | field: PackageField.PACKAGE_TYPE, |
138 | label: '包类型', | 138 | label: '包类型', |
139 | component: 'Select', | 139 | component: 'Select', |
140 | - helpMessage: ['上传包后,您将无法修改标题、版本、设备配置文件和包类型'], | 140 | + helpMessage: ['上传包后,您将无法修改标题、版本、产品文件和包类型'], |
141 | defaultValue: PackageType.FIRMWARE, | 141 | defaultValue: PackageType.FIRMWARE, |
142 | rules: [{ required: true, message: '包类型为必填项' }], | 142 | rules: [{ required: true, message: '包类型为必填项' }], |
143 | componentProps: () => { | 143 | componentProps: () => { |
@@ -146,7 +146,7 @@ export const formSchema: FormSchema[] = [ | @@ -146,7 +146,7 @@ export const formSchema: FormSchema[] = [ | ||
146 | { label: '固件', value: PackageType.FIRMWARE }, | 146 | { label: '固件', value: PackageType.FIRMWARE }, |
147 | { label: '软件', value: PackageType.SOFTWARE }, | 147 | { label: '软件', value: PackageType.SOFTWARE }, |
148 | ], | 148 | ], |
149 | - placeholder: '请选择设备配置', | 149 | + placeholder: '请选择所属产品', |
150 | }; | 150 | }; |
151 | }, | 151 | }, |
152 | }, | 152 | }, |
@@ -21,7 +21,7 @@ export const formSchema: FormSchema[] = [ | @@ -21,7 +21,7 @@ export const formSchema: FormSchema[] = [ | ||
21 | }, | 21 | }, |
22 | { | 22 | { |
23 | field: PackageField.DEVICE_PROFILE_INFO, | 23 | field: PackageField.DEVICE_PROFILE_INFO, |
24 | - label: '设备配置', | 24 | + label: '所属产品', |
25 | component: 'Input', | 25 | component: 'Input', |
26 | }, | 26 | }, |
27 | { | 27 | { |
@@ -35,7 +35,7 @@ export const formSchema: FormSchema[] = [ | @@ -35,7 +35,7 @@ export const formSchema: FormSchema[] = [ | ||
35 | { label: '固件', value: PackageType.FIRMWARE }, | 35 | { label: '固件', value: PackageType.FIRMWARE }, |
36 | { label: '软件', value: PackageType.SOFTWARE }, | 36 | { label: '软件', value: PackageType.SOFTWARE }, |
37 | ], | 37 | ], |
38 | - placeholder: '请选择设备配置', | 38 | + placeholder: '请选择所属产品', |
39 | }; | 39 | }; |
40 | }, | 40 | }, |
41 | }, | 41 | }, |
@@ -32,6 +32,8 @@ | @@ -32,6 +32,8 @@ | ||
32 | onClick: handleEdit.bind(null, record), | 32 | onClick: handleEdit.bind(null, record), |
33 | ifShow: record.creator === userId && record.status !== 1, | 33 | ifShow: record.creator === userId && record.status !== 1, |
34 | }, | 34 | }, |
35 | + ]" | ||
36 | + :drop-down-actions="[ | ||
35 | { | 37 | { |
36 | label: '删除', | 38 | label: '删除', |
37 | auth: 'api:yt:sceneLinkage:delete', | 39 | auth: 'api:yt:sceneLinkage:delete', |
@@ -60,7 +60,8 @@ | @@ -60,7 +60,8 @@ | ||
60 | converScriptRef.value?.setFormData(data.record); | 60 | converScriptRef.value?.setFormData(data.record); |
61 | } | 61 | } |
62 | if (unref(isTitle) == 'test') { | 62 | if (unref(isTitle) == 'test') { |
63 | - converScriptRef.value?.setScriptContentData(''); | 63 | + // converScriptRef.value?.setScriptContentData(''); |
64 | + converScriptRef.value?.setFormData(data.record); | ||
64 | } | 65 | } |
65 | setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); | 66 | setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); |
66 | if (!unref(isUpdate)) { | 67 | if (!unref(isUpdate)) { |
@@ -28,7 +28,7 @@ export const columns: BasicColumn[] = [ | @@ -28,7 +28,7 @@ export const columns: BasicColumn[] = [ | ||
28 | slots: { customRender: 'convertJs' }, | 28 | slots: { customRender: 'convertJs' }, |
29 | }, | 29 | }, |
30 | { | 30 | { |
31 | - title: '描述', | 31 | + title: '备注', |
32 | dataIndex: 'description', | 32 | dataIndex: 'description', |
33 | width: 120, | 33 | width: 120, |
34 | }, | 34 | }, |
@@ -61,6 +61,8 @@ | @@ -61,6 +61,8 @@ | ||
61 | onClick: handleEdit.bind(null, record), | 61 | onClick: handleEdit.bind(null, record), |
62 | ifShow: record.level != 0, | 62 | ifShow: record.level != 0, |
63 | }, | 63 | }, |
64 | + ]" | ||
65 | + :drop-down-actions="[ | ||
64 | { | 66 | { |
65 | label: '删除', | 67 | label: '删除', |
66 | auth: 'api:yt:user:delete', | 68 | auth: 'api:yt:user:delete', |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | </script> | 15 | </script> |
16 | 16 | ||
17 | <template> | 17 | <template> |
18 | - <section class="widget"> | 18 | + <section class="widget !dark:bg-dark-900"> |
19 | <slot name="header"></slot> | 19 | <slot name="header"></slot> |
20 | 20 | ||
21 | <div class="widget-content"> | 21 | <div class="widget-content"> |
@@ -45,7 +45,14 @@ | @@ -45,7 +45,14 @@ | ||
45 | 45 | ||
46 | .widget-select:deep(.ant-card-body) { | 46 | .widget-select:deep(.ant-card-body) { |
47 | /* height: 240px; */ | 47 | /* height: 240px; */ |
48 | - width: 240px; | 48 | + |
49 | + /* width: 236px; | ||
50 | + height: 196px; */ | ||
51 | + | ||
52 | + /* width: 100%; | ||
53 | + height: 100%; */ | ||
54 | + width: 236px; | ||
55 | + height: 236px; | ||
49 | padding: 0; | 56 | padding: 0; |
50 | box-sizing: border-box; | 57 | box-sizing: border-box; |
51 | display: flex; | 58 | display: flex; |
@@ -64,10 +71,18 @@ | @@ -64,10 +71,18 @@ | ||
64 | } | 71 | } |
65 | 72 | ||
66 | .widget-select .widget-container { | 73 | .widget-select .widget-container { |
67 | - width: 240px; | ||
68 | - height: 200px; | 74 | + width: 236px; |
75 | + height: 196px; | ||
69 | display: flex; | 76 | display: flex; |
70 | justify-content: center; | 77 | justify-content: center; |
71 | align-items: center; | 78 | align-items: center; |
72 | } | 79 | } |
80 | + | ||
81 | + [data-theme='dark'] .widget-select:deep(.ant-card-body) { | ||
82 | + @apply bg-dark-900; | ||
83 | + } | ||
84 | + | ||
85 | + [data-theme='dark'] .widget-select:deep(.ant-card) { | ||
86 | + @apply border-dark-300; | ||
87 | + } | ||
73 | </style> | 88 | </style> |
@@ -565,6 +565,10 @@ | @@ -565,6 +565,10 @@ | ||
565 | background-color: #fff; | 565 | background-color: #fff; |
566 | } | 566 | } |
567 | 567 | ||
568 | + [data-theme='dark'] .board-detail:deep(.ant-page-header-heading) { | ||
569 | + @apply bg-dark-900; | ||
570 | + } | ||
571 | + | ||
568 | .board-detail:deep(.ant-page-header-heading-extra) { | 572 | .board-detail:deep(.ant-page-header-heading-extra) { |
569 | margin: 0; | 573 | margin: 0; |
570 | line-height: 78px; | 574 | line-height: 78px; |
@@ -189,13 +189,13 @@ | @@ -189,13 +189,13 @@ | ||
189 | 189 | ||
190 | <template> | 190 | <template> |
191 | <PageWrapper> | 191 | <PageWrapper> |
192 | - <div class="flex items-center mb-3 bg-light-100 h-78px"> | 192 | + <div class="flex items-center mb-3 bg-light-100 h-78px dark:text-gray-300 dark:bg-dark-900"> |
193 | <div class="text-lg ml-30px mr-9px font-bold">自定义看板</div> | 193 | <div class="text-lg ml-30px mr-9px font-bold">自定义看板</div> |
194 | <Authority value="api:yt:data_board:add:post"> | 194 | <Authority value="api:yt:data_board:add:post"> |
195 | <Button type="primary" @click="handleOpenDetailModal">创建看板</Button> | 195 | <Button type="primary" @click="handleOpenDetailModal">创建看板</Button> |
196 | </Authority> | 196 | </Authority> |
197 | </div> | 197 | </div> |
198 | - <div class="bg-light-100 mb-6 w-full p-3 search-form"> | 198 | + <div class="bg-light-100 mb-6 w-full p-3 search-form dark:text-gray-300 dark:bg-dark-900"> |
199 | <BasicForm class="flex-auto w-full" @register="searchFormRegister" /> | 199 | <BasicForm class="flex-auto w-full" @register="searchFormRegister" /> |
200 | </div> | 200 | </div> |
201 | <Spin :spinning="loading"> | 201 | <Spin :spinning="loading"> |
@@ -309,4 +309,9 @@ | @@ -309,4 +309,9 @@ | ||
309 | padding: 10px; | 309 | padding: 10px; |
310 | background-color: #fff; | 310 | background-color: #fff; |
311 | } | 311 | } |
312 | + | ||
313 | + [data-theme='dark'] .data-board-list:deep(.ant-list-pagination) { | ||
314 | + padding: 10px; | ||
315 | + background-color: #000; | ||
316 | + } | ||
312 | </style> | 317 | </style> |