Przeglądaj źródła

feat: 平台接入

wzyyy 3 lat temu
rodzic
commit
5ab8d05a68

+ 10 - 1
src/components/RadioCard/index.tsx

@@ -10,6 +10,7 @@ interface RadioCardItem {
   label: string;
   value: string;
   imgUrl?: string;
+  imgSize?: number[];
 }
 
 export interface RadioCardProps {
@@ -80,7 +81,15 @@ export default (props: RadioCardProps) => {
               }
             }}
           >
-            {item.imgUrl && <img width={32} height={32} src={item.imgUrl} alt={''} />}
+            {item.imgUrl && (
+              <img
+                width={32}
+                height={32}
+                src={item.imgUrl}
+                alt={''}
+                style={{ width: item.imgSize?.[0], height: item.imgSize?.[1] }}
+              />
+            )}
             <span>{item.label}</span>
             <div className={'checked-icon'}>
               <div>

+ 167 - 0
src/pages/iot-card/Platform/Detail/index.tsx

@@ -0,0 +1,167 @@
+import { RadioCard, TitleComponent } from '@/components';
+import { PageContainer } from '@ant-design/pro-layout';
+import { Form, FormButtonGroup, FormGrid, FormItem, Input } from '@formily/antd';
+import { createForm, onFormInit } from '@formily/core';
+import { createSchemaField, observer } from '@formily/react';
+import { Button, Card, Col, Row } from 'antd';
+import { useEffect, useMemo } from 'react';
+import { useParams } from 'umi';
+import { useAsyncDataSource } from '@/utils/util';
+// import './index.less';
+import { service } from '@/pages/Northbound/AliCloud';
+import { useModel } from '@@/plugin-model/useModel';
+
+const Detail = observer(() => {
+  const params = useParams<{ id: string }>();
+  const { initialState } = useModel('@@initialState');
+
+  const form = useMemo(
+    () =>
+      createForm({
+        validateFirst: true,
+        effects() {
+          onFormInit(async (form1) => {
+            if (params.id === ':id') return;
+            const resp = await service.detail(params.id);
+            form1.setInitialValues(resp.result);
+          });
+        },
+      }),
+    [],
+  );
+
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      FormGrid,
+      Input,
+      RadioCard,
+    },
+  });
+
+  const schema: any = {
+    type: 'object',
+    properties: {
+      operatorName: {
+        title: '平台类型',
+        'x-component': 'RadioCard',
+        'x-decorator': 'FormItem',
+        'x-decorator-props': {
+          gridSpan: 1,
+        },
+        default: 'onelink',
+        'x-component-props': {
+          model: 'singular',
+          itemStyle: {
+            display: 'flex',
+            flexDirection: 'column',
+            justifyContent: 'center',
+            minWidth: '130px',
+          },
+          options: [
+            {
+              label: '移动OneLink',
+              value: 'onelink',
+              imgUrl: require('/public/images/iot-card/onelink.png'),
+              imgSize: [78, 20],
+            },
+            {
+              label: '电信Ctwing',
+              value: 'ctwing',
+              imgUrl: require('/public/images/iot-card/ctwingcmp.png'),
+              imgSize: [52, 25],
+            },
+            {
+              label: '联通Unicom',
+              value: 'unicom',
+              imgUrl: require('/public/images/iot-card/unicom.png'),
+              imgSize: [56, 41],
+            },
+          ],
+        },
+        'x-validator': [
+          {
+            required: true,
+            message: '请选择类型',
+          },
+        ],
+      },
+      name: {
+        type: 'string',
+        title: '名称',
+        required: true,
+        'x-decorator': 'FormItem',
+        'x-component': 'Input',
+        'x-component-props': {
+          placeholder: '请输入名称',
+        },
+        'x-validator': [
+          {
+            max: 64,
+            message: '最多可输入64个字符',
+          },
+          {
+            required: true,
+            message: '请输入名称',
+          },
+        ],
+      },
+      description: {
+        title: '说明',
+        'x-component': 'Input.TextArea',
+        'x-decorator': 'FormItem',
+        'x-component-props': {
+          rows: 3,
+          showCount: true,
+          maxLength: 200,
+          placeholder: '请输入说明',
+        },
+      },
+    },
+  };
+
+  const handleSave = async () => {
+    const data: any = await form.submit();
+    console.log(data);
+  };
+
+  useEffect(() => {
+    setTimeout(() => {
+      if (initialState?.settings?.title) {
+        document.title = `物联卡 - ${initialState?.settings?.title}`;
+      } else {
+        document.title = '物联卡';
+      }
+    }, 0);
+  }, []);
+
+  return (
+    <PageContainer>
+      <Card>
+        <Row gutter={24}>
+          <Col span={12}>
+            <TitleComponent data={'详情'} />
+            <Form form={form} layout="vertical">
+              <SchemaField
+                schema={schema}
+                scope={{
+                  useAsyncDataSource,
+                }}
+              />
+              <FormButtonGroup.Sticky>
+                <FormButtonGroup.FormItem>
+                  <Button type="primary" onClick={() => handleSave()}>
+                    保存
+                  </Button>
+                </FormButtonGroup.FormItem>
+              </FormButtonGroup.Sticky>
+            </Form>
+          </Col>
+          <Col span={12} className="aliyun"></Col>
+        </Row>
+      </Card>
+    </PageContainer>
+  );
+});
+
+export default Detail;

