Commit 904cbc287aaf24a675f43c50ac5a23e4bf0665fe

Authored by ww
1 parent f5190842

perf: 优化组态管理独立组态页面

... ... @@ -174,13 +174,12 @@
174 174 overflow-x: hidden;
175 175 overflow-y: auto;
176 176
177   - .ant-row {
178   - row-gap: 16px;
179   -
180   - .ant-list-item {
181   - margin-bottom: 0;
182   - }
183   - }
  177 + // .ant-row {
  178 + // .ant-col {
  179 + // }
  180 + // .ant-list-item {
  181 + // }
  182 + // }
184 183 }
185 184
186 185 .ant-list-header {
... ...
1 1 import { Ref, computed, reactive, unref } from 'vue';
2 2 import { BasicCardListPropsType, ListGridType } from '../types';
3 3 import { getListGridByColumn } from '../utils';
  4 +import { screenMap, sizeEnum } from '/@/enums/breakpointEnum';
4 5
5 6 export function useListGrid(getProps: Ref<BasicCardListPropsType>) {
6 7 const cardListLayout = reactive({ row: 2, col: 5 });
... ... @@ -15,8 +16,31 @@ export function useListGrid(getProps: Ref<BasicCardListPropsType>) {
15 16 } as ListGridType;
16 17 });
17 18
  19 + function getScreenSize() {
  20 + const width = document.body.clientWidth;
  21 + const xs = screenMap.get(sizeEnum.XS)!;
  22 + const sm = screenMap.get(sizeEnum.SM)!;
  23 + const md = screenMap.get(sizeEnum.MD)!;
  24 + const lg = screenMap.get(sizeEnum.LG)!;
  25 + const xl = screenMap.get(sizeEnum.XL)!;
  26 + if (width < xs) {
  27 + return sizeEnum.XS;
  28 + } else if (width < sm) {
  29 + return sizeEnum.SM;
  30 + } else if (width < md) {
  31 + return sizeEnum.MD;
  32 + } else if (width < lg) {
  33 + return sizeEnum.LG;
  34 + } else if (width < xl) {
  35 + return sizeEnum.XL;
  36 + } else {
  37 + return sizeEnum.XXL;
  38 + }
  39 + }
  40 +
18 41 return {
19 42 getListGrid,
20 43 cardListLayout,
  44 + getScreenSize,
21 45 };
22 46 }
... ...
... ... @@ -3,10 +3,10 @@ import { ListGridType } from '../types';
3 3 export const getListGridByColumn = (col: number): Omit<ListGridType, 'gutter' | 'column'> => {
4 4 return {
5 5 xxl: col,
6   - xl: col,
7   - lg: Math.min(col - 1, 2),
8   - md: Math.min(col - 1, 2),
9   - sm: Math.min(col - 2, 2),
10   - xs: Math.min(col - 2, 2),
  6 + xl: Math.max(1, col - 1),
  7 + lg: Math.max(1, col - 2),
  8 + md: Math.max(1, col - 3),
  9 + sm: Math.max(1, col - 4),
  10 + xs: Math.max(1, col - 5),
11 11 };
12 12 };
... ...
1 1 <script setup lang="ts">
2   - import { List, Card, Button, PaginationProps, Tooltip } from 'ant-design-vue';
3   - import { ReloadOutlined } from '@ant-design/icons-vue';
4   - import { computed, onMounted, reactive, ref, unref } from 'vue';
5   - import { OrganizationIdTree, useResetOrganizationTree } from '../../common/organizationIdTree';
  2 + import { BasicCardList, useCardList } from '/@/components/CardList';
6 3 import {
7 4 deleteConfigurationCenter,
8 5 getPage,
9 6 shareConfiguration,
10 7 } from '/@/api/configuration/center/configurationCenter';
  8 + import { searchFormSchema, ConfigurationPermission } from './center.data';
11 9 import { ConfigurationCenterItemsModal } from '/@/api/configuration/center/model/configurationCenterModal';
12   - import { PageWrapper } from '/@/components/Page';
13   - import { BasicForm, useForm } from '/@/components/Form';
14   - import { ConfigurationPermission, Platform, searchFormSchema } from './center.data';
15   - import { useMessage } from '/@/hooks/web/useMessage';
16 10 import { Authority } from '/@/components/Authority';
17   - import ConfigurationCenterDrawer from './ConfigurationCenterDrawer.vue';
18   - import { useDrawer } from '/@/components/Drawer';
19   - import { getBoundingClientRect } from '/@/utils/domUtils';
  11 + import { Button, Card, Tooltip } from 'ant-design-vue';
  12 + import { useRole } from '/@/hooks/business/useRole';
