tianyunperfect %!s(int64=5) %!d(string=hai) anos
pai
achega
53c0c55e38

+ 36 - 30
config/config.ts

@@ -55,41 +55,47 @@ export default defineConfig({
           routes: [
             {
               path: '/',
-              redirect: '/welcome',
+              redirect: '/modelList',
             },
+            // {
+            //   path: '/welcome',
+            //   name: 'welcome',
+            //   icon: 'smile',
+            //   component: './Welcome',
+            // },
+            // {
+            //   path: '/admin',
+            //   name: 'admin',
+            //   icon: 'crown',
+            //   component: './Admin',
+            //   authority: ['admin'],
+            //   routes: [
+            //     {
+            //       path: '/admin/sub-page',
+            //       name: 'sub-page',
+            //       icon: 'smile',
+            //       component: './Welcome',
+            //       authority: ['admin'],
+            //     },
+            //   ],
+            // },
+            // {
+            //   name: 'list.table-list',
+            //   icon: 'table',
+            //   path: '/list',
+            //   component: './ListTableList',
+            // },
             {
-              path: '/welcome',
-              name: 'welcome',
+              name: 'list.model-list',
               icon: 'smile',
-              component: './Welcome',
-            },
-            {
-              path: '/admin',
-              name: 'admin',
-              icon: 'crown',
-              component: './Admin',
-              authority: ['admin'],
-              routes: [
-                {
-                  path: '/admin/sub-page',
-                  name: 'sub-page',
-                  icon: 'smile',
-                  component: './Welcome',
-                  authority: ['admin'],
-                },
-              ],
-            },
-            {
-              name: 'list.table-list',
-              icon: 'table',
-              path: '/list',
-              component: './ListTableList',
+              path: '/modelList',
+              component: './ModelList',
             },
             {
-              name: 'list.model-list',
+              name: 'list.service-list',
               icon: 'smile',
-              path: '/modellist',
-              component: './ModelList',
+              path: '/serviceList',
+              component: './ServiceList',
             },
             {
               component: './404',
@@ -126,7 +132,7 @@ export default defineConfig({
           resourcePath: string;
         },
         _: string,
-        localName: string
+        localName: string,
       ) => {
         if (
           context.resourcePath.includes('node_modules') ||

+ 1 - 1
package.json

@@ -52,7 +52,7 @@
   "dependencies": {
     "@ant-design/icons": "^4.0.0",
     "@ant-design/pro-layout": "^5.0.8",
-    "@ant-design/pro-table": "^2.1.11",
+    "@ant-design/pro-table": "2.2.0",
     "antd": "^4.0.0",
     "classnames": "^2.2.6",
     "immer": "^6.0.3",

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
src/assets/logo_white.svg


+ 12 - 22
src/layouts/BasicLayout.tsx

@@ -11,7 +11,7 @@ import ProLayout, {
 } from '@ant-design/pro-layout';
 import React, { useEffect } from 'react';
 import { Link, useIntl, connect, Dispatch } from 'umi';
-import { GithubOutlined } from '@ant-design/icons';
+// import { GithubOutlined } from '@ant-design/icons';
 import { Result, Button } from 'antd';
 import Authorized from '@/utils/Authorized';
 import RightContent from '@/components/GlobalHeader/RightContent';
@@ -58,27 +58,17 @@ const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
 
 const defaultFooterDom = (
   <DefaultFooter
-    copyright="2019 蚂蚁金服体验技术部出品"
-    links={[
-      {
-        key: 'Ant Design Pro',
-        title: 'Ant Design Pro',
-        href: 'https://pro.ant.design',
-        blankTarget: true,
-      },
-      {
-        key: 'github',
-        title: <GithubOutlined />,
-        href: 'https://github.com/ant-design/ant-design-pro',
-        blankTarget: true,
-      },
-      {
-        key: 'Ant Design',
-        title: 'Ant Design',
-        href: 'https://ant.design',
-        blankTarget: true,
-      },
-    ]}
+    copyright="2019 云知声智能科技股份有限公司"
+    links={
+      [
+        // {
+        //   key: '云知声-智享未来',
+        //   title: '云知声-智享未来',
+        //   href: 'www.unisound.com',
+        //   blankTarget: true,
+        // }
+      ]
+    }
   />
 );
 

+ 89 - 0
src/pages/ModelList/components/QueryForm.tsx

@@ -0,0 +1,89 @@
+import React, { useState } from 'react';
+import { Button, Form, Input, Modal } from 'antd';
+import service from '../service';
+
+const { TextArea } = Input;
+
+// 表单特殊字段
+export interface FormValueType {
+  modelName?: string;
+  queryStr?: string;
+}
+
+export interface FormProps {
+  onCancel: (flag?: boolean) => void;
+  // onSubmit: (values: FormValueType) => void;
+  modalVisible: boolean;
+  values: FormValueType;
+}
+
+const FormItem = Form.Item;
+
+const formLayout = {
+  labelCol: { span: 7 },
+  wrapperCol: { span: 13 },
+};
+
+const QueryForm: React.FC<FormProps> = (props) => {
+  const [resultStr, setResultStr] = useState('');
+
+  const [form] = Form.useForm();
+
+  const query = async () => {
+    const fields = await form.validateFields();
+    const result = await service.query(fields);
+    setResultStr(result);
+  };
+
+  const {
+    // onSubmit: handleUpdate,
+    onCancel: cancelModalVisible,
+    modalVisible,
+    values,
+  } = props;
+
+  const renderFooter = () => {
+    return (
+      <>
+        <Button onClick={() => cancelModalVisible()}>取消</Button>
+        <Button type="primary" onClick={() => query()}>
+          查询
+        </Button>
+      </>
+    );
+  };
+
+  return (
+    <Modal
+      width={640}
+      bodyStyle={{ padding: '32px 40px 48px' }}
+      destroyOnClose
+      title="相似度查询"
+      visible={modalVisible}
+      footer={renderFooter()}
+      onCancel={() => cancelModalVisible()}
+    >
+      <Form {...formLayout} form={form} initialValues={values}>
+        <FormItem
+          name="modelName"
+          label="模型名称"
+          rules={[{ required: true, message: '请输入规则名称!' }]}
+        >
+          <Input placeholder="请输入" readOnly />
+        </FormItem>
+        <FormItem
+          name="queryStr"
+          label="查询文字"
+          rules={[{ required: true, message: '请输入规则名称!' }]}
+        >
+          <Input placeholder="请输入" />
+        </FormItem>
+        <FormItem label="查询结果">
+          <TextArea value={resultStr} rows={4} readOnly />
+        </FormItem>
+      </Form>
+    </Modal>
+  );
+};
+
+export default QueryForm;

+ 25 - 39
src/pages/ModelList/components/UpdateForm.tsx

@@ -1,12 +1,10 @@
-import React, {useEffect, useState} from 'react';
-import {Button, Form, Input, message, Modal, Radio, Upload} from 'antd';
-import {TableListItem} from '../data.d';
-import {UploadOutlined} from '@ant-design/icons';
+import React, { useState } from 'react';
+import { Button, Form, Input, message, Modal, Radio, Upload } from 'antd';
+import { TableListItem } from '../data.d';
+import { UploadOutlined } from '@ant-design/icons';
 
 // 表单特殊字段
-export interface FormValueType extends Partial<TableListItem> {
-
-}
+export interface FormValueType extends Partial<TableListItem> {}
 
 export interface UpdateFormProps {
   onCancel: (flag?: boolean, formVals?: FormValueType) => void;
@@ -18,8 +16,8 @@ export interface UpdateFormProps {
 const FormItem = Form.Item;
 
 const formLayout = {
-  labelCol: {span: 7},
-  wrapperCol: {span: 13},
+  labelCol: { span: 7 },
+  wrapperCol: { span: 13 },
 };
 
 const UpdateForm: React.FC<UpdateFormProps> = (props) => {
@@ -36,7 +34,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
 
   const submit = async () => {
     const fieldsValue = await form.validateFields();
-    const newValue = {...formVals, ...fieldsValue};
+    const newValue = { ...formVals, ...fieldsValue };
     setFormVals(newValue);
     handleUpdate(newValue);
   };
@@ -46,36 +44,36 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
     // @ts-ignore
     onChange(info) {
       if (info.file.status === 'done') {
-        setFormVals({...formVals, ...{"modelFile": info.file.response.url}});
+        setFormVals({ ...formVals, ...{ modelFile: info.file.response.url } });
         message.success(`file uploaded successfully`);
       } else if (info.file.status === 'error') {
         message.error(`file upload failed.`);
       }
-    }
+    },
   };
   const vocabFileProps = {
     action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
     // @ts-ignore
     onChange(info) {
       if (info.file.status === 'done') {
-        setFormVals({...formVals, ...{"vocabFile": info.file.response.url}});
+        setFormVals({ ...formVals, ...{ vocabFile: info.file.response.url } });
         message.success(`file uploaded successfully`);
       } else if (info.file.status === 'error') {
         message.error(`file upload failed.`);
       }
-    }
+    },
   };
   const labelFileProps = {
     action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
     // @ts-ignore
     onChange(info) {
       if (info.file.status === 'done') {
-        setFormVals({...formVals, ...{"labelFile": info.file.response.url}});
+        setFormVals({ ...formVals, ...{ labelFile: info.file.response.url } });
         message.success(`file uploaded successfully`);
       } else if (info.file.status === 'error') {
         message.error(`file upload failed.`);
       }
-    }
+    },
   };
 
   const renderFooter = () => {
@@ -92,61 +90,50 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
   return (
     <Modal
       width={640}
-      bodyStyle={{padding: '32px 40px 48px'}}
+      bodyStyle={{ padding: '32px 40px 48px' }}
       destroyOnClose
       title="配置模型"
       visible={updateModalVisible}
       footer={renderFooter()}
       onCancel={() => handleUpdateModalVisible()}
     >
-      <Form
-        {...formLayout}
-        form={form}
-        initialValues={formVals}
-      >
+      <Form {...formLayout} form={form} initialValues={formVals}>
         <FormItem
           name="modelName"
           label="模型名称"
-          rules={[{required: true, message: '请输入规则名称!'}]}
+          rules={[{ required: true, message: '请输入规则名称!' }]}
         >
-          <Input placeholder="请输入"/>
+          <Input placeholder="请输入" />
         </FormItem>
 
-
         <FormItem
           name="modelType"
           label="模型类型"
-          rules={[{required: true, message: '请选择模型类型!'}]}
+          rules={[{ required: true, message: '请选择模型类型!' }]}
         >
           <Radio.Group>
             <Radio.Button value="0">aubert</Radio.Button>
             <Radio.Button value="1">blstm</Radio.Button>
           </Radio.Group>
         </FormItem>
-        <FormItem
-          label="模型文件"
-        >
+        <FormItem label="模型文件">
           <Upload {...modelFileProps}>
             <Button>
-              <UploadOutlined/> Upload
+              <UploadOutlined /> Upload
             </Button>
           </Upload>
         </FormItem>
-        <FormItem
-          label="词向量文件"
-        >
+        <FormItem label="词向量文件">
           <Upload {...vocabFileProps}>
             <Button>
-              <UploadOutlined/> Upload
+              <UploadOutlined /> Upload
             </Button>
           </Upload>
         </FormItem>
-        <FormItem
-          label="标签文件"
-        >
+        <FormItem label="标签文件">
           <Upload {...labelFileProps}>
             <Button>
-              <UploadOutlined/> Upload
+              <UploadOutlined /> Upload
             </Button>
           </Upload>
         </FormItem>
@@ -155,5 +142,4 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
   );
 };
 
-
 export default UpdateForm;

+ 49 - 34
src/pages/ModelList/index.tsx

@@ -1,11 +1,12 @@
-import {PlusOutlined} from '@ant-design/icons';
-import {Button, Divider, message, Modal, Radio} from 'antd';
-import React, {useRef, useState} from 'react';
-import {PageHeaderWrapper} from '@ant-design/pro-layout';
-import ProTable, {ActionType, ProColumns} from '@ant-design/pro-table';
-import {SorterResult} from 'antd/es/table/interface';
-import {TableListItem} from './data.d';
+import { PlusOutlined } from '@ant-design/icons';
+import { Button, Divider, message, Modal, Radio } from 'antd';
+import React, { useRef, useState } from 'react';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import ProTable, { ActionType, ProColumns } from '@ant-design/pro-table';
+import { SorterResult } from 'antd/es/table/interface';
+import { TableListItem } from './data.d';
 import service from './service';
+import QueryForm from '@/pages/ModelList/components/QueryForm';
 
 /**
  * 添加节点
@@ -14,7 +15,7 @@ import service from './service';
 const handleAdd = async (fields: TableListItem) => {
   const hide = message.loading('正在添加');
   try {
-    await service.addModel({...fields});
+    await service.addModel({ ...fields });
     hide();
     message.success('添加成功');
     return true;
@@ -41,7 +42,6 @@ const handleUpdate = async (fields: TableListItem) => {
     message.error('配置失败请重试!');
     return false;
   }
-
 };
 
 /**
@@ -62,14 +62,13 @@ const handleRemove = async (fields: TableListItem) => {
   }
 };
 
-
 const TableList: React.FC<{}> = () => {
-
-
   const [sorter, setSorter] = useState<string>('');
   const [modelVisible, setModalVisible] = useState<boolean>(false);
   const [formValues, setFormValues] = useState({});
   const actionRef = useRef<ActionType>();
+  const [queryVisible, setQueryVisible] = useState<boolean>(false);
+
   const columns: ProColumns<TableListItem>[] = [
     {
       title: '模型类型',
@@ -90,8 +89,8 @@ const TableList: React.FC<{}> = () => {
         );
       },
       valueEnum: {
-        0: {text: 'albert'},
-        1: {text: 'Blstm'}
+        0: { text: 'albert' },
+        1: { text: 'Blstm' },
       },
     },
     {
@@ -116,7 +115,7 @@ const TableList: React.FC<{}> = () => {
       ],
     },
     {
-      title: '向量文件',
+      title: '向量文件',
       dataIndex: 'vocabFile',
       hideInSearch: true,
       rules: [
@@ -144,7 +143,7 @@ const TableList: React.FC<{}> = () => {
     },
     {
       title: '必不包含',
-      dataIndex: 'mustTag',
+      dataIndex: 'mustNotTag',
       hideInSearch: true,
     },
     {
@@ -160,8 +159,8 @@ const TableList: React.FC<{}> = () => {
         );
       },
       valueEnum: {
-        "true": {text: '是'},
-        "false": {text: '否'}
+        true: { text: '是' },
+        false: { text: '否' },
       },
     },
 
@@ -175,27 +174,35 @@ const TableList: React.FC<{}> = () => {
             onClick={() => {
               setModalVisible(true);
               setFormValues(record);
-              console.log(record)
+              console.log(record);
             }}
           >
             配置
           </a>
-          <Divider type="vertical"/>
+          <Divider type="vertical" />
           <a
             onClick={() => {
               handleRemove(record);
-              console.log(record)
+              console.log(record);
             }}
           >
             删除
           </a>
+          <Divider type="vertical" />
+          <a
+            onClick={() => {
+              setQueryVisible(true);
+              setFormValues(record);
+              console.log(record);
+            }}
+          >
+            查询
+          </a>
         </>
       ),
     },
   ];
 
-  const [searchForm,setSearchForm] = useState({});
-
   return (
     <PageHeaderWrapper>
       <ProTable<TableListItem>
@@ -209,19 +216,22 @@ const TableList: React.FC<{}> = () => {
           }
         }}
         pagination={{
-          defaultPageSize: 10
+          defaultPageSize: 10,
         }}
         params={{
           sorter,
         }}
         /* eslint-disable */
-        toolBarRender={(action, {selectedRows}) => [
-          <Button type="primary" onClick={() => {
-            setModalVisible(true);
-            setFormValues({});
-          }}>
-            <PlusOutlined/> 新建
-          </Button>
+        toolBarRender={(action, { selectedRows }) => [
+          <Button
+            type="primary"
+            onClick={() => {
+              setModalVisible(true);
+              setFormValues({});
+            }}
+          >
+            <PlusOutlined /> 新建
+          </Button>,
         ]}
         request={(params) => service.queryModel(params)}
         columns={columns}
@@ -229,7 +239,7 @@ const TableList: React.FC<{}> = () => {
       />
       <Modal
         destroyOnClose
-        title={"id" in formValues ? "编辑" : "新建"}
+        title={'id' in formValues ? '编辑' : '新建'}
         visible={modelVisible}
         onCancel={() => setModalVisible(false)}
         footer={null}
@@ -250,14 +260,19 @@ const TableList: React.FC<{}> = () => {
               }
             }
           }}
-          rowKey="key"
+          rowKey="id"
           type="form"
           columns={columns}
           rowSelection={{}}
-          form={{initialValues: formValues}}
+          form={{ initialValues: formValues }}
         />
       </Modal>
 
+      <QueryForm
+        onCancel={() => setQueryVisible(false)}
+        modalVisible={queryVisible}
+        values={formValues}
+      />
     </PageHeaderWrapper>
   );
 };

+ 3 - 3
src/pages/ModelList/service.ts

@@ -4,6 +4,6 @@ export default {
   queryModel: api.get('/api/model'),
   removeModel: api.post('/api/rule'),
   addModel: api.post('/api/rule'),
-  updateModel: api.post('/api/rule')
-}
-
+  updateModel: api.post('/api/rule'),
+  query: api.post('/api/rule'),
+};

+ 49 - 0
src/pages/ServiceList/_mock.ts

@@ -0,0 +1,49 @@
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { Request, Response } from 'express';
+import { parse } from 'url';
+import { TableListItem, TableListParams } from './data.d';
+
+// mock tableListDataSource
+const genList = (current: number, pageSize: number) => {
+  const tableListDataSource: TableListItem[] = [];
+
+  for (let i = 0; i < pageSize; i += 1) {
+    const index = (current - 1) * 10 + i;
+    tableListDataSource.push({
+      id: index,
+      serviceIp: `${index}name`,
+      modelName: `${index}name`,
+      modelVersion: `${index}name`,
+      currentVersion: `${index}name`,
+    });
+  }
+  tableListDataSource.reverse();
+  return tableListDataSource;
+};
+
+const tableListDataSource = genList(1, 100);
+
+function getModels(req: Request, res: Response, u: string) {
+  let realUrl = u;
+  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
+    realUrl = req.url;
+  }
+  const { current = 1, pageSize = 10 } = req.query;
+  const params = (parse(realUrl, true).query as unknown) as TableListParams;
+
+  const dataSource = [...tableListDataSource].slice((current - 1) * pageSize, current * pageSize);
+
+  const result = {
+    data: dataSource,
+    total: tableListDataSource.length,
+    success: true,
+    pageSize,
+    current: parseInt(`${params.currentPage}`, 10) || 1,
+  };
+
+  return res.json(result);
+}
+
+export default {
+  'GET /api/service': getModels,
+};

+ 29 - 0
src/pages/ServiceList/data.d.ts

@@ -0,0 +1,29 @@
+// 表单
+export interface TableListItem {
+  id?: number;
+  serviceIp: string;
+  modelName: string;
+  modelVersion: string;
+  currentVersion: string;
+}
+// 分页参数
+export interface TableListPagination {
+  total: number;
+  pageSize: number;
+  current: number;
+}
+// 返回的分页数据
+export interface TableListData {
+  list: TableListItem[];
+  pagination: Partial<TableListPagination>;
+}
+// 查询参数
+export interface TableListParams {
+  sorter?: string;
+  status?: string;
+  name?: string;
+  desc?: string;
+  id?: number;
+  pageSize?: number;
+  currentPage?: number;
+}

+ 3 - 0
src/pages/ServiceList/index.less

@@ -0,0 +1,3 @@
+.upload {
+  display: inline;
+}

+ 95 - 0
src/pages/ServiceList/index.tsx

@@ -0,0 +1,95 @@
+import { message } from 'antd';
+import React, { useRef, useState } from 'react';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import ProTable, { ActionType, ProColumns } from '@ant-design/pro-table';
+import { SorterResult } from 'antd/es/table/interface';
+import { TableListItem } from './data.d';
+import service from './service';
+
+/**
+ * 更新节点
+ * @param fields
+ */
+const handleUpdate = async (fields: TableListItem) => {
+  const hide = message.loading('正在配置');
+  try {
+    await service.updateModel(fields);
+    hide();
+    message.success('配置成功');
+    return true;
+  } catch (error) {
+    hide();
+    message.error('配置失败请重试!');
+    return false;
+  }
+};
+
+const TableList: React.FC<{}> = () => {
+  const [sorter, setSorter] = useState<string>('');
+  const actionRef = useRef<ActionType>();
+
+  const columns: ProColumns<TableListItem>[] = [
+    {
+      title: '服务IP',
+      dataIndex: 'serviceIp',
+    },
+    {
+      title: '模型名称',
+      dataIndex: 'modelName',
+    },
+    {
+      title: '模型版本',
+      dataIndex: 'modelVersion',
+      hideInSearch: true,
+    },
+    {
+      title: '当前版本',
+      dataIndex: 'currentVersion',
+      hideInSearch: true,
+    },
+    {
+      title: '操作',
+      dataIndex: 'option',
+      valueType: 'option',
+      render: (_, record) => (
+        <>
+          <a
+            onClick={async () => {
+              await handleUpdate(record);
+              console.log(record);
+            }}
+          >
+            强制更新
+          </a>
+        </>
+      ),
+    },
+  ];
+
+  return (
+    <PageHeaderWrapper>
+      <ProTable<TableListItem>
+        headerTitle="查询表格"
+        actionRef={actionRef}
+        rowKey="id"
+        onChange={(_, _filter, _sorter) => {
+          const sorterResult = _sorter as SorterResult<TableListItem>;
+          if (sorterResult.field) {
+            setSorter(`${sorterResult.field}_${sorterResult.order}`);
+          }
+        }}
+        pagination={{
+          defaultPageSize: 10,
+        }}
+        params={{
+          sorter,
+        }}
+        request={(params) => service.queryList(params)}
+        columns={columns}
+        rowSelection={{}}
+      />
+    </PageHeaderWrapper>
+  );
+};
+
+export default TableList;

+ 8 - 0
src/pages/ServiceList/service.ts

@@ -0,0 +1,8 @@
+import api from '@/utils/api';
+
+export default {
+  queryList: api.get('/api/service'),
+  removeModel: api.post('/api/rule'),
+  addModel: api.post('/api/rule'),
+  updateModel: api.post('/api/rule'),
+};

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio