|
@@ -9,13 +9,22 @@ import {
|
|
|
Switch,
|
|
|
message,
|
|
|
} from "antd";
|
|
|
+import { FC, useEffect, useRef, useState } from "react";
|
|
|
// @ts-ignore
|
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
-import { FC, useEffect, useRef, useState } from "react";
|
|
|
+
|
|
|
+export type AnswerType = {
|
|
|
+ answer: {
|
|
|
+ key: string;
|
|
|
+ val: number;
|
|
|
+ name?: string;
|
|
|
+ _save?: boolean;
|
|
|
+ }[];
|
|
|
+};
|
|
|
|
|
|
export type QuestionType = {
|
|
|
id: number;
|
|
|
- answer: string;
|
|
|
+ answer: AnswerType | string;
|
|
|
hasDiy: boolean;
|
|
|
question: string;
|
|
|
type: number;
|
|
@@ -31,6 +40,8 @@ export interface TopicDrawerProps {
|
|
|
edit: (params: QuestionType) => void;
|
|
|
}
|
|
|
|
|
|
+let id = 1;
|
|
|
+
|
|
|
export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
item,
|
|
|
open,
|
|
@@ -42,43 +53,57 @@ export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
const optionsFormRef = useRef<FormInstance>(null);
|
|
|
const basicFormRef = useRef<FormInstance>(null);
|
|
|
|
|
|
- const [options, setOptions] = useState<
|
|
|
- {
|
|
|
- val: string;
|
|
|
- name?: string;
|
|
|
- }[]
|
|
|
- >([]);
|
|
|
+ const [options, setOptions] = useState<AnswerType["answer"]>([]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
- if (item) {
|
|
|
+ if (item && open) {
|
|
|
const { answer, ...rest } = item;
|
|
|
+ const a = (
|
|
|
+ typeof answer !== "string" ? answer : JSON.parse(answer as string)
|
|
|
+ ).answer.map((i: (typeof options)[0]) => ({
|
|
|
+ ...i,
|
|
|
+ val: Number(i.val),
|
|
|
+ }));
|
|
|
basicFormRef.current?.setFieldsValue(rest);
|
|
|
|
|
|
- setOptions(JSON.parse(answer).answer);
|
|
|
- } else {
|
|
|
- handleReset();
|
|
|
+ setOptions(a);
|
|
|
+ id = a[a.length - 1].val + 1;
|
|
|
}
|
|
|
- }, [item]);
|
|
|
+ }, [item, open]);
|
|
|
|
|
|
const handleAddOption = () => {
|
|
|
setOptions((prev) => [
|
|
|
...prev,
|
|
|
{
|
|
|
- val: uuidv4(),
|
|
|
+ val: id++,
|
|
|
+ key: uuidv4(),
|
|
|
},
|
|
|
]);
|
|
|
};
|
|
|
|
|
|
const handleRemoveOption = (idx: number) => {
|
|
|
+ id -= 1;
|
|
|
setOptions((prev) => {
|
|
|
- prev.splice(idx, 1);
|
|
|
- return [...prev];
|
|
|
+ const newList = [...prev];
|
|
|
+ newList.splice(idx, 1);
|
|
|
+ // 如果是新增的选项,被删除目标后面的选项id需要减一
|
|
|
+ // 保持与 `选项${idx + 1}` 一致
|
|
|
+ return newList.map((i, index) => ({
|
|
|
+ ...i,
|
|
|
+ val: !i._save && index >= idx ? i.val - 1 : i.val,
|
|
|
+ }));
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
+ console.log(options);
|
|
|
+ }, [options]);
|
|
|
+
|
|
|
const handleReset = () => {
|
|
|
- setOptions([]);
|
|
|
+ id = 1;
|
|
|
+ optionsFormRef.current?.resetFields();
|
|
|
basicFormRef.current?.resetFields();
|
|
|
+ setOptions([]);
|
|
|
};
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
@@ -91,12 +116,14 @@ export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
const vals = optionsFormRef.current?.getFieldsValue();
|
|
|
const params: QuestionType = {
|
|
|
...basicFormRef.current?.getFieldsValue(),
|
|
|
- answer: JSON.stringify({
|
|
|
- answer: Object.keys(vals).map((val) => ({
|
|
|
- val,
|
|
|
- name: vals[val],
|
|
|
+ answer: {
|
|
|
+ answer: Object.keys(vals).map((key, index) => ({
|
|
|
+ val: options[index].val,
|
|
|
+ name: vals[key],
|
|
|
+ key: key,
|
|
|
+ _save: options[index]._save,
|
|
|
})),
|
|
|
- }),
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
if (!item) {
|
|
@@ -114,21 +141,26 @@ export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- close();
|
|
|
+ handleClose();
|
|
|
+ };
|
|
|
|
|
|
+ const handleClose = () => {
|
|
|
handleReset();
|
|
|
+ close();
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
<Drawer
|
|
|
+ destroyOnClose
|
|
|
title={item ? "编辑题目" : "新增题目"}
|
|
|
placement="right"
|
|
|
width={500}
|
|
|
open={open}
|
|
|
- onClose={close}
|
|
|
+ maskClosable={false}
|
|
|
+ onClose={handleClose}
|
|
|
extra={
|
|
|
<Space>
|
|
|
- <Button onClick={close}>取消</Button>
|
|
|
+ <Button onClick={handleClose}>取消</Button>
|
|
|
<Button loading={loading} type="primary" onClick={handleSubmit}>
|
|
|
保存
|
|
|
</Button>
|
|
@@ -177,7 +209,7 @@ export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
|
|
|
{options.map((i, idx) => (
|
|
|
<div
|
|
|
- key={i.val}
|
|
|
+ key={i.key}
|
|
|
style={{
|
|
|
display: "flex",
|
|
|
alignItems: "center",
|
|
@@ -185,7 +217,7 @@ export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
>
|
|
|
<Form.Item
|
|
|
label={`选项${idx + 1}`}
|
|
|
- name={i.val}
|
|
|
+ name={i.key}
|
|
|
initialValue={i.name}
|
|
|
rules={[{ required: true, message: "请输入" }]}
|
|
|
style={{ flex: 1 }}
|
|
@@ -197,15 +229,17 @@ export const TopicDrawer: FC<TopicDrawerProps> = ({
|
|
|
/>
|
|
|
</Form.Item>
|
|
|
|
|
|
- <Button
|
|
|
- type="text"
|
|
|
- danger
|
|
|
- size="small"
|
|
|
- style={{ marginBottom: 24 }}
|
|
|
- onClick={handleRemoveOption.bind(undefined, idx)}
|
|
|
- >
|
|
|
- 删除
|
|
|
- </Button>
|
|
|
+ {!i?._save && (
|
|
|
+ <Button
|
|
|
+ type="text"
|
|
|
+ danger
|
|
|
+ size="small"
|
|
|
+ style={{ marginBottom: 24 }}
|
|
|
+ onClick={handleRemoveOption.bind(undefined, idx)}
|
|
|
+ >
|
|
|
+ 删除
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
</div>
|
|
|
))}
|
|
|
</Form>
|