Commit 7ae1f9c9a2b1755eed51ddf5f3655d1ff6541485

Authored by ww
1 parent 01f7c9e0

feat: 新增大屏设计的分享页面

1   -import { defHttp } from '/@/utils/http/axios';
2   -import type {
3   - queryPageParams,
4   - BigScreenCenterParams,
5   - ConfigurationCenterInfo,
6   - BigScreenCenterItemsModel,
7   - BigScreenInterfaceParams,
8   -} from './model/bigscreenCenterModel';
9   -import { getPageData } from '../../base';
10   -import { FileUploadResponse } from '../../oem/model';
11   -enum API {
12   - basicUrl = '/data_view',
13   - UPLOAD = '/oss/upload',
14   - //大屏公共接口
15   - DATA_VIEW_INTERFACE = '/data_view_interface',
16   -}
17   -
18   -export const getPage = (params: queryPageParams) => {
19   - return getPageData<BigScreenCenterItemsModel>(params, API.basicUrl);
20   -};
21   -
22   -export const saveConfigurationCenter = (params: BigScreenCenterParams) => {
23   - return defHttp.post({
24   - url: API.basicUrl,
25   - data: params,
26   - });
27   -};
28   -
29   -export const updateConfigurationCenter = (params: BigScreenCenterParams) => {
30   - return defHttp.put({
31   - url: API.basicUrl,
32   - data: params,
33   - });
34   -};
35   -
36   -export const deleteBigScreenenter = (ids: string[]) => {
37   - return defHttp.delete({
38   - url: API.basicUrl,
39   - data: {
40   - ids: ids,
41   - },
42   - });
43   -};
44   -
45   -export const saveOrUpdateBigScreenCenter = (params: ConfigurationCenterInfo, isUpdate: boolean) => {
46   - return isUpdate ? updateConfigurationCenter(params) : saveConfigurationCenter(params);
47   -};
48   -
49   -export const uploadThumbnail = (file: FormData) => {
50   - return defHttp.post<FileUploadResponse>({ url: API.UPLOAD, params: file });
51   -};
52   -
53   -export const bigScreenPublish = (id) => {
54   - return defHttp.get({
55   - url: API.basicUrl + '/publish/' + id,
56   - });
57   -};
58   -
59   -export const bigScreenCancelPublish = (id) => {
60   - return defHttp.get({
61   - url: API.basicUrl + '/cancel_publish/' + id,
62   - });
63   -};
64   -
65   -/**
66   - * 大屏公共接口
67   - */
68   -
69   -export const getDataViewInterfacePage = (params: queryPageParams) => {
70   - return getPageData<BigScreenCenterItemsModel>(params, API.DATA_VIEW_INTERFACE);
71   -};
72   -
73   -export const saveDataViewInterface = (params: BigScreenInterfaceParams) => {
74   - return defHttp.post({
75   - url: API.DATA_VIEW_INTERFACE,
76   - data: params,
77   - });
78   -};
79   -
80   -export const updateDataViewInterface = (params: BigScreenInterfaceParams) => {
81   - return defHttp.put({
82   - url: API.DATA_VIEW_INTERFACE,
83   - data: params,
84   - });
85   -};
86   -
87   -export const deleteBigViewInterface = (ids: string[]) => {
88   - return defHttp.delete({
89   - url: API.DATA_VIEW_INTERFACE,
90   - data: {
91   - ids: ids,
92   - },
93   - });
94   -};
95   -
96   -export const getPublish = (id) => {
97   - return defHttp.get({
98   - url: API.DATA_VIEW_INTERFACE + '/publish/' + id,
99   - });
100   -};
101   -
102   -export const getCancelPublish = (id) => {
103   - return defHttp.get({
104   - url: API.DATA_VIEW_INTERFACE + '/cancel_publish/' + id,
105   - });
106   -};
107   -
108   -//批量发布和取消发布
109   -export const putPublishOrCancelPublish = (type, ids) => {
110   - return defHttp.put({
111   - url: `${API.DATA_VIEW_INTERFACE}/${
112   - type === 'batchPublish' ? 'batch_publish' : 'batch_cancel_publish'
113   - }/?ids=${ids.join(',')}`,
114   - });
115   -};
  1 +import { defHttp } from '/@/utils/http/axios';
  2 +import type {
  3 + queryPageParams,
  4 + BigScreenCenterParams,
  5 + ConfigurationCenterInfo,
  6 + BigScreenCenterItemsModel,
  7 + BigScreenInterfaceParams,
  8 +} from './model/bigscreenCenterModel';
  9 +import { getPageData } from '../../base';
  10 +import { FileUploadResponse } from '../../oem/model';
  11 +enum API {
  12 + basicUrl = '/data_view',
  13 + UPLOAD = '/oss/upload',
  14 + //大屏公共接口
  15 + DATA_VIEW_INTERFACE = '/data_view_interface',
  16 +
  17 + SHARE = '/data_view/share',
  18 +}
  19 +
  20 +export const getPage = (params: queryPageParams) => {
  21 + return getPageData<BigScreenCenterItemsModel>(params, API.basicUrl);
  22 +};
  23 +
  24 +export const saveConfigurationCenter = (params: BigScreenCenterParams) => {
  25 + return defHttp.post({
  26 + url: API.basicUrl,
  27 + data: params,
  28 + });
  29 +};
  30 +
  31 +export const updateConfigurationCenter = (params: BigScreenCenterParams) => {
  32 + return defHttp.put({
  33 + url: API.basicUrl,
  34 + data: params,
  35 + });
  36 +};
  37 +
  38 +export const deleteBigScreenenter = (ids: string[]) => {
  39 + return defHttp.delete({
  40 + url: API.basicUrl,
  41 + data: {
  42 + ids: ids,
  43 + },
  44 + });
  45 +};
  46 +
  47 +export const saveOrUpdateBigScreenCenter = (params: ConfigurationCenterInfo, isUpdate: boolean) => {
  48 + return isUpdate ? updateConfigurationCenter(params) : saveConfigurationCenter(params);
  49 +};
  50 +
  51 +export const uploadThumbnail = (file: FormData) => {
  52 + return defHttp.post<FileUploadResponse>({ url: API.UPLOAD, params: file });
  53 +};
  54 +
  55 +export const bigScreenPublish = (id) => {
  56 + return defHttp.get({
  57 + url: API.basicUrl + '/publish/' + id,
  58 + });
  59 +};
  60 +
  61 +export const bigScreenCancelPublish = (id) => {
  62 + return defHttp.get({
  63 + url: API.basicUrl + '/cancel_publish/' + id,
  64 + });
  65 +};
  66 +
  67 +/**
  68 + * 大屏公共接口
  69 + */
  70 +
  71 +export const getDataViewInterfacePage = (params: queryPageParams) => {
  72 + return getPageData<BigScreenCenterItemsModel>(params, API.DATA_VIEW_INTERFACE);
  73 +};
  74 +
  75 +export const saveDataViewInterface = (params: BigScreenInterfaceParams) => {
  76 + return defHttp.post({
  77 + url: API.DATA_VIEW_INTERFACE,
  78 + data: params,
  79 + });
  80 +};
  81 +
  82 +export const updateDataViewInterface = (params: BigScreenInterfaceParams) => {
  83 + return defHttp.put({
  84 + url: API.DATA_VIEW_INTERFACE,
  85 + data: params,
  86 + });
  87 +};
  88 +
  89 +export const deleteBigViewInterface = (ids: string[]) => {
  90 + return defHttp.delete({
  91 + url: API.DATA_VIEW_INTERFACE,
  92 + data: {
  93 + ids: ids,
  94 + },
  95 + });
  96 +};
  97 +
  98 +export const getPublish = (id) => {
  99 + return defHttp.get({
  100 + url: API.DATA_VIEW_INTERFACE + '/publish/' + id,
  101 + });
  102 +};
  103 +
  104 +export const getCancelPublish = (id) => {
  105 + return defHttp.get({
  106 + url: API.DATA_VIEW_INTERFACE + '/cancel_publish/' + id,
  107 + });
  108 +};
  109 +
  110 +//批量发布和取消发布
  111 +export const putPublishOrCancelPublish = (type, ids) => {
  112 + return defHttp.put({
  113 + url: `${API.DATA_VIEW_INTERFACE}/${
  114 + type === 'batchPublish' ? 'batch_publish' : 'batch_cancel_publish'
  115 + }/?ids=${ids.join(',')}`,
  116 + });
  117 +};
  118 +
  119 +export const shareLargeScreen = (record: {
  120 + id: string;
  121 + accessCredentials?: string;
  122 + isShare: boolean;
  123 +}) => {
  124 + const { accessCredentials, isShare, id } = record;
  125 + return defHttp.post(
  126 + {
  127 + url: `${API.SHARE}/${id}`,
  128 + params: { isShare, ...(accessCredentials ? { accessCredentials } : {}) },
  129 + },
  130 + {
  131 + joinParamsToUrl: true,
  132 + }
  133 + );
  134 +};
