فهرست منبع

fix: 修改流媒体卡片

sun-chaochao 3 سال پیش
والد
کامیت
08e280179a

BIN
public/images/alarm/io.png


BIN
public/images/device-access.png


BIN
public/images/stream.png


+ 11 - 21
src/components/ProTableCard/CardItems/AccessConfig/index.less

@@ -20,6 +20,7 @@
   .context-access {
     display: flex;
     width: 100%;
+    height: 120px;
 
     .card {
       display: flex;
@@ -29,36 +30,16 @@
       margin-left: 20px;
 
       .header {
-        .title {
+        .access-title {
           width: calc(100% - 70px);
-          overflow: hidden;
           font-weight: 700;
           font-size: 18px;
-          white-space: nowrap;
-          text-overflow: ellipsis;
-        }
-
-        .title::before {
-          display: none;
-        }
-
-        .desc {
-          width: 100%;
-          margin-top: 10px;
-          overflow: hidden;
-          color: #666;
-          font-weight: 400;
-          font-size: 12px;
-          white-space: nowrap;
-          text-overflow: ellipsis;
         }
       }
 
       .container {
         display: flex;
         width: 100%;
-        min-height: 60px;
-        margin-top: 10px;
 
         .server,
         .procotol {
@@ -104,6 +85,15 @@
           }
         }
       }
+
+      .desc {
+        width: 100%;
+        margin-right: 10px;
+        margin-bottom: 10px;
+        color: #666;
+        font-weight: 400;
+        font-size: 12px;
+      }
     }
   }
 }

+ 50 - 24
src/components/ProTableCard/CardItems/AccessConfig/index.tsx

@@ -6,6 +6,7 @@ import { Badge, Tooltip } from 'antd';
 import type { AccessItem } from '@/pages/link/AccessConfig/typings';
 import './index.less';
 import classNames from 'classnames';