20 13 import configurationSrc from '/@/assets/icons/configuration.svg';
21   - import { cloneDeep } from 'lodash';
  14 + import { Platform } from '../center/center.data';
  15 + import { computed, unref } from 'vue';
  16 + import { createScadaPageLink, ScadaModeEnum } from '../center/help';
  17 + import { useDrawer } from '/@/components/Drawer';
22 18 import { usePermission } from '/@/hooks/web/usePermission';
23   - import { AuthIcon, CardLayoutButton } from '/@/components/Widget';
24   - import AuthDropDown from '/@/components/Widget/AuthDropDown.vue';
25   - import { ShareModal } from '/@/views/common/ShareModal';
26   - import { ViewTypeNameEnum } from '../../common/ShareModal/config';
27   - import { useModal } from '/@/components/Modal';
28   - import { ViewType } from '../../visual/board/config/panelDetail';
29   - import { useRole } from '/@/hooks/business/useRole';
30   - import { useClipboard } from '@vueuse/core';
  19 + import { useMessage } from '/@/hooks/web/useMessage';
31 20 import { Icon } from '/@/components/Icon';
32   - import { createScadaPageLink, ScadaModeEnum } from './help';
33   -
34   - const listColumn = ref(5);
35   -
36   - const { createMessage } = useMessage();
37   -
38   - const { isCustomerUser } = useRole();
39   -
40   - const organizationId = ref<Nullable<number>>(null);
  21 + import { AuthIcon, AuthDropDown } from '/@/components/Widget';
  22 + import { cloneDeep } from 'lodash-es';
  23 + import { OrganizationIdTree, useOrganizationTree } from '../../common/organizationIdTree';
  24 + import ConfigurationCenterDrawer from './ConfigurationCenterDrawer.vue';
  25 + import { useClipboard } from '@vueuse/core';
  26 + import { useModal } from '/@/components/Modal';
  27 + import { ShareModal } from '/@/views/common/ShareModal';
