|
@@ -0,0 +1,735 @@
|
|
|
+import React, { forwardRef, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
|
|
+import BaseTmp from '@/components/BaseTmp';
|
|
|
+import { Row, Col, Radio, RadioChangeEvent , Select, Input, Button, message } from 'antd'
|
|
|
+import classNames from 'classnames';
|
|
|
+import type { Position } from 'react-rnd';
|
|
|
+import { Rnd } from 'react-rnd'
|
|
|
+import styles from './style/index.less'
|
|
|
+import logo from '@/static/common/logo.png'
|
|
|
+import { useStatePrevious } from '@/hooks'
|
|
|
+import RightClick from '@/components/RightClick'
|
|
|
+import UploadImg from '@/components/UploadImage/index'
|
|
|
+import api from '@/services/api'
|
|
|
+import { history, useLocation, useParams, useRouteMatch } from 'umi';
|
|
|
+
|
|
|
+const { getQuestionBank, getQuestionBook, addQuestionCard, getQuestionCardByid, putQuestionCard } = api.question
|
|
|
+
|
|
|
+type TMerge = IQPData & IQData & IIData & {
|
|
|
+ color: string,
|
|
|
+ imgUrl: string,
|
|
|
+}
|
|
|
+
|
|
|
+interface IQPData {
|
|
|
+ pw: number,
|
|
|
+ ph: number,
|
|
|
+ px: number,
|
|
|
+ py: number
|
|
|
+}
|
|
|
+
|
|
|
+interface IQData {
|
|
|
+ w: number,
|
|
|
+ h: number,
|
|
|
+ x: number,
|
|
|
+ y: number
|
|
|
+}
|
|
|
+
|
|
|
+/** 命名和小程序对应 */
|
|
|
+interface IIData {
|
|
|
+ iw: number,
|
|
|
+ ih: number,
|
|
|
+ ix: number,
|
|
|
+ iy: number
|
|
|
+}
|
|
|
+
|
|
|
+type TType = 'parent' | 'children' | 'button'
|
|
|
+
|
|
|
+/** 红 绿 黄 蓝 */
|
|
|
+const colorList = [
|
|
|
+ {color: '#FA0F0C', label: '红色'},
|
|
|
+ {color: '#396C28', label: '绿色'},
|
|
|
+ {color: '#F7DF1E', label: '黄色'},
|
|
|
+ {color: '#23398C', label: '蓝色'},
|
|
|
+ {color: '', label: ''}
|
|
|
+]
|
|
|
+
|
|
|
+const QPData = { pw: 100, ph: 100, px: 100, py: 100}
|
|
|
+const QData = { w: 80, h: 80, x: 0, y: 0}
|
|
|
+const QIData = { iw: 40, ih: 40, ix: 0, iy: 0 }
|
|
|
+
|
|
|
+const permutationKey = ( type: TType ) => {
|
|
|
+
|
|
|
+ if ( type === 'parent' ) return ['pw', 'ph', 'px', 'py']
|
|
|
+ else if ( type === "children" ) return ['w', 'h', 'x', 'y']
|
|
|
+ else return ['iw', 'ih', 'ix', 'iy']
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+interface IQuestionCard {
|
|
|
+ content: TMerge[],
|
|
|
+ onResizeStop: (
|
|
|
+ type: TType,
|
|
|
+ index: number,
|
|
|
+ {w, h, pos}: {w: string, h: string, pos: Position}
|
|
|
+ ) => void,
|
|
|
+ resizeChildrenRnd: (index: number) => void
|
|
|
+ label: string,
|
|
|
+ onInput: (e: InputEvent) => void,
|
|
|
+ deleteImg: ( _imgUrl: string ) => void,
|
|
|
+ onDragStop: (type: TType, index: number, {x, y}: {x: number, y: number}) => void
|
|
|
+ saveImageUrl: (imgUrl: string, index: number) => void
|
|
|
+}
|
|
|
+
|
|
|
+const QuestionCard: React.FC<IQuestionCard> = ({
|
|
|
+ content,
|
|
|
+ onResizeStop,
|
|
|
+ label,
|
|
|
+ deleteImg,
|
|
|
+ onInput,
|
|
|
+ saveImageUrl,
|
|
|
+ onDragStop
|
|
|
+}) => {
|
|
|
+
|
|
|
+ const [ menuState, setMenuState ] = useState<boolean>(false)
|
|
|
+
|
|
|
+ const bordeLiene = classNames(styles['border-line'], styles['question-card-timing'])
|
|
|
+
|
|
|
+ const questionId = 'questionId'
|
|
|
+
|
|
|
+ console.log("content:", content);
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description 鼠标右键事件
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+ const pictureRightClick = ( e: React.MouseEvent ) => {
|
|
|
+ e.preventDefault()
|
|
|
+ if (e.button === 2) {
|
|
|
+ setMenuState(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const RenderButton = ({color}: {color: string}) => {
|
|
|
+ return <div className={styles['render-button']} style={{backgroundColor: color}} ></div>
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.question} >
|
|
|
+ <RightClick render={menuState} deleteImg={(_imgUrl) => deleteImg(_imgUrl)} />
|
|
|
+ <div className={styles['question-card-iphonex']} >
|
|
|
+ <img src={require('@/static/common/iPhoneX-top.png')} alt="" />
|
|
|
+ </div>
|
|
|
+ <Row className={bordeLiene} justify='center' align='middle' >
|
|
|
+ <Col span={24} >计时区</Col>
|
|
|
+ </Row>
|
|
|
+ <Row className={styles.stem} justify='center' align='middle' >
|
|
|
+ <Col span={24} >
|
|
|
+ <Input.TextArea
|
|
|
+ style={{height: '90px'}}
|
|
|
+ placeholder="请输入题卡描述"
|
|
|
+ maxLength={6}
|
|
|
+ value={label}
|
|
|
+ onInput={onInput}
|
|
|
+ />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ <Row className={styles['opration-area']} justify='start' >
|
|
|
+ <Col className='opration-left' span={16} style={{height: `438px`}}>
|
|
|
+ {
|
|
|
+ content?.map( (item, index) => (
|
|
|
+ <Rnd
|
|
|
+ key={index}
|
|
|
+ minHeight={80}
|
|
|
+ minWidth={80}
|
|
|
+ bounds='parent'
|
|
|
+ className='parent-rnd'
|
|
|
+ style={{ border: `1px solid ${item.color}`}}
|
|
|
+ size={{ width: item.pw, height: item.ph }}
|
|
|
+ position={{ x: item.px, y: item.py }}
|
|
|
+ onDragStop={(e, d) => { onDragStop('parent', index, { x: d.x, y: d.y }) }}
|
|
|
+ onResizeStop={(e, direction, ref, delta, position) => {
|
|
|
+ onResizeStop('parent', index, {
|
|
|
+ w: ref.style.width,
|
|
|
+ h: ref.style.height,
|
|
|
+ pos: position,
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Rnd
|
|
|
+ bounds='parent'
|
|
|
+ onMouseDown={e => e.stopPropagation()}
|
|
|
+ style={{ border: `1px dashed ${item.color}`}}
|
|
|
+ size={{ width: item.w, height: item.h }}
|
|
|
+ position={{ x: item.x, y: item.y }}
|
|
|
+ onDragStop={(e, d) => { onDragStop( 'children', index, { x: d.x, y: d.y }) }}
|
|
|
+ onResizeStop={(e, direction, ref, delta, position) => {
|
|
|
+ onResizeStop( 'children', index, {
|
|
|
+ w: ref.style.width,
|
|
|
+ h: ref.style.height,
|
|
|
+ pos: position,
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {
|
|
|
+ item.imgUrl ?
|
|
|
+ <img
|
|
|
+ src={item.imgUrl}
|
|
|
+ id={questionId}
|
|
|
+ style={{width: item.w + 'px', height: item.h + 'px', boxSizing: 'border-box'}}
|
|
|
+ onMouseDown={ (e: React.MouseEvent) => pictureRightClick(e) }
|
|
|
+ />
|
|
|
+ :
|
|
|
+ <UploadImg
|
|
|
+ imageUrl={item.imgUrl}
|
|
|
+ saveImageUrl={ (imgUrl) => saveImageUrl(imgUrl, index)}
|
|
|
+ uploadCount={1}
|
|
|
+ />
|
|
|
+ }
|
|
|
+ </Rnd>
|
|
|
+ <Rnd
|
|
|
+ bounds='parent'
|
|
|
+ onMouseDown={e => e.stopPropagation()}
|
|
|
+ size={{ width: item.iw, height: item.ih }}
|
|
|
+ position={{ x: item.ix, y: item.iy }}
|
|
|
+ onDragStop={(e, d) => { onDragStop( 'button', index, { x: d.x, y: d.y }) }}
|
|
|
+ >
|
|
|
+ <RenderButton color={colorList[index].color} />
|
|
|
+ </Rnd>
|
|
|
+ </Rnd>
|
|
|
+ ))
|
|
|
+ }
|
|
|
+ </Col>
|
|
|
+ <Col span={8} className={styles['answer-area']} > 答案区域 </Col>
|
|
|
+ </Row>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+interface IAnswer {
|
|
|
+ color: string,
|
|
|
+ imgUrl: string
|
|
|
+}
|
|
|
+
|
|
|
+interface IAnswerCard {
|
|
|
+ onChangeAnswer: (e: RadioChangeEvent, index: number) => void,
|
|
|
+ saveImageAnswerUrl: (imgUrl: string, index: number) => void,
|
|
|
+ answerList: IAnswer[]
|
|
|
+}
|
|
|
+
|
|
|
+const AnswerCard: React.FC<IAnswerCard> = ({
|
|
|
+ onChangeAnswer,
|
|
|
+ saveImageAnswerUrl,
|
|
|
+ answerList
|
|
|
+}) => {
|
|
|
+
|
|
|
+ /**渲染颜色选择radio */
|
|
|
+ const RenderColorRadio = ({_color, index}: {_color: string, index: number}) => {
|
|
|
+ return (
|
|
|
+ <Radio.Group value={_color} >
|
|
|
+ {
|
|
|
+ colorList.map( (_color, i) => (
|
|
|
+ _color.color ?
|
|
|
+ <Radio value={_color.color} key={i} onChange={(e) => onChangeAnswer(e, index)}>
|
|
|
+ {_color.label}
|
|
|
+ </Radio>
|
|
|
+ :
|
|
|
+ <></>
|
|
|
+ )
|
|
|
+
|
|
|
+ )
|
|
|
+ }
|
|
|
+ </Radio.Group>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @description 答案选择render */
|
|
|
+ const RenderAnswer = () => {
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Row style={{width: '100%'}}>
|
|
|
+ {
|
|
|
+ answerList.map( (answer, index) => (
|
|
|
+ <Col span={24} key={index} >
|
|
|
+ <Row gutter={3} style={{width: '100%'}} align="middle" justify="space-around" >
|
|
|
+ <Col>选项1:</Col>
|
|
|
+ <Col>
|
|
|
+ <UploadImg
|
|
|
+ saveImageUrl={(imageUrl) => saveImageAnswerUrl(imageUrl, index) }
|
|
|
+ imageUrl={answer.imgUrl}
|
|
|
+ />
|
|
|
+ </Col>
|
|
|
+ <Col>对应答案</Col>
|
|
|
+ <Col>
|
|
|
+
|
|
|
+ <RenderColorRadio _color={answer.color} index={index} />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </Col>
|
|
|
+ ))
|
|
|
+ }
|
|
|
+ </Row>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Row className={styles['answer-card'] } >
|
|
|
+ <Col
|
|
|
+ span={24}
|
|
|
+ className={styles['ability-point']}
|
|
|
+ >
|
|
|
+
|
|
|
+ {/* 能力选择: */}
|
|
|
+ </Col>
|
|
|
+ <Col
|
|
|
+ span={24}
|
|
|
+ className={styles['answer-setting']}
|
|
|
+ style={{height: '232px', borderTop: '1px solid #000', paddingTop: '40px'}}
|
|
|
+ >
|
|
|
+ <RenderAnswer />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+interface ISelectTmp {
|
|
|
+ defaultValue: string
|
|
|
+ dataList: Record<string, any>[],
|
|
|
+ onChange: (value: string) => void
|
|
|
+}
|
|
|
+
|
|
|
+const SelectTmp: React.FC<ISelectTmp> = ({
|
|
|
+ dataList,
|
|
|
+ onChange,
|
|
|
+ defaultValue
|
|
|
+}) => {
|
|
|
+ console.log('defaultValue', defaultValue, dataList);
|
|
|
+
|
|
|
+ return <Select defaultValue={defaultValue} style={{ width: 120 }} onChange={onChange} >
|
|
|
+ {
|
|
|
+ dataList.map( data =>
|
|
|
+ <Select.Option value={data.id} key={data.id} >{data.label}</Select.Option>)
|
|
|
+ }
|
|
|
+ </Select>
|
|
|
+}
|
|
|
+
|
|
|
+const QuestionBankManage: React.FC = () => {
|
|
|
+
|
|
|
+ const [ bankList, setBankList ] = useState<{id: string, label: string}[]>([])
|
|
|
+
|
|
|
+ const [ bookList, setBookList ] = useState([])
|
|
|
+
|
|
|
+ const [ currentBank, setCurrentBank ] = useState({})
|
|
|
+
|
|
|
+ const [ currentBook, setCurrentBook ] = useState({})
|
|
|
+
|
|
|
+ const [ title, setTitle ] = useState<string>()
|
|
|
+
|
|
|
+ const [ content, setContent ] = useState<TMerge[]>([])
|
|
|
+
|
|
|
+ const [ previous, setPrevious ] = useStatePrevious<TMerge[]>()
|
|
|
+
|
|
|
+ const [ label, setLabel ] = useState<string>('')
|
|
|
+
|
|
|
+ /**当前操作的父盒子下标 */
|
|
|
+ const [ OIndex, setOIndex ] = useState<number>()
|
|
|
+
|
|
|
+ const [ answerList, setAnswerList ] = useState<IAnswer[]>([
|
|
|
+ {color: '', imgUrl: ''},
|
|
|
+ {color: '', imgUrl: ''},
|
|
|
+ {color: '', imgUrl: ''},
|
|
|
+ {color: '', imgUrl: ''},
|
|
|
+ ])
|
|
|
+
|
|
|
+ /**能力点 */
|
|
|
+ const [ ability, setAbility ] = useState<string>('')
|
|
|
+
|
|
|
+ const location = useLocation()
|
|
|
+
|
|
|
+ const cardId = location.query.cardId
|
|
|
+
|
|
|
+ const submitButtonLabel = cardId ? '编辑题卡' : '新增题卡'
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+ _getQuestionBank()
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+ _getQuestionBook()
|
|
|
+ }, [currentBank])
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+
|
|
|
+
|
|
|
+ if (cardId) {
|
|
|
+ _getQuestionCardByid(cardId)
|
|
|
+ } else {
|
|
|
+ initContent()
|
|
|
+ }
|
|
|
+ }, [])
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ useEffect( () => {
|
|
|
+
|
|
|
+ typeof OIndex === 'number' && resizeChildrenRnd(OIndex!)
|
|
|
+
|
|
|
+ }, [previous])
|
|
|
+
|
|
|
+ /**保存结果答案 */
|
|
|
+ const saveImageAnswerUrl = (imgUrl: string, index: number) => {
|
|
|
+ const r = answerList.map( (answer, i) => {
|
|
|
+ return {
|
|
|
+ ...answer,
|
|
|
+ imgUrl: index === i ? imgUrl: answer.imgUrl
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setAnswerList(r)
|
|
|
+ }
|
|
|
+
|
|
|
+ /** */
|
|
|
+ const onChangeAnswer = (e: RadioChangeEvent, index: number) => {
|
|
|
+ const r = answerList.map( (answer, i) => {
|
|
|
+ return {
|
|
|
+ ...answer,
|
|
|
+ color: index === i ? e.target.value: answer.color
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setAnswerList(r)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**修改title */
|
|
|
+ const onInputTitle = (e: InputEvent) => setTitle(e.target.value)
|
|
|
+
|
|
|
+ /**修改title */
|
|
|
+ const onInputAbility = (e: InputEvent) => setAbility(e.target.value)
|
|
|
+
|
|
|
+ const onInput = (e: InputEvent) => setLabel(e.target.value)
|
|
|
+
|
|
|
+ /** 保存图片 */
|
|
|
+ const saveImageUrl = (imgUrl: string, index: number) => {
|
|
|
+ const r = content?.map( (item, i) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ imgUrl: index === i ? imgUrl : item.imgUrl
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ setContent(r)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onDragStop = (
|
|
|
+ type: TType,
|
|
|
+ index: number,
|
|
|
+ {x, y}: {x: number, y: number}
|
|
|
+ ) => {
|
|
|
+
|
|
|
+ const [ _w, _h , _x, _y ] = permutationKey(type)
|
|
|
+
|
|
|
+ const r = content?.map( (item, i) => {
|
|
|
+ const target = i === index
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ [_x]: target? x : item[_x],
|
|
|
+ [_y]: target? y : item[_y]
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ setContent(r)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const deleteImg = (_imgUrl: string) => {
|
|
|
+ const r = content?.map( (item, index) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ imgUrl: _imgUrl === item.imgUrl ? '' : item.imgUrl
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setContent(r)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description 初始化init数据
|
|
|
+ */
|
|
|
+
|
|
|
+ const initContent = () => {
|
|
|
+ let mergeList: TMerge[] = []
|
|
|
+ Array.from(new Array(4)).forEach( (count, index) => {
|
|
|
+ console.log('count:', index);
|
|
|
+ mergeList.push({
|
|
|
+ ...QPData,
|
|
|
+ ...QData,
|
|
|
+ ...QIData,
|
|
|
+ color: colorList[index].color,
|
|
|
+ imgUrl:
|
|
|
+ ''}
|
|
|
+ )
|
|
|
+ })
|
|
|
+ setContent(mergeList)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onChangeBank = (id: string) => {
|
|
|
+ const bank = bankList.find( bank => bank.id === id )
|
|
|
+ setCurrentBank({
|
|
|
+ ...bank,
|
|
|
+ id
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const onChangeBook = (id: string) => {
|
|
|
+ const book = bookList.find( book => book.id === id )
|
|
|
+ setCurrentBook({
|
|
|
+ ...book,
|
|
|
+ id
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description 当父盒子缩小 宽高小于子盒子时 按照缩放比例 缩小子盒子
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+ const resizeChildrenRnd = ( index: number) => {
|
|
|
+
|
|
|
+ const _previous: TMerge = previous![index]
|
|
|
+
|
|
|
+ const _contentItem = content![index]
|
|
|
+
|
|
|
+ let rate = 1
|
|
|
+
|
|
|
+ let _ix = 0
|
|
|
+ let _iy = 0
|
|
|
+
|
|
|
+ if ( _contentItem.pw < _contentItem.w ) {
|
|
|
+
|
|
|
+ rate = _contentItem.pw / _previous.pw
|
|
|
+
|
|
|
+ } else if ( _contentItem.ph < _contentItem.h ) {
|
|
|
+
|
|
|
+ rate = _contentItem.ph / _previous.ph
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( _contentItem.pw < (_contentItem.ix + _contentItem.iw)) {
|
|
|
+
|
|
|
+ _ix = _contentItem.pw - _contentItem.iw
|
|
|
+ } else if (_contentItem.ph < (_contentItem.iy + _contentItem.ih)) {
|
|
|
+
|
|
|
+ _iy = _contentItem.ph - _contentItem.ih
|
|
|
+ }
|
|
|
+
|
|
|
+ const r = content?.map( (item, i) => {
|
|
|
+ const target = i === index
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ w: target? item.w * rate: item.w,
|
|
|
+ h: target? item.h * rate: item.h,
|
|
|
+ x: target? item.x * rate: item.x,
|
|
|
+ y: target? item.y * rate: item.y,
|
|
|
+ ix: target && _ix !== 0 ? _ix : item.ix,
|
|
|
+ iy: target && _iy !== 0 ? _iy : item.iy,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ setContent(r)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**修改题卡大小 */
|
|
|
+ const onResizeStop = (
|
|
|
+ type: TType,
|
|
|
+ index: number,
|
|
|
+ {w, h, pos}: {w: string, h: string, pos: Position}
|
|
|
+ ) => {
|
|
|
+
|
|
|
+ const rw = Number(w.replace('px', ''))
|
|
|
+ const rh = Number(h.replace('px', ''))
|
|
|
+
|
|
|
+ const [ _w, _h , _x, _y ] = permutationKey(type)
|
|
|
+
|
|
|
+ const r = content?.map( (item, i) => {
|
|
|
+ const target = i === index
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ [_w]: target? rw : item[_w],
|
|
|
+ [_h]: target? rh : item[_h],
|
|
|
+ [_x]: target? pos.x : item[_x],
|
|
|
+ [_y]: target? pos.y : item[_y]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (type === 'parent') {
|
|
|
+ setPrevious(content!)
|
|
|
+ }
|
|
|
+ setContent(r)
|
|
|
+ setOIndex(index)
|
|
|
+ }
|
|
|
+
|
|
|
+ /***根据id获取卡片数据, 用于编辑 */
|
|
|
+ const _getQuestionCardByid = async (cardId: string) => {
|
|
|
+
|
|
|
+ const { status, result } = await getQuestionCardByid(cardId)
|
|
|
+
|
|
|
+ if ( status === 200 ) {
|
|
|
+
|
|
|
+ setContent(result.content)
|
|
|
+ setAnswerList(result.options)
|
|
|
+ setLabel(result.label)
|
|
|
+ setTitle(result.title)
|
|
|
+ setAbility(result.ableVar)
|
|
|
+
|
|
|
+ console.log('bankList:', bankList);
|
|
|
+
|
|
|
+ setCurrentBank({
|
|
|
+ label: result.bankLabel,
|
|
|
+ id: result.bankId
|
|
|
+ })
|
|
|
+
|
|
|
+ setCurrentBook({
|
|
|
+ label: result.bookLabel,
|
|
|
+ id: result.bookId
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** submit question card */
|
|
|
+ const submit = () => {
|
|
|
+
|
|
|
+ const _colorlist = answerList.map( answer => answer.color )
|
|
|
+
|
|
|
+ if (!label.length) {
|
|
|
+ message.error("请填写卡片描述")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_colorlist.includes('')) {
|
|
|
+ message.error("存在未选择的答案")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let hasSameColor = false
|
|
|
+ _colorlist.forEach( (_color, index) => {
|
|
|
+ const r = _colorlist.lastIndexOf(_color)
|
|
|
+ if ( r !== -1 && r !== index ) {
|
|
|
+ hasSameColor = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (hasSameColor) {
|
|
|
+ message.error("存在一样的答案")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const $par = {
|
|
|
+ content,
|
|
|
+ options: answerList,
|
|
|
+ label,
|
|
|
+ title,
|
|
|
+ bookId: currentBook.id,
|
|
|
+ ableVar: ability,
|
|
|
+ id: cardId ? cardId : ''
|
|
|
+ }
|
|
|
+
|
|
|
+ _addQuestionCard($par)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**增加题卡 */
|
|
|
+ const _addQuestionCard = async ($par: any) => {
|
|
|
+ let $r = null
|
|
|
+ if (cardId) {
|
|
|
+ $r = await putQuestionCard(1, $par)
|
|
|
+ } else {
|
|
|
+ $r = await addQuestionCard(1, $par)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if ( $r.status === 200 ) {
|
|
|
+ message.success( cardId ? "编辑成功" : "增加成功" )
|
|
|
+ history.goBack()
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**获取教材 */
|
|
|
+ const _getQuestionBook = async () => {
|
|
|
+ const { status, result } = await getQuestionBook({bankId: currentBank.id})
|
|
|
+ if ( status === 200 ) {
|
|
|
+ setBookList(result)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**获取学段 */
|
|
|
+ const _getQuestionBank = async () => {
|
|
|
+ const { status, result } = await getQuestionBank()
|
|
|
+ if ( status === 200 ) {
|
|
|
+ setBankList(result)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <BaseTmp>
|
|
|
+ <Row style={{marginTop: '20px'}} >
|
|
|
+ <Col> 卡片名称: </Col>
|
|
|
+ <Col> <Input onInput={onInputTitle} value={title} /> </Col>
|
|
|
+ </Row>
|
|
|
+ <Row style={{marginTop: '20px'}} >
|
|
|
+ <Col> 学段: </Col>
|
|
|
+ <Col>
|
|
|
+ <SelectTmp key={currentBank.id} defaultValue={currentBank.id} dataList={bankList} onChange={onChangeBank} />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ <Row style={{marginTop: '20px'}} >
|
|
|
+ <Col> 教材: </Col>
|
|
|
+ <Col>
|
|
|
+ <SelectTmp
|
|
|
+ key={currentBook.id}
|
|
|
+ defaultValue={currentBook.id}
|
|
|
+ dataList={bookList}
|
|
|
+ onChange={onChangeBook}
|
|
|
+ />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ <Row style={{marginTop: '20px'}} >
|
|
|
+ <Col> 能力点: </Col>
|
|
|
+ <Col> <Input onInput={onInputAbility} value={ability} /> </Col>
|
|
|
+ </Row>
|
|
|
+ <Row
|
|
|
+ className={styles['question-bank-manage']}
|
|
|
+ style={{marginTop: '20px'}}
|
|
|
+ >
|
|
|
+ <Col>题卡:</Col>
|
|
|
+ <Col span={7.5} >
|
|
|
+ <QuestionCard
|
|
|
+ label={label}
|
|
|
+ content={content}
|
|
|
+ onDragStop={onDragStop}
|
|
|
+ resizeChildrenRnd={resizeChildrenRnd}
|
|
|
+ onResizeStop={onResizeStop}
|
|
|
+ onInput={onInput}
|
|
|
+ deleteImg={deleteImg}
|
|
|
+ saveImageUrl={saveImageUrl}
|
|
|
+ />
|
|
|
+ </Col>
|
|
|
+ <Col span={13.5}>
|
|
|
+ <AnswerCard
|
|
|
+ answerList={answerList}
|
|
|
+ saveImageAnswerUrl={saveImageAnswerUrl}
|
|
|
+ onChangeAnswer={onChangeAnswer}
|
|
|
+ />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ <Row justify="center" style={{marginTop: "20px"}} >
|
|
|
+ <Col><Button type="primary" onClick={submit} >
|
|
|
+ {submitButtonLabel}
|
|
|
+ </Button></Col>
|
|
|
+ </Row>
|
|
|
+ </BaseTmp>
|
|
|
+ )
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+export default QuestionBankManage
|
|
|
+
|
|
|
+
|