+import { Store } from 'jetlinks-store';
 
 export interface AccessConfigCardProps extends AccessItem {
   detail?: React.ReactNode;
@@ -38,35 +39,60 @@ export default (props: AccessConfigCardProps) => {
         </div>
         <div className="card">
           <div className="header">
-            <div className="title ellipsis">
-              <Tooltip title={props.name}>{props.name || '--'}</Tooltip>
-            </div>
-            <div className="desc">
-              <Tooltip title={props.description}>{props.description || '--'}</Tooltip>
+            <div className="access-title ellipsis">
+              <Tooltip placement="topLeft" title={props.name}>
+                {props.name}
+              </Tooltip>
             </div>
           </div>
-          <div className="container">
-            <div className="server">
-              <div className="subTitle">{props?.channelInfo?.name || '--'}</div>
-              <div className="serverItem">
-                {props.channelInfo?.addresses.slice(0, 2).map((i: any, index: number) => (
-                  <div className="subItem" key={i.address + `_address${index}`}>
-                    <Tooltip title={i.address}>
-                      <Badge color={i.health === -1 ? 'red' : 'green'} />
-                      {i.address}
+          {(props.protocolDetail?.name || props?.channelInfo?.name) && (
+            <div className="container">
+              {props?.channelInfo?.name && (
+                <div className="server">
+                  <div className="subTitle">{props?.channelInfo?.name}</div>
+                  <div className="serverItem">
+                    {props.channelInfo?.addresses.slice(0, 1).map((i: any, index: number) => (
+                      <div className="subItem" key={i.address + `_address${index}`}>
+                        <Tooltip placement="topLeft" title={i.address}>
+                          <Badge color={i.health === -1 ? 'red' : 'green'} />
+                          {i.address}
+                        </Tooltip>
+                      </div>
+                    ))}
+                  </div>
+                </div>
+              )}
+              {props.protocolDetail?.name && (
+                <div className="procotol">
+                  <div className="subTitle">协议</div>
+                  <div className="desc">
+                    <Tooltip placement="topLeft" title={props.protocolDetail?.name}>
+                      {props.protocolDetail?.name}
                     </Tooltip>
                   </div>
-                ))}
-              </div>
-            </div>
-            <div className="procotol">
-              <div className="subTitle">{props?.protocolDetail?.name || '--'}</div>
-              <div className="desc">
-                <Tooltip title={props.protocolDetail?.description}>
-                  {props.protocolDetail?.description || '--'}
-                </Tooltip>
-              </div>
+                </div>
+              )}
             </div>
+          )}
+          <div className="desc ellipsis">
+            {!!props?.description ? (
+              <Tooltip placement="topLeft" title={props?.description}>
+                {props?.description}
+              </Tooltip>
+            ) : (
+              <Tooltip
+                placement="topLeft"
+                title={
+                  (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)
+                    ?.description
+                }
+              >
+                {
+                  (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)
+                    ?.description
+                }
+              </Tooltip>
+            )}
           </div>
         </div>
       </div>

+ 56 - 0
src/components/ProTableCard/CardItems/Stream/index.less

@@ -0,0 +1,56 @@
+@import '~antd/es/style/themes/default.less';
+
+.stream-card-item {
+  width: 100%;
+  background: url('/images/access-config-enabled.png') no-repeat;
+  background-size: 100% 100%;
+
+  .context-stream {
+    display: flex;
+    width: 100%;
+
+    .card {
+      display: flex;
+      flex-direction: column;
+      flex-grow: 1;
+      width: 0;
+      margin-left: 20px;
+
+      .header {
+        .stream-title {
+          width: 100%;
+          font-weight: 700;
+          font-size: 18px;
+        }
+      }
+      .container {
+        display: flex;
+        justify-content: space-between;
+        width: 100%;
+        margin-bottom: 20px;
+        padding-right: 20px;
+
+        div {
+          label {
+            color: #000;
+            font-size: 12px;
+            opacity: 0.45;
+          }
+
+          div {
+            color: #000;
+            font-weight: 700;
+            font-size: 12px;
+            opacity: 0.75;
+          }
+        }
+      }
+    }
+  }
+}
+
+:global {
+  .ant-pagination-item {
+    display: none;
+  }
+}

+ 60 - 0
src/components/ProTableCard/CardItems/Stream/index.tsx

@@ -0,0 +1,60 @@
+import React from 'react';
+import { TableCard } from '@/components';
+import '@/style/common.less';
+import './index.less';
+import { Tooltip } from 'antd';
+
+export interface StreamCardProps extends StreamItem {
+  detail?: React.ReactNode;
+  actions?: React.ReactNode[];
+  avatarSize?: number;
+}
+
+const defaultImage = require('/public/images/stream.png');
+
+export default (props: StreamCardProps) => {
+  return (
+    <TableCard
+      detail={props.detail}
+      actions={props.actions}
+      showStatus={false}
+      showMask={false}
+      className={'stream-card-item'}
+    >
+      <div className="context-stream">
+        <div>
+          <img width={88} height={88} src={defaultImage} alt={''} />
+        </div>
+        <div className="card">
+          <div className="header">
+            <div className="stream-title ellipsis">
+              <Tooltip title={props.name}>{props.name}</Tooltip>
+            </div>
+          </div>
+          <div className="container">
+            <div>
+              <label>服务商</label>
+              <div className={'ellipsis'}>
+                <Tooltip title={props?.provider}>{props?.provider}</Tooltip>
+              </div>
+            </div>
+            <div>
+              <label>RTP IP</label>
+              <div className={'ellipsis'}>
+                <Tooltip title={props?.configuration?.rtpIp}>{props?.configuration?.rtpIp}</Tooltip>
+              </div>
+            </div>
+            <div>
+              <label>API HOST</label>
+              <div className={'ellipsis'}>
+                <Tooltip title={props?.configuration?.apiHost}>
+                  {props?.configuration?.apiHost}
+                </Tooltip>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </TableCard>
+  );
+};

+ 2 - 2
src/components/ProTableCard/CardItems/product.tsx

@@ -132,11 +132,11 @@ export default (props: ProductCardProps) => {
           <div className={'card-item-content'}>
             <div>
               <label>设备类型</label>
-              <div className={'ellipsis'}>{props.deviceType ? props.deviceType.text : '--'}</div>
+              <div className={'ellipsis'}>{props?.deviceType?.text}</div>
             </div>
             <div>
               <label>接入方式</label>
-              <div className={'ellipsis'}>{props.transportProtocol || '--'}</div>
+              <div className={'ellipsis'}>{props.transportProtocol || '未接入'}</div>
             </div>
           </div>
         </div>

+ 19 - 0
src/pages/link/AccessConfig/index.tsx

@@ -10,6 +10,7 @@ import { DeleteOutlined, EditOutlined, PlayCircleOutlined, StopOutlined } from '
 import AccessConfigCard from '@/components/ProTableCard/CardItems/AccessConfig';
 import { PermissionButton, Empty } from '@/components';
 import { useDomFullHeight } from '@/hooks';
+import { Store } from 'jetlinks-store';
 
 export const service = new Service('gateway/device');
 
@@ -26,6 +27,19 @@ const AccessConfig = () => {
       dataIndex: 'name',
     },
     {
+      title: '网关类型',
+      dataIndex: 'provider',
+      renderText: (text) => text?.text,
+      valueType: 'select',
+      request: () =>
+        service.getProviders().then((resp: any) => {
+          return (resp?.result || []).map((item: any) => ({
+            label: item.name,
+            value: item.id,
+          }));
+        }),
+    },
+    {
       title: '状态',
       dataIndex: 'state',
       valueType: 'select',
@@ -65,6 +79,11 @@ const AccessConfig = () => {
   };
 
   useEffect(() => {
+    service.getProviders().then((resp: any) => {
+      if (resp.status === 200) {
+        Store.set('access-providers', resp.result);
+      }
+    });
     handleSearch(param);
   }, []);
 

+ 1 - 1
src/pages/link/AccessConfig/typings.d.ts

@@ -3,7 +3,7 @@ import type { BaseItem } from '@/utils/typings';
 type AccessItem = {
   id: string | undefined;
   name: string;
-  description: string;
+  description?: string;
   provider: string;
   protocol: string;
   transport: string;

+ 0 - 57
src/pages/media/Stream/index.less

@@ -1,57 +0,0 @@
-.cardRender {
-  width: 100%;
-  background: url('/images/access.png') no-repeat;
-  background-size: 100% 100%;
-
-  .card {
-    .header {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      width: 100%;
-
-      .title {
-        width: 50%;
-        overflow: hidden;
-        color: rgba(0, 0, 0, 0.85);
-        font-weight: 700;
-        font-size: 16px;
-        white-space: nowrap;
-        text-overflow: ellipsis;
-      }
-
-      .actions {
-        .action span {
-          margin-left: 5px;
-          color: #4f4f4f;
-        }
-      }
-    }
-
-    .content {
-      display: flex;
-      justify-content: space-between;
-      width: 100%;
-      margin-top: 20px;
-
-      .item {
-        display: flex;
-        flex-direction: column;
-
-        .itemTitle {
-          color: rgba(0, 0, 0, 0.45);
-          font-size: 12px;
-        }
-
-        p {
-          color: rgba(0, 0, 0, 0.75);
-          font-weight: 700;
-          font-size: 12px;
-        }
-      }
-    }
-  }
-}
-.stream {
-  display: flex;
-}

+ 39 - 83
src/pages/media/Stream/index.tsx

@@ -1,17 +1,16 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import type { StreamItem } from '@/pages/media/Stream/typings';
 import SearchComponent from '@/components/SearchComponent';
 import type { ProColumns } from '@jetlinks/pro-table';
-import { Button, Card, Col, Empty, message, Pagination, Row, Space } from 'antd';
+import { Button, Card, Col, Empty, message, Pagination, Row } from 'antd';
 import { useEffect, useState } from 'react';
 import Service from '@/pages/media/Stream/service';
 import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { useHistory } from 'umi';
-import styles from './index.less';
 import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
 import { model } from '@formily/reactive';
 import { PermissionButton } from '@/components';
 import { useDomFullHeight } from '@/hooks';
+import StreamCard from '@/components/ProTableCard/CardItems/Stream';
 
 export const service = new Service('media/server');
 
@@ -92,89 +91,46 @@ const Stream = () => {
             >
               新增
             </PermissionButton>
-
             <Row gutter={[16, 16]} style={{ marginTop: 10 }}>
               {(dataSource?.data || []).map((item: any) => (
                 <Col key={item.id} span={12}>
-                  <Card hoverable className={styles.cardRender}>
-                    <div className={styles.card}>
-                      <div className={styles.header}>
-                        <div className={styles.title}>{item?.name}</div>
-                        <div className={styles.actions}>
-                          <Space>
-                            <PermissionButton
-                              isPermission={permission.update}
-                              className={styles.action}
-                              onClick={() => {
-                                history.push(
-                                  `${getMenuPathByParams(
-                                    MENUS_CODE['media/Stream/Detail'],
-                                    item.id,
-                                  )}`,
-                                );
-                                StreamModel.current = { ...item };
-                              }}
-                              key="button"
-                              type="link"
-                            >
-                              <EditOutlined
-                                style={{
-                                  color: permission.update ? '#000000' : 'rgba(0, 0, 0, .65)',
-                                  cursor: permission.update ? 'pointer' : 'not-allowed',
-                                }}
-                              />
-                              <span>编辑</span>
-                            </PermissionButton>
-                            <PermissionButton
-                              isPermission={permission.delete}
-                              popConfirm={{
-                                title: '确认删除',
-                                onConfirm: () => {
-                                  service.remove(item.id).then((resp: any) => {
-                                    if (resp.status === 200) {
-                                      message.success('操作成功!');
-                                      handleSearch({ pageSize: 10, terms: [] });
-                                    }
-                                  });
-                                },
-                              }}
-                              key="delete"
-                              type="link"
-                            >
-                              <span
-                                className={styles.action}
-                                style={{
-                                  color: permission.update ? '#000000' : 'rgba(0, 0, 0, .65)',
-                                  cursor: permission.update ? 'pointer' : 'not-allowed',
-                                }}
-                              >
-                                <DeleteOutlined
-                                  style={{
-                                    color: permission.update ? '#E50012' : 'rgba(0, 0, 0, .65)',
-                                  }}
-                                />
-                                <span>删除</span>
-                              </span>
-                            </PermissionButton>
-                          </Space>
-                        </div>
-                      </div>
-                      <div className={styles.content}>
-                        <div className={styles.item}>
-                          <div className={styles.itemTitle}>服务商</div>
-                          <p>{item?.provider}</p>
-                        </div>
-                        <div className={styles.item}>
-                          <div className={styles.itemTitle}>RTP IP</div>
-                          <p>{item?.configuration?.rtpIp}</p>
-                        </div>
-                        <div className={styles.item}>
-                          <div className={styles.itemTitle}>API HOST</div>
-                          <p>{item?.configuration?.apiHost}</p>
-                        </div>
-                      </div>
-                    </div>
-                  </Card>
+                  <StreamCard
+                    {...item}
+                    actions={[
+                      <PermissionButton
+                        isPermission={permission.update}
+                        onClick={() => {
+                          history.push(
+                            `${getMenuPathByParams(MENUS_CODE['media/Stream/Detail'], item.id)}`,
+                          );
+                          StreamModel.current = { ...item };
+                        }}
+                        key="button"
+                        type="link"
+                      >
+                        <EditOutlined />
+                        编辑
+                      </PermissionButton>,
+                      <PermissionButton
+                        isPermission={permission.delete}
+                        popConfirm={{
+                          title: '确认删除',
+                          onConfirm: () => {
+                            service.remove(item.id).then((resp: any) => {
+                              if (resp.status === 200) {
+                                message.success('操作成功!');
+                                handleSearch({ pageSize: 10, terms: [] });
+                              }
+                            });
+                          },
+                        }}
+                        key="delete"
+                        type="link"
+                      >
+                        <DeleteOutlined />
+                      </PermissionButton>,
+                    ]}
+                  />
                 </Col>
               ))}
             </Row>

+ 0 - 1
src/pages/media/Stream/service.ts

@@ -1,7 +1,6 @@
 import BaseService from '@/utils/BaseService';
 import { request } from 'umi';
 import SystemConst from '@/utils/const';
-import type { StreamItem } from './typings';
 
 class Service extends BaseService<StreamItem> {
   queryProviders = () =>

+ 4 - 4
src/pages/media/Stream/typings.d.ts

@@ -1,7 +1,7 @@
-import type { BaseItem } from '@/utils/typings';
-
 type StreamItem = {
-  description: string;
+  id?: string;
+  name: string;
+  description?: string;
   provider: string;
   configuration: {
     secret?: string;
@@ -12,4 +12,4 @@ type StreamItem = {
     dynamicRtpPort: boolean;
     dynamicRtpPortRange: number[];
   };
-} & BaseItem;
+};

+ 1 - 1
src/pages/notice/Template/Detail/doc/AliyunSms.tsx

@@ -16,7 +16,7 @@ const AliyunSms = () => {
 
       <div>
         <h2> 1、绑定配置</h2>
-        <div> 绑定通知配置</div>
+        <div> 使用固定的通知配置发送此通知模板</div>
         <h2> 2、模板</h2>
         <div> 阿里云短信平台自定义的模板名称</div>
         <h2> 3、收信人</h2>

+ 1 - 1
src/pages/notice/Template/Detail/doc/AliyunVoice.tsx

@@ -15,7 +15,7 @@ const AliyunVoice = () => {
       <h1>2.模板配置说明</h1>
       <div>
         <h2>1、绑定配置</h2>
-        <div> 绑定通知配置</div>
+        <div> 使用固定的通知配置发送此通知模板</div>
         <h2> 2、模板ID</h2>
         <div> 阿里云语音对每一条语音通知分配的唯一ID标识</div>
         <h2> 3、被叫号码</h2>

+ 1 - 1
src/pages/notice/Template/Detail/doc/DingTalk.tsx

@@ -19,7 +19,7 @@ const DingTalk = () => {
       </div>
       <h1> 2.模板配置说明</h1>
       <h2> 1、绑定配置</h2>
-      <div> 绑定通知配置</div>
+      <div> 使用固定的通知配置发送此通知模板</div>
       <h2> 2. Agentid</h2>
       <div> 应用唯一标识</div>
       <div className="image">

+ 1 - 1
src/pages/notice/Template/Detail/doc/DingTalkRebot.tsx

@@ -14,7 +14,7 @@ const DingTalkRebot = () => {
       <h1>2.模板配置说明</h1>
       <div>
         <h2> 1、绑定配置</h2>
-        <div> 绑定通知配置</div>
+        <div> 使用固定的通知配置发送此通知模板</div>
         <h2> 2、消息类型</h2>
         <div> 目前支持text、markdown、link3种。</div>
         <h2> 3. 模板内容</h2>

+ 1 - 1
src/pages/notice/Template/Detail/doc/WeixinApp.tsx

@@ -16,7 +16,7 @@ const WeixinApp = () => {
       <h1>2.模板配置说明</h1>
       <div>
         <h2>1. 绑定配置</h2>
-        <div>绑定通知配置</div>
+        <div>使用固定的通知配置发送此通知模板</div>
       </div>
       <div>
         <h2>2. 用户标签</h2>

+ 1 - 1
src/pages/notice/Template/Detail/doc/WeixinCorp.tsx

@@ -19,7 +19,7 @@ const WeixinCorp = () => {
       <h1>2.模版配置说明</h1>
       <div>
         <h2> 1、绑定配置</h2>
-        <div> 绑定通知配置</div>
+        <div> 使用固定的通知配置发送此通知模板</div>
         <h2> 2. Agentid</h2>
         <div> 应用唯一标识</div>
         <div> 获取路径:“企业微信”管理后台--“应用管理”--“应用”--“查看应用”</div>

+ 1 - 1
src/pages/rule-engine/Alarm/Config/index.less

@@ -1,5 +1,5 @@
 .doc {
-  height: 750px;
+  height: 100%;
   padding: 24px;
   overflow-y: auto;
   color: rgba(#000, 0.8);