Browse Source

fix: 3.23修改bug

sun-chaochao 3 năm trước cách đây
mục cha
commit
4e50bd2a36

+ 26 - 21
src/pages/device/Instance/Detail/Running/Property/index.tsx

@@ -28,6 +28,7 @@ const ColResponsiveProps = {
 
 const Property = (props: Props) => {
   const { data } = props;
+  console.log(data);
   const device = InstanceModel.detail;
   const params = useParams<{ id: string }>();
   const [subscribeTopic] = useSendWebsocketMessage();
@@ -193,9 +194,6 @@ const Property = (props: Props) => {
             }}
             style={{ width: 300 }}
           />
-          {/* <Checkbox onChange={() => {
-
-                    }}>仅显示当前有数据的属性</Checkbox> */}
         </Space>
         <CheckButton
           value={check}
@@ -216,25 +214,32 @@ const Property = (props: Props) => {
         ) : (
           <Table pagination={false} columns={columns} dataSource={dataSource.data} rowKey="id" />
         )}
-        <div
-          style={{ marginTop: '20px', width: '100%', display: 'flex', justifyContent: 'flex-end' }}
-        >
-          <Pagination
-            className={styles.page}
-            defaultCurrent={1}
-            total={dataSource.total}
-            showSizeChanger
-            pageSize={dataSource.pageSize}
-            onChange={(page: number, size: number) => {
-              setDataSource({
-                total: propertyList.length,
-                data: (propertyList || []).slice((page - 1) * size, page * size),
-                pageSize: size,
-                currentPage: page - 1,
-              });
+        {dataSource.data.length > 0 && (
+          <div
+            style={{
+              marginTop: '20px',
+              width: '100%',
+              display: 'flex',
+              justifyContent: 'flex-end',
             }}
-          />
-        </div>
+          >
+            <Pagination
+              className={styles.page}
+              defaultCurrent={1}
+              total={dataSource.total}
+              showSizeChanger
+              pageSize={dataSource.pageSize}
+              onChange={(page: number, size: number) => {
+                setDataSource({
+                  total: propertyList.length,
+                  data: (propertyList || []).slice((page - 1) * size, page * size),
+                  pageSize: size,
+                  currentPage: page - 1,
+                });
+              }}
+            />
+          </div>
+        )}
       </div>
       <EditProperty
         data={currentInfo}

+ 1 - 1
src/pages/device/Instance/Detail/Running/index.tsx

@@ -11,7 +11,7 @@ const Running = () => {
     <Card>
       <Tabs defaultActiveKey="1" tabPosition="left" style={{ height: 600 }}>
         <Tabs.TabPane tab="属性" key="1">
-          <Property data={metadata?.properties || {}} />
+          <Property data={metadata?.properties || []} />
         </Tabs.TabPane>
         {metadata.events?.map((item) => (
           <Tabs.TabPane tab={item.name} key={item.id}>

+ 14 - 0
src/pages/device/Product/Detail/Access/index.less

@@ -73,3 +73,17 @@
     display: none;
   }
 }
+
+.config {
+  width: 48%;
+  .title {
+    width: 100%;
+    margin-bottom: 10px;
+    font-weight: 600;
+  }
+  .title::before {
+    margin-right: 10px;
+    background-color: #2810ff;
+    content: '|';
+  }
+}

+ 94 - 34
src/pages/device/Product/Detail/Access/index.tsx

@@ -1,4 +1,5 @@
 import {
+  Alert,
   Badge,
   Button,
   Card,
@@ -17,6 +18,8 @@ import Service from '@/pages/device/Product/service';
 import { productModel } from '@/pages/device/Product';
 import type { ProColumns } from '@jetlinks/pro-table';
 import SearchComponent from '@/components/SearchComponent';
+import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
+import { useHistory } from 'umi';
 
 const Access = () => {
   const service1 = new Service('device-product');
@@ -31,8 +34,21 @@ const Access = () => {
   });
   const [visible, setVisible] = useState<boolean>(true);
   const [config, setConfig] = useState<any>();
+  const [access, setAccess] = useState<any>();
+  const [providers, setProviders] = useState<any[]>([]);
+  const [networkList, setNetworkList] = useState<any[]>([]);
+
+  const MetworkTypeMapping = new Map();
+  MetworkTypeMapping.set('websocket-server', 'WEB_SOCKET_SERVER');
+  MetworkTypeMapping.set('http-server-gateway', 'HTTP_SERVER');
+  MetworkTypeMapping.set('udp-device-gateway', 'UDP');
+  MetworkTypeMapping.set('coap-server-gateway', 'COAP_SERVER');
+  MetworkTypeMapping.set('mqtt-client-gateway', 'MQTT_CLIENT');
+  MetworkTypeMapping.set('mqtt-server-gateway', 'MQTT_SERVER');
+  MetworkTypeMapping.set('tcp-server-gateway', 'TCP_SERVER');
 
   const [param, setParam] = useState<any>({ pageSize: 10 });
+  const history = useHistory();
 
   const columns: ProColumns<any>[] = [
     {
@@ -41,6 +57,14 @@ const Access = () => {
     },
   ];
 
+  const queryNetworkList = (id: string) => {
+    service.getNetworkList(MetworkTypeMapping.get(id)).then((resp) => {
+      if (resp.status === 200) {
+        setNetworkList(resp.result);
+      }
+    });
+  };
+
   const [dataSource, setDataSource] = useState<any>({
     data: [],
     pageSize: 10,
@@ -56,6 +80,24 @@ const Access = () => {
         setDataSource(resp.result);
       });
   };
+
+  const queryProviders = () => {
+    service.getProviders().then((resp) => {
+      if (resp.status === 200) {
+        setProviders(resp.result);
+      }
+    });
+  };
+
+  const queryAccess = (id: string) => {
+    service.queryList({ pageSize: 1000 }).then((resp) => {
+      const dt = resp.result.data.find((i: any) => i.id === id);
+      setAccess(dt);
+      if (dt) {
+        queryNetworkList(dt?.provider);
+      }
+    });
+  };
   const columnsMQTT: any[] = [
     {
       title: '分组',
@@ -165,33 +207,33 @@ const Access = () => {
     },
   ];
 
-  const getDetail = () => {
-    service
-      .getConfigView(
-        productModel.current?.messageProtocol || '',
-        productModel.current?.transportProtocol || '',
-      )
-      .then((resp) => {
-        if (resp.status === 200) {
-          setConfig(resp.result);
-        }
-      });
+  const getDetail = (messageProtocol: string, transportProtocol: string) => {
+    service.getConfigView(messageProtocol, transportProtocol).then((resp) => {
+      if (resp.status === 200) {
+        setConfig(resp.result);
+      }
+    });
   };
 
   useEffect(() => {
+    queryProviders();
     setVisible(!!productModel.current?.accessId);
     if (productModel.current?.accessId) {
-      getDetail();
+      getDetail(
+        productModel.current?.messageProtocol || '',
+        productModel.current?.transportProtocol || '',
+      );
+      queryAccess(productModel.current?.accessId);
     } else {
       handleSearch(param);
     }
-  }, [productModel.current?.accessId]);
+  }, []);
 
   return (
     <div>
       {!visible ? (
         <div style={{ padding: '20px 0' }}>
-          {/* <Alert message="选择与设备通信的网络组件" type="warning" showIcon /> */}
+          <Alert message="请选择使用的设备接入网关,用以提供设备接入能力" type="info" showIcon />
           <SearchComponent
             field={columns}
             pattern={'simple'}
@@ -206,6 +248,14 @@ const Access = () => {
               handleSearch({ pageSize: 10 });
             }}
           />
+          <Button
+            type="primary"
+            onClick={() => {
+              history.push(`${getMenuPathByCode(MENUS_CODE['link/AccessConfig/Detail'])}`);
+            }}
+          >
+            新增
+          </Button>
           <Row gutter={[16, 16]} style={{ marginTop: 10 }}>
             {dataSource.data.map((item: any) => (
               <Col key={item.name} span={12}>
@@ -296,9 +346,15 @@ const Access = () => {
                     })
                     .then((resp) => {
                       if (resp.status === 200) {
-                        message.success('操作成功!');
-                        setVisible(true);
-                        getDetail();
+                        service1.detail(productModel.current?.id || '').then((res) => {
+                          if (res.status === 200) {
+                            productModel.current = { ...res.result };
+                            message.success('操作成功!');
+                            setVisible(true);
+                            getDetail(res.result.messageProtocol, res.result.transportProtocol);
+                            queryAccess(res.result.accessId);
+                          }
+                        });
                       }
                     });
                 } else {
@@ -314,25 +370,29 @@ const Access = () => {
         <div className={styles.config}>
           <div className={styles.title}>配置概览</div>
           <Descriptions column={1}>
-            {/* <Descriptions.Item label="接入方式">{config?.id || ''}</Descriptions.Item> */}
-            {/* <Descriptions.Item>{props.data?.description || ''}</Descriptions.Item> */}
+            <Descriptions.Item label="接入方式">
+              {providers.find((i) => i.id === access?.provider)?.name || ''}
+            </Descriptions.Item>
+            <Descriptions.Item>
+              {providers.find((i) => i.id === access?.provider)?.description || ''}
+            </Descriptions.Item>
             <Descriptions.Item label="消息协议">
-              {productModel.current?.messageProtocol}
+              {access?.protocolDetail?.name || ''}
+            </Descriptions.Item>
+            <Descriptions.Item>{access?.protocolDetail?.description || ''}</Descriptions.Item>
+            <Descriptions.Item label="网络组件">
+              {(networkList.find((i) => i.id === access?.channelId)?.addresses || []).map(
+                (item: any) => (
+                  <div key={item.address}>
+                    <Badge
+                      color={item.health === -1 ? 'red' : 'green'}
+                      text={item.address}
+                      style={{ marginLeft: '20px' }}
+                    />
+                  </div>
+                ),
+              )}
             </Descriptions.Item>
-            {/* <Descriptions.Item>----缺少描述呀----</Descriptions.Item>
-                        <Descriptions.Item label="网络组件">
-                             {(networkList.find((i) => i.id === productModel.current.)?.addresses || []).map(
-                                (item: any) => (
-                                    <div key={item.address}>
-                                        <Badge
-                                            color={item.health === -1 ? 'red' : 'green'}
-                                            text={item.address}
-                                            style={{ marginLeft: '20px' }}
-                                        />
-                                    </div>
-                                ),
-                            )}
-                        </Descriptions.Item> */}
           </Descriptions>
           {config?.routes && config?.routes?.length > 0 && (
             <div>

+ 44 - 57
src/pages/link/AccessConfig/Detail/Access/index.less

@@ -1,44 +1,26 @@
 .box {
   display: flex;
-  justify-content: space-between;
-}
-
-.images {
-  width: 64px;
-  height: 64px;
-  color: white;
-  font-size: 18px;
-  line-height: 64px;
-  text-align: center;
-  background: linear-gradient(
-    128.453709216706deg,
-    rgba(255, 255, 255, 1) 4%,
-    rgba(113, 187, 255, 1) 43%,
-    rgba(24, 144, 255, 1) 100%
-  );
-  border: 1px solid rgba(242, 242, 242, 1);
-  border-radius: 50%;
-}
-
-.content {
-  display: flex;
   flex-direction: column;
-  width: calc(100% - 80px);
-}
-
-.top {
-  display: flex;
-  justify-content: space-between;
+  align-items: center;
+  margin: 20px 30px;
+  .steps {
+    width: 100%;
+  }
 
-  .left {
-    display: flex;
+  .content {
+    width: 100%;
+    margin: 20px 0;
   }
 
-  .action a {
-    margin: 0 5px;
+  .action {
+    width: 100%;
   }
 }
 
+.title {
+  font-weight: 600;
+}
+
 .desc {
   width: 100%;
   margin-top: 10px;
@@ -50,35 +32,40 @@
   text-overflow: ellipsis;
 }
 
-.title {
-  font-weight: 600;
-  font-size: 14px;
-}
-
-.container {
+.cardContent {
   display: flex;
-  width: 100%;
-  height: 90px;
   margin-top: 10px;
+  color: rgba(0, 0, 0, 0.55);
+  .item {
+    width: 100%;
+    margin: 5px 0;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
 }
 
-.server {
-  align-items: center;
-  width: 50%;
-  margin-right: 20px;
-}
-
-.procotol {
-  display: -webkit-box;
-  width: 50%;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  -webkit-box-orient: vertical;
-  -webkit-line-clamp: 4;
+.view {
+  display: flex;
+  justify-content: space-between;
+  .info,
+  .config {
+    width: 48%;
+    .title {
+      width: 100%;
+      margin-bottom: 10px;
+      font-weight: 600;
+    }
+    .title::before {
+      margin-right: 10px;
+      background-color: #2810ff;
+      content: '|';
+    }
+  }
 }
 
-:global {
-  .ant-pagination-item {
-    display: none;
-  }
+.search {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
 }

+ 82 - 36
src/pages/link/AccessConfig/Detail/Access/index.tsx

@@ -24,6 +24,7 @@ import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 interface Props {
   change: () => void;
   data: any;
+  access: any;
 }
 const Access = (props: Props) => {
   const [form] = Form.useForm();
@@ -33,9 +34,10 @@ const Access = (props: Props) => {
   const [current, setCurrent] = useState<number>(0);
   const [networkList, setNetworkList] = useState<any[]>([]);
   const [procotolList, setProcotolList] = useState<any[]>([]);
-  const [procotolCurrent, setProcotolCurrent] = useState<string>('');
-  const [networkCurrent, setNetworkCurrent] = useState<string>('');
+  const [procotolCurrent, setProcotolCurrent] = useState<string>(props.access?.protocol || '');
+  const [networkCurrent, setNetworkCurrent] = useState<string>(props.access?.channelId || '');
   const [config, setConfig] = useState<any>();
+  const [providers, setProviders] = useState<any[]>([]);
 
   const MetworkTypeMapping = new Map();
   MetworkTypeMapping.set('websocket-server', 'WEB_SOCKET_SERVER');
@@ -56,17 +58,29 @@ const Access = (props: Props) => {
   ProcotoleMapping.set('tcp-server-gateway', 'TCP');
 
   const queryNetworkList = (params?: any) => {
-    service.getNetworkList(MetworkTypeMapping.get(props.data?.id), params).then((resp) => {
-      if (resp.status === 200) {
-        setNetworkList(resp.result);
-      }
-    });
+    service
+      .getNetworkList(MetworkTypeMapping.get(props.data?.id || props.access?.provider), params)
+      .then((resp) => {
+        if (resp.status === 200) {
+          setNetworkList(resp.result);
+        }
+      });
   };
 
   const queryProcotolList = (params?: any) => {
-    service.getProtocolList(ProcotoleMapping.get(props.data?.id), params).then((resp) => {
+    service
+      .getProtocolList(ProcotoleMapping.get(props.data?.id || props.access?.provider), params)
+      .then((resp) => {
+        if (resp.status === 200) {
+          setProcotolList(resp.result);
+        }
+      });
+  };
+
+  const queryProviders = () => {
+    service.getProviders().then((resp) => {
       if (resp.status === 200) {
-        setProcotolList(resp.result);
+        setProviders(resp.result);
       }
     });
   };
@@ -78,6 +92,14 @@ const Access = (props: Props) => {
     }
   }, [props.data]);
 
+  useEffect(() => {
+    form.setFieldsValue({
+      name: props.access?.name,
+      description: props.access?.name,
+    });
+    queryProviders();
+  }, [props.access]);
+
   const next = () => {
     if (current === 0) {
       if (!networkCurrent) {
@@ -92,7 +114,10 @@ const Access = (props: Props) => {
         message.error('请选择消息协议!');
       } else {
         service
-          .getConfigView(procotolCurrent, ProcotoleMapping.get(props.data?.id))
+          .getConfigView(
+            procotolCurrent,
+            ProcotoleMapping.get(props.data?.id || props.access?.provider),
+          )
           .then((resp) => {
             if (resp.status === 200) {
               setConfig(resp.result);
@@ -353,7 +378,7 @@ const Access = (props: Props) => {
                       }}
                     >
                       <div className={styles.title}>{item.name}</div>
-                      <div className={styles.desc}>缺少描述呀</div>
+                      <div className={styles.desc}>{item.description}</div>
                     </Card>
                   </Col>
                 ))}
@@ -401,14 +426,15 @@ const Access = (props: Props) => {
             <div className={styles.config}>
               <div className={styles.title}>配置概览</div>
               <Descriptions column={1}>
-                <Descriptions.Item label="接入方式">{props.data?.name || ''}</Descriptions.Item>
+                <Descriptions.Item label="接入方式">
+                  {props.data?.name || providers.find((i) => i.id === props.access?.provider)?.name}
+                </Descriptions.Item>
                 <Descriptions.Item>{props.data?.description || ''}</Descriptions.Item>
                 <Descriptions.Item label="消息协议">
                   {procotolList.find((i) => i.id === procotolCurrent)?.name || ''}
                 </Descriptions.Item>
                 <Descriptions.Item>
-                  {procotolList.find((i) => i.id === procotolCurrent)?.description ||
-                    '----缺少描述呀----'}
+                  {procotolList.find((i) => i.id === procotolCurrent)?.description || ''}
                 </Descriptions.Item>
                 <Descriptions.Item label="网络组件">
                   {(networkList.find((i) => i.id === networkCurrent)?.addresses || []).map(
@@ -449,6 +475,8 @@ const Access = (props: Props) => {
         type="link"
         onClick={() => {
           props.change();
+          setNetworkCurrent('');
+          setProcotolCurrent('');
         }}
       >
         返回
@@ -463,6 +491,11 @@ const Access = (props: Props) => {
         </div>
         <div className={styles.content}>{renderSteps(current)}</div>
         <div className={styles.action}>
+          {current > 0 && (
+            <Button style={{ margin: '0 8px' }} onClick={() => prev()}>
+              上一步
+            </Button>
+          )}
           {current < steps.length - 1 && (
             <Button type="primary" onClick={() => next()}>
               下一步
@@ -474,23 +507,41 @@ const Access = (props: Props) => {
               onClick={async () => {
                 try {
                   const values = await form.validateFields();
-                  const params = {
-                    name: values.name,
-                    description: values.description,
-                    provider: props.data.id,
-                    protocol: procotolCurrent,
-                    transport: ProcotoleMapping.get(props.data.id),
-                    channel: 'network', // 网络组件
-                    channelId: networkCurrent,
-                  };
-                  service.save(params).then((resp: any) => {
-                    if (resp.status === 200) {
-                      message.success('操作成功!');
-                      setCurrent(0);
-                      setNetworkCurrent('');
-                      setProcotolCurrent('');
-                    }
-                  });
+                  // 编辑还是保存
+                  if (!!props.access.id) {
+                    const params = {
+                      name: values.name,
+                      description: values.description,
+                      provider: props.data.id,
+                      protocol: procotolCurrent,
+                      transport: ProcotoleMapping.get(props.data.id),
+                      channel: 'network', // 网络组件
+                      channelId: networkCurrent,
+                    };
+                    service.save(params).then((resp: any) => {
+                      if (resp.status === 200) {
+                        message.success('操作成功!');
+                        history.push(`${getMenuPathByCode(MENUS_CODE['link/AccessConfig'])}`);
+                      }
+                    });
+                  } else {
+                    const params = {
+                      id: props.access?.id,
+                      name: values.name,
+                      description: values.description,
+                      provider: props.data.id,
+                      protocol: procotolCurrent,
+                      transport: ProcotoleMapping.get(props.data.id),
+                      channel: 'network', // 网络组件
+                      channelId: networkCurrent,
+                    };
+                    service.update(params).then((resp: any) => {
+                      if (resp.status === 200) {
+                        message.success('操作成功!');
+                        history.push(`${getMenuPathByCode(MENUS_CODE['link/AccessConfig'])}`);
+                      }
+                    });
+                  }
                 } catch (errorInfo) {
                   console.error('Failed:', errorInfo);
                 }
@@ -499,11 +550,6 @@ const Access = (props: Props) => {
               保存
             </Button>
           )}
-          {current > 0 && (
-            <Button style={{ margin: '0 8px' }} onClick={() => prev()}>
-              上一步
-            </Button>
-          )}
         </div>
       </div>
     </Card>

+ 25 - 5
src/pages/link/AccessConfig/Detail/index.tsx

@@ -1,24 +1,44 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
+import { useLocation } from 'umi';
 import Access from './Access';
 import Provider from './Provider';
+import { service } from '@/pages/link/AccessConfig';
+
+type LocationType = {
+  id?: string;
+};
 
 const Detail = () => {
   const [visible, setVisible] = useState<boolean>(true);
-  const [id, setId] = useState<any>({});
+  const [data, setData] = useState<any>({});
+  const [config, setConfig] = useState<any>({});
+
+  const location = useLocation<LocationType>();
+
+  useEffect(() => {
+    const params = new URLSearchParams(location.search);
+    if (params.get('id')) {
+      service.detail(params.get('id') || '').then((resp) => {
+        setConfig(resp.result);
+        setVisible(false);
+      });
+    }
+  }, []);
 
   return (
     <PageContainer>
       {visible ? (
         <Provider
-          change={(data: string) => {
-            setId(data);
+          change={(param: any) => {
+            setData(param);
             setVisible(false);
           }}
         />
       ) : (
         <Access
-          data={id}
+          data={data}
+          access={config}
           change={() => {
             setVisible(true);
           }}

+ 58 - 40
src/pages/link/AccessConfig/index.less

@@ -1,31 +1,46 @@
+.box {
+  display: flex;
+  justify-content: space-between;
+}
+
+.images {
+  width: 64px;
+  height: 64px;
+  color: white;
+  font-size: 18px;
+  line-height: 64px;
+  text-align: center;
+  background: linear-gradient(
+    128.453709216706deg,
+    rgba(255, 255, 255, 1) 4%,
+    rgba(113, 187, 255, 1) 43%,
+    rgba(24, 144, 255, 1) 100%
+  );
+  border: 1px solid rgba(242, 242, 242, 1);
+  border-radius: 50%;
+}
+
 .content {
   display: flex;
-  width: 90%;
-  height: 100px;
-  margin: 0 78px;
-  overflow: hidden;
-  .server {
-    width: calc(50% - 78px);
+  flex-direction: column;
+  width: calc(100% - 80px);
+}
+
+.top {
+  display: flex;
+  justify-content: space-between;
 
-    :global {
-      .ant-badge-status-text {
-        color: rgba(0, 0, 0, 0.55);
-      }
-    }
+  .left {
+    display: flex;
   }
 
-  .procotol {
-    display: -webkit-box;
-    width: calc(50% - 78px);
-    overflow: hidden;
-    text-overflow: ellipsis;
-    -webkit-box-orient: vertical;
-    -webkit-line-clamp: 4;
+  .action a {
+    margin: 0 5px;
   }
 }
 
 .desc {
-  width: 50%;
+  width: 100%;
   margin-top: 10px;
   overflow: hidden;
   color: rgba(0, 0, 0, 0.55);
@@ -33,34 +48,37 @@
   font-size: 13px;
   white-space: nowrap;
   text-overflow: ellipsis;
-  background-color: antiquewhite;
 }
 
 .title {
-  margin-bottom: 10px;
   font-weight: 600;
   font-size: 14px;
 }
 
-:global {
-  .ant-list-item-meta-avatar {
-    width: 64px !important;
-    height: 64px !important;
-  }
+.container {
+  display: flex;
+  width: 100%;
+  height: 90px;
+  margin-top: 10px;
 }
 
-.images {
-  width: 64px;
-  height: 64px;
-  color: white;
-  font-size: 18px;
-  line-height: 64px;
-  text-align: center;
-  background: linear-gradient(
-    128.453709216706deg,
-    rgba(255, 255, 255, 1) 4%,
-    rgba(113, 187, 255, 1) 43%,
-    rgba(24, 144, 255, 1) 100%
-  );
-  border: 1px solid rgba(242, 242, 242, 1);
+.server {
+  align-items: center;
+  width: 50%;
+  margin-right: 20px;
+}
+
+.procotol {
+  display: -webkit-box;
+  width: 50%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 4;
+}
+
+:global {
+  .ant-pagination-item {
+    display: none;
+  }
 }

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

@@ -110,12 +110,14 @@ const AccessConfig = () => {
                                   service.shutDown(item.id).then((resp) => {
                                     if (resp.status === 200) {
                                       message.success('操作成功!');
+                                      handleSearch(param);
                                     }
                                   });
                                 } else {
                                   service.startUp(item.id).then((resp) => {
                                     if (resp.status === 200) {
                                       message.success('操作成功!');
+                                      handleSearch(param);
                                     }
                                   });
                                 }
@@ -141,6 +143,7 @@ const AccessConfig = () => {
                                 service.remove(item.id).then((resp: any) => {
                                   if (resp.status === 200) {
                                     message.success('操作成功!');
+                                    handleSearch(param);
                                   }
                                 });
                               }}

+ 1 - 1
src/pages/link/AccessConfig/service.ts

@@ -14,7 +14,7 @@ class Service extends BaseService<AccessItem> {
       method: 'POST',
     });
   public shutDown = (id: string) =>
-    request(`/${SystemConst.API_BASE}/gateway/device/${id}/__shutdown`, {
+    request(`/${SystemConst.API_BASE}/gateway/device/${id}/_shutdown`, {
       method: 'POST',
     });
   public getProviders = () =>

+ 0 - 1
src/pages/link/Protocol/FileUpload/index.tsx

@@ -37,7 +37,6 @@ const FileUpload = connect((props: Props) => {
         <Input
           style={{ width: 'calc(100% - 100px)' }}
           value={url}
-          readOnly
           onClick={(e) => {
             e.preventDefault();
             e.stopPropagation();

+ 34 - 40
src/pages/link/Protocol/index.tsx

@@ -2,13 +2,8 @@ import { PageContainer } from '@ant-design/pro-layout';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
 import { useRef } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { message, Popconfirm, Tag, Tooltip } from 'antd';
-import {
-  CloudSyncOutlined,
-  DeleteOutlined,
-  EditOutlined,
-  PlayCircleOutlined,
-} from '@ant-design/icons';
+import { Badge, message, Popconfirm, Tooltip } from 'antd';
+import { CheckCircleOutlined, DeleteOutlined, EditOutlined, StopOutlined } from '@ant-design/icons';
 import BaseCrud from '@/components/BaseCrud';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import type { ISchema } from '@formily/json-schema';
@@ -57,8 +52,9 @@ const Protocol = () => {
     {
       dataIndex: 'state',
       title: '状态',
-      renderText: (text) =>
-        text === 1 ? <Tag color="#108ee9">正常</Tag> : <Tag color="#F50">禁用</Tag>,
+      renderText: (text) => (
+        <Badge color={text !== 1 ? 'red' : 'green'} text={text !== 1 ? '未发布' : '已发布'} />
+      ),
     },
     {
       dataIndex: 'description',
@@ -91,51 +87,49 @@ const Protocol = () => {
         </a>,
         record.state !== 1 && (
           <a key="publish">
-            <Popconfirm title="发布?" onConfirm={() => modifyState(record.id, 'deploy')}>
+            <Popconfirm title="确认发布?" onConfirm={() => modifyState(record.id, 'deploy')}>
               <Tooltip title="发布">
-                <PlayCircleOutlined />
+                <CheckCircleOutlined />
               </Tooltip>
             </Popconfirm>
           </a>
         ),
         record.state === 1 && (
           <a key="reload">
-            <Popconfirm title="重新发布?" onConfirm={() => modifyState(record.id, 'deploy')}>
-              <Tooltip title="重新发布">
-                <CloudSyncOutlined />
+            <Popconfirm title="确认撤销?" onConfirm={() => modifyState(record.id, 'un-deploy')}>
+              <Tooltip title="撤销">
+                <StopOutlined />
               </Tooltip>
             </Popconfirm>
           </a>
         ),
-        record.state !== 1 && (
-          <a key="delete">
-            <Popconfirm
+        <a key="delete">
+          <Popconfirm
+            title={intl.formatMessage({
+              id: 'pages.data.option.remove.tips',
+              defaultMessage: '确认删除?',
+            })}
+            onConfirm={async () => {
+              await service.remove(record.id);
+              message.success(
+                intl.formatMessage({
+                  id: 'pages.data.option.success',
+                  defaultMessage: '操作成功!',
+                }),
+              );
+              actionRef.current?.reload();
+            }}
+          >
+            <Tooltip
               title={intl.formatMessage({
-                id: 'pages.data.option.remove.tips',
-                defaultMessage: '确认删除?',
+                id: 'pages.data.option.remove',
+                defaultMessage: '删除',
               })}
-              onConfirm={async () => {
-                await service.remove(record.id);
-                message.success(
-                  intl.formatMessage({
-                    id: 'pages.data.option.success',
-                    defaultMessage: '操作成功!',
-                  }),
-                );
-                actionRef.current?.reload();
-              }}
             >
-              <Tooltip
-                title={intl.formatMessage({
-                  id: 'pages.data.option.remove',
-                  defaultMessage: '删除',
-                })}
-              >
-                <DeleteOutlined />
-              </Tooltip>
-            </Popconfirm>
-          </a>
-        ),
+              <DeleteOutlined />
+            </Tooltip>
+          </Popconfirm>
+        </a>,
       ],
     },
   ];