... ...
1   -import { BasicPageParams } from '/@/api/model/baseModel';
2   -
3   -export interface BigScreenCenterItemsModel {
4   - id: string;
5   - name: string;
6   - createTime: string;
7   - creator: string;
8   - remark: string;
9   - state: number;
10   -}
11   -export type queryPageParams = BasicPageParams & {
12   - name?: Nullable<string>;
13   - organizationId?: Nullable<number>;
14   -};
15   -
16   -export interface ConfigurationModal {
17   - items: BigScreenCenterItemsModel[];
18   - total: number;
19   -}
20   -
21   -export interface BigScreenCenterParams {
22   - name: string;
23   - createTime: string;
24   - creator: string;
25   - remark: string;
26   - defaultContent?: string;
27   -}
28   -export type ConfigurationCenterInfo = BigScreenCenterParams;
29   -
30   -/**
31   - * 大屏公共接口
32   - */
33   -export interface BigScreenInterfaceParams {
34   - createTime: string;
35   - creator: string;
36   - defaultConfig: string;
37   - description: string;
38   - enabled: boolean;
39   - icon: string;
40   - id: string;
41   - interfaceName: string;
42   - name: string;
43   - remark: string;
44   - requestContentType: 0;
45   - requestHttpType: string;
46   - requestOriginUrl: string;
47   - requestParams: string;
48   - requestUrl: string;
49   - roleIds: [string];
50   - state: number;
51   - tenantExpireTime: string;
52   - tenantId: string;
53   - tenantProfileId: string;
54   - tenantStatus: string;
55   - updateTime: string;
56   - updater: string;
57   -}
  1 +import { BasicPageParams } from '/@/api/model/baseModel';
  2 +
  3 +export interface BigScreenCenterItemsModel {
  4 + id: string;
  5 + name: string;
  6 + createTime: string;
  7 + creator: string;
  8 + remark: string;
  9 + state: number;
  10 + publicId: string;
  11 +}
  12 +export type queryPageParams = BasicPageParams & {
  13 + name?: Nullable<string>;
  14 + organizationId?: Nullable<number>;
  15 +};
  16 +
  17 +export interface ConfigurationModal {
  18 + items: BigScreenCenterItemsModel[];
  19 + total: number;
  20 +}
  21 +
  22 +export interface BigScreenCenterParams {
  23 + name: string;
  24 + createTime: string;
  25 + creator: string;
  26 + remark: string;
  27 + defaultContent?: string;
  28 +}
  29 +export type ConfigurationCenterInfo = BigScreenCenterParams;
  30 +
  31 +/**
  32 + * 大屏公共接口
  33 + */
  34 +export interface BigScreenInterfaceParams {
  35 + createTime: string;
  36 + creator: string;
  37 + defaultConfig: string;
  38 + description: string;
  39 + enabled: boolean;
  40 + icon: string;
  41 + id: string;
  42 + interfaceName: string;
  43 + name: string;
  44 + remark: string;
  45 + requestContentType: 0;
  46 + requestHttpType: string;
  47 + requestOriginUrl: string;
  48 + requestParams: string;
  49 + requestUrl: string;
  50 + roleIds: [string];
  51 + state: number;
  52 + tenantExpireTime: string;
  53 + tenantId: string;
  54 + tenantProfileId: string;
  55 + tenantStatus: string;
  56 + updateTime: string;
  57 + updater: string;
  58 +}
