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

feat(firmware): add firmware

Lind пре 4 година
родитељ
комит
e26d44f37c

+ 7 - 0
config/routes.ts

@@ -138,6 +138,13 @@
         component: './device/Firmware',
       },
       {
+        hideInMenu: true,
+        path: '/device/firmware/detail/:id',
+        name: 'firmware-detail',
+        icon: 'smile',
+        component: './device/Firmware/Detail',
+      },
+      {
         path: '/device/alarm',
         name: 'alarm',
         icon: 'smile',

+ 0 - 1
src/components/Upload/index.tsx

@@ -12,7 +12,6 @@ interface Props {
 }
 
 const FUploadImage = connect((props: Props) => {
-  console.log(props, 'pro');
   const [url, setUrl] = useState<string>(props?.value);
   const [loading, setLoading] = useState<boolean>(false);
   const uploadButton = (

+ 54 - 0
src/pages/device/Firmware/Detail/History/index.tsx

@@ -0,0 +1,54 @@
+import type { ProColumns } from '@jetlinks/pro-table';
+import ProTable from '@jetlinks/pro-table';
+import { service } from '@/pages/device/Firmware';
+import type { HistoryItem } from '@/pages/device/Firmware/typings';
+import { useParams } from 'umi';
+
+const History = () => {
+  const param = useParams<{ id: string }>();
+
+  const columns: ProColumns<HistoryItem>[] = [
+    {
+      dataIndex: 'index',
+      valueType: 'indexBorder',
+      width: 48,
+    },
+    {
+      title: '设备名称',
+      dataIndex: 'deviceName',
+    },
+    {
+      title: '任务名称',
+      dataIndex: 'taskName',
+    },
+    {
+      title: '版本',
+      dataIndex: 'version',
+    },
+    {
+      title: '状态',
+      dataIndex: 'state',
+      renderText: (text) => text.text,
+    },
+    {
+      title: '进度(%)',
+      dataIndex: 'progress',
+    },
+    {
+      title: '创建时间',
+      dataIndex: 'createTime',
+      valueType: 'dateTime',
+    },
+  ];
+  return (
+    <ProTable
+      columns={columns}
+      defaultParams={{
+        firmwareId: param.id,
+      }}
+      request={(params) => service.history(params)}
+      rowKey="id"
+    />
+  );
+};
+export default History;

+ 83 - 0
src/pages/device/Firmware/Detail/Task/index.tsx

@@ -0,0 +1,83 @@
+import type { ProColumns } from '@jetlinks/pro-table';
+import ProTable from '@jetlinks/pro-table';
+import type { TaskItem } from '@/pages/device/Firmware/typings';
+import { service } from '@/pages/device/Firmware';
+import { Button, Tooltip } from 'antd';
+import { DeleteOutlined, EyeOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl, useParams } from 'umi';
+
+const Task = () => {
+  const intl = useIntl();
+  const param = useParams<{ id: string }>();
+  const columns: ProColumns<TaskItem>[] = [
+    {
+      dataIndex: 'index',
+      valueType: 'indexBorder',
+      width: 48,
+    },
+    {
+      dataIndex: 'id',
+      title: 'id',
+      width: 200,
+    },
+    {
+      dataIndex: 'name',
+      title: '任务名称',
+    },
+    {
+      dataIndex: 'mode',
+      title: '升级方式',
+      renderText: (text) => text.text,
+    },
+    {
+      dataIndex: 'timeoutSeconds',
+      title: '超时时间(秒)',
+    },
+    {
+      dataIndex: 'createTime',
+      valueType: 'dateTime',
+      title: '创建时间',
+    },
+    {
+      title: '操作',
+      valueType: 'option',
+      align: 'center',
+      render: (text, record) => [
+        <a
+          key="cat"
+          onClick={() => {
+            console.log(record);
+          }}
+        >
+          <Tooltip title="查看">
+            <EyeOutlined />
+          </Tooltip>
+        </a>,
+        <a key="remove">
+          <Tooltip title="删除">
+            <DeleteOutlined />
+          </Tooltip>
+        </a>,
+      ],
+    },
+  ];
+  return (
+    <ProTable
+      columns={columns}
+      rowKey="id"
+      defaultParams={{
+        firmwareId: param.id,
+      }}
+      toolBarRender={() => [
+        <Button onClick={() => {}} key="button" icon={<PlusOutlined />} type="primary">
+          {intl.formatMessage({
+            id: 'pages.data.option.add',
+            defaultMessage: '新增',
+          })}
+        </Button>,
+      ]}
+      request={async (params) => service.task(params)}
+    />
+  );
+};
+export default Task;

+ 62 - 0
src/pages/device/Firmware/Detail/index.tsx

@@ -0,0 +1,62 @@
+import { PageContainer } from '@ant-design/pro-layout';
+import { history, useParams } from 'umi';
+import { Descriptions } from 'antd';
+import { service, state } from '@/pages/device/Firmware';
+import History from './History';
+import { useEffect, useState } from 'react';
+import type { FirmwareItem } from '@/pages/device/Firmware/typings';
+import Task from '@/pages/device/Firmware/Detail/Task';
+
+const Detail = () => {
+  const [data, setData] = useState<FirmwareItem | undefined>(state.current);
+  const param = useParams<{ id: string }>();
+  useEffect(() => {
+    if (!state.current) {
+      service.detail(param.id).then((resp) => {
+        if (resp.status === 200) {
+          setData(resp.result);
+        }
+      });
+    }
+  }, [param.id]);
+  const [tab, setTab] = useState<string>('task');
+  const list = [
+    {
+      key: 'task',
+      tab: '升级任务',
+      component: <Task />,
+    },
+    {
+      key: 'history',
+      tab: '升级记录',
+      component: <History />,
+    },
+  ];
+  return (
+    <PageContainer
+      onBack={history.goBack}
+      onTabChange={setTab}
+      content={
+        <>
+          <Descriptions size="small" column={3}>
+            {[
+              { key: 'ID', value: data?.id },
+              { key: '所属产品', value: data?.productName },
+              { key: '版本号', value: data?.version },
+              { key: '版本序号', value: data?.versionOrder },
+              { key: '签名方式', value: data?.signMethod },
+              { key: '签名', value: data?.sign },
+            ].map((item) => (
+              <Descriptions.Item label={item.key}>{item.value}</Descriptions.Item>
+            ))}
+          </Descriptions>
+        </>
+      }
+      title={<>固件: {state.current?.name}</>}
+      tabList={list}
+    >
+      {list.find((k) => k.key === tab)?.component}
+    </PageContainer>
+  );
+};
+export default Detail;

+ 90 - 0
src/pages/device/Firmware/Save/index.tsx

@@ -0,0 +1,90 @@
+import { Modal } from 'antd';
+import type { FirmwareItem } from '@/pages/device/Firmware/typings';
+import { createSchemaField } from '@formily/react';
+import { Form, FormItem, Input, Select, Upload } from '@formily/antd';
+import { createForm } from '@formily/core';
+import type { ISchema } from '@formily/json-schema';
+
+interface Props {
+  data?: FirmwareItem;
+  close: () => void;
+  visible: boolean;
+}
+
+const Save = (props: Props) => {
+  const { data, close, visible } = props;
+
+  const form = createForm({
+    validateFirst: true,
+    initialValues: data,
+  });
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      Upload,
+      Select,
+    },
+  });
+
+  const schema: ISchema = {
+    type: 'object',
+    properties: {
+      productId: {
+        title: '产品',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+      },
+      name: {
+        title: '名称',
+        'x-decorator': 'FormItem',
+        'x-component': 'Input',
+      },
+      version: {
+        title: '版本号',
+        'x-decorator': 'FormItem',
+        'x-component': 'Input',
+      },
+      versionOrder: {
+        title: '版本序号',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+      },
+      signMethod: {
+        title: '签名方式',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+        enum: [
+          { label: 'MD5', value: 'MD5' },
+          { label: 'SHA256', value: 'SHA256' },
+        ],
+      },
+      sign: {
+        title: '签名',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+      },
+      file: {
+        title: '文件上传',
+        'x-decorator': 'FormItem',
+        'x-component': 'Upload',
+      },
+      describe: {
+        title: '描述信息',
+        'x-decorator': 'FormItem',
+        'x-component': 'Input.TextArea',
+        'x-component-props': {
+          rows: 3,
+        },
+      },
+    },
+  };
+  return (
+    <Modal title="新增固件版本" onCancel={() => close()} onOk={console.log} visible={visible}>
+      <Form form={form} labelCol={5} wrapperCol={16}>
+        <SchemaField schema={schema} />
+      </Form>
+    </Modal>
+  );
+};
+export default Save;

+ 51 - 22
src/pages/device/Firmware/index.tsx

@@ -1,17 +1,27 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import BaseService from '@/utils/BaseService';
 import type { ProColumns, ActionType } from '@jetlinks/pro-table';
-import { message, Popconfirm, Tooltip } from 'antd';
+import { Button, message, Popconfirm, Tooltip } from 'antd';
 import moment from 'moment';
 import { useRef } from 'react';
-import BaseCrud from '@/components/BaseCrud';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { EditOutlined, EyeOutlined, MinusOutlined } from '@ant-design/icons';
-import { CurdModel } from '@/components/BaseCrud/model';
+import { EditOutlined, EyeOutlined, MinusOutlined, PlusOutlined } from '@ant-design/icons';
+import { Link } from 'umi';
+import { model } from '@formily/reactive';
+import ProTable from '@jetlinks/pro-table';
+import { observer } from '@formily/react';
+import type { FirmwareItem } from '@/pages/device/Firmware/typings';
+import Service from '@/pages/device/Firmware/service';
+import Save from '@/pages/device/Firmware/Save';
 
-const service = new BaseService('firmware');
+export const service = new Service('firmware');
 
-const Firmware = () => {
+export const state = model<{
+  current?: FirmwareItem;
+  visible: boolean;
+}>({
+  visible: false,
+});
+const Firmware = observer(() => {
   const actionRef = useRef<ActionType>();
   const intl = useIntl();
 
@@ -71,10 +81,12 @@ const Firmware = () => {
       width: 200,
 
       render: (text, record) => [
-        <a
+        <Link
           onClick={() => {
-            // router.push(`/device/firmware/save/${record.id}`);
+            state.current = record;
           }}
+          to={`/device/firmware/detail/${record.id}`}
+          key="link"
         >
           <Tooltip
             title={intl.formatMessage({
@@ -85,8 +97,13 @@ const Firmware = () => {
           >
             <EyeOutlined />
           </Tooltip>
-        </a>,
-        <a key="editable" onClick={() => CurdModel.update(record)}>
+        </Link>,
+        <a
+          key="editable"
+          onClick={() => {
+            state.visible = true;
+          }}
+        >
           <Tooltip
             title={intl.formatMessage({
               id: 'pages.data.option.edit',
@@ -96,7 +113,7 @@ const Firmware = () => {
             <EditOutlined />
           </Tooltip>
         </a>,
-        <a>
+        <a key="delete">
           <Popconfirm
             title={intl.formatMessage({
               id: 'pages.data.option.remove.tips',
@@ -127,21 +144,33 @@ const Firmware = () => {
     },
   ];
 
-  const schema = {};
-
   return (
     <PageContainer>
-      <BaseCrud<FirmwareItem>
+      <ProTable<FirmwareItem>
+        toolBarRender={() => [
+          <Button
+            onClick={() => {
+              state.visible = true;
+            }}
+            key="button"
+            icon={<PlusOutlined />}
+            type="primary"
+          >
+            新增
+          </Button>,
+        ]}
+        request={async (params) => service.query(params)}
         columns={columns}
-        service={service}
-        title={intl.formatMessage({
-          id: 'pages.device.firmware',
-          defaultMessage: '固件升级',
-        })}
-        schema={schema}
         actionRef={actionRef}
       />
+      <Save
+        data={state.current}
+        visible={state.visible}
+        close={() => {
+          state.visible = false;
+        }}
+      />
     </PageContainer>
   );
-};
+});
 export default Firmware;

+ 20 - 0
src/pages/device/Firmware/service.ts

@@ -0,0 +1,20 @@
+import BaseService from '@/utils/BaseService';
+import { request } from '@@/plugin-request/request';
+import SystemConst from '@/utils/const';
+import type { FirmwareItem } from '@/pages/device/Firmware/typings';
+
+class Service extends BaseService<FirmwareItem> {
+  task = (params: Record<string, unknown>) =>
+    request(`/${SystemConst.API_BASE}/firmware/upgrade/task/_query`, {
+      method: 'GET',
+      params,
+    });
+
+  history = (params: Record<string, unknown>) =>
+    request(`/${SystemConst.API_BASE}/firmware/upgrade/history/_query`, {
+      method: 'GET',
+      params,
+    });
+}
+
+export default Service;

+ 28 - 0
src/pages/device/Firmware/typings.d.ts

@@ -1,3 +1,5 @@
+import type { State } from '@/utils/typings';
+
 type FirmwareItem = {
   createTime: number;
   id: string;
@@ -11,3 +13,29 @@ type FirmwareItem = {
   version: string;
   versionOrder: number;
 };
+
+type TaskItem = {
+  id: string;
+  name: string;
+  productId: string;
+  createTime: number;
+  firmwareId: string;
+  mode: State;
+  timeoutSeconds: number;
+};
+
+type HistoryItem = {
+  id: string;
+  createTime: number;
+  deviceId: string;
+  deviceName: string;
+  firmwareId: string;
+  productId: string;
+  progress: number;
+  state: State;
+  taskId: string;
+  taskName: string;
+  timeoutSeconds: number;
+  version: string;
+  versionOrder: number;
+};