|
@@ -1,364 +1,226 @@
|
|
|
-import {PlusOutlined} from '@ant-design/icons';
|
|
|
-import {Button, Divider, message, Modal, Radio} from 'antd';
|
|
|
-import React, {useRef, useState} from 'react';
|
|
|
+import {Button, message} from 'antd';
|
|
|
+import React, {useEffect} 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 QueryForm from '@/pages/Memory/components/QueryForm';
|
|
|
-import {TableListItem} from './data.d';
|
|
|
+import {useSingleState} from "nice-hooks";
|
|
|
+import ReactQuill from "react-quill";
|
|
|
+import 'react-quill/dist/quill.snow.css';
|
|
|
+import {Memory} from './data.d';
|
|
|
import service from './service';
|
|
|
|
|
|
-/**
|
|
|
- * 添加节点
|
|
|
- * @param fields
|
|
|
- */
|
|
|
-const handleAdd = async (fields: TableListItem) => {
|
|
|
- const hide = message.loading('正在添加');
|
|
|
- try {
|
|
|
- const res = await service.addModel({...fields});
|
|
|
- hide();
|
|
|
- if (res.success) {
|
|
|
- message.success('添加成功');
|
|
|
- return true;
|
|
|
+enum Step {
|
|
|
+ MAIN = 0,
|
|
|
+ MEMORY = 1,
|
|
|
+ ADD = 2,
|
|
|
+}
|
|
|
+
|
|
|
+interface State {
|
|
|
+ remindCount: number;
|
|
|
+ step: Step;
|
|
|
+ showBack?: boolean
|
|
|
+}
|
|
|
+
|
|
|
+const TableList: React.FC<{}> = () => {
|
|
|
+
|
|
|
+
|
|
|
+ const [state, setState] = useSingleState<State>({
|
|
|
+ remindCount: 0,
|
|
|
+ step: Step.MAIN, // 0 主页,1 复习,2 添加
|
|
|
+ showBack: false
|
|
|
+ })
|
|
|
+
|
|
|
+ const [memory, setMemory] = useSingleState<Memory>({
|
|
|
+ id: null,
|
|
|
+ userId: null,
|
|
|
+ front: "",
|
|
|
+ back: "",
|
|
|
+ tag: ''
|
|
|
+ })
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询用户待提醒数量
|
|
|
+ * @param fields
|
|
|
+ */
|
|
|
+ const countRemind = async () => {
|
|
|
+ const hide = message.loading('正在查询');
|
|
|
+ try {
|
|
|
+ const res = await service.countRemind({});
|
|
|
+ hide();
|
|
|
+ if (res.success) {
|
|
|
+ setState({remindCount: parseInt(res.data, 10)}, () => {
|
|
|
+ if (state.remindCount === 0) {
|
|
|
+ message.info('复习完毕!');
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ } catch (error) {
|
|
|
+ hide();
|
|
|
+ message.error('查询异常!');
|
|
|
+ return false;
|
|
|
}
|
|
|
- message.error('添加失败请重试!');
|
|
|
- return false;
|
|
|
+ };
|
|
|
+ useEffect(() => {
|
|
|
+ countRemind();
|
|
|
+ }, []);
|
|
|
|
|
|
- } catch (error) {
|
|
|
- hide();
|
|
|
- message.error('添加失败请重试!');
|
|
|
- return false;
|
|
|
+ useEffect(() => {
|
|
|
+ // console.log(state)
|
|
|
+ // console.log(memory)
|
|
|
+ })
|
|
|
+ /**
|
|
|
+ * 进入统计页面
|
|
|
+ */
|
|
|
+ const changStepMain = () => {
|
|
|
+ setState({step: Step.MAIN})
|
|
|
+ countRemind();
|
|
|
}
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 更新节点
|
|
|
- * @param fields
|
|
|
- */
|
|
|
-const handleUpdate = async (fields: TableListItem) => {
|
|
|
- const hide = message.loading('正在配置');
|
|
|
- try {
|
|
|
- const res = await service.updateModel(fields);
|
|
|
- hide();
|
|
|
+ /**
|
|
|
+ * 进入复习页面
|
|
|
+ */
|
|
|
+ const changStepMemory = async () => {
|
|
|
+ if (state.remindCount <= 0) {
|
|
|
+ message.info('已经复习完了哟!');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setState({step: Step.MEMORY});
|
|
|
+ const res = await service.findNext({});
|
|
|
if (res.success) {
|
|
|
- message.success('配置成功');
|
|
|
- return true;
|
|
|
+ setMemory({...memory, ...res.data});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const memorySuccess = async (factorInt: number) => {
|
|
|
+ const res = await service.memorySuccess({id: memory.id, factor: factorInt});
|
|
|
+ if (res.success) {
|
|
|
+ setMemory({...memory, ...res.data});
|
|
|
+ } else {
|
|
|
+ message.info('恭喜!复习完毕!');
|
|
|
+ setState({step: Step.MAIN});
|
|
|
}
|
|
|
- message.error('配置失败请重试!');
|
|
|
- return false;
|
|
|
- } catch (error) {
|
|
|
- hide();
|
|
|
- message.error('配置失败请重试!');
|
|
|
- return false;
|
|
|
}
|
|
|
-};
|
|
|
|
|
|
-/**
|
|
|
- * 删除节点
|
|
|
- * @param fields
|
|
|
- */
|
|
|
-const handleRemove = async (fields: TableListItem) => {
|
|
|
- const hide = message.loading('正在删除');
|
|
|
- try {
|
|
|
- const res = await service.removeModel(fields);
|
|
|
- hide();
|
|
|
- message.success('删除成功,即将刷新');
|
|
|
- return res.success;
|
|
|
- } catch (error) {
|
|
|
- hide();
|
|
|
- message.error('删除失败,请重试');
|
|
|
- return false;
|
|
|
+ const changStepAdd = () => {
|
|
|
+ setState({step: Step.ADD})
|
|
|
}
|
|
|
-};
|
|
|
|
|
|
-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);
|
|
|
+ /**
|
|
|
+ * 清空memory
|
|
|
+ */
|
|
|
+ const clearMemory = () => {
|
|
|
+ setMemory({
|
|
|
+ id: null,
|
|
|
+ front: "",
|
|
|
+ back: ""
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- const columns: ProColumns<TableListItem>[] = [
|
|
|
- {
|
|
|
- title: '模型类型',
|
|
|
- dataIndex: 'modelType',
|
|
|
- hideInSearch: true,
|
|
|
- width: 120,
|
|
|
- rules: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '模型类型为必填项',
|
|
|
- },
|
|
|
- ],
|
|
|
- renderFormItem: () => {
|
|
|
- return (
|
|
|
- <Radio.Group>
|
|
|
- <Radio value={0}>albert</Radio>
|
|
|
- <Radio value={1}>bilstm</Radio>
|
|
|
- </Radio.Group>
|
|
|
- );
|
|
|
- },
|
|
|
- valueEnum: {
|
|
|
- 0: {text: 'albert'},
|
|
|
- 1: {text: 'bilstm'},
|
|
|
- },
|
|
|
- },
|
|
|
- {
|
|
|
- title: '模型名称',
|
|
|
- dataIndex: 'modelName',
|
|
|
- width: 150,
|
|
|
- copyable: true,
|
|
|
- rules: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '模型名称为必填项',
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- {
|
|
|
- title: '模型文件',
|
|
|
- dataIndex: 'modelFile',
|
|
|
- hideInSearch: true,
|
|
|
- width: 200,
|
|
|
- copyable: true,
|
|
|
- rules: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '模型文件为必填项',
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- {
|
|
|
- title: '向量文件',
|
|
|
- dataIndex: 'vocabFile',
|
|
|
- hideInSearch: true,
|
|
|
- width: 200,
|
|
|
- copyable: true,
|
|
|
- rules: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '词向量文件为必填项',
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- {
|
|
|
- title: '标签文件',
|
|
|
- dataIndex: 'labelFile',
|
|
|
- hideInSearch: true,
|
|
|
- width: 200,
|
|
|
- copyable: true,
|
|
|
- rules: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '标签文件为必填项',
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- {
|
|
|
- title: '必包含',
|
|
|
- dataIndex: 'mustTag',
|
|
|
- hideInSearch: true,
|
|
|
- copyable: true,
|
|
|
- formItemProps: {
|
|
|
- placeholder: '逗号分隔'
|
|
|
- },
|
|
|
- hideInTable: true,
|
|
|
- },
|
|
|
- {
|
|
|
- title: '必不包含',
|
|
|
- dataIndex: 'mustNotTag',
|
|
|
- hideInSearch: true,
|
|
|
- copyable: true,
|
|
|
- formItemProps: {
|
|
|
- placeholder: '逗号分隔'
|
|
|
- },
|
|
|
- hideInTable: true,
|
|
|
- },
|
|
|
+ return (
|
|
|
+ <PageHeaderWrapper title={false}>
|
|
|
+ {state.step === Step.MAIN ? (
|
|
|
+ <div>
|
|
|
+ <div>待复习: {state.remindCount}</div>
|
|
|
+ <p/>
|
|
|
+ <Button type="primary" size="large" onClick={changStepMemory}>复习</Button>
|
|
|
+ <p/>
|
|
|
+ <Button type="primary" size="large" onClick={changStepAdd}>添加</Button>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
|
|
|
- {
|
|
|
- title: 'BatchSize',
|
|
|
- dataIndex: 'maxBatchSize',
|
|
|
- hideInSearch: true,
|
|
|
- hideInTable: true,
|
|
|
- },
|
|
|
- {
|
|
|
- title: 'SeqLength',
|
|
|
- dataIndex: 'maxSeqLength',
|
|
|
- hideInSearch: true,
|
|
|
- hideInTable: true,
|
|
|
- },
|
|
|
+ {state.step === Step.MEMORY ? (
|
|
|
+ <div>
|
|
|
+ 问题
|
|
|
+ <hr/>
|
|
|
+ <div dangerouslySetInnerHTML={{__html: memory.front}}/>
|
|
|
+ <hr/>
|
|
|
+ {state.showBack ? (
|
|
|
+ <div>
|
|
|
+ <div dangerouslySetInnerHTML={{__html: memory.back}}/>
|
|
|
+ <hr/>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ memorySuccess(0.5)
|
|
|
+ }}>生疏</Button>
|
|
|
+ <span> </span>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ memorySuccess(2)
|
|
|
+ }}>一般</Button>
|
|
|
+ <span> </span>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ memorySuccess(3)
|
|
|
+ }}>简单</Button>
|
|
|
+ <p/>
|
|
|
+ <div>
|
|
|
+ <Button type="primary" onClick={async () => {
|
|
|
+ await service.restart(memory);
|
|
|
+ changStepMemory();
|
|
|
+ }}>重新开始复习</Button>
|
|
|
+ <span> </span>
|
|
|
+ <Button type="primary" onClick={async () => {
|
|
|
+ await service.noMemory(memory);
|
|
|
+ changStepMemory();
|
|
|
+ }}>不在复习</Button>
|
|
|
+ <span> </span>
|
|
|
+ <Button type="primary" onClick={async () => {
|
|
|
+ await service.delete(memory);
|
|
|
+ changStepMemory();
|
|
|
+ }}>删除</Button>
|
|
|
+ </div>
|
|
|
+ <p/>
|
|
|
+ <div>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ changStepAdd();
|
|
|
+ }}>编辑</Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- {
|
|
|
- title: 'HiddenLayers',
|
|
|
- dataIndex: 'numHiddenLayers',
|
|
|
- hideInSearch: true,
|
|
|
- hideInTable: true,
|
|
|
- },
|
|
|
- {
|
|
|
- title: 'AttentionHeads',
|
|
|
- dataIndex: 'numAttentionHeads',
|
|
|
- hideInSearch: true,
|
|
|
- hideInTable: true,
|
|
|
- },
|
|
|
- {
|
|
|
- title: '纯文本',
|
|
|
- dataIndex: 'onlyWord',
|
|
|
- hideInSearch: true,
|
|
|
- hideInTable: true,
|
|
|
- renderFormItem: () => {
|
|
|
- return (
|
|
|
- <Radio.Group>
|
|
|
- <Radio value="true">是</Radio>
|
|
|
- <Radio value="false">否</Radio>
|
|
|
- </Radio.Group>
|
|
|
- );
|
|
|
- },
|
|
|
- valueEnum: {
|
|
|
- true: {text: '是'},
|
|
|
- false: {text: '否'},
|
|
|
- },
|
|
|
- },
|
|
|
- {
|
|
|
- title: '大小写',
|
|
|
- dataIndex: 'doLowerCase',
|
|
|
- hideInSearch: true,
|
|
|
- hideInTable: true,
|
|
|
- renderFormItem: () => {
|
|
|
- return (
|
|
|
- <Radio.Group>
|
|
|
- <Radio value={0}>区分</Radio>
|
|
|
- <Radio value={1}>不分区</Radio>
|
|
|
- </Radio.Group>
|
|
|
- );
|
|
|
- },
|
|
|
- valueEnum: {
|
|
|
- 0: {text: '区分'},
|
|
|
- 1: {text: '不分区'},
|
|
|
- },
|
|
|
- },
|
|
|
|
|
|
- {
|
|
|
- title: '操作',
|
|
|
- width: 200,
|
|
|
- dataIndex: 'option',
|
|
|
- valueType: 'option',
|
|
|
- render: (_, record,index,action) => (
|
|
|
- <>
|
|
|
- <a
|
|
|
- onClick={() => {
|
|
|
- setFormValues(record);
|
|
|
- setModalVisible(true);
|
|
|
- console.log(record);
|
|
|
- }}
|
|
|
- >
|
|
|
- 配置
|
|
|
- </a>
|
|
|
- <Divider type="vertical"/>
|
|
|
- <a
|
|
|
- onClick={async () => {
|
|
|
- const success = await handleRemove(record);
|
|
|
- if (success) {
|
|
|
- await action.reload();
|
|
|
- }
|
|
|
- console.log(record);
|
|
|
- }}
|
|
|
- >
|
|
|
- 删除
|
|
|
- </a>
|
|
|
- <Divider type="vertical"/>
|
|
|
- <a
|
|
|
- onClick={async () => {
|
|
|
- setFormValues(record);
|
|
|
- setQueryVisible(true);
|
|
|
- }}
|
|
|
- >
|
|
|
- 查询
|
|
|
- </a>
|
|
|
- </>
|
|
|
- ),
|
|
|
- },
|
|
|
- ];
|
|
|
+ ) : (
|
|
|
+ <div>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ setState({showBack: true})
|
|
|
+ }}>显示答案</Button>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
|
|
|
- return (
|
|
|
- <PageHeaderWrapper title={false}>
|
|
|
- <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,
|
|
|
- }}
|
|
|
- /* eslint-disable */
|
|
|
- toolBarRender={(action, {selectedRows}) => [
|
|
|
- <Button
|
|
|
- type="primary"
|
|
|
- onClick={() => {
|
|
|
- setModalVisible(true);
|
|
|
- setFormValues({
|
|
|
- maxBatchSize: 1,
|
|
|
- maxSeqLength: 40,
|
|
|
- numAttentionHeads: 12,
|
|
|
- numHiddenLayers: 3,
|
|
|
- doLowerCase: "1",
|
|
|
- onlyWord: "true",
|
|
|
- });
|
|
|
- }}
|
|
|
- >
|
|
|
- <PlusOutlined/> 新建
|
|
|
- </Button>,
|
|
|
- ]}
|
|
|
- request={(params) => service.queryModel(params)}
|
|
|
- columns={columns}
|
|
|
- rowSelection={{}}
|
|
|
- />
|
|
|
- <Modal
|
|
|
- destroyOnClose
|
|
|
- title={'id' in formValues ? '编辑' : '新建'}
|
|
|
- visible={modelVisible}
|
|
|
- onCancel={() => setModalVisible(false)}
|
|
|
- footer={null}
|
|
|
- >
|
|
|
- <ProTable<TableListItem, TableListItem>
|
|
|
- onSubmit={async (value) => {
|
|
|
- let success = false;
|
|
|
- if ('id' in formValues) {
|
|
|
- value['id'] = formValues['id']
|
|
|
- success = await handleUpdate(value);
|
|
|
+
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {state.step === Step.ADD ? (
|
|
|
+ <div>
|
|
|
+ <h4>正面</h4>
|
|
|
+ <ReactQuill theme="snow" value={memory.front} onChange={(value) => {
|
|
|
+ setMemory({front: value})
|
|
|
+ }}/>
|
|
|
+ <p/>
|
|
|
+ <h4>反面</h4>
|
|
|
+ <ReactQuill theme="snow" value={memory.back} onChange={(value) => {
|
|
|
+ setMemory({back: value})
|
|
|
+ }}/>
|
|
|
+ <p/>
|
|
|
+ <Button type="primary" onClick={async () => {
|
|
|
+ let res;
|
|
|
+ if (memory != null && memory.id != null) {
|
|
|
+ res = await service.update(memory);
|
|
|
} else {
|
|
|
- success = await handleAdd(value);
|
|
|
+ res = await service.insert(memory);
|
|
|
}
|
|
|
- if (success) {
|
|
|
- setModalVisible(false);
|
|
|
- if (actionRef.current) {
|
|
|
- actionRef.current.reload();
|
|
|
- }
|
|
|
+ if (res.success) {
|
|
|
+ message.info('操作成功');
|
|
|
+ clearMemory();
|
|
|
+ } else {
|
|
|
+ message.info(`操作失败: ${res.message}`);
|
|
|
}
|
|
|
- }}
|
|
|
- rowKey="id"
|
|
|
- type="form"
|
|
|
- columns={columns}
|
|
|
- rowSelection={{}}
|
|
|
- form={{initialValues: formValues}}
|
|
|
- />
|
|
|
- </Modal>
|
|
|
-
|
|
|
- {queryVisible ? (
|
|
|
- <QueryForm
|
|
|
- onCancel={() => setQueryVisible(false)}
|
|
|
- modalVisible={queryVisible}
|
|
|
- values={formValues}
|
|
|
- />
|
|
|
+ }}>确定</Button>
|
|
|
+ <span> </span>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ clearMemory();
|
|
|
+ changStepMain();
|
|
|
+ }}>关闭</Button>
|
|
|
+ </div>
|
|
|
) : null}
|
|
|
|
|
|
+
|
|
|
</PageHeaderWrapper>
|
|
|
);
|
|
|
};
|