... ...
1   -import { FormSchema } from '/@/components/Table';
2   -import { getOrganizationList } from '/@/api/system/system';
3   -import { copyTransFun } from '/@/utils/fnUtils';
4   -import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
5   -import { createImgPreview } from '/@/components/Preview';
6   -import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
7   -export enum Platform {
8   - PHONE = 0,
9   - PC = 1,
10   -}
11   -
12   -export enum ConfigurationPermission {
13   - CREATE = 'api:yt:dataview:center:post',
14   - UPDATE = 'api:yt:dataview:center:update',
15   - DELETE = 'api:yt:dataview:center:delete',
16   - DESIGN = 'api:yt:dataview:center:get_configuration_info:design',
17   - PREVIEW = 'api:yt:dataview:center:get_configuration_info:preview',
18   -}
19   -
20   -// 查询字段
21   -export const searchFormSchema: FormSchema[] = [
22   - {
23   - field: 'name',
24   - label: '大屏名称',
25   - component: 'Input',
26   - colProps: { span: 8 },
27   - componentProps: {
28   - maxLength: 36,
29   - placeholder: '请输入大屏名称',
30   - },
31   - },
32   -];
33   -
34   -export const formSchema: FormSchema[] = [
35   - {
36   - field: 'thumbnail',
37   - label: '缩略图',
38   - component: 'ApiUpload',
39   - changeEvent: 'update:fileList',
40   - valueField: 'fileList',
41   - componentProps: () => {
42   - return {
43   - listType: 'picture-card',
44   - maxFileLimit: 1,
45   - api: async (file: File) => {
46   - try {
47   - const formData = new FormData();
48   - formData.set('file', file);
49   - const { fileStaticUri, fileName } = await uploadThumbnail(formData);
50   - return {
51   - uid: fileStaticUri,
52   - name: fileName,
53   - url: fileStaticUri,
54   - } as FileItem;
55   - } catch (error) {
56   - return {};
57   - }
58   - },
59   - onPreview: (fileList: FileItem) => {
60   - createImgPreview({ imageList: [fileList.url!] });
61   - },
62   - };
63   - },
64   - },
65   -
66   - {
67   - field: 'name',
68   - label: '大屏名称',
69   - required: true,
70   - component: 'Input',
71   - componentProps: {
72   - placeholder: '请输入大屏名称',
73   - maxLength: 255,
74   - },
75   - },
76   - {
77   - field: 'organizationId',
78   - label: '所属组织',
79   - required: true,
80   - component: 'ApiTreeSelect',
81   - componentProps: {
82   - api: async () => {
83   - const data = await getOrganizationList();
84   - copyTransFun(data as any as any[]);
85   - return data;
86   - },
87   - },
88   - },
89   - // {
90   - // field: 'state',
91   - // label: '发布状态',
92   - // required: true,
93   - // component: 'RadioGroup',
94   - // defaultValue: Platform.PC,
95   - // componentProps: {
96   - // defaultValue: Platform.PC,
97   - // options: [
98   - // { label: '未发布', value: Platform.PC },
99   - // { label: '已发布', value: Platform.PHONE },
100   - // ],
101   - // },
102   - // },
103   - {
104   - field: 'remark',
105   - label: '备注',
106   - component: 'InputTextArea',
107   - componentProps: {
108   - placeholder: '请输入备注',
109   - maxLength: 255,
110   - },
111   - },
112   - {
113   - field: 'id',
114   - label: '',
115   - component: 'Input',
116   - show: false,
117   - componentProps: {
118   - maxLength: 36,
119   - placeholder: 'id',
120   - },
121   - },
122   -];
  1 +import { FormSchema } from '/@/components/Table';
  2 +import { getOrganizationList } from '/@/api/system/system';
  3 +import { copyTransFun } from '/@/utils/fnUtils';
  4 +import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
  5 +import { createImgPreview } from '/@/components/Preview';
  6 +import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
  7 +export enum Platform {
  8 + PHONE = 0,
  9 + PC = 1,
  10 +}
  11 +
  12 +export enum ConfigurationPermission {
  13 + CREATE = 'api:yt:dataview:center:post',
  14 + UPDATE = 'api:yt:dataview:center:update',
  15 + DELETE = 'api:yt:dataview:center:delete',
  16 + SHARE = 'api:yt:dataview:center:share',
  17 + DESIGN = 'api:yt:dataview:center:get_configuration_info:design',
  18 + PREVIEW = 'api:yt:dataview:center:get_configuration_info:preview',
  19 +}
  20 +
  21 +// 查询字段
  22 +export const searchFormSchema: FormSchema[] = [
  23 + {
  24 + field: 'name',
  25 + label: '大屏名称',
  26 + component: 'Input',
  27 + colProps: { span: 8 },
  28 + componentProps: {
  29 + maxLength: 36,
  30 + placeholder: '请输入大屏名称',
  31 + },
  32 + },
  33 +];
  34 +
  35 +export const formSchema: FormSchema[] = [
  36 + {
  37 + field: 'thumbnail',
  38 + label: '缩略图',
  39 + component: 'ApiUpload',
  40 + changeEvent: 'update:fileList',
  41 + valueField: 'fileList',
  42 + componentProps: () => {
  43 + return {
  44 + listType: 'picture-card',
  45 + maxFileLimit: 1,
  46 + api: async (file: File) => {
  47 + try {
  48 + const formData = new FormData();
  49 + formData.set('file', file);
  50 + const { fileStaticUri, fileName } = await uploadThumbnail(formData);
  51 + return {
  52 + uid: fileStaticUri,
  53 + name: fileName,
  54 + url: fileStaticUri,
  55 + } as FileItem;
  56 + } catch (error) {
  57 + return {};
  58 + }
  59 + },
  60 + onPreview: (fileList: FileItem) => {
  61 + createImgPreview({ imageList: [fileList.url!] });
  62 + },
  63 + };
  64 + },
  65 + },
  66 +
  67 + {
  68 + field: 'name',
  69 + label: '大屏名称',
  70 + required: true,
  71 + component: 'Input',
  72 + componentProps: {
  73 + placeholder: '请输入大屏名称',
  74 + maxLength: 255,
  75 + },
  76 + },
  77 + {
  78 + field: 'organizationId',
  79 + label: '所属组织',
  80 + required: true,
  81 + component: 'ApiTreeSelect',
  82 + componentProps: {
  83 + api: async () => {
  84 + const data = await getOrganizationList();
  85 + copyTransFun(data as any as any[]);
  86 + return data;
  87 + },
  88 + },
  89 + },
  90 + // {
  91 + // field: 'state',
  92 + // label: '发布状态',
  93 + // required: true,
  94 + // component: 'RadioGroup',
  95 + // defaultValue: Platform.PC,
  96 + // componentProps: {
  97 + // defaultValue: Platform.PC,
  98 + // options: [
  99 + // { label: '未发布', value: Platform.PC },
  100 + // { label: '已发布', value: Platform.PHONE },
  101 + // ],
  102 + // },
  103 + // },
  104 + {
  105 + field: 'remark',
  106 + label: '备注',
  107 + component: 'InputTextArea',
  108 + componentProps: {
  109 + placeholder: '请输入备注',
  110 + maxLength: 255,
  111 + },
  112 + },
  113 + {
  114 + field: 'id',
  115 + label: '',
  116 + component: 'Input',
  117 + show: false,
  118 + componentProps: {
  119 + maxLength: 36,
  120 + placeholder: 'id',
  121 + },
  122 + },
  123 +];
