فهرست منبع

fix(分屏展示): 添加loading

xieyonghong 3 سال پیش
والد
کامیت
3c53d736de

+ 4 - 0
src/components/Player/ScreenPlayer.tsx

@@ -70,6 +70,7 @@ export default forwardRef((props: ScreenProps, ref) => {
   const [playerActive, setPlayerActive] = useState(0);
   const [historyList, setHistoryList] = useState<any>([]);
   const [visible, setVisible] = useState(false);
+  const [loading, setLoading] = useState(false);
 
   const fullscreenRef = useRef(null);
   const [isFullscreen, { setFull }] = useFullscreen(fullscreenRef);
@@ -189,7 +190,9 @@ export default forwardRef((props: ScreenProps, ref) => {
         players: players.map((item) => ({ deviceId: item.id, channelId: item.channelId })),
       }),
     };
+    setLoading(true);
     const resp = await service.history.save(DEFAULT_SAVE_CODE, param);
+    setLoading(false);
     if (resp.status === 200) {
       setVisible(false);
       getHistory();
@@ -347,6 +350,7 @@ export default forwardRef((props: ScreenProps, ref) => {
                       <Button
                         type={'primary'}
                         onClick={saveHistory}
+                        loading={loading}
                         style={{ width: '100%', marginTop: 16 }}
                       >
                         保存

+ 23 - 19
src/components/ProTableCard/index.tsx

@@ -38,12 +38,14 @@ const ProTableCard = <
   const [pageSize, setPageSize] = useState(Default_Size * 2); // 每页条数
   const [column, setColumn] = useState(props.gridColumn || 4);
   const [loading, setLoading] = useState(false);
+  const [dataLength, setDataLength] = useState<number>(0);
 
   /**
    * 处理 Card
    * @param dataSource
    */
   const handleCard = (dataSource: readonly T[] | undefined): JSX.Element => {
+    setDataLength(dataSource ? dataSource.length : 0);
     return (
       <>
         {dataSource && dataSource.length ? (
@@ -178,25 +180,27 @@ const ProTableCard = <
           <div className={classNames('mask-loading', { show: loading })}>
             <LoadingComponent />
           </div>
-          <Pagination
-            showSizeChanger
-            size="small"
-            className={'pro-table-card-pagination'}
-            total={total}
-            current={current}
-            onChange={(page, size) => {
-              setCurrent(page);
-              setPageIndex(page - 1);
-              setPageSize(size);
-            }}
-            pageSizeOptions={pageSizeOptions}
-            pageSize={pageSize}
-            showTotal={(num) => {
-              const minSize = pageIndex * pageSize + 1;
-              const MaxSize = (pageIndex + 1) * pageSize;
-              return `第 ${minSize} - ${MaxSize > num ? num : MaxSize} 条/总共 ${num} 条`;
-            }}
-          />
+          {!!dataLength && (
+            <Pagination
+              showSizeChanger
+              size="small"
+              className={'pro-table-card-pagination'}
+              total={total}
+              current={current}
+              onChange={(page, size) => {
+                setCurrent(page);
+                setPageIndex(page - 1);
+                setPageSize(size);
+              }}
+              pageSizeOptions={pageSizeOptions}
+              pageSize={pageSize}
+              showTotal={(num) => {
+                const minSize = pageIndex * pageSize + 1;
+                const MaxSize = (pageIndex + 1) * pageSize;
+                return `第 ${minSize} - ${MaxSize > num ? num : MaxSize} 条/总共 ${num} 条`;
+              }}
+            />
+          )}
         </>
       )}
     </div>

+ 16 - 8
src/pages/device/Instance/index.tsx

@@ -154,13 +154,17 @@ const Instance = () => {
       key={'delete'}
       style={{ padding: 0 }}
       isPermission={permission.delete}
+      tooltip={
+        record.state.value !== 'notActive'
+          ? { title: intl.formatMessage({ id: 'pages.device.instance.deleteTip' }) }
+          : undefined
+      }
+      disabled={record.state.value !== 'notActive'}
       popConfirm={{
         title: intl.formatMessage({
-          id:
-            record.state.value === 'notActive'
-              ? 'pages.data.option.remove.tips'
-              : 'pages.device.instance.deleteTip',
+          id: 'pages.data.option.remove.tips',
         }),
+        disabled: record.state.value !== 'notActive',
         onConfirm: async () => {
           if (record.state.value === 'notActive') {
             await service.remove(record.id);
@@ -621,13 +625,17 @@ const Instance = () => {
                 isPermission={permission.delete}
                 type={'link'}
                 style={{ padding: 0 }}
+                tooltip={
+                  record.state.value !== 'notActive'
+                    ? { title: intl.formatMessage({ id: 'pages.device.instance.deleteTip' }) }
+                    : undefined
+                }
+                disabled={record.state.value !== 'notActive'}
                 popConfirm={{
                   title: intl.formatMessage({
-                    id:
-                      record.state.value === 'notActive'
-                        ? 'pages.data.option.remove.tips'
-                        : 'pages.device.instance.deleteTip',
+                    id: 'pages.data.option.remove.tips',
                   }),
+                  disabled: record.state.value !== 'notActive',
                   onConfirm: async () => {
                     if (record.state.value === 'notActive') {
                       await service.remove(record.id);

+ 1 - 0
src/pages/rule-engine/Scene/Save/index.tsx

@@ -0,0 +1 @@
+export default () => {};

+ 177 - 92
src/pages/rule-engine/Scene/index.tsx

@@ -1,32 +1,125 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import BaseService from '@/utils/BaseService';
-import { useRef } from 'react';
+import { useRef, useState } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import type { SceneItem } from '@/pages/rule-engine/Scene/typings';
-import { Tooltip } from 'antd';
-import {
-  CaretRightOutlined,
-  EditOutlined,
-  EyeOutlined,
-  MinusOutlined,
-  ReloadOutlined,
-  StopOutlined,
-} from '@ant-design/icons';
-import BaseCrud from '@/components/BaseCrud';
+import { Badge, message } from 'antd';
+import { EditOutlined, PlayCircleOutlined, PlusOutlined, StopOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { PermissionButton, ProTableCard } from '@/components';
+import { statusMap } from '@/pages/device/Instance';
+import SearchComponent from '@/components/SearchComponent';
+import Service from './service';
+
+export const service = new Service('rule-engine/scene');
 
-export const service = new BaseService<SceneItem>('rule-engine/scene');
 const Scene = () => {
   const intl = useIntl();
   const actionRef = useRef<ActionType>();
+  const { permission } = PermissionButton.usePermission('rule-engine/Scene');
+  const [searchParams, setSearchParams] = useState<any>({});
+
+  const Tools = (record: any, type: 'card' | 'table') => {
+    return [
+      <PermissionButton
+        key={'update'}
+        type={'link'}
+        style={{ padding: 0 }}
+        isPermission={permission.update}
+        tooltip={
+          type === 'table'
+            ? {
+                title: intl.formatMessage({
+                  id: 'pages.data.option.edit',
+                  defaultMessage: '编辑',
+                }),
+              }
+            : undefined
+        }
+      >
+        <EditOutlined />
+        {type === 'table' &&
+          intl.formatMessage({
+            id: 'pages.data.option.edit',
+            defaultMessage: '编辑',
+          })}
+      </PermissionButton>,
+      <PermissionButton
+        key={'update'}
+        type={'link'}
+        style={{ padding: 0 }}
+        isPermission={permission.action}
+        popConfirm={{
+          title: intl.formatMessage({
+            id: `pages.data.option.${
+              record.state.value !== 'notActive' ? 'disabled' : 'enabled'
+            }.tips`,
+            defaultMessage: '确认禁用?',
+          }),
+          onConfirm: async () => {
+            message.success(
+              intl.formatMessage({
+                id: 'pages.data.option.success',
+                defaultMessage: '操作成功!',
+              }),
+            );
+            actionRef.current?.reload();
+          },
+        }}
+        tooltip={
+          type === 'table'
+            ? {
+                title: intl.formatMessage({
+                  id: 'pages.data.option.edit',
+                  defaultMessage: '编辑',
+                }),
+              }
+            : undefined
+        }
+      >
+        {record.state.value !== 'notActive' ? <StopOutlined /> : <PlayCircleOutlined />}
+        {type === 'table' &&
+          intl.formatMessage({
+            id: `pages.data.option.${record.state.value !== 'notActive' ? 'disabled' : 'enabled'}`,
+            defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
+          })}
+      </PermissionButton>,
+      <PermissionButton
+        key={'delete'}
+        type={'link'}
+        style={{ padding: 0 }}
+        isPermission={permission.delete}
+        popConfirm={{
+          title: intl.formatMessage({
+            id:
+              record.state.value === 'notActive'
+                ? 'pages.data.option.remove.tips'
+                : 'pages.device.instance.deleteTip',
+          }),
+          onConfirm: async () => {},
+        }}
+        tooltip={
+          type === 'table'
+            ? {
+                title: intl.formatMessage({
+                  id: 'pages.data.option.edit',
+                  defaultMessage: '编辑',
+                }),
+              }
+            : undefined
+        }
+      >
+        <EditOutlined />
+        {type === 'table' &&
+          intl.formatMessage({
+            id: 'pages.data.option.edit',
+            defaultMessage: '编辑',
+          })}
+      </PermissionButton>,
+    ];
+  };
 
   const columns: ProColumns<SceneItem>[] = [
     {
-      dataIndex: 'index',
-      valueType: 'indexBorder',
-      width: 48,
-    },
-    {
       dataIndex: 'name',
       title: intl.formatMessage({
         id: 'pages.table.name',
@@ -39,7 +132,13 @@ const Scene = () => {
         id: 'pages.ruleEngine.scene.triggers',
         defaultMessage: '触发方式',
       }),
-      render: () => 'todo',
+    },
+    {
+      dataIndex: 'describe',
+      title: intl.formatMessage({
+        id: 'pages.system.description',
+        defaultMessage: '说明',
+      }),
     },
     {
       dataIndex: 'state',
@@ -47,7 +146,26 @@ const Scene = () => {
         id: 'pages.searchTable.titleStatus',
         defaultMessage: '状态',
       }),
-      render: (text, record) => record.state.value,
+      width: '90px',
+      valueType: 'select',
+      renderText: (record) =>
+        record ? <Badge status={statusMap.get(record.value)} text={record.text} /> : '',
+      valueEnum: {
+        offline: {
+          text: intl.formatMessage({
+            id: 'pages.device.instance.status.offLine',
+            defaultMessage: '离线',
+          }),
+          status: 'offline',
+        },
+        online: {
+          text: intl.formatMessage({
+            id: 'pages.device.instance.status.onLine',
+            defaultMessage: '在线',
+          }),
+          status: 'online',
+        },
+      },
     },
     {
       title: intl.formatMessage({
@@ -57,85 +175,52 @@ const Scene = () => {
       valueType: 'option',
       align: 'center',
       width: 200,
-      render: (text, record) => [
-        <a>
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.ruleEngine.option.detail',
-              defaultMessage: '查看',
-            })}
-          >
-            <EyeOutlined />
-          </Tooltip>
-        </a>,
-        <a onClick={() => console.log(record)}>
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.data.option.edit',
-              defaultMessage: '编辑',
-            })}
-          >
-            <EditOutlined />
-          </Tooltip>
-        </a>,
-        <a onClick={() => console.log(record)}>
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.ruleEngine.option.start',
-              defaultMessage: '启动',
-            })}
-          >
-            <CaretRightOutlined />
-          </Tooltip>
-        </a>,
-        <a onClick={() => console.log(record)}>
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.ruleEngine.option.stop',
-              defaultMessage: '停止',
-            })}
-          >
-            <StopOutlined />
-          </Tooltip>
-        </a>,
-        <a onClick={() => console.log(record)}>
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.ruleEngine.option.restart',
-              defaultMessage: '重启',
-            })}
-          >
-            <ReloadOutlined />
-          </Tooltip>
-        </a>,
-
-        <a>
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.data.option.remove',
-              defaultMessage: '删除',
-            })}
-          >
-            <MinusOutlined />
-          </Tooltip>
-        </a>,
-      ],
+      render: (text, record) => Tools(record, 'table'),
     },
   ];
 
-  const schema = {};
-
   return (
     <PageContainer>
-      <BaseCrud
+      <SearchComponent
+        field={columns}
+        target={'rule-engine-scene'}
+        onSearch={(data) => {
+          actionRef.current?.reset?.();
+          setSearchParams(data);
+        }}
+      />
+      <ProTableCard
         columns={columns}
-        service={service}
-        title={intl.formatMessage({
-          id: 'pages.ruleEngine.scene',
-          defaultMessage: '场景联动',
-        })}
-        schema={schema}
         actionRef={actionRef}
+        params={searchParams}
+        options={{ fullScreen: true }}
+        request={(params) =>
+          service.query({
+            ...params,
+            sorts: [
+              {
+                name: 'createTime',
+                order: 'desc',
+              },
+            ],
+          })
+        }
+        rowKey="id"
+        search={false}
+        headerTitle={[
+          <PermissionButton
+            key="button"
+            icon={<PlusOutlined />}
+            type="primary"
+            isPermission={permission.add}
+            onClick={() => {}}
+          >
+            {intl.formatMessage({
+              id: 'pages.data.option.add',
+              defaultMessage: '新增',
+            })}
+          </PermissionButton>,
+        ]}
       />
     </PageContainer>
   );

+ 9 - 0
src/pages/rule-engine/Scene/service.ts

@@ -0,0 +1,9 @@
+import { request } from '@@/plugin-request/request';
+import BaseService from '@/utils/BaseService';
+import type { SceneItem } from '@/pages/rule-engine/Scene/typings';
+
+class Service extends BaseService<SceneItem> {
+  start = (id: string) => request(`${this.uri}/${id}`, { methods: 'GET' });
+}
+
+export default Service;

+ 1 - 0
src/pages/rule-engine/Scene/typings.d.ts

@@ -9,6 +9,7 @@ type Trigger = {
   trigger: string;
   device: Record<string, unknown>;
 };
+
 type SceneItem = {
   parallel: boolean;
   state: State;

+ 4 - 0
src/pages/system/Menu/Detail/buttons.tsx

@@ -23,6 +23,7 @@ export default (props: ButtonsProps) => {
   const [visible, setVisible] = useState(false); // Modal显示影藏
   const [id, setId] = useState(''); // 缓存ID
   const [form] = Form.useForm();
+  const [loading, setLoading] = useState(false);
   const { permission } = PermissionButton.usePermission('system/Menu');
 
   const { data: permissions, run: queryPermissions } = useRequest(service.queryPermission, {
@@ -67,10 +68,12 @@ export default (props: ButtonsProps) => {
   const updateMenuInfo = useCallback(
     async (data: MenuButtonInfo[]) => {
       if (props.data.id) {
+        setLoading(true);
         const response = await service.update({
           ...props.data,
           buttons: data,
         });
+        setLoading(false);
         if (response.status === 200) {
           message.success('操作成功!');
           props.onLoad();
@@ -283,6 +286,7 @@ export default (props: ButtonsProps) => {
           resetForm();
           setVisible(false);
         }}
+        confirmLoading={loading}
       >
         <Form form={form} layout={'vertical'}>
           <Form.Item