Commit 8974ba539f8c07fb70a0c439f228f0fc0fa8c912

Authored by ww
1 parent 17b6b5b1

perf: 优化数据大屏使用组件重构

1 1 import { BasicPageParams } from '/@/api/model/baseModel';
  2 +import { ViewType } from '/@/views/visual/board/config/panelDetail';
2 3
3 4 export interface BigScreenCenterItemsModel {
4 5 id: string;
  6 + thumbnail?: string;
5 7 name: string;
6 8 createTime: string;
7 9 creator: string;
... ... @@ -9,6 +11,8 @@ export interface BigScreenCenterItemsModel {
9 11 state: number;
10 12 publicId: string;
11 13 organizationId?: string;
  14 + viewType?: ViewType;
  15 + organizationDTO: { name: string };
12 16 }
13 17 export type queryPageParams = BasicPageParams & {
14 18 name?: Nullable<string>;
... ...
... ... @@ -25,10 +25,12 @@
25 25 import { useClipboard } from '@vueuse/core';
26 26 import { useModal } from '/@/components/Modal';
27 27 import { ShareModal } from '/@/views/common/ShareModal';
  28 + import { ViewTypeEnum, ViewTypeNameEnum } from '../../common/ShareModal/config';
28 29
29 30 const [register, { reload }] = useCardList({
30 31 api: getPage,
31 32 useSearchForm: true,
  33 + title: '组态列表',
32 34 formConfig: {
33 35 schemas: searchFormSchema,
34 36 labelWidth: 80,
... ... @@ -134,7 +136,7 @@
134 136 <template #renderItem="{ item }: CardListRenderItem<ConfigurationCenterItemsModal>">
135 137 <Card
136 138 :style="{
137   - '--viewType': item.publicId ? '#faad14' : '#1890ff',
  139 + '--viewType': item.viewType === ViewTypeEnum.PUBLIC_VIEW ? '#faad14' : '#1890ff',
138 140 }"
139 141 hoverable
140 142 class="card-container"
... ... @@ -144,13 +146,13 @@
144 146 class="img-container h-full w-full !flex justify-center items-center text-center p-1 relative bg-light-50 rounded-tl-10xl"
145 147 >
146 148 <img
147   - class="w-full max-h-32 object-contain !rounded-tl-10xl"
  149 + class="w-full max-h-32 h-32 object-contain !rounded-tl-10xl"
148 150 alt="example"
149 151 :src="item.thumbnail || configurationSrc"
150 152 @click="handlePreview(item)"
151 153 />
152 154 <span class="absolute top-0 left-0 text-light-50 transform -rotate-45 translate-y-1">
153   - {{ item.publicId ? '公开' : '私有' }}
  155 + {{ ViewTypeNameEnum[item.viewType] }}
154 156 </span>
155 157 </div>
156 158 </template>
... ...
... ... @@ -25,6 +25,7 @@
25 25 const [register, { reload }] = useCardList({
26 26 api: getPage,
27 27 useSearchForm: true,
  28 + title: '模版列表',
28 29 formConfig: {
29 30 schemas: searchFormSchema,
30 31 labelWidth: 80,
... ... @@ -116,7 +117,7 @@
116 117 class="img-container h-full w-full !flex justify-center items-center text-center p-1 relative"
117 118 >
118 119 <img
119   - class="w-full max-h-32"
  120 + class="w-full max-h-32 h-32"
120 121 alt="example"
121 122 :src="item.thumbnail || configurationSrc"
122 123 @click="handlePreview(item)"
... ...
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 { Card, Button, Tooltip } from 'ant-design-vue';
  3 + import { computed, unref } from 'vue';
  4 + import { OrganizationIdTree, useOrganizationTree } from '../common/organizationIdTree';
6 5 import {
7 6 bigScreenCancelPublish,
8 7 bigScreenPublish,
... ... @@ -12,17 +11,15 @@
12 11 } from '/@/api/bigscreen/center/bigscreenCenter';
13 12 import { BigScreenCenterItemsModel } from '/@/api/bigscreen/center/model/bigscreenCenterModel';
14 13 import { PageWrapper } from '/@/components/Page';
15   - import { BasicForm, useForm } from '/@/components/Form';
16 14 import { ConfigurationPermission, searchFormSchema } from './config';
17 15 import { useMessage } from '/@/hooks/web/useMessage';
18 16 import { Authority } from '/@/components/Authority';
19 17 import ConfigurationCenterDrawer from './BigScreenDrawer.vue';
20 18 import { useDrawer } from '/@/components/Drawer';
21   - import { getBoundingClientRect } from '/@/utils/domUtils';
22 19 import configurationSrc from '/@/assets/icons/configuration.svg';
23 20 import { cloneDeep } from 'lodash';
24 21 import { useGlobSetting } from '/@/hooks/setting';
25   - import { AuthIcon, CardLayoutButton } from '/@/components/Widget';
  22 + import { AuthIcon } from '/@/components/Widget';
26 23 import AuthDropDown from '/@/components/Widget/AuthDropDown.vue';
27 24 import { PublicApiDrawer } from './publicApi/index';
28 25 import { useModal } from '/@/components/Modal';
... ... @@ -33,79 +30,36 @@
33 30 import { RoleEnum } from '/@/enums/roleEnum';
34 31 import { useRole } from '/@/hooks/business/useRole';
35 32 import { useClipboard } from '@vueuse/core';
  33 + import { BasicCardList, useCardList } from '/@/components/CardList';
36 34
37   - const listColumn = ref(5);
38   -
39   - const { createMessage } = useMessage();
40   -
41   - const organizationId = ref<Nullable<number>>(null);
42   -
43   - const pagination = reactive<PaginationProps>({
44   - size: 'small',
45   - showTotal: (total: number) => `共 ${total} 条数据`,
46   - current: 1,
47   - pageSize: unref(listColumn) * 2,
48   - onChange: (page: number) => {
49   - pagination.current = page;
50   - getListData();
  35 + const [registerOrgTree, { getSelectKey, clearSelected }] = useOrganizationTree({
  36 + onSelect: () => {
  37 + reload();
51 38 },
52 39 });
53 40
54   - const loading = ref(false);
55   - const { isCustomerUser } = useRole();
56   -
57   - const dataSource = ref<BigScreenCenterItemsModel[]>([]);
58   -
59   - const [registerForm, { getFieldsValue }] = useForm({
60   - schemas: searchFormSchema,
61   - showAdvancedButton: true,
62   - labelWidth: 100,
63   - compact: true,
64   - resetFunc: () => {
65   - resetFn();
66   - organizationId.value = null;
67   - return getListData();
  41 + const [registerCardList, { reload }] = useCardList({
  42 + api: getPage,
  43 + title: '数据大屏',
  44 + useSearchForm: true,
  45 + formConfig: {
  46 + labelWidth: 80,
  47 + schemas: searchFormSchema,
  48 + resetFunc: async () => clearSelected(),
68 49 },
69   - submitFunc: async () => {
70   - const value = getFieldsValue();
71   - getListData(value);
  50 + beforeFetch: async (params: Recordable) => {
  51 + return { ...params, organizationId: getSelectKey() };
72 52 },
73 53 });
74 54
75   - async function getListData(value: Recordable = {}) {
76   - try {
77   - loading.value = true;
78   - const pageSize = unref(listColumn) * 2;
79   - const { items, total } = await getPage({
80   - organizationId: unref(organizationId),
81   - ...value,
82   - page: pagination.current!,
83   - pageSize,
84   - });
85   -
86   - dataSource.value = items;
87   - Object.assign(pagination, { total, pageSize });
88   - } catch (error) {
89   - } finally {
90   - loading.value = false;
91   - }
92   - }
93   -
94   - onMounted(() => {
95   - getListData();
96   - });
97   -
98   - const searchInfo = reactive<Recordable>({});
99   - const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
100   - const handleSelect = (orgId: number) => {
101   - organizationId.value = orgId;
102   - getListData();
103   - };
104   -
105 55 const [registerDrawer, { openDrawer }] = useDrawer();
106 56
107 57 const [registerPublicDrawer, { openDrawer: openPublicApiDrawer }] = useDrawer();
108 58
  59 + const { createMessage } = useMessage();
  60 +
  61 + const { isCustomerUser } = useRole();
  62 +
109 63 const handleCreateOrUpdate = (record?: BigScreenCenterItemsModel) => {
110 64 if (record) {
111 65 openDrawer(true, {
... ... @@ -140,37 +94,10 @@
140 94 try {
141 95 await deleteBigScreenenter([record.id]);
142 96 createMessage.success('删除成功');
143   - await getListData();
  97 + reload();
144 98 } catch (error) {}
145 99 };
146 100
147   - const handleCardLayoutChange = () => {
148   - pagination.current = 1;
149   - getListData();
150   - };
151   -
152   - const listEl = ref<Nullable<ComponentElRef>>(null);
153   -
154   - onMounted(() => {
155   - const clientHeight = document.documentElement.clientHeight;
156   - const rect = getBoundingClientRect(unref(listEl)!.$el!) as DOMRect;
157   - // margin-top 24 height 24
158   - const paginationHeight = 24 + 24 + 8;
159   - // list pading top 8 maring-top 8 extra slot 56
160   - const listContainerMarginBottom = 8 + 8 + 56;
161   - const listContainerHeight =
162   - clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
163   - const listContainerEl = (unref(listEl)!.$el as HTMLElement).querySelector(
164   - '.ant-spin-container'
165   - ) as HTMLElement;
166   - listContainerEl &&
167   - (listContainerEl.style.height = listContainerHeight + 'px') &&
168   - (listContainerEl.style.overflowY = 'auto') &&
169   - (listContainerEl.style.overflowX = 'hidden');
170   - });
171   -
172   - const getPublicApiListData = () => {};
173   -
174 101 const [registerShareModal, { openModal }] = useModal();
175 102 const handleOpenShareModal = (record: BigScreenCenterItemsModel) => {
176 103 openModal(true, { record, href: createShareUrl(record) });
... ... @@ -182,6 +109,7 @@
182 109 };
183 110
184 111 const userStore = useUserStore();
  112 +
185 113 const hasPublicInterfacePermission = computed(() => {
186 114 return userStore.getUserInfo.roles![0] !== RoleEnum.CUSTOMER_USER;
187 115 });
... ... @@ -197,166 +125,143 @@
197 125 const handlePublish = async ({ id, state }) => {
198 126 state === 0 ? await bigScreenPublish(id) : await bigScreenCancelPublish(id);
199 127 createMessage.success(state === 0 ? '发布成功' : '取消发布成功');
200   - getListData();
  128 + reload();
201 129 };
202 130 </script>
203 131
204 132 <template>
205 133 <PageWrapper dense contentFullHeight contentClass="flex">
206   - <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
207   - <section class="flex-auto p-4 w-3/4 xl:w-4/5 w-full configuration-list">
208   - <div class="flex-auto w-full bg-light-50 dark:bg-dark-900 p-4">
209   - <BasicForm @register="registerForm" />
210   - </div>
211   - <List
212   - ref="listEl"
213   - :loading="loading"
214   - class="flex-auto bg-light-50 dark:bg-dark-900 !p-2 !mt-4"
215   - position="bottom"
216   - :pagination="pagination"
217   - :data-source="dataSource"
218   - :grid="{ gutter: 4, column: listColumn }"
219   - >
220   - <template #header>
221   - <div class="flex gap-3 justify-end">
222   - <Authority v-if="!isCustomerUser" :value="ConfigurationPermission.CREATE">
223   - <Button type="primary" @click="handleCreateOrUpdate()"> 新增大屏 </Button>
224   - </Authority>
225   - <Authority
226   - v-if="hasPublicInterfacePermission"
227   - :value="ConfigurationPermission.PUBLISH_INTERFACE"
228   - >
229   - <Button type="primary" @click="handleCreateOrUpdatePublicApi()">公共接口管理</Button>
230   - </Authority>
231   - <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" />
232   - <Tooltip title="刷新">
233   - <Button type="primary" @click="getListData">
234   - <ReloadOutlined />
235   - </Button>
236   - </Tooltip>
237   - </div>
238   - </template>
239   - <template #renderItem="{ item }">
240   - <List.Item>
241   - <Card
242   - :style="{
243   - '--viewType': item.viewType === ViewType.PUBLIC_VIEW ? '#1890ff' : '#faad14',
244   - }"
245   - class="card-container"
246   - >
247   - <template #cover>
248   - <div class="h-full w-full relative hover-show-modal-content img-container">
249   - <img
250   - style="position: relative"
251   - class="w-full h-45 hover-show-modal"
252   - alt="example"
253   - :src="item.thumbnail || configurationSrc"
254   - @click="handlePreview(item)"
255   - />
256   - <span
257   - class="absolute top-0 left-0 text-light-50 transform -rotate-45 translate-y-1"
  134 + <OrganizationIdTree @register="registerOrgTree" />
  135 + <BasicCardList
  136 + @register="registerCardList"
  137 + class="flex-auto p-4 w-3/4 xl:w-4/5 w-full configuration-list"
  138 + >
  139 + <template #toolbar>
  140 + <section class="flex gap-4">
  141 + <Authority v-if="!isCustomerUser" :value="ConfigurationPermission.CREATE">
  142 + <Button type="primary" @click="handleCreateOrUpdate()"> 新增大屏 </Button>
  143 + </Authority>
  144 + <Authority
  145 + v-if="hasPublicInterfacePermission"
  146 + :value="ConfigurationPermission.PUBLISH_INTERFACE"
  147 + >
  148 + <Button type="primary" @click="handleCreateOrUpdatePublicApi()">公共接口管理</Button>
  149 + </Authority>
  150 + </section>
  151 + </template>
  152 + <template #renderItem="{ item }: CardListRenderItem<BigScreenCenterItemsModel>">
  153 + <Card
  154 + :style="{
  155 + '--viewType': item.viewType === ViewType.PUBLIC_VIEW ? '#1890ff' : '#faad14',
  156 + }"
  157 + class="card-container"
  158 + >
  159 + <template #cover>
  160 + <div class="h-full w-full relative hover-show-modal-content img-container">
  161 + <img
  162 + style="position: relative"
  163 + class="w-full h-45 hover-show-modal"
  164 + alt="example"
  165 + :src="item.thumbnail || configurationSrc"
  166 + @click="handlePreview(item)"
  167 + />
  168 + <span class="absolute top-0 left-0 text-light-50 transform -rotate-45 translate-y-1">
  169 + {{
  170 + item.viewType ? ViewTypeNameEnum[item.viewType] : ViewTypeNameEnum.PRIVATE_VIEW
  171 + }}
  172 + </span>
  173 + <div class="masker-content">
  174 + <div class="masker-text">
  175 + <div
  176 + ><span>{{ item.name }}</span></div
258 177 >
259   - {{ ViewTypeNameEnum[item.viewType] || ViewTypeNameEnum.PRIVATE_VIEW }}
260   - </span>
261   - <div class="masker-content">
262   - <div class="masker-text">
263   - <div
264   - ><span>{{ item.name }}</span></div
265   - >
266   - <div>
267   - <span class="masker-text-org"
268   - >所属组织:{{ item?.organizationDTO?.name }}</span
269   - >
270   - </div>
271   - <div>
272   - <span class="masker-text-state"
273   - >发布状态:{{ item.state === 1 ? '已发布' : '未发布' }}</span
274   - >
275   - </div>
276   - </div>
  178 + <div>
  179 + <span class="masker-text-org">所属组织:{{ item?.organizationDTO?.name }}</span>
  180 + </div>
  181 + <div>
  182 + <span class="masker-text-state"
  183 + >发布状态:{{ item.state === 1 ? '已发布' : '未发布' }}</span
  184 + >
277 185 </div>
278 186 </div>
279   - </template>
280   - <template class="ant-card-actions" #actions>
281   - <Tooltip title="预览">
282   - <AuthIcon
283   - class="!text-lg"
284   - icon="ant-design:eye-outlined"
285   - @click="handlePreview(item)"
286   - />
287   - </Tooltip>
288   - <Tooltip v-if="!isCustomerUser" title="设计">
289   - <AuthIcon
290   - :auth="ConfigurationPermission.DESIGN"
291   - :disabled="item.state === 1"
292   - icon="ant-design:edit-outlined"
293   - @click="handleDesign(item)"
294   - />
295   - </Tooltip>
296   - <Tooltip title="点击复制分享链接">
297   - <AuthIcon
298   - :auth="ConfigurationPermission.SHARE"
299   - :disabled="!item.publicId"
300   - class="!text-lg"
301   - icon="ant-design:share-alt-outlined"
302   - @click="handleCreateShareUrl(item)"
303   - />
304   - </Tooltip>
305   - <AuthDropDown
306   - v-if="!isCustomerUser"
307   - :dropMenuList="[
308   - {
309   - text: '分享',
310   - auth: ConfigurationPermission.SHARE,
311   - icon: 'ant-design:share-alt-outlined',
312   - event: '',
313   - onClick: handleOpenShareModal.bind(null, item),
314   - },
315   - {
316   - text: item.state == 0 ? '发布' : '取消发布',
317   - auth: ConfigurationPermission.PUBLISH,
318   - icon:
319   - item.state == 0
320   - ? 'ant-design:node-expand-outlined'
321   - : 'ant-design:node-collapse-outlined',
322   - event: '',
323   - onClick: handlePublish.bind(null, item),
324   - },
325   - {
326   - text: '编辑',
327   - auth: ConfigurationPermission.UPDATE,
328   - icon: 'clarity:note-edit-line',
329   - event: '',
330   - onClick: handleCreateOrUpdate.bind(null, item),
331   - disabled: item.state === 0 ? false : true,
332   - },
333   - {
334   - text: '删除',
335   - auth: ConfigurationPermission.DELETE,
336   - icon: 'ant-design:delete-outlined',
337   - disabled: item.state === 0 ? false : true,
338   - event: '',
339   - popconfirm: {
340   - title: '是否确认删除操作?',
341   - onConfirm: handleDelete.bind(null, item),
342   - },
343   - },
344   - ]"
345   - :trigger="['hover']"
346   - />
347   - </template>
348   - </Card>
349   - </List.Item>
350   - </template>
351   - </List>
352   - </section>
353   - <ShareModal
354   - @register="registerShareModal"
355   - :shareApi="shareLargeScreen"
356   - @success="getListData"
357   - />
358   - <ConfigurationCenterDrawer @register="registerDrawer" @success="getListData" />
359   - <PublicApiDrawer @register="registerPublicDrawer" @success="getPublicApiListData" />
  187 + </div>
  188 + </div>
  189 + </template>
  190 + <template class="ant-card-actions" #actions>
  191 + <Tooltip title="预览">
  192 + <AuthIcon
  193 + class="!text-lg"
  194 + icon="ant-design:eye-outlined"
  195 + @click="handlePreview(item)"
  196 + />
  197 + </Tooltip>
  198 + <Tooltip v-if="!isCustomerUser" title="设计">
  199 + <AuthIcon
  200 + :auth="ConfigurationPermission.DESIGN"
  201 + :disabled="item.state === 1"
  202 + icon="ant-design:edit-outlined"
  203 + @click="handleDesign(item)"
  204 + />
  205 + </Tooltip>
  206 + <Tooltip title="点击复制分享链接">
  207 + <AuthIcon
  208 + :auth="ConfigurationPermission.SHARE"
  209 + :disabled="!item.publicId"
  210 + class="!text-lg"
  211 + icon="ant-design:share-alt-outlined"
  212 + @click="handleCreateShareUrl(item)"
  213 + />
  214 + </Tooltip>
  215 + <AuthDropDown
  216 + v-if="!isCustomerUser"
  217 + :dropMenuList="[
  218 + {
  219 + text: '分享',
  220 + auth: ConfigurationPermission.SHARE,
  221 + icon: 'ant-design:share-alt-outlined',
  222 + event: '',
  223 + onClick: handleOpenShareModal.bind(null, item),
  224 + },
  225 + {
  226 + text: item.state == 0 ? '发布' : '取消发布',
  227 + auth: ConfigurationPermission.PUBLISH,
  228 + icon:
  229 + item.state == 0
  230 + ? 'ant-design:node-expand-outlined'
  231 + : 'ant-design:node-collapse-outlined',
  232 + event: '',
  233 + onClick: handlePublish.bind(null, item),
  234 + },
  235 + {
  236 + text: '编辑',
  237 + auth: ConfigurationPermission.UPDATE,
  238 + icon: 'clarity:note-edit-line',
  239 + event: '',
  240 + onClick: handleCreateOrUpdate.bind(null, item),
  241 + disabled: item.state === 0 ? false : true,
  242 + },
  243 + {
  244 + text: '删除',
  245 + auth: ConfigurationPermission.DELETE,
  246 + icon: 'ant-design:delete-outlined',
  247 + disabled: item.state === 0 ? false : true,
  248 + event: '',
  249 + popconfirm: {
  250 + title: '是否确认删除操作?',
  251 + onConfirm: handleDelete.bind(null, item),
  252 + },
  253 + },
  254 + ]"
  255 + :trigger="['hover']"
  256 + />
  257 + </template>
  258 + </Card>
  259 + </template>
  260 + </BasicCardList>
  261 +
  262 + <ShareModal @register="registerShareModal" :shareApi="shareLargeScreen" @success="reload()" />
  263 + <ConfigurationCenterDrawer @register="registerDrawer" @success="reload()" />
  264 + <PublicApiDrawer @register="registerPublicDrawer" />
360 265 </PageWrapper>
361 266 </template>
362 267
... ...
... ... @@ -22,6 +22,7 @@
22 22 import { useClipboard } from '@vueuse/core';
23 23 import { DATA_BOARD_SHARE_URL } from '../palette';
24 24 import { BasicCardList, useCardList } from '/@/components/CardList';
  25 + import Authority from '/@/components/Authority/src/Authority.vue';
25 26
26 27 const router = useRouter();
27 28
... ... @@ -139,7 +140,9 @@
139 140 <section>
140 141 <BasicCardList @register="registerCardList">
141 142 <template #toolbar>
142   - <Button type="primary" @click="handleOpenDetailModal">新增看板</Button>
  143 + <Authority :value="VisualBoardPermission.CREATE">
  144 + <Button type="primary" @click="handleOpenDetailModal">新增看板</Button>
  145 + </Authority>
143 146 </template>
144 147 <template #renderItem="{ item }: CardListRenderItem<DataBoardRecord>">
145 148 <Card class="data-card cursor-pointer">
... ...