... ...
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 { onMounted, reactive, ref, unref } from 'vue';
5   - import { OrganizationIdTree, useResetOrganizationTree } from '../common/organizationIdTree';
6   - import {
7   - bigScreenCancelPublish,
8   - bigScreenPublish,
9   - deleteBigScreenenter,
10   - getPage,
11   - } from '/@/api/bigscreen/center/bigscreenCenter';
12   - import { BigScreenCenterItemsModel } from '/@/api/bigscreen/center/model/bigscreenCenterModel';
13   - import { PageWrapper } from '/@/components/Page';
14   - import { BasicForm, useForm } from '/@/components/Form';
15   - import { ConfigurationPermission, searchFormSchema } from './config';
16   - import { useMessage } from '/@/hooks/web/useMessage';
17   - import { Authority } from '/@/components/Authority';
18   - import ConfigurationCenterDrawer from './BigScreenDrawer.vue';
19   - import { useDrawer } from '/@/components/Drawer';
20   - import { getBoundingClientRect } from '/@/utils/domUtils';
21   - import configurationSrc from '/@/assets/icons/configuration.svg';
22   - import { cloneDeep } from 'lodash';
23   - import { useGlobSetting } from '/@/hooks/setting';
24   - import { AuthIcon, CardLayoutButton } from '/@/components/Widget';
25   - import AuthDropDown from '/@/components/Widget/AuthDropDown.vue';
26   - import { PublicApiDrawer } from './publicApi/index';
27   -
28   - const listColumn = ref(5);
29   -
30   - const { createMessage } = useMessage();
31   -
32   - const organizationId = ref<Nullable<number>>(null);
33   -
34   - const pagination = reactive<PaginationProps>({
35   - size: 'small',
36   - showTotal: (total: number) => `共 ${total} 条数据`,
37   - current: 1,
38   - pageSize: unref(listColumn) * 2,
39   - onChange: (page: number) => {
40   - pagination.current = page;
41   - getListData();
42   - },
43   - });
44   -
45   - const loading = ref(false);
46   -
47   - const dataSource = ref<BigScreenCenterItemsModel[]>([]);
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();
58   - },
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 = unref(listColumn) * 2;
69   - const { items, total } = await getPage({
70   - organizationId: unref(organizationId),
71   - ...value,
72   - page: pagination.current!,
73   - pageSize,
74   - });
75   -
76   - dataSource.value = items;
77   - Object.assign(pagination, { total, 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 [registerPublicDrawer, { openDrawer: openPublicApiDrawer }] = useDrawer();
98   -
99   - const handleCreateOrUpdate = (record?: BigScreenCenterItemsModel) => {
100   - if (record) {
101   - openDrawer(true, {
102   - isUpdate: true,
103   - record: cloneDeep(record),
104   - });
105   - } else {
106   - openDrawer(true, {
107   - isUpdate: false,
108   - });
109   - }
110   - };
111   -
112   - const handleCreateOrUpdatePublicApi = () => openPublicApiDrawer(true);
113   -
114   - const { largeDesignerPrefix } = useGlobSetting();
115   -
116   - const handlePreview = (record: BigScreenCenterItemsModel) => {
117   - window.open(`${largeDesignerPrefix}/#/chart/preview/${record.id}`);
118   - };
119   -
120   - const handleDesign = (record: BigScreenCenterItemsModel) => {
121   - if (record.state === 1) return;
122   - window.open(`${largeDesignerPrefix}/#/chart/home/${record.id}`);
123   - };
124   -
125   - const handleDelete = async (record: BigScreenCenterItemsModel) => {
126   - try {
127   - await deleteBigScreenenter([record.id]);
128   - createMessage.success('删除成功');
129   - await getListData();
130   - } catch (error) {}
131   - };
132   -
133   - const handleCardLayoutChange = () => {
134   - pagination.current = 1;
135   - getListData();
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');
156   - });
157   -
158   - const getPublicApiListData = () => {};
159   -
160   - const handlePublish = async ({ id }) => {
161   - await bigScreenPublish(id);
162   - createMessage.success('发布成功');
163   - getListData();
164   - };
165   - const handleCancelPublish = async ({ id }) => {
166   - await bigScreenCancelPublish(id);
167   - createMessage.success('取消发布成功');
168   - getListData();
169   - };
170   -</script>
171   -
172   -<template>
173   - <PageWrapper dense contentFullHeight contentClass="flex">
174   - <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
175   - <section class="flex-auto p-4 w-3/4 xl:w-4/5 w-full configuration-list">
176   - <div class="flex-auto w-full bg-light-50 dark:bg-dark-900 p-4">
177   - <BasicForm @register="registerForm" />
178   - </div>
179   - <List
180   - ref="listEl"
181   - :loading="loading"
182   - class="flex-auto bg-light-50 dark:bg-dark-900 !p-2 !mt-4"
183   - position="bottom"
184   - :pagination="pagination"
185   - :data-source="dataSource"
186   - :grid="{ gutter: 4, column: listColumn }"
187   - >
188   - <template #header>
189   - <div class="flex gap-3 justify-end">
190   - <Authority :value="ConfigurationPermission.CREATE">
191   - <Button type="primary" @click="handleCreateOrUpdate()">新增大屏</Button>
192   - </Authority>
193   - <Authority :value="ConfigurationPermission.CREATE">
194   - <Button type="primary" @click="handleCreateOrUpdatePublicApi()">公共接口管理</Button>
195   - </Authority>
196   - <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" />
197   - <Tooltip title="刷新">
198   - <Button type="primary" @click="getListData">
199   - <ReloadOutlined />
200   - </Button>
201   - </Tooltip>
202   - </div>
203   - </template>
204   - <template #renderItem="{ item }">
205   - <List.Item>
206   - <Card>
207   - <template #cover>
208   - <div class="h-full w-full hover-show-modal-content">
209   - <img
210   - style="position: relative"
211   - class="w-full h-45 hover-show-modal"
212   - alt="example"
213   - :src="item.thumbnail || configurationSrc"
214   - @click="handlePreview(item)"
215   - />
216   - <div class="masker-content">
217   - <div class="masker-text">
218   - <div
219   - ><span>{{ item.name }}</span></div
220   - >
221   - <div>
222   - <span class="masker-text-org"
223   - >所属组织:{{ item.organizationDTO.name }}</span
224   - >
225   - </div>
226   - <div>
227   - <span class="masker-text-state"
228   - >发布状态:{{ item.state === 1 ? '已发布' : '未发布' }}</span
229   - >
230   - </div>
231   - </div>
232   - </div>
233   - </div>
234   - </template>
235   - <template class="ant-card-actions" #actions>
236   - <Tooltip title="预览">
237   - <AuthIcon
238   - class="!text-lg"
239   - icon="ant-design:eye-outlined"
240   - @click="handlePreview(item)"
241   - />
242   - </Tooltip>
243   - <Tooltip title="设计">
244   - <AuthIcon
245   - :class="`!text-lg ${
246   - item.state === 1 ? '!cursor-not-allowed !text-gray-200' : ''
247   - }`"
248   - icon="ant-design:edit-outlined"
249   - @click="handleDesign(item)"
250   - />
251   - </Tooltip>
252   - <AuthDropDown
253   - :dropMenuList="[
254   - {
255   - text: '发布',
256   - auth: ConfigurationPermission.UPDATE,
257   - icon: 'ant-design:node-expand-outlined',
258   - event: '',
259   - onClick: handlePublish.bind(null, item),
260   - disabled: item.state === 0 ? false : true,
261   - },
262   - {
263   - text: '取消发布',
264   - icon: 'ant-design:node-collapse-outlined',
265   - event: '',
266   - onClick: handleCancelPublish.bind(null, item),
267   - disabled: item.state === 1 ? false : true,
268   - },
269   - {
270   - text: '编辑',
271   - auth: ConfigurationPermission.UPDATE,
272   - icon: 'clarity:note-edit-line',
273   - event: '',
274   - onClick: handleCreateOrUpdate.bind(null, item),
275   - disabled: item.state === 0 ? false : true,
276   - },
277   - {
278   - text: '删除',
279   - auth: ConfigurationPermission.DELETE,
280   - icon: 'ant-design:delete-outlined',
281   - disabled: item.state === 0 ? false : true,
282   - event: '',
283   - popconfirm: {
284   - title: '是否确认删除操作?',
285   - onConfirm: handleDelete.bind(null, item),
286   - },
287   - },
288   - ]"
289   - :trigger="['hover']"
290   - />
291   - </template>
292   - </Card>
293   - </List.Item>
294   - </template>
295   - </List>
296   - </section>
297   - <ConfigurationCenterDrawer @register="registerDrawer" @success="getListData" />
298   - <PublicApiDrawer @register="registerPublicDrawer" @success="getPublicApiListData" />
299   - </PageWrapper>
300   -</template>
301   -
302   -<style lang="less" scoped>
303   - .configuration-list:deep(.ant-list-header) {
304   - border-bottom: none !important;
305   - }
306   -
307   - .configuration-list:deep(.ant-list-pagination) {
308   - height: 24px;
309   - }
310   -
311   - .configuration-list:deep(.ant-card-body) {
312   - padding: 16px !important;
313   - }
314   -
315   - .configuration-list:deep(.ant-list-empty-text) {
316   - @apply w-full h-full flex justify-center items-center;
317   - }
318   -
319   - :deep(.ant-card-body) {
320   - display: none;
321   - }
322   -
323   - .masker-content {
324   - opacity: 0;
325   - z-index: 1000;
326   - width: 100%;
327   - height: 11.25rem;
328   - background-color: rgba(0, 0, 0, 0.5);
329   - position: absolute;
330   - transition: opacity 0.5;
331   - pointer-events: none;
332   - top: 0;
333   - left: 0;
334   - right: 0;
335   - bottom: 0;
336   -
337   - .masker-text {
338   - color: #fff;
339   - font-size: 16px;
340   - display: flex;
341   - flex-direction: column;
342   - align-items: center;
343   - justify-content: center;
344   - line-height: 2.5rem;
345   - margin: 4rem 0;
346   -
347   - .masker-text-org {
348   - font-size: 12px;
349   - position: absolute;
350   - bottom: 0;
351   - left: 0.8rem;
352   - }
353   -
354   - .masker-text-state {
355   - font-size: 12px;
356   - position: absolute;
357   - bottom: 0;
358   - right: 0.8rem;
359   - }
360   - }
361   - }
362   -
363   - .hover-show-modal-content:hover > .masker-content {
364   - opacity: 1;
365   - }
366   -</style>
  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 { onMounted, reactive, ref, unref } from 'vue';
  5 + import { OrganizationIdTree, useResetOrganizationTree } from '../common/organizationIdTree';
  6 + import {
  7 + bigScreenCancelPublish,
  8 + bigScreenPublish,
  9 + deleteBigScreenenter,
  10 + getPage,
  11 + shareLargeScreen,
  12 + } from '/@/api/bigscreen/center/bigscreenCenter';
  13 + import { BigScreenCenterItemsModel } from '/@/api/bigscreen/center/model/bigscreenCenterModel';
  14 + import { PageWrapper } from '/@/components/Page';
  15 + import { BasicForm, useForm } from '/@/components/Form';
  16 + import { ConfigurationPermission, searchFormSchema } from './config';
  17 + import { useMessage } from '/@/hooks/web/useMessage';
  18 + import { Authority } from '/@/components/Authority';
  19 + import ConfigurationCenterDrawer from './BigScreenDrawer.vue';
  20 + import { useDrawer } from '/@/components/Drawer';
  21 + import { getBoundingClientRect } from '/@/utils/domUtils';
  22 + import configurationSrc from '/@/assets/icons/configuration.svg';
  23 + import { cloneDeep } from 'lodash';
  24 + import { useGlobSetting } from '/@/hooks/setting';
  25 + import { AuthIcon, CardLayoutButton } from '/@/components/Widget';
  26 + import AuthDropDown from '/@/components/Widget/AuthDropDown.vue';
  27 + import { PublicApiDrawer } from './publicApi/index';
  28 + import { useModal } from '/@/components/Modal';
  29 + import { ShareModal } from '/@/views/common/ShareModal';
  30 + import { ViewTypeNameEnum } from '../common/ShareModal/config';
  31 + import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
  32 +
  33 + const listColumn = ref(5);
  34 +
  35 + const { createMessage } = useMessage();
  36 +
  37 + const organizationId = ref<Nullable<number>>(null);
  38 +
  39 + const pagination = reactive<PaginationProps>({
  40 + size: 'small',
  41 + showTotal: (total: number) => `共 ${total} 条数据`,
  42 + current: 1,
  43 + pageSize: unref(listColumn) * 2,
  44 + onChange: (page: number) => {
  45 + pagination.current = page;
  46 + getListData();
  47 + },
  48 + });
  49 +
  50 + const loading = ref(false);
  51 +
  52 + const dataSource = ref<BigScreenCenterItemsModel[]>([]);
  53 +
  54 + const [registerForm, { getFieldsValue }] = useForm({
  55 + schemas: searchFormSchema,
  56 + showAdvancedButton: true,
  57 + labelWidth: 100,
  58 + compact: true,
  59 + resetFunc: () => {
  60 + resetFn();
  61 + organizationId.value = null;
  62 + return getListData();
  63 + },
  64 + submitFunc: async () => {
  65 + const value = getFieldsValue();
  66 + getListData(value);
  67 + },
  68 + });
  69 +
  70 + async function getListData(value: Recordable = {}) {
  71 + try {
  72 + loading.value = true;
  73 + const pageSize = unref(listColumn) * 2;
  74 + const { items, total } = await getPage({
  75 + organizationId: unref(organizationId),
  76 + ...value,
  77 + page: pagination.current!,
  78 + pageSize,
  79 + });
  80 +
  81 + dataSource.value = items;
  82 + Object.assign(pagination, { total, pageSize });
  83 + } catch (error) {
  84 + } finally {
  85 + loading.value = false;
  86 + }
  87 + }
  88 +
  89 + onMounted(() => {
  90 + getListData();
  91 + });
  92 +
  93 + const searchInfo = reactive<Recordable>({});
  94 + const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
  95 + const handleSelect = (orgId: number) => {
  96 + organizationId.value = orgId;
  97 + getListData();
  98 + };
  99 +
  100 + const [registerDrawer, { openDrawer }] = useDrawer();
  101 +
  102 + const [registerPublicDrawer, { openDrawer: openPublicApiDrawer }] = useDrawer();
  103 +
  104 + const handleCreateOrUpdate = (record?: BigScreenCenterItemsModel) => {
  105 + if (record) {
  106 + openDrawer(true, {
  107 + isUpdate: true,
  108 + record: cloneDeep(record),
  109 + });
  110 + } else {
  111 + openDrawer(true, {
  112 + isUpdate: false,
  113 + });
  114 + }
  115 + };
  116 +
  117 + const handleCreateOrUpdatePublicApi = () => openPublicApiDrawer(true);
  118 +
  119 + const { largeDesignerPrefix } = useGlobSetting();
  120 +
  121 + const handlePreview = (record: BigScreenCenterItemsModel) => {
  122 + window.open(`${largeDesignerPrefix}/#/chart/preview/${record.id}`);
  123 + };
  124 +
  125 + const handleDesign = (record: BigScreenCenterItemsModel) => {
  126 + if (record.state === 1) return;
  127 + window.open(`${largeDesignerPrefix}/#/chart/home/${record.id}`);
  128 + };
  129 +
  130 + const handleDelete = async (record: BigScreenCenterItemsModel) => {
  131 + try {
  132 + await deleteBigScreenenter([record.id]);
  133 + createMessage.success('删除成功');
  134 + await getListData();
  135 + } catch (error) {}
  136 + };
  137 +
  138 + const handleCardLayoutChange = () => {
  139 + pagination.current = 1;
  140 + getListData();
  141 + };
  142 +
  143 + const listEl = ref<Nullable<ComponentElRef>>(null);
  144 +
  145 + onMounted(() => {
  146 + const clientHeight = document.documentElement.clientHeight;
  147 + const rect = getBoundingClientRect(unref(listEl)!.$el!) as DOMRect;
  148 + // margin-top 24 height 24
  149 + const paginationHeight = 24 + 24 + 8;
  150 + // list pading top 8 maring-top 8 extra slot 56
  151 + const listContainerMarginBottom = 8 + 8 + 56;
  152 + const listContainerHeight =
  153 + clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
  154 + const listContainerEl = (unref(listEl)!.$el as HTMLElement).querySelector(
  155 + '.ant-spin-container'
  156 + ) as HTMLElement;
  157 + listContainerEl &&
  158 + (listContainerEl.style.height = listContainerHeight + 'px') &&
  159 + (listContainerEl.style.overflowY = 'auto') &&
  160 + (listContainerEl.style.overflowX = 'hidden');
  161 + });
  162 +
  163 + const getPublicApiListData = () => {};
  164 +
  165 + const [registerShareModal, { openModal }] = useModal();
  166 + const handleOpenShareModal = (item: BigScreenCenterItemsModel) => {
  167 + openModal(true, item);
  168 + };
  169 +
  170 + const { clipboardRef, isSuccessRef } = useCopyToClipboard();
  171 + const handleCreateShareUrl = (record: BigScreenCenterItemsModel) => {
  172 + const { origin } = location;
  173 + const { largeDesignerPrefix } = useGlobSetting();
  174 + clipboardRef.value = `${origin}${largeDesignerPrefix}/#/share/preview/${record.id}/${record.publicId}`;
  175 + if (unref(isSuccessRef)) {
  176 + createMessage.success('复制成功~');
  177 + }
  178 + };
  179 +
  180 + const handlePublish = async ({ id }) => {
  181 + await bigScreenPublish(id);
  182 + createMessage.success('发布成功');
  183 + getListData();
  184 + };
  185 + const handleCancelPublish = async ({ id }) => {
  186 + await bigScreenCancelPublish(id);
  187 + createMessage.success('取消发布成功');
  188 + getListData();
  189 + };
  190 +</script>
  191 +
  192 +<template>
  193 + <PageWrapper dense contentFullHeight contentClass="flex">
  194 + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
  195 + <section class="flex-auto p-4 w-3/4 xl:w-4/5 w-full configuration-list">
  196 + <div class="flex-auto w-full bg-light-50 dark:bg-dark-900 p-4">
  197 + <BasicForm @register="registerForm" />
  198 + </div>
  199 + <List
  200 + ref="listEl"
  201 + :loading="loading"
  202 + class="flex-auto bg-light-50 dark:bg-dark-900 !p-2 !mt-4"
  203 + position="bottom"
  204 + :pagination="pagination"
  205 + :data-source="dataSource"
  206 + :grid="{ gutter: 4, column: listColumn }"
  207 + >
  208 + <template #header>
  209 + <div class="flex gap-3 justify-end">
  210 + <Authority :value="ConfigurationPermission.CREATE">
  211 + <Button type="primary" @click="handleCreateOrUpdate()">新增大屏</Button>
  212 + </Authority>
  213 + <Authority :value="ConfigurationPermission.CREATE">
  214 + <Button type="primary" @click="handleCreateOrUpdatePublicApi()">公共接口管理</Button>
  215 + </Authority>
  216 + <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" />
  217 + <Tooltip title="刷新">
  218 + <Button type="primary" @click="getListData">
  219 + <ReloadOutlined />
  220 + </Button>
  221 + </Tooltip>
  222 + </div>
  223 + </template>
  224 + <template #renderItem="{ item }">
  225 + <List.Item>
  226 + <Card class="card-container">
  227 + <template #cover>
  228 + <div class="h-full w-full relative hover-show-modal-content img-container">
  229 + <img
  230 + style="position: relative"
  231 + class="w-full h-45 hover-show-modal"
  232 + alt="example"
  233 + :src="item.thumbnail || configurationSrc"
  234 + @click="handlePreview(item)"
  235 + />
  236 + <span
  237 + class="absolute top-0 left-0 text-light-50 transform -rotate-45 translate-y-1"
  238 + >
  239 + {{ ViewTypeNameEnum[item.viewType] }}
  240 + </span>
  241 + <div class="masker-content">
  242 + <div class="masker-text">
  243 + <div
  244 + ><span>{{ item.name }}</span></div
  245 + >
  246 + <div>
  247 + <span class="masker-text-org"
  248 + >所属组织:{{ item.organizationDTO.name }}</span
  249 + >
  250 + </div>
  251 + <div>
  252 + <span class="masker-text-state"
  253 + >发布状态:{{ item.state === 1 ? '已发布' : '未发布' }}</span
  254 + >
  255 + </div>
  256 + </div>
  257 + </div>
  258 + </div>
  259 + </template>
  260 + <template class="ant-card-actions" #actions>
  261 + <Tooltip title="预览">
  262 + <AuthIcon
  263 + class="!text-lg"
  264 + icon="ant-design:eye-outlined"
  265 + @click="handlePreview(item)"
  266 + />
  267 + </Tooltip>
  268 + <Tooltip title="设计">
  269 + <AuthIcon
  270 + :class="`!text-lg ${
  271 + item.state === 1 ? '!cursor-not-allowed !text-gray-200' : ''
  272 + }`"
  273 + icon="ant-design:edit-outlined"
  274 + @click="handleDesign(item)"
  275 + />
  276 + </Tooltip>
  277 + <Tooltip title="分享">
  278 + <AuthIcon
  279 + :auth="ConfigurationPermission.SHARE"
  280 + class="!text-lg"
  281 + icon="ant-design:share-alt-outlined"
  282 + @click="handleCreateShareUrl(item)"
  283 + />
  284 + </Tooltip>
  285 + <AuthDropDown
  286 + :dropMenuList="[
  287 + {
  288 + text: '分享',
  289 + auth: ConfigurationPermission.SHARE,
  290 + icon: 'ant-design:share-alt-outlined',
  291 + event: '',
  292 + onClick: handleOpenShareModal.bind(null, item),
  293 + },
  294 + {
  295 + text: '发布',
  296 + auth: ConfigurationPermission.UPDATE,
  297 + icon: 'ant-design:node-expand-outlined',
  298 + event: '',
  299 + onClick: handlePublish.bind(null, item),
  300 + disabled: item.state === 0 ? false : true,
  301 + },
  302 + {
  303 + text: '取消发布',
  304 + icon: 'ant-design:node-collapse-outlined',
  305 + event: '',
  306 + onClick: handleCancelPublish.bind(null, item),
  307 + disabled: item.state === 1 ? false : true,
  308 + },
  309 + {
  310 + text: '编辑',
  311 + auth: ConfigurationPermission.UPDATE,
  312 + icon: 'clarity:note-edit-line',
  313 + event: '',
  314 + onClick: handleCreateOrUpdate.bind(null, item),
  315 + disabled: item.state === 0 ? false : true,
  316 + },
  317 + {
  318 + text: '删除',
  319 + auth: ConfigurationPermission.DELETE,
  320 + icon: 'ant-design:delete-outlined',
  321 + disabled: item.state === 0 ? false : true,
  322 + event: '',
  323 + popconfirm: {
  324 + title: '是否确认删除操作?',
  325 + onConfirm: handleDelete.bind(null, item),
  326 + },
  327 + },
  328 + ]"
  329 + :trigger="['hover']"
  330 + />
  331 + </template>
  332 + </Card>
  333 + </List.Item>
  334 + </template>
  335 + </List>
  336 + </section>
  337 + <ShareModal
  338 + @register="registerShareModal"
  339 + :shareApi="shareLargeScreen"
  340 + @success="getListData"
  341 + />
  342 + <ConfigurationCenterDrawer @register="registerDrawer" @success="getListData" />
  343 + <PublicApiDrawer @register="registerPublicDrawer" @success="getPublicApiListData" />
  344 + </PageWrapper>
  345 +</template>
  346 +
  347 +<style lang="less" scoped>
  348 + .configuration-list:deep(.ant-list-header) {
  349 + border-bottom: none !important;
  350 + }
  351 +
  352 + .configuration-list:deep(.ant-list-pagination) {
  353 + height: 24px;
  354 + }
  355 +
  356 + .configuration-list:deep(.ant-card-body) {
  357 + padding: 16px !important;
  358 + }
  359 +
  360 + .configuration-list:deep(.ant-list-empty-text) {
  361 + @apply w-full h-full flex justify-center items-center;
  362 + }
  363 +
  364 + :deep(.ant-card-body) {
  365 + display: none;
  366 + }
  367 +
  368 + .masker-content {
  369 + opacity: 0;
  370 + z-index: 1000;
  371 + width: 100%;
  372 + height: 11.25rem;
  373 + background-color: rgba(0, 0, 0, 0.5);
  374 + position: absolute;
  375 + transition: opacity 0.5;
  376 + pointer-events: none;
  377 + top: 0;
  378 + left: 0;
  379 + right: 0;
  380 + bottom: 0;
  381 +
  382 + .masker-text {
  383 + color: #fff;
  384 + font-size: 16px;
  385 + display: flex;
  386 + flex-direction: column;
  387 + align-items: center;
  388 + justify-content: center;
  389 + line-height: 2.5rem;
  390 + margin: 4rem 0;
  391 +
  392 + .masker-text-org {
  393 + font-size: 12px;
  394 + position: absolute;
  395 + bottom: 0;
  396 + left: 0.8rem;
  397 + }
  398 +
  399 + .masker-text-state {
  400 + font-size: 12px;
  401 + position: absolute;
  402 + bottom: 0;
  403 + right: 0.8rem;
  404 + }
  405 + }
  406 + }
  407 +
  408 + .hover-show-modal-content:hover > .masker-content {
  409 + opacity: 1;
  410 + }
  411 +
  412 + .card-container {
  413 + // background-color: red;
  414 + .img-container {
  415 + border-top-left-radius: 80px;
  416 + background-color: #fff;
  417 +
  418 + img {
  419 + border-top-left-radius: 80px;
  420 + }
  421 + }
  422 + }
  423 +
  424 + .card-container:deep(.ant-card-cover) {
  425 + background-color: red;
  426 + }
  427 +</style>
... ...