41 28
42   - const pagination = reactive<PaginationProps>({
43   - size: 'small',
44   - showTotal: (total: number) => `共 ${total} 条数据`,
45   - current: 1,
46   - pageSize: unref(listColumn) * 2,
47   - onChange: (page: number) => {
48   - pagination.current = page;
49   - getListData();
  29 + const [register, { reload }] = useCardList({
  30 + api: getPage,
  31 + useSearchForm: true,
  32 + formConfig: {
  33 + schemas: searchFormSchema,
  34 + labelWidth: 80,
  35 + resetFunc: async () => {
  36 + clearSelected();
  37 + },
  38 + },
  39 + beforeFetch: async (params: Recordable) => {
  40 + return { ...params, organizationId: getSelectKey(), isTemplate: 0 };
50 41 },
51 42 });
52 43
53   - const loading = ref(false);
54   -
55   - const dataSource = ref<ConfigurationCenterItemsModal[]>([]);
56   -
57   - const [registerForm, { getFieldsValue }] = useForm({
58   - schemas: searchFormSchema,
59   - showAdvancedButton: true,
60   - labelWidth: 100,
61   - compact: true,
62   - resetFunc: () => {
63   - resetFn();
64   - organizationId.value = null;
65   - return getListData();
66   - },
67   - submitFunc: async () => {
68   - const value = getFieldsValue();
69   - getListData(value);
  44 + const [registerOrgTree, { getSelectKey, clearSelected }] = useOrganizationTree({
  45 + onSelect: () => {
  46 + reload();
70 47 },
71 48 });
72 49
73   - async function getListData(value: Recordable = {}) {
74   - try {
75   - loading.value = true;
76   - const pageSize = unref(listColumn) * 2;
77   - const { items, total } = await getPage({
78   - organizationId: unref(organizationId),
79   - ...value,
80   - isTemplate: 0,
81   - page: pagination.current!,
82   - pageSize,
83   - });
84   -
85   - dataSource.value = items;
86   - Object.assign(pagination, { total, pageSize });
87   - } catch (error) {
88   - } finally {
89   - loading.value = false;
90   - }
91   - }
  50 + const [registerDrawer, { openDrawer }] = useDrawer();
92 51
93   - onMounted(() => {
94   - getListData();
95   - });
  52 + const [registerShareModal, { openModal }] = useModal();
96 53
97   - const searchInfo = reactive<Recordable>({});
98   - const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
99   - const handleSelect = (orgId: number) => {
100   - organizationId.value = orgId;
101   - getListData();
  54 + const handleOpenShareModal = (record: ConfigurationCenterItemsModal) => {
  55 + openModal(true, { record, href: createShareUrl(record) });
102 56 };
103 57
104   - const [registerDrawer, { openDrawer }] = useDrawer();
  58 + const { createMessage } = useMessage();
  59 +
  60 + const { isCustomerUser } = useRole();
105 61
106 62 const { hasPermission } = usePermission();
107 63
... ... @@ -141,19 +97,6 @@
141 97 createScadaPageLink(record, ScadaModeEnum.DESIGN);
142 98 };
143 99
144   - const handleDelete = async (record: ConfigurationCenterItemsModal) => {
145   - try {
146   - await deleteConfigurationCenter([record.id]);
147   - createMessage.success('删除成功');
148   - await getListData();
149   - } catch (error) {}
150   - };
151   -
152   - const handleCardLayoutChange = () => {
153   - pagination.current = 1;
154   - getListData();
155   - };
156   -
157 100 const createShareUrl = (record: ConfigurationCenterItemsModal) => {
158 101 return createScadaPageLink(record, ScadaModeEnum.SHARE, false);
159 102 };
... ... @@ -168,209 +111,130 @@
168 111 }
169 112 };
170 113
171   - const [registerShareModal, { openModal }] = useModal();
172   -
173   - const handleOpenShareModal = (record: ConfigurationCenterItemsModal) => {
174   - openModal(true, { record, href: createShareUrl(record) });
  114 + const handleDelete = async (record: ConfigurationCenterItemsModal) => {
  115 + try {
  116 + await deleteConfigurationCenter([record.id]);
  117 + createMessage.success('删除成功');
  118 + await reload();
  119 + } catch (error) {}
175 120 };
176   -
177   - const listEl = ref<Nullable<ComponentElRef>>(null);
178   -
179   - onMounted(() => {
180   - const clientHeight = document.documentElement.clientHeight;
181   - const rect = getBoundingClientRect(unref(listEl)!.$el! as HTMLElement) as DOMRect;
182   - // margin-top 24 height 24
183   - const paginationHeight = 24 + 24 + 8;
184   - // list pading top 8 maring-top 8 extra slot 56
185   - const listContainerMarginBottom = 8 + 8 + 56;
186   - const listContainerHeight =
187   - clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
188   - const listContainerEl = (unref(listEl)!.$el as HTMLElement).querySelector(
189   - '.ant-spin-container'
190   - ) as HTMLElement;
191   - listContainerEl &&
192   - (listContainerEl.style.height = listContainerHeight + 'px') &&
193   - (listContainerEl.style.overflowY = 'auto') &&
194   - (listContainerEl.style.overflowX = 'hidden');
195   - });
196 121 </script>
197 122
198 123 <template>
199   - <PageWrapper dense contentFullHeight contentClass="flex">
200   - <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
201   - <section class="flex-auto p-4 w-3/4 xl:w-4/5 w-full configuration-list">
202   - <div class="flex-auto w-full bg-light-50 dark:bg-dark-900 p-4">
203   - <BasicForm @register="registerForm" />
204   - </div>
205   - <List
206   - ref="listEl"
207   - :loading="loading"
208   - class="flex-auto bg-light-50 dark:bg-dark-900 !p-2 !mt-4"
209   - position="bottom"
210   - :pagination="pagination"
211   - :data-source="dataSource"
212   - :grid="{ gutter: 4, column: listColumn }"
213   - >
214   - <template #header>
215   - <div class="flex gap-3 justify-end">
216   - <Authority v-if="!isCustomerUser" :value="ConfigurationPermission.CREATE">
217   - <Button type="primary" @click="handleCreateOrUpdate()">新增组态</Button>
218   - </Authority>
219   - <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" />
220   - <Tooltip title="刷新">
221   - <Button type="primary" @click="getListData">
222   - <ReloadOutlined />
223   - </Button>
224   - </Tooltip>
225   - </div>
226   - </template>
227   - <template #renderItem="{ item }">
228   - <List.Item>
229   - <Card
230   - :style="{
231   - '--viewType': item.viewType === ViewType.PUBLIC_VIEW ? '#1890ff' : '#faad14',
232   - }"
233   - hoverable
234   - class="card-container"
  124 + <section class="flex w-full h-full">
  125 + <OrganizationIdTree @register="registerOrgTree" />
  126 + <BasicCardList class="flex-auto p-4 w-3/4 xl:w-4/5 w-full" @register="register">
  127 + <template #toolbar>
  128 + <div class="flex gap-3 justify-end">
  129 + <Authority v-if="!isCustomerUser" :value="ConfigurationPermission.CREATE">
  130 + <Button type="primary" @click="handleCreateOrUpdate()">新增组态</Button>
  131 + </Authority>
  132 + </div>
  133 + </template>
  134 + <template #renderItem="{ item }: CardListRenderItem<ConfigurationCenterItemsModal>">
  135 + <Card
  136 + :style="{
  137 + '--viewType': '#1890ff',
  138 + }"
  139 + hoverable
  140 + class="card-container"
  141 + >
  142 + <template #cover>
  143 + <div
  144 + class="img-container h-full w-full !flex justify-center items-center text-center p-1 relative"
235 145 >
236   - <template #cover>
237   - <div
238   - class="img-container h-full w-full !flex justify-center items-center text-center p-1 relative"
239   - >
240   - <img
241   - class="w-full h-36"
242   - alt="example"
243   - :src="item.thumbnail || configurationSrc"
244   - @click="handlePreview(item)"
  146 + <img
  147 + class="w-full h-36"
  148 + alt="example"
  149 + :src="item.thumbnail || configurationSrc"
  150 + @click="handlePreview(item)"
  151 + />
  152 + <span class="absolute top-0 left-0 text-light-50 transform -rotate-45 translate-y-1">
  153 + 母版
  154 + </span>
  155 + </div>
  156 + </template>
  157 + <template class="ant-card-actions" #actions>
  158 + <Tooltip title="预览">
  159 + <AuthIcon
  160 + :auth="ConfigurationPermission.PREVIEW"
  161 + class="!text-lg"
  162 + icon="ant-design:eye-outlined"
  163 + @click="handlePreview(item)"
  164 + />
  165 + </Tooltip>
  166 + <Tooltip v-if="!isCustomerUser" title="设计">
  167 + <AuthIcon
  168 + :auth="ConfigurationPermission.DESIGN"
  169 + class="!text-lg"
  170 + icon="ant-design:edit-outlined"
  171 + @click="handleDesign(item)"
  172 + />
  173 + </Tooltip>
  174 + <Tooltip title="点击复制分享链接">
  175 + <AuthIcon
  176 + :auth="ConfigurationPermission.SHARE"
  177 + :disabled="!item.publicId"
  178 + class="!text-lg"
  179 + icon="ant-design:share-alt-outlined"
  180 + @click="handleCreateShareUrl(item)"
  181 + />
  182 + </Tooltip>
  183 + <AuthDropDown
  184 + v-if="!isCustomerUser"
  185 + :dropMenuList="[
  186 + {
  187 + text: '分享',
  188 + auth: ConfigurationPermission.SHARE,
  189 + icon: 'ant-design:share-alt-outlined',
  190 + event: '',
  191 + onClick: handleOpenShareModal.bind(null, item),
  192 + },
  193 + {
  194 + text: '编辑',
  195 + auth: ConfigurationPermission.UPDATE,
  196 + icon: 'clarity:note-edit-line',
  197 + event: '',
  198 + onClick: handleCreateOrUpdate.bind(null, item),
  199 + },
  200 + {
  201 + text: '删除',
  202 + auth: ConfigurationPermission.DELETE,
  203 + icon: 'ant-design:delete-outlined',
  204 + event: '',
  205 + popconfirm: {
  206 + title: '是否确认删除操作?',
  207 + onConfirm: handleDelete.bind(null, item),
  208 + },
  209 + },
  210 + ]"
  211 + :trigger="['hover']"
  212 + />
  213 + </template>
  214 + <Card.Meta>
  215 + <template #title>
  216 + <span class="truncate">{{ item.name }}</span>
  217 + </template>
  218 + <template #description>
  219 + <div class="truncate h-11">
  220 + <div class="truncate flex justify-between items-center">
  221 + <div>{{ item.organizationDTO?.name }}</div>
  222 + <Icon
  223 + :icon="
  224 + item.platform === Platform.PC
  225 + ? 'ri:computer-line'
  226 + : 'clarity:mobile-phone-solid'
  227 + "
245 228 />
246   - <span
247   - class="absolute top-0 left-0 text-light-50 transform -rotate-45 translate-y-1"
248   - >
249   - {{ ViewTypeNameEnum[item.viewType] || ViewTypeNameEnum.PRIVATE_VIEW }}
250   - </span>
251 229 </div>
252   - </template>
253   - <template class="ant-card-actions" #actions>
254   - <Tooltip title="预览">
255   - <AuthIcon
256   - :auth="ConfigurationPermission.PREVIEW"
257   - class="!text-lg"
258   - icon="ant-design:eye-outlined"
259   - @click="handlePreview(item)"
260   - />
261   - </Tooltip>
262   - <Tooltip v-if="!isCustomerUser" title="设计">
263   - <AuthIcon
264   - :auth="ConfigurationPermission.DESIGN"
265   - class="!text-lg"
266   - icon="ant-design:edit-outlined"
267   - @click="handleDesign(item)"
268   - />
269   - </Tooltip>
270   - <Tooltip title="点击复制分享链接">
271   - <AuthIcon
272   - :auth="ConfigurationPermission.SHARE"
273   - :disabled="!item.publicId"
274   - class="!text-lg"
275   - icon="ant-design:share-alt-outlined"
276   - @click="handleCreateShareUrl(item)"
277   - />
278   - </Tooltip>
279   - <AuthDropDown
280   - v-if="!isCustomerUser"
281   - :dropMenuList="[
282   - {
283   - text: '分享',
284   - auth: ConfigurationPermission.SHARE,
285   - icon: 'ant-design:share-alt-outlined',
286   - event: '',
287   - onClick: handleOpenShareModal.bind(null, item),
288   - },
289   - {
290   - text: '编辑',
291   - auth: ConfigurationPermission.UPDATE,
292   - icon: 'clarity:note-edit-line',
293   - event: '',
294   - onClick: handleCreateOrUpdate.bind(null, item),
295   - },
296   - {
297   - text: '删除',
298   - auth: ConfigurationPermission.DELETE,
299   - icon: 'ant-design:delete-outlined',
300   - event: '',
301   - popconfirm: {
302   - title: '是否确认删除操作?',
303   - onConfirm: handleDelete.bind(null, item),
304   - },
305   - },
306   - ]"
307   - :trigger="['hover']"
308   - />
309   - </template>
310   - <Card.Meta>
311   - <template #title>
312   - <span class="truncate">{{ item.name }}</span>
313   - </template>
314   - <template #description>
315   - <div class="truncate h-11">
316   - <div class="truncate flex justify-between items-center">
317   - <div>{{ item.organizationDTO.name }}</div>
318   - <Icon
319   - :icon="
320   - item.platform === Platform.PC
321   - ? 'ri:computer-line'
322   - : 'clarity:mobile-phone-solid'
323   - "
324   - />
325   - </div>
326   - <div class="truncate">{{ item.remark || '' }} </div>
327   - </div>
328   - </template>
329   - </Card.Meta>
330   - </Card>
331   - </List.Item>
332   - </template>
333   - </List>
334   - </section>
335   - <ConfigurationCenterDrawer @register="registerDrawer" @success="getListData" />
336   - <ShareModal
337   - @register="registerShareModal"
338   - :shareApi="shareConfiguration"
339   - @success="getListData"
340   - />
341   - </PageWrapper>
  230 + <div class="truncate">{{ item.remark || '' }} </div>
  231 + </div>
  232 + </template>
  233 + </Card.Meta>
  234 + </Card>
  235 + </template>
  236 + </BasicCardList>
  237 + <ConfigurationCenterDrawer @register="registerDrawer" @success="reload()" />
  238 + <ShareModal @register="registerShareModal" :shareApi="shareConfiguration" @success="reload" />
  239 + </section>
342 240 </template>
343   -
344   -<style lang="less" scoped>
345   - .configuration-list:deep(.ant-list-header) {
346   - border-bottom: none !important;
347   - }
348   -
349   - .configuration-list:deep(.ant-list-pagination) {
350   - height: 24px;
351   - }
352   -
353   - .configuration-list:deep(.ant-card-body) {
354   - padding: 16px !important;
355   - }
356   -
357   - .configuration-list:deep(.ant-list-empty-text) {
358   - @apply w-full h-full flex justify-center items-center;
359   - }
360   -
361   - .card-container {
362   - // background-color: red;
363   - .img-container {
364   - border-top-left-radius: 80px;
365   - background-color: #fff;
366   -
367   - img {
368   - border-top-left-radius: 80px;
369   - }
370   - }
371   - }
372   -
373   - .card-container:deep(.ant-card-cover) {
374   - background-color: var(--viewType);
375   - }
376   -</style>
... ...