+ 206 - 1
src/pages/iot-card/Platform/index.tsx

@@ -1,4 +1,209 @@
+import { PermissionButton } from '@/components';
+import SearchComponent from '@/components/SearchComponent';
+import useDomFullHeight from '@/hooks/document/useDomFullHeight';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { onlyMessage } from '@/utils/util';
+import {
+  DeleteOutlined,
+  EditOutlined,
+  PlayCircleOutlined,
+  PlusOutlined,
+  StopOutlined,
+} from '@ant-design/icons';
+import { PageContainer } from '@ant-design/pro-layout';
+import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
+import { Badge } from 'antd';
+import { useRef, useState } from 'react';
+import Service from './service';
+import { useHistory } from '@/hooks';
+
+export const service = new Service('network/card/platfrom');
+
 const Platform = () => {
-  return <>平台对接</>;
+  const { minHeight } = useDomFullHeight(`.record`, 24);
+  const actionRef = useRef<ActionType>();
+  const [param, setParam] = useState({});
+  const history = useHistory();
+
+  const statusUpdate = async (data: any) => {
+    const res = await service.update(data);
+    if (res.status === 200) {
+      onlyMessage('操作成功');
+      actionRef.current?.reload();
+    }
+  };
+
+  const columns: ProColumns<any>[] = [
+    {
+      title: '名称',
+      dataIndex: 'name',
+      ellipsis: true,
+    },
+    {
+      title: '平台类型',
+      dataIndex: 'operatorName',
+      ellipsis: true,
+      valueType: 'select',
+      valueEnum: {
+        onelink: {
+          text: '移动OneLink',
+          status: 'onelink',
+        },
+        ctwing: {
+          text: '电信Ctwing',
+          status: 'ctwing',
+        },
+        unicom: {
+          text: '联通Unicom',
+          status: 'unicom',
+        },
+      },
+    },
+    {
+      title: '状态',
+      dataIndex: 'state',
+      ellipsis: true,
+      valueType: 'select',
+      valueEnum: {
+        enabled: {
+          text: '启用',
+          status: 'enabled',
+        },
+        disabled: {
+          text: '禁用',
+          status: 'disabled',
+        },
+      },
+      render: (_, record: any) => (
+        <Badge
+          status={record.state?.value === 'disabled' ? 'error' : 'success'}
+          text={record.state?.text}
+        />
+      ),
+    },
+    {
+      title: '说明',
+      dataIndex: 'explain',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '操作',
+      valueType: 'option',
+      fixed: 'right',
+      render: (text, record) => [
+        <PermissionButton
+          isPermission={true}
+          key="edit"
+          onClick={() => {}}
+          type={'link'}
+          style={{ padding: 0 }}
+          tooltip={{
+            title: '编辑',
+          }}
+        >
+          <EditOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          isPermission={true}
+          key="action"
+          type={'link'}
+          style={{ padding: 0 }}
+          tooltip={{
+            title: record.state.value === 'enabled' ? '禁用' : '启用',
+          }}
+          popConfirm={{
+            title: `确认${record.state.value === 'enabled' ? '禁用' : '启用'}`,
+            onConfirm: () => {
+              if (record.state.value === 'enabled') {
+                statusUpdate({
+                  id: record.id,
+                  config: { ...record.config },
+                  state: 'disabled',
+                  operatorName: record.operatorName,
+                });
+              } else {
+                statusUpdate({
+                  id: record.id,
+                  config: { ...record.config },
+                  state: 'enabled',
+                  operatorName: record.operatorName,
+                });
+              }
+            },
+          }}
+        >
+          {record.state === 'enabled' ? <StopOutlined /> : <PlayCircleOutlined />}
+        </PermissionButton>,
+        <PermissionButton
+          isPermission={true}
+          tooltip={{
+            title: record.state.value !== 'enabled' ? '删除' : '请先禁用该协议,再删除',
+          }}
+          style={{ padding: 0 }}
+          disabled={record.state.value === 'enabled'}
+          popConfirm={{
+            title: '确认删除',
+            disabled: record.state.value === 'enabled',
+            onConfirm: async () => {
+              const res: any = await service.remove(record.id);
+              if (res.status === 200) {
+                onlyMessage('操作成功');
+                actionRef.current?.reload();
+              }
+            },
+          }}
+          key="delete"
+          type="link"
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
+      ],
+    },
+  ];
+
+  return (
+    <PageContainer>
+      <SearchComponent
+        field={columns}
+        target="record"
+        onSearch={(data) => {
+          // 重置分页数据
+          actionRef.current?.reset?.();
+          setParam(data);
+        }}
+      />
+      <ProTable
+        actionRef={actionRef}
+        params={param}
+        columns={columns}
+        search={false}
+        rowKey="id"
+        tableClassName={'record'}
+        columnEmptyText={''}
+        tableStyle={{ minHeight }}
+        headerTitle={
+          <>
+            <PermissionButton
+              onClick={() => {
+                const url = `${getMenuPathByParams(MENUS_CODE['iot-card/Platform/Detail'])}`;
+                history.push(url);
+              }}
+              style={{ marginRight: 12 }}
+              isPermission={true}
+              key="button"
+              icon={<PlusOutlined />}
+              type="primary"
+            >
+              新增
+            </PermissionButton>
+          </>
+        }
+        request={async (params) =>
+          service.getList({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
+        }
+      />
+    </PageContainer>
+  );
 };
 export default Platform;

+ 12 - 0
src/pages/iot-card/Platform/service.ts

@@ -0,0 +1,12 @@
+import { request } from 'umi';
+import SystemConst from '@/utils/const';
+import BaseService from '@/utils/BaseService';
+
+class Service extends BaseService<any> {
+  getList = (data: any) =>
+    request(`${SystemConst.API_BASE}/network/card/platform/_query`, {
+      method: 'POST',
+      data,
+    });
+}
+export default Service;

+ 12 - 8
src/pages/iot-card/Recharge/detail.tsx

@@ -1,4 +1,5 @@
 import { Modal, Descriptions } from 'antd';
+import moment from 'moment';
 
 interface Props {
   data: any;
@@ -6,22 +7,25 @@ interface Props {
 }
 
 const Detail = (props: Props) => {
+  const { data } = props;
   return (
     <Modal
-      title={'充值'}
+      title={'详情'}
       maskClosable={false}
       visible
       onCancel={props.close}
       onOk={props.close}
       width="35vw"
     >
-      <Descriptions title="User Info">
-        <Descriptions.Item label="UserName">Zhou Maomao</Descriptions.Item>
-        <Descriptions.Item label="Telephone">1810000000</Descriptions.Item>
-        <Descriptions.Item label="Live">Hangzhou, Zhejiang</Descriptions.Item>
-        <Descriptions.Item label="Remark">empty</Descriptions.Item>
-        <Descriptions.Item label="Address">
-          No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
+      <Descriptions bordered column={2}>
+        <Descriptions.Item label="充值金额">{data.chargeMoney}</Descriptions.Item>
+        <Descriptions.Item label="账户id">{data?.rechargeId}</Descriptions.Item>
+        <Descriptions.Item label="平台对接">{data.configName}</Descriptions.Item>
+        <Descriptions.Item label="订单号">{data.orderNumber}</Descriptions.Item>
+        <Descriptions.Item label="支付方式">{data.paymentType}</Descriptions.Item>
+        <Descriptions.Item label="支付URL">{data.url ? data.url : ''}</Descriptions.Item>
+        <Descriptions.Item label="订单时间">
+          {data.createTime ? moment(data.createTime).format('YYYY-MM-DD HH:mm:ss') : '-'}
         </Descriptions.Item>
       </Descriptions>
     </Modal>

+ 4 - 11
src/pages/iot-card/Recharge/index.tsx

@@ -22,12 +22,6 @@ const Recharge = () => {
   const [current, setCurrent] = useState<any>({});
 
   const columns: ProColumns<any>[] = [
-    // {
-    //   title: '充值类型',
-    //   dataIndex: 'rechargeType',
-    //   ellipsis: true,
-    //   hideInSearch: true
-    // },
     {
       title: '充值金额',
       dataIndex: 'chargeMoney',
@@ -69,9 +63,7 @@ const Recharge = () => {
         <a
           key="editable"
           onClick={() => {
-            // console.log(record);
             setDetail(true);
-            // setVisible(true);
             setCurrent(record);
           }}
         >
@@ -129,15 +121,16 @@ const Recharge = () => {
             </div>
           </>
         }
-        // request={async (params) =>
-        //   service.getList({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
-        // }
+        request={async (params) =>
+          service.queryRechargeList({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
+        }
       />
       {visible && (
         <TopUp
           data={{}}
           close={() => {
             setVisible(false);
+            actionRef.current?.reload();
           }}
         />
       )}

+ 3 - 2
src/pages/iot-card/Recharge/topUp.tsx

@@ -6,7 +6,8 @@ import { Modal } from '@/components';
 // import { onlyMessage } from '@/utils/util';
 import { ExclamationCircleOutlined } from '@ant-design/icons';
 import { action } from '@formily/reactive';
-import { service } from '.';
+import { service } from './index';
+import { PaymentMethod } from '../data';
 
 interface Props {
   data: any;
@@ -162,7 +163,7 @@ const TopUp = (props: Props) => {
                 message: '请选择支付方式',
               },
             ],
-            enum: [],
+            enum: PaymentMethod,
           },
         },
       },

+ 2 - 0
src/utils/menu/router.ts

@@ -139,6 +139,7 @@ export enum MENUS_CODE {
   'system/License' = 'system/License',
   'iot-card/Home' = 'iot-card/Home',
   'iot-card/Platform' = 'iot-card/Platform',
+  'iot-card/Platform/Detail' = 'iot-card/Platform/Detail',
   'iot-card/Recharge' = 'iot-card/Recharge',
   'iot-card/Dashboard' = 'iot-card/Dashboard',
   'iot-card/CardManagement' = 'iot-card/CardManagement',
@@ -193,6 +194,7 @@ export const getDetailNameByCode = {
   'rule-engine/Alarm/Log/Detail': '告警日志',
   'Northbound/AliCloud/Detail': '阿里云详情',
   'link/Certificate/Detail': '证书详情',
+  'iot-card/Platform/Detail': '平台对接详情',
 };
 
 // 开源版路由