123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- import {Button, Input, message, Modal} from 'antd';
- import React, {useEffect, useState} from 'react';
- import {PageHeaderWrapper} from '@ant-design/pro-layout';
- import {useSingleState} from 'nice-hooks';
- import Quill from '@/pages/Memory/components/Quill';
- import UpdateForm from '@/pages/Memory/components/UpdateForm';
- import {TableListItem} from '../MemoryList/data.d';
- import service from './service';
- import styles from './index.less';
- import {DownOutlined, ExclamationCircleOutlined} from '@ant-design/icons/lib';
- import {getRandom, getTextFromHtml} from '@/utils/utils';
- const {TextArea} = Input;
- enum Step {
- MAIN = 0,
- MEMORY = 1,
- ADD = 2,
- }
- interface State {
- remindCount: number;
- step: Step;
- showBack?: boolean;
- }
- const practice = "practice";
- const TableList: React.FC<{}> = () => {
- const [btnDisable, setBtnDisable] = useState(false);
- const [showMore, setShowMore] = useState(false);
- const [backPractice, setBackPractice] = useState("");
- let counting = false;
- const {confirm} = Modal;
- const [state, setState] = useSingleState<State>({
- remindCount: 0,
- step: Step.MAIN, // 0 主页,1 复习,2 添加
- showBack: false,
- });
- const [memory, setMemory] = useSingleState<TableListItem>({
- back: '',
- front: '',
- id: undefined,
- period: 0,
- remindTime: new Date(),
- tag: '',
- updateTime: '',
- userId: 0,
- });
- const isPracticeFocus = () => {
- // @ts-ignore
- return document.activeElement.id === practice;
- }
- /**
- * 查询用户待提醒数量
- * @param fields
- */
- const countRemind = async () => {
- // 如果上一个查询还没有结束,则直接返回
- // console.log(counting);
- if (counting) {
- return;
- }
- counting = true;
- const hide = message.loading('正在查询');
- try {
- const res = await service.countRemind({});
- hide();
- if (res.success) {
- setState({remindCount: parseInt(res.data, 10)});
- }
- counting = false;
- } catch (error) {
- hide();
- message.error('查询异常!');
- counting = false;
- }
- };
- /**
- * 清空memory
- */
- const clearMemory = () => {
- setMemory({
- id: undefined,
- front: '',
- back: '',
- });
- };
- /**
- * 处理返回值
- * @param res
- */
- const memoryRes = (res: any) => {
- // 只要有返回值,就使按钮可见
- setBtnDisable(false);
- if (res.success) {
- setMemory({...memory, ...res.data});
- } else {
- setState({step: Step.MAIN});
- }
- };
- const memorySuccess = async (factorInt: number) => {
- setBtnDisable(true);
- memoryRes(await service.memorySuccess({id: memory.id, factor: factorInt * getRandom()}));
- };
- const findNextLine = async () => {
- const res = await service.findNext({});
- if (res.success) {
- setMemory({...memory, ...res.data});
- } else {
- setState({step: Step.MAIN});
- }
- };
- // 绑定快捷键
- const bindShortKey = () => {
- document.onkeydown = (ev) => {
- // 在input有焦点的时候
- if (isPracticeFocus()) {
- // 按esc
- if (ev.key.toLowerCase() === 'escape') {
- // @ts-ignore
- document.getElementById(practice).blur();
- }
- // 其他情况
- return;
- }
- if (ev.key === 'i' && state.step === Step.MEMORY && !isPracticeFocus()) {
- ev.preventDefault();
- // @ts-ignore
- document.getElementById(practice).focus();
- }
- // 空格显示背面和默认选择
- if (ev.key === ' ' && state.step === Step.MEMORY) {
- ev.preventDefault(); // 关闭浏览器快捷键
- if (state.showBack === false) {
- setState({showBack: true});
- } else {
- memorySuccess(2);
- }
- } else if (ev.key === ' ' && state.step === Step.MAIN) {
- // 空格刷新
- // 如果待复习大于0,则直接进去
- if (state.remindCount > 0) {
- setState({step: Step.MEMORY});
- } else {
- // 刷新一下,再判断是否应该去复习
- countRemind();
- if (state.remindCount > 0) {
- setState({step: Step.MEMORY});
- }
- }
- } else if (ev.key.toLowerCase() === 'e') {
- // 快捷 E,进入编辑、新建页面
- setState({step: Step.ADD});
- } else if (ev.key.toLowerCase() === 'escape') {
- // esc键回到主页
- setState({step: Step.MAIN});
- }
- };
- };
- // 判断背面是否是空
- const isBackEmpty=()=>{
- return getTextFromHtml(memory.back).length === 0 && memory.back.indexOf('img') < 0;
- }
- useEffect(() => {
- countRemind();
- setTimeout(() => {
- countRemind();
- }, 1000 * 60 * 60); // 每隔一个小时查询一次
- bindShortKey();
- }, []);
- useEffect(() => {
- // 关闭背面,清空 memory
- setState({showBack: false});
- clearMemory();
- if (state.step === Step.MAIN) {
- // 进入统计页面
- countRemind();
- } else if (state.step === Step.MEMORY) {
- findNextLine();
- }
- }, [state.step]);
- useEffect(() => {
- // 判断是否为主页面刷新
- if (memory.front.length === 0) {
- return;
- }
- // 进入复习页面后
- // 如果没有文字,并且也没有图片
- if (isBackEmpty()) {
- setState({showBack: true});
- } else {
- setState({showBack: false});
- }
- // 隐藏更多按钮
- setShowMore(false);
- setBackPractice("")
- }, [memory.front]);
- return (
- <PageHeaderWrapper title={false}>
- {state.step === Step.MAIN ? (
- <div>
- <div>
- 待复习:<b>{state.remindCount}</b>
- </div>
- <p/>
- <Button
- type="primary"
- size="large"
- onClick={() => {
- if (state.remindCount <= 0) {
- message.info('已经复习完了哟!');
- return;
- }
- setState({step: Step.MEMORY});
- }}
- >
- 复习
- </Button>
- <p/>
- <Button type="primary" size="large" onClick={() => setState({step: Step.ADD})}>
- 添加
- </Button>
- </div>
- ) : null}
- {state.step === Step.MEMORY ? (
- <div>
- 正面:
- <p/>
- <Quill theme="bubble" readonly onChange={() => {
- }} value={memory.front}/>
- <p/>
- {state.showBack ? (
- <div>
- {
- !isBackEmpty() ? (
- <div>
- 反面:
- <p/>
- <Quill theme="bubble" readonly onChange={() => {
- }} value={memory.back}/>
- <p/>
- </div>
- ) : null}
- <div className={styles.divBottom}>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={() => {
- memorySuccess(0.5);
- }}
- >
- 生疏
- </Button>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={() => {
- memorySuccess(2);
- }}
- >
- <b> 一般 </b>
- </Button>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={() => {
- memorySuccess(3);
- }}
- >
- 简单
- </Button>
- <Button
- type="text"
- onClick={() => {
- setShowMore(!showMore);
- }}
- >
- <DownOutlined/>
- </Button>
- {showMore ? (
- <div>
- <div>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={async () => {
- setBtnDisable(true);
- memoryRes(await service.delay(memory));
- }}
- >
- 搁置
- </Button>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={async () => {
- setBtnDisable(true);
- memoryRes(await service.restart(memory));
- }}
- >
- 重新复习
- </Button>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={async () => {
- confirm({
- title: '确定删除吗?',
- icon: <ExclamationCircleOutlined/>,
- content: '删除后无法恢复',
- okText: '确定',
- okType: 'danger',
- cancelText: '取消',
- async onOk() {
- setBtnDisable(true);
- memoryRes(await service.delete(memory));
- },
- onCancel() {
- console.log('Cancel');
- },
- });
- }}
- >
- 删除
- </Button>
- <Button
- type="primary"
- disabled={btnDisable}
- onClick={async () => {
- setBtnDisable(true);
- memoryRes(await service.noMemory(memory));
- }}
- >
- 不再复习
- </Button>
- </div>
- <div>
- <Button
- type="primary"
- onClick={() => {
- setState({step: Step.ADD});
- }}
- >
- 编辑
- </Button>
- <Button
- type="primary"
- onClick={() => {
- setState({step: Step.MAIN});
- }}
- >
- 关闭
- </Button>
- </div>
- </div>
- ) : null}
- </div>
- </div>
- ) : (
- <div>
- <Button
- type="primary"
- onClick={() => {
- setState({showBack: true});
- }}
- >
- 显示反面
- </Button>
- </div>
- )}
- {/* 答案演练板 */}
- <br/>
- <TextArea
- id={practice}
- autoSize
- value={backPractice}
- onChange={(e) => setBackPractice(e.target.value)}
- placeholder="答案演练板"
- />
- </div>
- ) : null}
- {state.step === Step.ADD ? (
- <UpdateForm
- onCancel={() => {
- bindShortKey();
- setState({step: Step.MAIN});
- }}
- modalVisible={state.step === Step.ADD}
- values={memory}
- />
- ) : null}
- </PageHeaderWrapper>
- );
- };
- export default TableList;
|