Преглед изворни кода

feat(设备管理): 修改设备管理Card

xieyonghong пре 3 година
родитељ
комит
f799c6b143

+ 14 - 9
src/components/ProTableCard/CardItems/device.tsx

@@ -1,10 +1,12 @@
 import React from 'react';
 import type { DeviceInstance } from '@/pages/device/Instance/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import '../index.less';
 import { TableCard } from '@/components';
+import '@/style/common.less';
+import '../index.less';
 
 export interface DeviceCardProps extends DeviceInstance {
+  detail?: React.ReactNode;
   actions?: React.ReactNode[];
   avatarSize?: number;
 }
@@ -14,13 +16,14 @@ const defaultImage = require('/public/images/device-type-3-big.png');
 export default (props: DeviceCardProps) => {
   return (
     <TableCard
+      detail={props.detail}
       actions={props.actions}
       status={props.state.value}
       statusText={props.state.text}
       statusNames={{
-        online: StatusColorEnum.success,
+        online: StatusColorEnum.processing,
         offline: StatusColorEnum.error,
-        notActive: StatusColorEnum.processing,
+        notActive: StatusColorEnum.warning,
       }}
     >
       <div className={'pro-table-card-item'}>
@@ -32,12 +35,14 @@ export default (props: DeviceCardProps) => {
             <span className={'card-item-header-name ellipsis'}>{props.name}</span>
           </div>
           <div className={'card-item-content'}>
-            <label>设备类型:</label> <br />
-            <span className={'ellipsis'}>{props.deviceType ? props.deviceType.text : '--'}</span>
-          </div>
-          <div className={'card-item-content'}>
-            <label>产品名称:</label> <br />
-            <span className={'ellipsis'}>{props.productName || '--'}</span>
+            <div>
+              <label>设备类型</label>
+              <div className={'ellipsis'}>{props.deviceType ? props.deviceType.text : '--'}</div>
+            </div>
+            <div>
+              <label>产品名称</label>
+              <div className={'ellipsis'}>{props.productName || '--'}</div>
+            </div>
           </div>
         </div>
       </div>

+ 8 - 1
src/components/ProTableCard/TableCard.tsx

@@ -20,7 +20,14 @@ export interface TableCardProps {
 function getAction(actions: React.ReactNode[]) {
   return actions.map((item: any) => {
     return (
-      <div className={classNames('card-button', { delete: item.key === 'delete' })}>{item}</div>
+      <div
+        className={classNames('card-button', {
+          delete: item.key === 'delete',
+          disabled: item.disabled,
+        })}
+      >
+        {item}
+      </div>
     );
   });
 }

+ 67 - 34
src/components/ProTableCard/index.less

@@ -25,8 +25,6 @@
     display: grid;
     grid-gap: 26px;
     grid-template-columns: repeat(4, 1fr);
-    //display: flex;
-    //flex-wrap: wrap;
     padding-bottom: 38px;
 
     .pro-table-card-item {
@@ -57,8 +55,21 @@
         .card-item-content {
           display: flex;
 
-          > span {
-            flex: 1;
+          > div:last-child {
+            flex-grow: 1;
+            width: 0;
+            margin-left: 12px;
+          }
+
+          label {
+            color: rgba(#000, 0.75);
+            font-size: 12px;
+          }
+
+          .ellipsis {
+            width: 100%;
+            font-weight: bold;
+            font-size: 14px;
           }
         }
       }
@@ -162,57 +173,79 @@
     .card-button {
       display: flex;
       flex-grow: 1;
-      justify-content: center;
-      background: #f6f6f6;
-      border: 1px solid #e6e6e6;
-      cursor: pointer;
 
-      button {
+      > span,
+      & button {
         width: 100%;
+        border-radius: 0;
       }
 
-      &:not(:last-child) {
-        margin-right: 8px;
-      }
+      button {
+        background: #f6f6f6;
+        border: 1px solid #e6e6e6;
 
-      &:hover {
-        background-color: @primary-color-hover;
-        border-color: @primary-color-hover;
-        span {
-          color: #fff !important;
+        &:hover {
+          background-color: @primary-color-hover;
+          border-color: @primary-color-hover;
+          span {
+            color: #fff !important;
+          }
         }
-      }
 
-      &:active {
-        background-color: @primary-color-active;
-        border-color: @primary-color-active;
-        span {
-          color: #fff !important;
+        &:active {
+          background-color: @primary-color-active;
+          border-color: @primary-color-active;
+          span {
+            color: #fff !important;
+          }
         }
       }
 
+      &:not(:last-child) {
+        margin-right: 8px;
+      }
+
       &.delete {
         flex-basis: 60px;
         flex-grow: 0;
-        background: @error-color-deprecated-bg;
-        border: 1px solid @error-color-outline;
+
+        button {
+          background: @error-color-deprecated-bg;
+          border: 1px solid @error-color-outline;
+          span {
+            color: @error-color !important;
+          }
+
+          &:hover {
+            background-color: @error-color-hover;
+            span {
+              color: #fff !important;
+            }
+          }
+
+          &:active {
+            background-color: @error-color-active;
+            span {
+              color: #fff !important;
+            }
+          }
+        }
+      }
+
+      button[disabled] {
+        background: @disabled-bg;
+        border-color: @disabled-color;
 
         span {
-          color: @error-color !important;
+          color: @disabled-color !important;
         }
 
         &:hover {
-          background-color: @error-color-hover;
-          span {
-            color: #fff !important;
-          }
+          background-color: @disabled-active-bg;
         }
 
         &:active {
-          background-color: @error-color-active;
-          span {
-            color: #fff !important;
-          }
+          background-color: @disabled-active-bg;
         }
       }
     }

+ 94 - 1
src/pages/device/Instance/index.tsx

@@ -14,6 +14,7 @@ import {
   PlusOutlined,
   StopOutlined,
   SyncOutlined,
+  EditOutlined,
 } from '@ant-design/icons';
 import { model } from '@formily/reactive';
 import Service from '@/pages/device/Instance/service';
@@ -405,7 +406,99 @@ const Instance = () => {
             <Button>批量操作</Button>
           </Dropdown>,
         ]}
-        cardRender={(record) => <DeviceCard {...record} actions={tools(record)} />}
+        cardRender={(record) => (
+          <DeviceCard
+            {...record}
+            detail={
+              <div
+                style={{ padding: 8, fontSize: 24 }}
+                onClick={() => {
+                  InstanceModel.current = record;
+                  const url = getMenuPathByParams(MENUS_CODE['device/Instance/Detail'], record.id);
+                  history.push(url);
+                }}
+              >
+                <EyeOutlined />
+              </div>
+            }
+            actions={[
+              <Button
+                type={'link'}
+                onClick={() => {
+                  setCurrent(record);
+                  setVisible(true);
+                }}
+                key={'edit'}
+              >
+                <EditOutlined />
+                {intl.formatMessage({
+                  id: 'pages.data.option.edit',
+                  defaultMessage: '编辑',
+                })}
+              </Button>,
+              <Popconfirm
+                key={'state'}
+                title={intl.formatMessage({
+                  id: `pages.data.option.${
+                    record.state.value !== 'notActive' ? 'disabled' : 'enabled'
+                  }.tips`,
+                  defaultMessage: '确认禁用?',
+                })}
+                onConfirm={async () => {
+                  if (record.state.value !== 'notActive') {
+                    await service.undeployDevice(record.id);
+                  } else {
+                    await service.deployDevice(record.id);
+                  }
+                  message.success(
+                    intl.formatMessage({
+                      id: 'pages.data.option.success',
+                      defaultMessage: '操作成功!',
+                    }),
+                  );
+                  actionRef.current?.reload();
+                }}
+              >
+                <Button type={'link'} style={{ padding: 0 }}>
+                  {record.state.value !== 'notActive' ? <StopOutlined /> : <CheckCircleOutlined />}
+                  {intl.formatMessage({
+                    id: `pages.data.option.${
+                      record.state.value !== 'notActive' ? 'disabled' : 'enabled'
+                    }`,
+                    defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
+                  })}
+                </Button>
+              </Popconfirm>,
+              <Popconfirm
+                title={intl.formatMessage({
+                  id:
+                    record.state.value === 'notActive'
+                      ? 'pages.data.option.remove.tips'
+                      : 'pages.device.instance.deleteTip',
+                })}
+                key={'delete'}
+                onConfirm={async () => {
+                  if (record.state.value === 'notActive') {
+                    await service.remove(record.id);
+                    message.success(
+                      intl.formatMessage({
+                        id: 'pages.data.option.success',
+                        defaultMessage: '操作成功!',
+                      }),
+                    );
+                    actionRef.current?.reload();
+                  } else {
+                    message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
+                  }
+                }}
+              >
+                <Button type={'link'} style={{ padding: 0 }}>
+                  <DeleteOutlined />
+                </Button>
+              </Popconfirm>,
+            ]}
+          />
+        )}
       />
       <Save
         data={current}