Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xiaomai-cloud-class-web
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xiaomai-cloud-class
xiaomai-cloud-class-web
Commits
96b7a4c4
Commit
96b7a4c4
authored
Mar 15, 2021
by
yuananting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:题目模块联调
parent
69411c9a
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1437 additions
and
352 deletions
+1437
-352
src/data-source/questionBank/request-apis.ts
+10
-1
src/domains/question-bank-domain/QuestionBankService.ts
+13
-2
src/modules/teach-tool/AddNewQuestion.jsx
+104
-32
src/modules/teach-tool/QuestionBankIndex.jsx
+12
-7
src/modules/teach-tool/QuestionCategoryManage.jsx
+30
-14
src/modules/teach-tool/components/NewQuestionTab.jsx
+476
-230
src/modules/teach-tool/components/NewQuestionTab.less
+83
-0
src/modules/teach-tool/components/QuestionBankSider.jsx
+14
-5
src/modules/teach-tool/components/QuestionEditor.jsx
+13
-23
src/modules/teach-tool/components/QuestionManageContent.jsx
+129
-26
src/modules/teach-tool/components/QuestionManageContent.less
+4
-6
src/modules/teach-tool/components/model.js
+2
-2
src/modules/teach-tool/modal/NewEditQuestionBankCategory.jsx
+3
-4
src/modules/teach-tool/modal/QuestionPreviewModal.jsx
+347
-0
src/modules/teach-tool/modal/QuestionPreviewModal.less
+197
-0
No files found.
src/data-source/questionBank/request-apis.ts
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-03-03 15:13:12
* @Date: 2021-03-03 15:13:12
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 20:46:54
* @LastEditTime: 2021-03-1
5 19:44:31
* @Description: 助学工具接口
* @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -43,4 +43,12 @@ export function addQuestion(params: object) {
...
@@ -43,4 +43,12 @@ export function addQuestion(params: object) {
export
function
deleteQuestion
(
params
:
object
)
{
export
function
deleteQuestion
(
params
:
object
)
{
return
Service
.
Hades
(
"anon/hades/question/deleteQuestion"
,
params
);
return
Service
.
Hades
(
"anon/hades/question/deleteQuestion"
,
params
);
}
export
function
queryQuestionDetails
(
params
:
object
)
{
return
Service
.
Hades
(
"anon/hades/question/queryQuestionDetails"
,
params
);
}
export
function
editQuestion
(
params
:
object
)
{
return
Service
.
Hades
(
"anon/hades/question/editQuestion"
,
params
);
}
}
\ No newline at end of file
src/domains/question-bank-domain/QuestionBankService.ts
View file @
96b7a4c4
...
@@ -2,11 +2,11 @@
...
@@ -2,11 +2,11 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-03-11 11:34:37
* @Date: 2021-03-11 11:34:37
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 20:46:28
* @LastEditTime: 2021-03-1
5 19:45:10
* @Description: 描述一下咯
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
import
{
queryCategoryTree
,
addCategory
,
delCategory
,
editCategory
,
editCategoryTree
,
queryQuestionCategoryTree
,
addQuestion
,
queryQuestionPageList
,
deleteQuestion
}
from
'@/data-source/questionBank/request-apis'
;
import
{
queryCategoryTree
,
addCategory
,
delCategory
,
editCategory
,
editCategoryTree
,
queryQuestionCategoryTree
,
addQuestion
,
queryQuestionPageList
,
deleteQuestion
,
queryQuestionDetails
,
editQuestion
}
from
'@/data-source/questionBank/request-apis'
;
export
default
class
QuestionBankService
{
export
default
class
QuestionBankService
{
// 获取题目分类树
// 获取题目分类树
static
queryCategoryTree
(
params
:
any
)
{
static
queryCategoryTree
(
params
:
any
)
{
...
@@ -52,4 +52,14 @@ export default class QuestionBankService {
...
@@ -52,4 +52,14 @@ export default class QuestionBankService {
static
deleteQuestion
(
params
:
any
)
{
static
deleteQuestion
(
params
:
any
)
{
return
deleteQuestion
(
params
);
return
deleteQuestion
(
params
);
}
}
// 预览题目
static
queryQuestionDetails
(
params
:
any
)
{
return
queryQuestionDetails
(
params
);
}
// 编辑题目
static
editQuestion
(
params
:
any
)
{
return
editQuestion
(
params
);
}
}
}
\ No newline at end of file
src/modules/teach-tool/AddNewQuestion.jsx
View file @
96b7a4c4
...
@@ -2,12 +2,12 @@
...
@@ -2,12 +2,12 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-25 13:46:35
* @Date: 2021-02-25 13:46:35
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 20:12:14
* @LastEditTime: 2021-03-1
5 21:14:47
* @Description: 助学工具-题库-题目管理-新增题目
* @Description: 助学工具-题库-题目管理-新增题目
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
import
React
,
{
Component
}
from
"react"
;
import
React
,
{
Component
}
from
"react"
;
import
{
Tabs
,
Button
,
Tooltip
}
from
"antd"
;
import
{
Tabs
,
Button
,
Tooltip
,
message
}
from
"antd"
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
"./AddNewQuestion.less"
;
import
"./AddNewQuestion.less"
;
...
@@ -21,7 +21,7 @@ class AddNewQuestion extends Component {
...
@@ -21,7 +21,7 @@ class AddNewQuestion extends Component {
constructor
(
props
)
{
constructor
(
props
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
activeKey
:
"SINGLE_CHOICE"
,
activeKey
:
getParameterByName
(
"type"
)
||
"SINGLE_CHOICE"
,
// 构建题目基本结构
// 构建题目基本结构
singleChoiceContent
:
defineQuestionInfo
(
"SINGLE_CHOICE"
),
// 单选题
singleChoiceContent
:
defineQuestionInfo
(
"SINGLE_CHOICE"
),
// 单选题
multiChoiceContent
:
defineQuestionInfo
(
"MULTI_CHOICE"
),
// 多选题
multiChoiceContent
:
defineQuestionInfo
(
"MULTI_CHOICE"
),
// 多选题
...
@@ -31,34 +31,97 @@ class AddNewQuestion extends Component {
...
@@ -31,34 +31,97 @@ class AddNewQuestion extends Component {
};
};
}
}
componentDidMount
()
{}
componentDidMount
()
{
if
(
getParameterByName
(
"id"
))
{
// 编辑
this
.
queryQuestionDetails
();
}
}
queryQuestionDetails
=
()
=>
{
let
query
=
{
id
:
getParameterByName
(
"id"
),
source
:
0
,
userId
:
User
.
getStoreUserId
(),
tenantId
:
User
.
getStoreId
(),
};
QuestionBankService
.
queryQuestionDetails
(
query
).
then
((
res
)
=>
{
const
{
result
=
[]
}
=
res
;
const
{
questionTypeEnum
}
=
result
;
switch
(
questionTypeEnum
)
{
case
"SINGLE_CHOICE"
:
this
.
setState
({
singleChoiceContent
:
result
});
break
;
case
"MULTI_CHOICE"
:
this
.
setState
({
multiChoiceContent
:
result
});
break
;
case
"JUDGE"
:
this
.
setState
({
judgeContent
:
result
});
break
;
case
"GAP_FILLING"
:
this
.
setState
({
gapFillingContent
:
result
});
break
;
case
"INDEFINITE_CHOICE"
:
this
.
setState
({
indefiniteChoiceContent
:
result
});
break
;
}
});
};
saveCurrentQuestion
=
(
content
)
=>
{
saveCurrentQuestion
=
(
content
)
=>
{
content
.
questionStemList
.
map
((
item
,
index
)
=>
{
content
.
questionStemList
.
map
((
item
,
index
)
=>
{
item
.
sort
=
index
;
item
.
sort
=
index
;
return
item
;
return
item
;
})
})
;
content
.
optionList
.
map
((
item
)
=>
{
content
.
optionList
.
map
((
item
)
=>
{
item
.
questionOptionContentList
.
map
((
childItem
,
childIndex
)
=>
{
item
.
questionOptionContentList
.
map
((
childItem
,
childIndex
)
=>
{
childItem
.
sort
=
childIndex
;
childItem
.
sort
=
childIndex
;
return
childItem
;
return
childItem
;
})
})
;
return
item
;
return
item
;
})
})
;
content
.
questionAnswerDescList
.
map
((
item
,
index
)
=>
{
content
.
questionAnswerDescList
.
map
((
item
,
index
)
=>
{
item
.
sort
=
index
;
item
.
sort
=
index
;
return
item
;
return
item
;
})
let
params
=
{
...
content
,
categoryId
:
getParameterByName
(
"categoryId"
),
source
:
0
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
};
QuestionBankService
.
addQuestion
(
params
).
then
((
res
)
=>
{
console
.
log
(
res
);
});
});
let
params
=
{};
let
categoryId
=
getParameterByName
(
"categoryId"
);
if
(
getParameterByName
(
"id"
))
{
params
=
{
...
content
,
id
:
getParameterByName
(
"id"
),
categoryId
:
categoryId
||
null
,
source
:
0
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
};
QuestionBankService
.
editQuestion
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
"保存成功"
);
window
.
RCHistory
.
push
({
pathname
:
`/question-bank-index?categoryId=
${
params
.
categoryId
}
`
,
});
}
});
}
else
{
params
=
{
...
content
,
categoryId
:
getParameterByName
(
"categoryId"
),
source
:
0
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
};
QuestionBankService
.
addQuestion
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
"保存成功"
);
window
.
RCHistory
.
push
({
pathname
:
`/question-bank-index?categoryId=
${
params
.
categoryId
}
`
,
});
}
});
}
};
};
confirmSaveQuestion
=
()
=>
{
confirmSaveQuestion
=
()
=>
{
...
@@ -71,12 +134,14 @@ class AddNewQuestion extends Component {
...
@@ -71,12 +134,14 @@ class AddNewQuestion extends Component {
}
=
this
.
state
;
}
=
this
.
state
;
switch
(
this
.
state
.
activeKey
)
{
switch
(
this
.
state
.
activeKey
)
{
case
"SINGLE_CHOICE"
:
case
"SINGLE_CHOICE"
:
if
(
this
.
singleRef
.
checkInput
()
===
0
)
{
if
(
this
.
single
Choice
Ref
.
checkInput
()
===
0
)
{
this
.
saveCurrentQuestion
(
singleChoiceContent
);
this
.
saveCurrentQuestion
(
singleChoiceContent
);
}
}
break
;
break
;
case
"MULTI_CHOICE"
:
case
"MULTI_CHOICE"
:
this
.
multipleRef
.
checkInput
();
if
(
this
.
multiChoiceRef
.
checkInput
()
===
0
)
{
this
.
saveCurrentQuestion
(
multiChoiceContent
);
}
break
;
break
;
case
"JUDGE"
:
case
"JUDGE"
:
this
.
judgeRef
.
checkInput
();
this
.
judgeRef
.
checkInput
();
...
@@ -85,19 +150,21 @@ class AddNewQuestion extends Component {
...
@@ -85,19 +150,21 @@ class AddNewQuestion extends Component {
this
.
CompletionRef
.
checkInput
();
this
.
CompletionRef
.
checkInput
();
break
;
break
;
case
"INDEFINITE_CHOICE"
:
case
"INDEFINITE_CHOICE"
:
this
.
indefiniteRef
.
checkInput
();
if
(
this
.
indefiniteRef
.
checkInput
()
===
0
)
{
this
.
saveCurrentQuestion
(
indefiniteChoiceContent
);
}
break
;
break
;
}
}
};
};
handleLogger
=
(
en
,
cn
)
=>
{
const
{
onLogger
}
=
this
.
props
;
onLogger
&&
onLogger
(
en
,
cn
);
};
render
()
{
render
()
{
const
{
const
{
activeKey
,
activeKey
,
singleContent
,
multipleContent
,
judgeContent1
,
completionContent
,
indefiniteContent
,
singleChoiceContent
,
singleChoiceContent
,
multiChoiceContent
,
multiChoiceContent
,
judgeContent
,
judgeContent
,
...
@@ -106,7 +173,10 @@ class AddNewQuestion extends Component {
...
@@ -106,7 +173,10 @@ class AddNewQuestion extends Component {
}
=
this
.
state
;
}
=
this
.
state
;
return
(
return
(
<
div
className=
"page add-new-question"
>
<
div
className=
"page add-new-question"
>
<
Breadcrumbs
navList=
"新增题目"
goBack=
{
()
=>
RCHistory
.
goBack
()
}
/>
<
Breadcrumbs
navList=
{
getParameterByName
(
"id"
)
?
"编辑题目"
:
"新增题目"
}
goBack=
{
()
=>
RCHistory
.
goBack
()
}
/>
<
div
className=
"box"
>
<
div
className=
"box"
>
<
div
className=
"show-tips"
>
<
div
className=
"show-tips"
>
<
ShowTips
message=
"请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企培保有依据国家规定及平台规则进行处理的权利"
/>
<
ShowTips
message=
"请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企培保有依据国家规定及平台规则进行处理的权利"
/>
...
@@ -125,13 +195,13 @@ class AddNewQuestion extends Component {
...
@@ -125,13 +195,13 @@ class AddNewQuestion extends Component {
<
NewQuestionTab
<
NewQuestionTab
questionTypeKey=
"SINGLE_CHOICE"
questionTypeKey=
"SINGLE_CHOICE"
onRef=
{
(
ref
)
=>
{
onRef=
{
(
ref
)
=>
{
this
.
singleRef
=
ref
;
this
.
single
Choice
Ref
=
ref
;
}
}
}
}
questionInfo=
{
singleChoiceContent
}
questionInfo=
{
singleChoiceContent
}
onSetState=
{
(
newContent
)
=>
{
onSetState=
{
(
newContent
)
=>
{
console
.
log
(
newContent
);
Object
.
assign
(
singleChoiceContent
,
newContent
);
Object
.
assign
(
singleChoiceContent
,
newContent
);
}
}
}
}
onLogger=
{
this
.
handleLogger
}
/>
/>
</
TabPane
>
</
TabPane
>
<
TabPane
<
TabPane
...
@@ -141,12 +211,13 @@ class AddNewQuestion extends Component {
...
@@ -141,12 +211,13 @@ class AddNewQuestion extends Component {
<
NewQuestionTab
<
NewQuestionTab
questionTypeKey=
"MULTI_CHOICE"
questionTypeKey=
"MULTI_CHOICE"
onRef=
{
(
ref
)
=>
{
onRef=
{
(
ref
)
=>
{
this
.
multi
pl
eRef
=
ref
;
this
.
multi
Choic
eRef
=
ref
;
}
}
}
}
questionInfo=
{
multiChoiceContent
}
questionInfo=
{
multiChoiceContent
}
onSetState=
{
(
newContent
)
=>
{
onSetState=
{
(
newContent
)
=>
{
Object
.
assign
(
multiChoiceContent
,
newContent
);
Object
.
assign
(
multiChoiceContent
,
newContent
);
}
}
}
}
onLogger=
{
this
.
handleLogger
}
/>
/>
</
TabPane
>
</
TabPane
>
<
TabPane
<
TabPane
...
@@ -199,6 +270,7 @@ class AddNewQuestion extends Component {
...
@@ -199,6 +270,7 @@ class AddNewQuestion extends Component {
onSetState=
{
(
newContent
)
=>
{
onSetState=
{
(
newContent
)
=>
{
Object
.
assign
(
indefiniteChoiceContent
,
newContent
);
Object
.
assign
(
indefiniteChoiceContent
,
newContent
);
}
}
}
}
onLogger=
{
this
.
handleLogger
}
/>
/>
</
TabPane
>
</
TabPane
>
</
Tabs
>
</
Tabs
>
...
...
src/modules/teach-tool/QuestionBankIndex.jsx
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-21 17:51:01
* @Date: 2021-02-21 17:51:01
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 16:48:23
* @LastEditTime: 2021-03-1
5 14:46:12
* @Description: 助学工具-题库-题库主页面
* @Description: 助学工具-题库-题库主页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
import
React
,
{
Component
}
from
"react"
;
import
React
,
{
Component
}
from
"react"
;
import
"./QuestionBankIndex.less"
;
import
"./QuestionBankIndex.less"
;
import
QuestionBankSider
from
"./components/QuestionBankSider"
;
import
QuestionBankSider
from
"./components/QuestionBankSider"
;
import
QuestionManage
Lis
t
from
"./components/QuestionManageContent"
;
import
QuestionManage
Conten
t
from
"./components/QuestionManageContent"
;
import
User
from
"@/common/js/user"
;
import
User
from
"@/common/js/user"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
...
@@ -25,10 +25,7 @@ class QuestionBankIndex extends Component {
...
@@ -25,10 +25,7 @@ class QuestionBankIndex extends Component {
};
};
}
}
componentDidMount
()
{
componentDidMount
()
{}
// TODO
// 接口请求 初始化数据
}
getCategoryIdFromSider
=
(
selectedCategoryId
)
=>
{
getCategoryIdFromSider
=
(
selectedCategoryId
)
=>
{
if
(
selectedCategoryId
&&
selectedCategoryId
.
length
>
0
)
{
if
(
selectedCategoryId
&&
selectedCategoryId
.
length
>
0
)
{
...
@@ -36,6 +33,10 @@ class QuestionBankIndex extends Component {
...
@@ -36,6 +33,10 @@ class QuestionBankIndex extends Component {
}
}
};
};
updatedSiderTreeFromList
=
(
updatedCategoryId
)
=>
{
this
.
setState
({
updatedCategoryId
});
};
render
()
{
render
()
{
return
(
return
(
<
div
className=
"question-bank-index page"
>
<
div
className=
"question-bank-index page"
>
...
@@ -44,10 +45,14 @@ class QuestionBankIndex extends Component {
...
@@ -44,10 +45,14 @@ class QuestionBankIndex extends Component {
<
div
className=
"sider"
>
<
div
className=
"sider"
>
<
QuestionBankSider
<
QuestionBankSider
getSelectedCategoryId=
{
this
.
getCategoryIdFromSider
.
bind
(
this
)
}
getSelectedCategoryId=
{
this
.
getCategoryIdFromSider
.
bind
(
this
)
}
updatedCategoryId=
{
this
.
state
.
updatedCategoryId
}
/>
/>
</
div
>
</
div
>
<
div
className=
"content"
>
<
div
className=
"content"
>
<
QuestionManageList
selectedCategoryId=
{
this
.
state
.
selectedCategoryId
}
/>
<
QuestionManageContent
updatedSiderTree=
{
this
.
updatedSiderTreeFromList
.
bind
(
this
)
}
selectedCategoryId=
{
this
.
state
.
selectedCategoryId
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
src/modules/teach-tool/QuestionCategoryManage.jsx
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-23 18:28:50
* @Date: 2021-02-23 18:28:50
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 19:53:48
* @LastEditTime: 2021-03-1
5 15:14:10
* @Description: 助学工具-题库-主页面分类管理
* @Description: 助学工具-题库-主页面分类管理
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -23,7 +23,6 @@ import {
...
@@ -23,7 +23,6 @@ import {
Modal
,
Modal
,
}
from
"antd"
;
}
from
"antd"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
user
from
"@/common/js/user"
;
const
{
DirectoryTree
}
=
Tree
;
const
{
DirectoryTree
}
=
Tree
;
const
{
Search
}
=
Input
;
const
{
Search
}
=
Input
;
const
{
confirm
}
=
Modal
;
const
{
confirm
}
=
Modal
;
...
@@ -34,7 +33,7 @@ class QuestionCategoryManage extends Component {
...
@@ -34,7 +33,7 @@ class QuestionCategoryManage extends Component {
NewEditQuestionBankCategory
:
null
,
//新增或编辑分类模态框
NewEditQuestionBankCategory
:
null
,
//新增或编辑分类模态框
treeData
:
[],
treeData
:
[],
treeMap
:
{},
treeMap
:
{},
selectedKeys
:
[
"0"
]
selectedKeys
:
[
"0"
]
,
};
};
}
}
...
@@ -47,12 +46,12 @@ class QuestionCategoryManage extends Component {
...
@@ -47,12 +46,12 @@ class QuestionCategoryManage extends Component {
let
query
=
{
let
query
=
{
source
:
0
,
source
:
0
,
categoryName
,
categoryName
,
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
};
};
QuestionBankService
.
queryCategoryTree
(
query
).
then
((
res
)
=>
{
QuestionBankService
.
queryCategoryTree
(
query
).
then
((
res
)
=>
{
const
{
result
=
[]
}
=
res
;
const
{
result
=
[]
}
=
res
;
const
defaultNode
=
{
id
:
"0"
,
categoryName
:
"未分类"
,
categoryCount
:
0
}
const
defaultNode
=
{
id
:
"0"
,
categoryName
:
"未分类"
,
categoryCount
:
0
};
result
.
unshift
(
defaultNode
);
result
.
unshift
(
defaultNode
);
this
.
setState
({
treeData
:
this
.
renderTreeNodes
(
result
,
categoryName
)
});
this
.
setState
({
treeData
:
this
.
renderTreeNodes
(
result
,
categoryName
)
});
this
.
setState
({
this
.
setState
({
...
@@ -78,7 +77,7 @@ class QuestionCategoryManage extends Component {
...
@@ -78,7 +77,7 @@ class QuestionCategoryManage extends Component {
categoryId
:
item
.
id
,
categoryId
:
item
.
id
,
source
:
0
,
source
:
0
,
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
};
};
QuestionBankService
.
delCategory
(
params
).
then
((
res
)
=>
{
QuestionBankService
.
delCategory
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
res
.
success
)
{
...
@@ -168,7 +167,11 @@ class QuestionCategoryManage extends Component {
...
@@ -168,7 +167,11 @@ class QuestionCategoryManage extends Component {
onDrop
=
(
info
)
=>
{
onDrop
=
(
info
)
=>
{
// 未分类不可以拖拽
// 未分类不可以拖拽
if
(
info
.
dragNode
.
categoryName
===
"未分类"
||
info
.
node
.
categoryName
===
"未分类"
)
return
;
if
(
info
.
dragNode
.
categoryName
===
"未分类"
||
info
.
node
.
categoryName
===
"未分类"
)
return
;
// 不允许其他节点拖拽到未分类之前
// 不允许其他节点拖拽到未分类之前
if
(
if
(
info
.
node
.
categoryName
===
"未分类"
&&
info
.
node
.
categoryName
===
"未分类"
&&
...
@@ -209,7 +212,11 @@ class QuestionCategoryManage extends Component {
...
@@ -209,7 +212,11 @@ class QuestionCategoryManage extends Component {
});
});
if
(
sameNameNodes
.
length
>
0
)
{
if
(
sameNameNodes
.
length
>
0
)
{
sufIndex
++
;
sufIndex
++
;
return
getSuf
(
originCategoryName
+
`(
${
sufIndex
}
)`
,
originCategoryName
,
sufIndex
);
return
getSuf
(
originCategoryName
+
`(
${
sufIndex
}
)`
,
originCategoryName
,
sufIndex
);
}
}
}
}
return
sufIndex
;
return
sufIndex
;
...
@@ -225,9 +232,12 @@ class QuestionCategoryManage extends Component {
...
@@ -225,9 +232,12 @@ class QuestionCategoryManage extends Component {
item
.
originCategoryName
=
item
.
categoryName
;
item
.
originCategoryName
=
item
.
categoryName
;
}
}
info
.
dragNode
.
categoryName
=
item
.
originCategoryName
;
info
.
dragNode
.
categoryName
=
item
.
originCategoryName
;
let
sufIndex
=
getSuf
(
info
.
dragNode
.
categoryName
,
item
.
originCategoryName
,
0
);
let
sufIndex
=
getSuf
(
item
.
categoryName
=
info
.
dragNode
.
categoryName
,
item
.
categoryName
+
(
sufIndex
?
`(
${
sufIndex
}
)`
:
""
);
item
.
originCategoryName
,
0
);
item
.
categoryName
=
item
.
categoryName
+
(
sufIndex
?
`(
${
sufIndex
}
)`
:
""
);
item
.
categoryName
=
item
.
categoryName
=
item
.
originCategoryName
+
(
sufIndex
?
`(
${
sufIndex
}
)`
:
""
);
item
.
originCategoryName
+
(
sufIndex
?
`(
${
sufIndex
}
)`
:
""
);
dragObj
=
item
;
dragObj
=
item
;
...
@@ -267,7 +277,7 @@ class QuestionCategoryManage extends Component {
...
@@ -267,7 +277,7 @@ class QuestionCategoryManage extends Component {
categoryList
:
newTreeData
,
categoryList
:
newTreeData
,
source
:
0
,
source
:
0
,
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
};
};
QuestionBankService
.
editCategoryTree
(
params
).
then
((
res
)
=>
{
QuestionBankService
.
editCategoryTree
(
params
).
then
((
res
)
=>
{
this
.
queryCategoryTree
();
this
.
queryCategoryTree
();
...
@@ -430,14 +440,20 @@ class QuestionCategoryManage extends Component {
...
@@ -430,14 +440,20 @@ class QuestionCategoryManage extends Component {
/** 树状选中事件 */
/** 树状选中事件 */
onSelect
=
(
selectedKeys
)
=>
{
onSelect
=
(
selectedKeys
)
=>
{
this
.
setState
({
selectedKeys
});
this
.
setState
({
selectedKeys
});
// TODO调用查询题目接口
};
};
render
()
{
render
()
{
const
{
treeData
,
expandedKeys
,
selectedKeys
}
=
this
.
state
;
const
{
treeData
,
expandedKeys
,
selectedKeys
}
=
this
.
state
;
return
(
return
(
<
div
className=
"page question-category-manage"
>
<
div
className=
"page question-category-manage"
>
<
Breadcrumbs
navList=
"课程分类"
goBack=
{
()
=>
RCHistory
.
goBack
()
}
/>
<
Breadcrumbs
navList=
"课程分类"
goBack=
{
()
=>
window
.
RCHistory
.
push
({
pathname
:
"/question-bank-index"
,
})
}
/>
<
div
className=
"box"
>
<
div
className=
"box"
>
<
div
className=
"search-condition"
>
<
div
className=
"search-condition"
>
<
span
className=
"search-label"
>
搜索名称:
</
span
>
<
span
className=
"search-label"
>
搜索名称:
</
span
>
...
...
src/modules/teach-tool/components/NewQuestionTab.jsx
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-25 14:34:29
* @Date: 2021-02-25 14:34:29
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 20:09:55
* @LastEditTime: 2021-03-1
5 21:12:14
* @Description: 助学工具-题库-题目管理-新建题目Tab
* @Description: 助学工具-题库-题目管理-新建题目Tab
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -22,6 +22,7 @@ import UploadingProgress from "./UploadingProgress";
...
@@ -22,6 +22,7 @@ import UploadingProgress from "./UploadingProgress";
import
XMAudio
from
"./XMAudio"
;
import
XMAudio
from
"./XMAudio"
;
import
XMRecord
from
"./XMRecord"
;
import
XMRecord
from
"./XMRecord"
;
import
ScanFileModal
from
"@/modules/resource-disk/modal/ScanFileModal"
;
import
ScanFileModal
from
"@/modules/resource-disk/modal/ScanFileModal"
;
import
_
from
'lodash'
;
class
NewQuestionTab
extends
Component
{
class
NewQuestionTab
extends
Component
{
constructor
(
props
)
{
constructor
(
props
)
{
...
@@ -93,14 +94,19 @@ class NewQuestionTab extends Component {
...
@@ -93,14 +94,19 @@ class NewQuestionTab extends Component {
}
}
shouldComponentUpdate
(
nextProps
,
nextState
)
{
shouldComponentUpdate
(
nextProps
,
nextState
)
{
return
(
const
{
questionInfo
}
=
nextProps
;
JSON
.
stringify
(
nextProps
)
!==
JSON
.
stringify
(
this
.
props
)
||
if
(
this
.
props
.
questionInfo
!==
questionInfo
)
{
JSON
.
stringify
(
nextState
)
!==
JSON
.
stringify
(
this
.
state
)
this
.
setState
({
stemContent
:
JSON
.
parse
(
JSON
.
stringify
(
questionInfo
.
questionStemList
))});
// 题干内容
);
this
.
setState
({
chooseOptions
:
JSON
.
parse
(
JSON
.
stringify
(
questionInfo
.
optionList
))});
// 单选多选不定项-选项列表
this
.
setState
({
questionAnswerDesc
:
JSON
.
parse
(
JSON
.
stringify
(
questionInfo
.
questionAnswerDescList
))});
// 答案解析
this
.
_onSetState
()
}
return
true
;
}
}
_onSetState
=
(
params
=
{})
=>
{
_onSetState
=
(
params
=
{})
=>
{
this
.
setState
({
...
params
,
updateKey
:
window
.
random_string
(
16
)
},
()
=>
{
this
.
setState
({
...
params
,
updateKey
:
window
.
random_string
(
16
)
},
()
=>
{
this
.
props
.
onSetState
({
this
.
props
.
onSetState
({
questionStemList
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
state
.
stemContent
)),
questionStemList
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
state
.
stemContent
)),
optionList
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
state
.
chooseOptions
)),
optionList
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
state
.
chooseOptions
)),
...
@@ -108,7 +114,8 @@ class NewQuestionTab extends Component {
...
@@ -108,7 +114,8 @@ class NewQuestionTab extends Component {
JSON
.
stringify
(
this
.
state
.
questionAnswerDesc
)
JSON
.
stringify
(
this
.
state
.
questionAnswerDesc
)
),
),
});
});
});
}
);
};
};
// 保存校验
// 保存校验
...
@@ -218,7 +225,7 @@ class NewQuestionTab extends Component {
...
@@ -218,7 +225,7 @@ class NewQuestionTab extends Component {
*
*
* @memberof QuestionInputItem
* @memberof QuestionInputItem
*/
*/
handleDelOption
=
(
optionIndex
)
=>
{
handleDelOption
=
(
optionIndex
)
=>
{
const
{
chooseOptions
}
=
this
.
state
;
const
{
chooseOptions
}
=
this
.
state
;
this
.
handleLogger
(
"delete_option"
,
"删除选项"
);
this
.
handleLogger
(
"delete_option"
,
"删除选项"
);
if
(
chooseOptions
.
length
<
3
)
{
if
(
chooseOptions
.
length
<
3
)
{
...
@@ -246,7 +253,8 @@ class NewQuestionTab extends Component {
...
@@ -246,7 +253,8 @@ class NewQuestionTab extends Component {
*
*
* @memberof QuestionInputItem
* @memberof QuestionInputItem
*/
*/
handleChangeMedia
=
(
key
,
uploadItemTarget
,
inputType
)
=>
{
handleChangeMedia
=
(
key
,
uploadItemTarget
,
contentType
)
=>
{
this
.
setState
({
contentType
})
const
{
mediaFirstType
}
=
this
.
state
;
const
{
mediaFirstType
}
=
this
.
state
;
const
mediaArr
=
_
.
filter
(
uploadItemTarget
,
(
mediaItem
)
=>
{
const
mediaArr
=
_
.
filter
(
uploadItemTarget
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
!==
"RICH_TEXT"
;
return
mediaItem
.
type
!==
"RICH_TEXT"
;
...
@@ -254,11 +262,12 @@ class NewQuestionTab extends Component {
...
@@ -254,11 +262,12 @@ class NewQuestionTab extends Component {
if
(
mediaArr
.
length
===
0
)
{
if
(
mediaArr
.
length
===
0
)
{
this
.
setState
({
mediaFirstType
:
key
});
this
.
setState
({
mediaFirstType
:
key
});
}
}
if
(
mediaArr
.
length
>
0
&&
key
!==
mediaFirstType
)
{
switch
(
contentType
)
{
return
message
.
warning
(
"只能添加1种类型的多媒体文件"
);
case
"QUESTION_STEM"
:
}
case
"QUESTION_OPTION"
:
switch
(
inputType
)
{
if
(
mediaArr
.
length
>
0
&&
key
!==
mediaFirstType
)
{
case
"stem"
:
return
message
.
warning
(
"只能添加1种类型的多媒体文件"
);
}
if
(
mediaFirstType
===
"PICTURE"
&&
mediaArr
.
length
>
8
)
{
if
(
mediaFirstType
===
"PICTURE"
&&
mediaArr
.
length
>
8
)
{
return
message
.
warning
(
"只能添加9张图片"
);
return
message
.
warning
(
"只能添加9张图片"
);
}
}
...
@@ -269,23 +278,47 @@ class NewQuestionTab extends Component {
...
@@ -269,23 +278,47 @@ class NewQuestionTab extends Component {
return
message
.
warning
(
"只能添加3个录音"
);
return
message
.
warning
(
"只能添加3个录音"
);
}
}
break
;
break
;
case
"options"
:
case
"QUESTION_ANSWER_DESC"
:
if
(
mediaArr
.
length
>
0
)
{
var
existType
=
[];
return
message
.
warning
(
"只能添加1个多媒体文件"
);
const
pictureMediaArr
=
_
.
filter
(
uploadItemTarget
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"PICTURE"
;
});
const
voiceMediaArr
=
_
.
filter
(
uploadItemTarget
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"VOICE"
;
});
const
recordMediaArr
=
_
.
filter
(
uploadItemTarget
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"RECORD"
;
});
const
videodMediaArr
=
_
.
filter
(
uploadItemTarget
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"VIDEO"
;
});
if
(
pictureMediaArr
.
length
>
0
)
{
existType
.
push
(
"PICTURE"
)
}
}
break
;
if
(
voiceMediaArr
.
length
>
0
)
{
case
"analysis"
:
existType
.
push
(
"VOICE"
)
if
(
mediaFirstType
===
"PICTURE"
&&
mediaArr
.
length
>
8
)
{
return
message
.
warning
(
"只能添加9张图片"
);
}
}
if
(
mediaFirstType
===
"VOICE"
&&
mediaArr
.
length
>
2
)
{
if
(
recordMediaArr
.
length
>
0
)
{
return
message
.
warning
(
"只能添加3个音频"
);
existType
.
push
(
"RECORD"
)
}
}
if
(
mediaFirstType
===
"RECORD"
&&
mediaArr
.
length
>
2
)
{
if
(
videodMediaArr
.
length
>
0
)
{
return
message
.
warning
(
"只能添加3个录音"
);
existType
.
push
(
"VIDEO"
)
}
}
if
(
mediaFirstType
===
"VIDEO"
&&
mediaArr
.
length
>
2
)
{
if
(
existType
.
length
>
2
&&
!
existType
.
includes
(
key
))
{
return
message
.
warning
(
"只能添加3个视频"
);
return
message
.
warning
(
"只能添加3种类型的多媒体文件"
);
}
else
{
if
(
key
===
"PICTURE"
&&
pictureMediaArr
.
length
>
8
)
{
return
message
.
warning
(
"只能添加9张图片"
);
}
if
(
key
===
"VOICE"
&&
voiceMediaArr
.
length
>
2
)
{
return
message
.
warning
(
"只能添加3个音频"
);
}
if
(
key
===
"RECORD"
&&
recordMediaArr
.
length
>
2
)
{
return
message
.
warning
(
"只能添加3个录音"
);
}
if
(
key
===
"VIDEO"
&&
videodMediaArr
.
length
>
2
)
{
return
message
.
warning
(
"只能添加3个视频"
);
}
}
}
break
;
break
;
default
:
default
:
...
@@ -320,7 +353,7 @@ class NewQuestionTab extends Component {
...
@@ -320,7 +353,7 @@ class NewQuestionTab extends Component {
};
};
async
uploadFile
(
event
)
{
async
uploadFile
(
event
)
{
const
{
fileType
,
uploadItemTarget
}
=
this
.
state
;
const
{
fileType
,
uploadItemTarget
,
contentType
}
=
this
.
state
;
const
mediaFile
=
event
.
target
.
files
[
0
];
const
mediaFile
=
event
.
target
.
files
[
0
];
if
(
!
mediaFile
)
return
;
if
(
!
mediaFile
)
return
;
if
(
fileType
===
"VOICE"
)
{
if
(
fileType
===
"VOICE"
)
{
...
@@ -368,7 +401,7 @@ class NewQuestionTab extends Component {
...
@@ -368,7 +401,7 @@ class NewQuestionTab extends Component {
const
originType
=
originArr
[
originArr
.
length
-
1
];
const
originType
=
originArr
[
originArr
.
length
-
1
];
const
uploadObj
=
{
const
uploadObj
=
{
contentType
:
"QUESTION_STEM"
,
contentType
,
type
:
fileType
,
type
:
fileType
,
contentName
:
`
${
window
.
random_string
(
16
)}
.
${
originType
}
`
,
// 文件名
contentName
:
`
${
window
.
random_string
(
16
)}
.
${
originType
}
`
,
// 文件名
fileType
:
originType
,
// 文件后缀
fileType
:
originType
,
// 文件后缀
...
@@ -455,7 +488,7 @@ class NewQuestionTab extends Component {
...
@@ -455,7 +488,7 @@ class NewQuestionTab extends Component {
});
});
this
.
setState
({
blanksList
:
_blanksList
});
this
.
setState
({
blanksList
:
_blanksList
});
};
};
renderCompletionAnswer
=
(
optionItem
,
optionIndex
)
=>
{
renderCompletionAnswer
=
(
optionItem
,
optionIndex
)
=>
{
return
(
return
(
<
div
className=
"completion-answer-box"
>
<
div
className=
"completion-answer-box"
>
...
@@ -533,7 +566,7 @@ class NewQuestionTab extends Component {
...
@@ -533,7 +566,7 @@ class NewQuestionTab extends Component {
contentList
,
contentList
,
placehold
,
placehold
,
mediaBtn
,
mediaBtn
,
inpu
tType
,
conten
tType
,
validateStatus
validateStatus
)
=>
{
)
=>
{
const
isCompletion
=
this
.
props
.
questionTypeKey
===
"COMPLETION"
;
const
isCompletion
=
this
.
props
.
questionTypeKey
===
"COMPLETION"
;
...
@@ -541,10 +574,23 @@ class NewQuestionTab extends Component {
...
@@ -541,10 +574,23 @@ class NewQuestionTab extends Component {
contentList
,
contentList
,
(
contentItem
)
=>
contentItem
.
type
===
"RICH_TEXT"
(
contentItem
)
=>
contentItem
.
type
===
"RICH_TEXT"
);
);
const
pictureMediaList
=
_
.
filter
(
contentList
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"PICTURE"
;
});
const
voiceMediaList
=
_
.
filter
(
contentList
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"VOICE"
;
});
const
recordMediaList
=
_
.
filter
(
contentList
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"RECORD"
;
});
const
videoMediaList
=
_
.
filter
(
contentList
,
(
mediaItem
)
=>
{
return
mediaItem
.
type
===
"VIDEO"
;
});
return
(
return
(
<
React
.
Fragment
>
<
React
.
Fragment
>
<
div
>
<
div
>
{
isCompletion
&&
inputType
===
"stem
"
?
(
{
isCompletion
&&
contentType
===
"QUESTION_STEM
"
?
(
<
CompletionStem
<
CompletionStem
placehold=
{
placehold
}
placehold=
{
placehold
}
validateStatus=
{
validateStatus
}
validateStatus=
{
validateStatus
}
...
@@ -552,7 +598,7 @@ class NewQuestionTab extends Component {
...
@@ -552,7 +598,7 @@ class NewQuestionTab extends Component {
mediaBtn=
{
mediaBtn
}
mediaBtn=
{
mediaBtn
}
changeBlankCount=
{
this
.
changeBlankCount
.
bind
(
this
)
}
changeBlankCount=
{
this
.
changeBlankCount
.
bind
(
this
)
}
onUploadMedia=
{
(
key
)
=>
{
onUploadMedia=
{
(
key
)
=>
{
this
.
handleChangeMedia
(
key
,
contentList
,
inpu
tType
);
this
.
handleChangeMedia
(
key
,
contentList
,
conten
tType
);
}
}
}
}
/>
/>
)
:
(
)
:
(
...
@@ -560,7 +606,7 @@ class NewQuestionTab extends Component {
...
@@ -560,7 +606,7 @@ class NewQuestionTab extends Component {
markKey=
{
this
.
markKey
}
markKey=
{
this
.
markKey
}
placehold=
{
placehold
}
placehold=
{
placehold
}
validateStatus=
{
validateStatus
}
validateStatus=
{
validateStatus
}
detailInfo=
{
contentLis
t
}
detailInfo=
{
editorConten
t
}
mediaBtn=
{
mediaBtn
}
mediaBtn=
{
mediaBtn
}
bindChangeContent=
{
(
cb
,
textElemId
)
=>
{
bindChangeContent=
{
(
cb
,
textElemId
)
=>
{
this
.
setState
({
textElemId
});
this
.
setState
({
textElemId
});
...
@@ -572,99 +618,299 @@ class NewQuestionTab extends Component {
...
@@ -572,99 +618,299 @@ class NewQuestionTab extends Component {
this
.
_onSetState
();
this
.
_onSetState
();
}
}
}
}
onUploadMedia=
{
(
key
)
=>
{
onUploadMedia=
{
(
key
)
=>
{
this
.
handleChangeMedia
(
key
,
contentList
,
inpu
tType
);
this
.
handleChangeMedia
(
key
,
contentList
,
conten
tType
);
}
}
}
}
/>
/>
)
}
)
}
</
div
>
</
div
>
{
_
.
map
(
contentList
,
(
contentItem
,
index
)
=>
{
{
contentType
===
"QUESTION_ANSWER_DESC"
?
const
{
type
,
content
,
status
}
=
contentItem
;
<
div
className=
"question-desc-box"
>
let
dom
=
""
;
{
pictureMediaList
.
length
>
0
&&
<
div
className=
"desc-picture-box"
>
if
([
"init"
,
"fail"
].
includes
(
status
))
{
{
_
.
map
(
pictureMediaList
,
(
pictureItem
,
pictureIndex
)
=>
{
return
(
let
{
content
,
status
}
=
pictureItem
;
<
div
className=
"mt12"
key=
{
index
}
>
if
([
"init"
,
"fail"
].
includes
(
status
))
{
<
UploadingProgress
return
(
fileDesc=
{
contentItem
}
<
div
className=
"mt12"
key=
{
pictureIndex
}
>
canCancelUpload
<
UploadingProgress
onReupload=
{
()
=>
this
.
handleReupload
(
contentItem
)
}
fileDesc=
{
pictureItem
}
onAbort=
{
()
=>
this
.
handleAbort
(
contentItem
,
index
)
}
canCancelUpload
/>
onReupload=
{
()
=>
this
.
handleReupload
(
pictureItem
)
}
</
div
>
onAbort=
{
()
=>
this
.
handleAbort
(
pictureItem
,
pictureIndex
)
}
);
/>
}
</
div
>
switch
(
type
)
{
);
case
"PICTURE"
:
}
else
{
dom
=
(
return
(
<
div
className=
"picture-box"
>
<
div
className=
"picture-box"
key=
{
pictureIndex
}
>
<
img
<
img
className=
"img-box"
className=
"img-box"
src=
{
content
}
src=
{
content
}
onClick=
{
()
=>
this
.
handleScanFile
(
"JPG"
,
content
)
}
onClick=
{
()
=>
this
.
handleScanFile
(
"JPG"
,
content
)
}
/>
/>
</
div
>
<
span
);
className=
"icon_arrow iconfont"
break
;
onClick=
{
()
=>
{
case
"VOICE"
:
contentList
.
map
((
item
,
index
)
=>
{
dom
=
(
if
(
item
.
contentName
===
pictureItem
.
contentName
)
{
<
div
className=
"audio-box"
>
contentList
.
splice
(
index
,
1
);
<
XMAudio
return
item
forbidParse
}
url=
{
contentItem
.
content
}
})
getDuration=
{
(
size
)
=>
{
this
.
_onSetState
();
contentItem
.
size
=
size
;
}
}
this
.
setState
({});
>
}
}

index=
{
index
}
</
span
>
size=
{
contentItem
.
size
||
1000
}
</
div
>
/>
)
</
div
>
}
);
})
}
break
;
</
div
>
}
case
"VIDEO"
:
{
recordMediaList
.
length
>
0
&&
<
div
className=
"desc-audio-box"
>
dom
=
(
{
_
.
map
(
recordMediaList
,
(
recordItem
,
recordIndex
)
=>
{
<
div
let
{
content
,
status
,
size
}
=
recordItem
;
className=
"video-box"
if
([
"init"
,
"fail"
].
includes
(
status
))
{
onClick=
{
()
=>
this
.
handleScanFile
(
"MP4"
,
content
)
}
return
(
>
<
div
className=
"mt12"
key=
{
recordIndex
}
>
<
img
<
UploadingProgress
className=
"video-box_content"
fileDesc=
{
recordItem
}
src=
{
`${content}?x-oss-process=video/snapshot,t_0,m_fast`
}
canCancelUpload
/>
onReupload=
{
()
=>
this
.
handleReupload
(
recordItem
)
}
<
img
onAbort=
{
()
=>
this
.
handleAbort
(
recordItem
,
recordIndex
)
}
className=
"video-box_btn"
/>
src=
"https://image.xiaomaiketang.com/xm/r5H8cYm4ch.png"
</
div
>
);
}
else
{
return
(
<
div
className=
"audio-box"
key=
{
recordIndex
}
>
<
XMAudio
forbidParse
url=
{
content
}
getDuration=
{
(
durationSize
)
=>
{
size
=
durationSize
;
this
.
setState
({});
}
}
index=
{
recordIndex
}
size=
{
size
||
1000
}
/>
<
span
className=
"icon_sider iconfont"
onClick=
{
()
=>
{
contentList
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentName
===
recordItem
.
contentName
)
{
contentList
.
splice
(
index
,
1
);
return
item
}
})
this
.
_onSetState
();
}
}
>

</
span
>
</
div
>
)
}
})
}
</
div
>
}
{
voiceMediaList
.
length
>
0
&&
<
div
className=
"desc-audio-box"
>
{
_
.
map
(
voiceMediaList
,
(
voiceItem
,
voiceIndex
)
=>
{
let
{
content
,
status
,
size
}
=
voiceItem
;
if
([
"init"
,
"fail"
].
includes
(
status
))
{
return
(
<
div
className=
"mt12"
key=
{
voiceIndex
}
>
<
UploadingProgress
fileDesc=
{
voiceItem
}
canCancelUpload
onReupload=
{
()
=>
this
.
handleReupload
(
voiceItem
)
}
onAbort=
{
()
=>
this
.
handleAbort
(
voiceItem
,
voiceIndex
)
}
/>
</
div
>
);
}
else
{
return
(
<
div
className=
"audio-box"
key=
{
voiceIndex
}
>
<
XMAudio
forbidParse
url=
{
content
}
getDuration=
{
(
durationSize
)
=>
{
size
=
durationSize
;
this
.
setState
({});
}
}
index=
{
voiceIndex
}
size=
{
size
||
1000
}
/>
<
span
className=
"icon_sider iconfont"
onClick=
{
()
=>
{
contentList
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentName
===
voiceItem
.
contentName
)
{
contentList
.
splice
(
index
,
1
);
return
item
}
})
this
.
_onSetState
();
}
}
>

</
span
>
</
div
>
)
}
})
}
</
div
>
}
{
videoMediaList
.
length
>
0
&&
<
div
className=
"desc-video-box"
>
{
_
.
map
(
videoMediaList
,
(
videoItem
,
videoIndex
)
=>
{
let
{
content
,
status
}
=
videoItem
;
if
([
"init"
,
"fail"
].
includes
(
status
))
{
return
(
<
div
className=
"mt12"
key=
{
videoIndex
}
>
<
UploadingProgress
fileDesc=
{
videoItem
}
canCancelUpload
onReupload=
{
()
=>
this
.
handleReupload
(
videoItem
)
}
onAbort=
{
()
=>
this
.
handleAbort
(
videoItem
,
videoIndex
)
}
/>
</
div
>
);
}
else
{
return
(
<
div
className=
"video-box"
key=
{
videoIndex
}
>
<
img
className=
"video-box_content"
src=
{
`${content}?x-oss-process=video/snapshot,t_0,m_fast`
}
/>
<
img
className=
"video-box_btn"
src=
"https://image.xiaomaiketang.com/xm/r5H8cYm4ch.png"
onClick=
{
()
=>
this
.
handleScanFile
(
"MP4"
,
content
)
}
/>
<
span
className=
"icon_arrow iconfont"
onClick=
{
()
=>
{
contentList
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentName
===
videoItem
.
contentName
)
{
contentList
.
splice
(
index
,
1
);
return
item
}
})
this
.
_onSetState
();
}
}
>

</
span
>
</
div
>
)
}
})
}
</
div
>
}
</
div
>
:
_
.
map
(
contentList
,
(
contentItem
,
index
)
=>
{
const
{
type
,
content
,
status
}
=
contentItem
;
let
dom
=
""
;
if
([
"init"
,
"fail"
].
includes
(
status
))
{
return
(
<
div
className=
"mt12"
key=
{
index
}
>
<
UploadingProgress
fileDesc=
{
contentItem
}
canCancelUpload
onReupload=
{
()
=>
this
.
handleReupload
(
contentItem
)
}
onAbort=
{
()
=>
this
.
handleAbort
(
contentItem
,
index
)
}
/>
/>
</
div
>
</
div
>
);
);
break
;
}
}
switch
(
type
)
{
return
dom
?
(
case
"PICTURE"
:
<
div
dom
=
(
className=
"question-item_question-content"
<
div
className=
"picture-box"
>
style=
{
{
<
img
display
:
[
"PICTURE"
,
"VIDEO"
].
includes
(
type
)
className=
"img-box"
?
"inline-flex"
src=
{
content
}
:
"flex"
,
onClick=
{
()
=>
this
.
handleScanFile
(
"JPG"
,
content
)
}
}
}
/>
key=
{
index
}
</
div
>
>
);
{
dom
}
break
;
<
span
case
"VOICE"
:
className=
{
dom
=
(
[
"PICTURE"
,
"VIDEO"
].
includes
(
type
)
<
div
className=
"audio-box"
>
?
"icon_arrow iconfont"
<
XMAudio
:
"icon_sider iconfont"
forbidParse
}
url=
{
contentItem
.
content
}
onClick=
{
()
=>
{
getDuration=
{
(
size
)
=>
{
contentList
.
splice
(
index
,
1
);
contentItem
.
size
=
size
;
this
.
_onSetState
();
this
.
setState
({});
}
}
index=
{
index
}
size=
{
contentItem
.
size
||
1000
}
/>
</
div
>
);
break
;
case
"RECORD"
:
dom
=
(
<
div
className=
"audio-box"
>
<
XMAudio
forbidParse
url=
{
contentItem
.
content
}
getDuration=
{
(
size
)
=>
{
contentItem
.
size
=
size
;
this
.
setState
({});
}
}
index=
{
index
}
size=
{
contentItem
.
size
||
1000
}
/>
</
div
>
);
break
;
case
"VIDEO"
:
dom
=
(
<
div
className=
"video-box"
onClick=
{
()
=>
this
.
handleScanFile
(
"MP4"
,
content
)
}
>
<
img
className=
"video-box_content"
src=
{
`${content}?x-oss-process=video/snapshot,t_0,m_fast`
}
/>
<
img
className=
"video-box_btn"
src=
"https://image.xiaomaiketang.com/xm/r5H8cYm4ch.png"
/>
</
div
>
);
break
;
}
return
dom
?
(
<
div
className=
"question-item_question-content"
style=
{
{
display
:
[
"PICTURE"
,
"VIDEO"
].
includes
(
type
)
?
"inline-grid"
:
"flex"
,
}
}
}
}
key=
{
index
}
>
>

{
dom
}
<
span
className=
{
[
"PICTURE"
,
"VIDEO"
].
includes
(
type
)
?
"icon_arrow iconfont"
:
"icon_sider iconfont"
}
onClick=
{
()
=>
{
contentList
.
splice
(
index
,
1
);
this
.
_onSetState
();
}
}
>

</
span
>
</
span
>
</
div
>
</
div
>
)
:
null
;
)
:
null
;
})
}
})
}
</
React
.
Fragment
>
</
React
.
Fragment
>
);
);
};
};
...
@@ -723,10 +969,10 @@ class NewQuestionTab extends Component {
...
@@ -723,10 +969,10 @@ class NewQuestionTab extends Component {
* @memberof QuestionInputItem
* @memberof QuestionInputItem
*/
*/
handleFinishRecord
=
(
mp3URL
,
duration
)
=>
{
handleFinishRecord
=
(
mp3URL
,
duration
)
=>
{
const
{
uploadItemTarget
}
=
this
.
state
;
const
{
uploadItemTarget
,
contentType
}
=
this
.
state
;
uploadItemTarget
.
push
({
uploadItemTarget
.
push
({
contentType
:
"VOICE"
,
contentType
,
type
:
"
VOICE
"
,
type
:
"
RECORD
"
,
content
:
mp3URL
,
content
:
mp3URL
,
size
:
duration
,
size
:
duration
,
});
});
...
@@ -784,7 +1030,7 @@ class NewQuestionTab extends Component {
...
@@ -784,7 +1030,7 @@ class NewQuestionTab extends Component {
stemContent
,
stemContent
,
placehold
,
placehold
,
[
"VOICE"
,
"RECORD"
,
"PICTURE"
],
[
"VOICE"
,
"RECORD"
,
"PICTURE"
],
"
stem
"
,
"
QUESTION_STEM
"
,
stemValidate
stemValidate
)
}
)
}
</
Form
.
Item
>
</
Form
.
Item
>
...
@@ -828,62 +1074,62 @@ class NewQuestionTab extends Component {
...
@@ -828,62 +1074,62 @@ class NewQuestionTab extends Component {
>
>
{
isJudge
{
isJudge
?
_
.
map
(
judgeOptions
,
(
optionItem
,
optionIndex
)
=>
{
?
_
.
map
(
judgeOptions
,
(
optionItem
,
optionIndex
)
=>
{
return
(
return
(
<
div
className=
"question-item_options__content"
>
<
div
className=
"question-item_options__content"
>
<
div
className=
"question-item_options__setting"
>
<
div
className=
"question-item_options__setting"
>
<
Form
.
Item
<
Form
.
Item
validateStatus=
{
radioValidate
}
validateStatus=
{
radioValidate
}
help=
{
help=
{
optionIndex
===
judgeOptions
.
length
-
1
optionIndex
===
judgeOptions
.
length
-
1
?
radioText
?
radioText
:
""
:
""
}
}
>
>
{
/* 判断 */
}
{
/* 判断 */
}
<
Radio
<
Radio
checked=
{
optionItem
.
isCorrectAnswer
===
1
}
checked=
{
optionItem
.
isCorrectAnswer
===
1
}
onClick=
{
()
=>
{
onClick=
{
()
=>
{
_
.
each
(
judgeOptions
,
(
item
)
=>
{
_
.
each
(
judgeOptions
,
(
item
)
=>
{
item
.
isCorrectAnswer
=
0
;
item
.
isCorrectAnswer
=
0
;
});
});
optionItem
.
isCorrectAnswer
=
1
;
optionItem
.
isCorrectAnswer
=
1
;
this
.
_onSetState
();
this
.
_onSetState
();
}
}
}
}
/>
/>
</
Form
.
Item
>
</
Form
.
Item
>
</
div
>
</
div
>
<
div
className=
"question-item_options__sort mr12"
>
<
div
className=
"question-item_options__sort mr12"
>
{
NUM_TO_WORD_MAP
[
optionIndex
]
}
.
{
NUM_TO_WORD_MAP
[
optionIndex
]
}
.
</
div
>
<
div
className=
"question-item_options__input"
>
{
optionItem
.
label
}
</
div
>
</
div
>
</
div
>
);
<
div
className=
"question-item_options__input"
>
})
{
optionItem
.
label
}
</
div
>
</
div
>
);
})
:
_
.
map
(
chooseOptions
,
(
optionItem
,
optionIndex
)
=>
{
:
_
.
map
(
chooseOptions
,
(
optionItem
,
optionIndex
)
=>
{
const
{
const
{
questionOptionContentList
,
questionOptionContentList
,
isCorrectAnswer
,
isCorrectAnswer
,
}
=
optionItem
;
}
=
optionItem
;
optionItem
.
optionSort
=
optionIndex
;
optionItem
.
optionSort
=
optionIndex
;
const
mediaBtn
=
[
"VOICE"
,
"RECORD"
,
"PICTURE"
];
const
mediaBtn
=
[
"VOICE"
,
"RECORD"
,
"PICTURE"
];
const
placeHold
=
const
placeHold
=
"必填(1000字以内,可粘贴小图;可以不输入文字,只添加音频或图片)"
;
"必填(1000字以内,可粘贴小图;可以不输入文字,只添加音频或图片)"
;
return
(
return
(
<
div
className=
"question-item_options__content"
key=
{
optionIndex
}
>
<
div
className=
"question-item_options__content"
key=
{
optionIndex
}
>
<
div
className=
"question-item_options__setting"
>
<
div
className=
"question-item_options__setting"
>
<
Form
.
Item
<
Form
.
Item
validateStatus=
{
radioValidate
}
validateStatus=
{
radioValidate
}
help=
{
help=
{
optionIndex
===
chooseOptions
.
length
-
1
optionIndex
===
chooseOptions
.
length
-
1
?
radioText
?
radioText
:
""
:
""
}
}
>
>
{
/* 单选 */
}
{
/* 单选 */
}
{
this
.
props
.
questionTypeKey
===
{
this
.
props
.
questionTypeKey
===
"SINGLE_CHOICE"
&&
(
"SINGLE_CHOICE"
&&
(
<
Radio
<
Radio
checked=
{
isCorrectAnswer
}
checked=
{
isCorrectAnswer
}
onClick=
{
()
=>
{
onClick=
{
()
=>
{
...
@@ -895,10 +1141,10 @@ class NewQuestionTab extends Component {
...
@@ -895,10 +1141,10 @@ class NewQuestionTab extends Component {
}
}
}
}
/>
/>
)
}
)
}
{
/* 多选 or 不定项 */
}
{
/* 多选 or 不定项 */
}
{
[
"INDEFINITE_SELECT
"
,
"MULTI_CHOICE"
].
includes
(
{
[
"INDEFINITE_CHOICE
"
,
"MULTI_CHOICE"
].
includes
(
this
.
props
.
questionTypeKey
this
.
props
.
questionTypeKey
)
&&
(
)
&&
(
<
Checkbox
<
Checkbox
checked=
{
isCorrectAnswer
===
1
}
checked=
{
isCorrectAnswer
===
1
}
onChange=
{
(
e
)
=>
{
onChange=
{
(
e
)
=>
{
...
@@ -908,66 +1154,66 @@ class NewQuestionTab extends Component {
...
@@ -908,66 +1154,66 @@ class NewQuestionTab extends Component {
}
}
}
}
/>
/>
)
}
)
}
</
Form
.
Item
>
</
Form
.
Item
>
</
div
>
</
div
>
<
div
className=
"question-item_options__sort mr12"
>
<
div
className=
"question-item_options__sort mr12"
>
{
NUM_TO_WORD_MAP
[
optionIndex
]
}
.
{
NUM_TO_WORD_MAP
[
optionIndex
]
}
.
</
div
>
</
div
>
<
div
className=
"question-item_options__input"
>
<
div
className=
"question-item_options__input"
>
<
Form
.
Item
<
Form
.
Item
validateStatus=
{
validateStatus=
{
this
.
state
[
`optionsValidate_${optionIndex}`
]
this
.
state
[
`optionsValidate_${optionIndex}`
]
}
help=
{
this
.
state
[
`optionsText_${optionIndex}`
]
}
>
{
this
.
renderContent
(
questionOptionContentList
,
placeHold
,
mediaBtn
,
"QUESTION_OPTION"
,
this
.
state
[
`optionsValidate_${optionIndex}`
]
)
}
</
Form
.
Item
>
</
div
>
<
div
className=
"question-item_options__extra"
>
<
React
.
Fragment
>
<
span
className=
"option-operate_item__icon icon iconfont"
onClick=
{
()
=>
this
.
handleDelOption
(
optionIndex
)
}
}
help=
{
this
.
state
[
`optionsText_${optionIndex}`
]
}
>
>
{
this
.
renderContent
(

questionOptionContentList
,
</
span
>
placeHold
,
{
optionIndex
>
0
&&
(
mediaBtn
,
"options"
,
this
.
state
[
`optionsValidate_${optionIndex}`
]
)
}
</
Form
.
Item
>
</
div
>
<
div
className=
"question-item_options__extra"
>
<
React
.
Fragment
>
<
span
<
span
className=
"option-operate_item__icon icon iconfont"
className=
"option-operate_item__icon icon iconfont"
onClick=
{
()
=>
onClick=
{
()
=>
this
.
handle
DelOption
(
optionIndex
)
this
.
handle
MoveOption
(
optionIndex
,
-
1
)
}
}
>
>

81
a;

74
a;
</
span
>
</
span
>
{
optionIndex
>
0
&&
(
)
}
<
span
{
optionIndex
<
chooseOptions
.
length
-
1
&&
(
className=
"option-operate_item__icon icon iconfont"
<
span
onClick=
{
()
=>
className=
"option-operate_item__icon icon iconfont"
this
.
handleMoveOption
(
optionIndex
,
1
)
style=
{
{
}
transform
:
"rotate(180deg)"
,
>
display
:
"inline-block"
,

}
}
</
span
>
onClick=
{
()
=>
)
}
this
.
handleMoveOption
(
optionIndex
,
1
)
{
optionIndex
<
chooseOptions
.
length
-
1
&&
(
}
<
span
>
className=
"option-operate_item__icon icon iconfont"

style=
{
{
</
span
>
transform
:
"rotate(180deg)"
,
)
}
display
:
"inline-block"
,
</
React
.
Fragment
>
}
}
onClick=
{
()
=>
this
.
handleMoveOption
(
optionIndex
,
-
1
)
}
>

</
span
>
)
}
</
React
.
Fragment
>
</
div
>
</
div
>
</
div
>
);
</
div
>
})
}
);
})
}
{
!
isJudge
&&
(
{
!
isJudge
&&
(
<
div
<
div
className=
"question-item_options__add"
className=
"question-item_options__add"
...
@@ -987,7 +1233,7 @@ class NewQuestionTab extends Component {
...
@@ -987,7 +1233,7 @@ class NewQuestionTab extends Component {
questionAnswerDesc
,
questionAnswerDesc
,
"1000字以内,可粘贴小图"
,
"1000字以内,可粘贴小图"
,
[
"VOICE"
,
"RECORD"
,
"PICTURE"
,
"VIDEO"
],
[
"VOICE"
,
"RECORD"
,
"PICTURE"
,
"VIDEO"
],
"
analysis
"
"
QUESTION_ANSWER_DESC
"
)
}
)
}
</
div
>
</
div
>
</
Form
.
Item
>
</
Form
.
Item
>
...
...
src/modules/teach-tool/components/NewQuestionTab.less
View file @
96b7a4c4
...
@@ -284,6 +284,89 @@
...
@@ -284,6 +284,89 @@
.question-item_analysis__content {
.question-item_analysis__content {
flex: 1;
flex: 1;
margin-right: 187px;
margin-right: 187px;
.question-desc-box {
margin-top: 12px;
.desc-picture-box {
margin-bottom: 28px;
.picture-box {
position: relative;
display: inline-block;
width: 100px;
height: 100px;
overflow: hidden;
align-items: center;
justify-content: center;
padding: 12px 12px 0 0;
img {
max-width: 88px;
max-height: 88px;
border-radius: 4px;
}
.icon_arrow {
position: absolute;
top: 0px;
right: 5px;
color: #bfbfbf;
cursor: pointer;
font-size: 16px;
}
}
}
.desc-audio-box {
margin-bottom: 28px;
.audio-box {
position: relative;
box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1);
padding: 10px 20px;
width: 320px;
margin-bottom: 12px;
.icon_sider {
color: #bfbfbf;
cursor: pointer;
font-size: 16px;
padding: 12px;
position: absolute;
top: 0px;
left: 320px;
}
}
}
.desc-video-box {
.video-box {
position: relative;
display: inline-block;
width: 208px;
// height: calc(208px * 9 / 16);
position: relative;
overflow: hidden;
// background-color: #000;
padding-top: 12px;
margin: 0px 12px 12px 0;
&_content {
max-width: 200px;
max-height: 200px;
border-radius: 4px;
}
&_btn {
width: 32px;
height: 32px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -8px;
margin-left: -16px;
}
.icon_arrow {
position: absolute;
top: 0px;
right: 0px;
color: #bfbfbf;
cursor: pointer;
font-size: 16px;
}
}
}
}
}
}
.completion-answer-box {
.completion-answer-box {
...
...
src/modules/teach-tool/components/QuestionBankSider.jsx
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-22 10:59:43
* @Date: 2021-02-22 10:59:43
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 20:29:29
* @LastEditTime: 2021-03-1
5 15:22:13
* @Description: 助学工具-题库-题库主页面侧边栏
* @Description: 助学工具-题库-题库主页面侧边栏
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -19,7 +19,7 @@ class QuestionBankSider extends Component {
...
@@ -19,7 +19,7 @@ class QuestionBankSider extends Component {
constructor
(
props
)
{
constructor
(
props
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
selectedKeys
:
[
"0"
],
selectedKeys
:
getParameterByName
(
"categoryId"
)
?
[
getParameterByName
(
"categoryId"
)]
:
[
"0"
],
searchValue
:
null
,
searchValue
:
null
,
NewEditQuestionBankCategory
:
null
,
//新增或编辑分类模态框
NewEditQuestionBankCategory
:
null
,
//新增或编辑分类模态框
ImportCourseCategory
:
null
,
// 引用课程分类模态框
ImportCourseCategory
:
null
,
// 引用课程分类模态框
...
@@ -29,6 +29,15 @@ class QuestionBankSider extends Component {
...
@@ -29,6 +29,15 @@ class QuestionBankSider extends Component {
componentDidMount
()
{
componentDidMount
()
{
this
.
queryCategoryTree
();
this
.
queryCategoryTree
();
this
.
props
.
getSelectedCategoryId
(
getParameterByName
(
"categoryId"
)
?
[
getParameterByName
(
"categoryId"
)]
:
[
"0"
],)
}
shouldComponentUpdate
(
nextProps
,
nextState
)
{
const
{
updatedCategoryId
}
=
nextProps
;
if
(
this
.
props
.
updatedCategoryId
!==
updatedCategoryId
)
{
this
.
setState
({
selectedKeys
:
[
updatedCategoryId
]
},
()
=>
this
.
queryCategoryTree
());
}
return
true
;
}
}
/** 获取树状第一级key 设置默认展开第一项 */
/** 获取树状第一级key 设置默认展开第一项 */
...
@@ -58,12 +67,12 @@ class QuestionBankSider extends Component {
...
@@ -58,12 +67,12 @@ class QuestionBankSider extends Component {
let
query
=
{
let
query
=
{
source
:
0
,
source
:
0
,
categoryName
,
categoryName
,
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
};
};
QuestionBankService
.
queryQuestionCategoryTree
(
query
).
then
((
res
)
=>
{
QuestionBankService
.
queryQuestionCategoryTree
(
query
).
then
((
res
)
=>
{
const
{
categoryList
=
[]
}
=
res
.
result
;
const
{
categoryList
=
[]
,
noCategoryCnt
=
0
}
=
res
.
result
;
const
defaultNode
=
{
id
:
"0"
,
categoryName
:
"未分类"
,
categoryCount
:
0
}
const
defaultNode
=
{
id
:
"0"
,
categoryName
:
"未分类"
,
categoryCount
:
noCategoryCnt
}
categoryList
.
unshift
(
defaultNode
);
categoryList
.
unshift
(
defaultNode
);
this
.
setState
({
treeData
:
this
.
renderTreeNodes
(
categoryList
,
categoryName
)
});
this
.
setState
({
treeData
:
this
.
renderTreeNodes
(
categoryList
,
categoryName
)
});
this
.
setState
({
this
.
setState
({
...
...
src/modules/teach-tool/components/QuestionEditor.jsx
View file @
96b7a4c4
...
@@ -37,6 +37,7 @@ class QuestionEditor extends Component {
...
@@ -37,6 +37,7 @@ class QuestionEditor extends Component {
isShowSingleInput
:
true
,
isShowSingleInput
:
true
,
contentLength
:
0
,
contentLength
:
0
,
errorInput
:
false
,
errorInput
:
false
,
detailInfo
:
props
.
detailInfo
||
{}
};
};
}
}
...
@@ -44,6 +45,16 @@ class QuestionEditor extends Component {
...
@@ -44,6 +45,16 @@ class QuestionEditor extends Component {
this
.
renderEditor
();
this
.
renderEditor
();
}
}
shouldComponentUpdate
(
nextProps
,
nextState
)
{
const
{
detailInfo
}
=
nextProps
;
if
(
this
.
props
.
detailInfo
!==
detailInfo
)
{
this
.
setState
({
detailInfo
:
nextProps
.
detailInfo
},
()
=>
{
this
.
renderEditor
();
})
}
return
true
;
}
handleUploadMedia
=
(
key
)
=>
{
handleUploadMedia
=
(
key
)
=>
{
this
.
props
.
onUploadMedia
&&
this
.
props
.
onUploadMedia
(
key
);
this
.
props
.
onUploadMedia
&&
this
.
props
.
onUploadMedia
(
key
);
};
};
...
@@ -72,8 +83,8 @@ class QuestionEditor extends Component {
...
@@ -72,8 +83,8 @@ class QuestionEditor extends Component {
};
};
renderEditor
()
{
renderEditor
()
{
const
{
editorId
}
=
this
.
state
;
const
{
editorId
,
detailInfo
}
=
this
.
state
;
const
{
detail
=
{},
detailInfo
=
{},
onChange
,
bindChangeContent
}
=
this
.
props
;
const
{
onChange
,
bindChangeContent
}
=
this
.
props
;
const
editorRoot
=
new
E
(
const
editorRoot
=
new
E
(
`#editor
${
editorId
}
_tabbar`
,
`#editor
${
editorId
}
_tabbar`
,
`#editor
${
editorId
}
_content`
`#editor
${
editorId
}
_content`
...
@@ -156,27 +167,6 @@ class QuestionEditor extends Component {
...
@@ -156,27 +167,6 @@ class QuestionEditor extends Component {
editorRoot
.
create
();
editorRoot
.
create
();
this
.
editorRoot
=
editorRoot
;
this
.
editorRoot
=
editorRoot
;
if
(
detail
.
content
)
{
const
contentHtml
=
/^
\<
p/
.
test
(
detail
.
content
)
?
detail
.
content
:
`<p>
${
detail
.
content
}
</p>`
;
editorRoot
.
txt
.
html
(
detail
.
content
);
const
textLength
=
editorRoot
.
txt
.
text
().
replace
(
/
\&
nbsp
\;
/gi
,
" "
)
.
length
;
const
imgLength
=
contentHtml
.
match
(
/<img/g
)
?
contentHtml
.
match
(
/<img/g
).
length
*
2
:
0
;
const
contentLength
=
imgLength
+
textLength
;
this
.
setState
(
{
contentLength
,
visiblePlacehold
:
contentLength
===
0
&&
!
this
.
state
.
focusFlag
,
},
()
=>
{
onChange
&&
onChange
(
contentHtml
,
this
.
state
.
contentLength
);
}
);
}
if
(
detailInfo
.
content
)
{
if
(
detailInfo
.
content
)
{
const
contentHtml
=
/^
\<
p/
.
test
(
detailInfo
.
content
)
const
contentHtml
=
/^
\<
p/
.
test
(
detailInfo
.
content
)
?
detailInfo
.
content
?
detailInfo
.
content
...
...
src/modules/teach-tool/components/QuestionManageContent.jsx
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-25 11:23:47
* @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 21:04:36
* @LastEditTime: 2021-03-1
5 21:08:28
* @Description: 助学工具-题库-题目管理主页面列表数据
* @Description: 助学工具-题库-题目管理主页面列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -19,14 +19,24 @@ import {
...
@@ -19,14 +19,24 @@ import {
Space
,
Space
,
Button
,
Button
,
Modal
,
Modal
,
message
,
}
from
"antd"
;
}
from
"antd"
;
import
{
PageControl
}
from
"@/components"
;
import
{
PageControl
}
from
"@/components"
;
import
"./QuestionManageContent.less"
;
import
"./QuestionManageContent.less"
;
import
User
from
"@/common/js/user"
;
import
User
from
"@/common/js/user"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
import
_
from
"underscore"
;
import
_
from
"underscore"
;
import
QuestionPreviewModal
from
"../modal/QuestionPreviewModal"
;
const
{
Search
}
=
Input
;
const
{
Search
}
=
Input
;
const
questionTypeEnum
=
{
SINGLE_CHOICE
:
"单选题"
,
MULTI_CHOICE
:
"多选题"
,
JUDGE
:
"判断题"
,
GAP_FILLING
:
"填空题"
,
INDEFINITE_CHOICE
:
"不定项选择题"
,
};
const
questionTypeList
=
[
const
questionTypeList
=
[
{
{
label
:
"单选题"
,
label
:
"单选题"
,
...
@@ -63,32 +73,37 @@ class QuestionManageContent extends Component {
...
@@ -63,32 +73,37 @@ class QuestionManageContent extends Component {
questionType
:
null
,
// 题目类型
questionType
:
null
,
// 题目类型
source
:
0
,
source
:
0
,
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
},
},
questionTypeList
:
[],
// 题型列表
questionTypeList
:
[],
// 题型列表
dataSource
:
[],
dataSource
:
[],
totalCount
:
0
,
totalCount
:
0
,
QuestionPreviewModal
:
null
,
// 题目预览模态框
};
};
}
}
componentDidMount
()
{
componentDidMount
()
{}
this
.
queryQuestionPageList
();
}
shouldComponentUpdate
(
nextProps
,
nextState
)
{
shouldComponentUpdate
(
nextProps
,
nextState
)
{
const
{
selectedCategoryId
}
=
nextProps
;
const
{
selectedCategoryId
}
=
nextProps
;
const
_query
=
this
.
state
.
query
;
const
_query
=
this
.
state
.
query
;
if
(
this
.
props
.
selectedCategoryId
!==
selectedCategoryId
)
{
if
(
this
.
props
.
selectedCategoryId
!==
selectedCategoryId
)
{
_query
.
categoryId
=
selectedCategoryId
;
_query
.
categoryId
=
selectedCategoryId
;
_query
.
questionName
=
null
;
_query
.
questionType
=
null
;
_query
.
current
=
1
;
this
.
setState
({
query
:
_query
},
()
=>
this
.
queryQuestionPageList
());
this
.
setState
({
query
:
_query
},
()
=>
this
.
queryQuestionPageList
());
}
}
return
true
;
return
true
;
}
}
queryQuestionPageList
=
()
=>
{
queryQuestionPageList
=
()
=>
{
QuestionBankService
.
queryQuestionPageList
(
this
.
state
.
query
).
then
((
res
)
=>
{
const
_query
=
this
.
state
.
query
;
if
(
_query
.
categoryId
===
"0"
)
_query
.
categoryId
=
null
;
QuestionBankService
.
queryQuestionPageList
(
_query
).
then
((
res
)
=>
{
const
{
records
=
[],
total
=
0
}
=
res
.
result
;
const
{
records
=
[],
total
=
0
}
=
res
.
result
;
this
.
setState
({
dataSource
:
records
});
this
.
setState
({
dataSource
:
records
});
this
.
setState
({
total
});
});
});
};
};
...
@@ -116,16 +131,81 @@ class QuestionManageContent extends Component {
...
@@ -116,16 +131,81 @@ class QuestionManageContent extends Component {
deleteQuestion
=
(
record
)
=>
{
deleteQuestion
=
(
record
)
=>
{
let
params
=
{
let
params
=
{
id
:
record
.
id
,
id
:
record
.
id
,
categoryId
:
record
.
categoryId
,
source
:
0
,
source
:
0
,
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
userId
:
User
.
getStoreUserId
(),
};
QuestionBankService
.
deleteQuestion
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
"删除成功"
);
this
.
queryQuestionPageList
();
this
.
props
.
updatedSiderTree
(
this
.
props
.
selectedCategoryId
);
}
});
};
// 排序
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
let
sort
=
null
;
if
(
columnKey
===
"accuracy"
&&
order
===
"ascend"
)
{
sort
=
"ACCURACY_ASC"
;
}
}
console
.
log
(
params
)
if
(
columnKey
===
"accuracy"
&&
order
===
"descend"
)
{
QuestionBankService
.
delCategory
(
params
).
then
(
res
=>
{
sort
=
"ACCURACY_DESC"
;
console
.
log
(
res
)
}
})
if
(
columnKey
===
"updateTime"
&&
order
===
"ascend"
)
{
}
sort
=
"UPDATED_ASC"
;
}
if
(
columnKey
===
"updateTime"
&&
order
===
"descend"
)
{
sort
=
"UPDATED_DESC"
;
}
const
_query
=
this
.
state
.
query
;
_query
.
order
=
sort
;
_query
.
current
=
1
;
this
.
setState
({
query
:
_query
},
()
=>
this
.
queryQuestionPageList
());
};
// 清空搜索条件
handleReset
=
()
=>
{
const
_query
=
{
...
this
.
state
.
query
,
current
:
1
,
order
:
"ACCURACY_DESC"
,
// 排序规则
questionName
:
null
,
// 题目名称
questionType
:
null
,
// 题目类型
};
this
.
setState
({
query
:
_query
},
()
=>
{
this
.
queryQuestionPageList
();
});
};
previewQuestion
=
(
id
)
=>
{
const
m
=
(
<
QuestionPreviewModal
id=
{
id
}
close=
{
()
=>
{
this
.
setState
({
QuestionPreviewModal
:
null
,
});
}
}
/>
);
this
.
setState
({
QuestionPreviewModal
:
m
});
};
toEditQuetion
=
(
id
,
type
)
=>
{
const
{
categoryId
}
=
this
.
state
.
query
;
if
(
categoryId
)
{
window
.
RCHistory
.
push
({
pathname
:
`/create-new-question?id=
${
id
}
&type=
${
type
}
&categoryId=
${
categoryId
}
`
,
});
}
else
{
window
.
RCHistory
.
push
({
pathname
:
`/create-new-question?id=
${
id
}
&type=
${
type
}
`
,
});
}
};
// 表头设置
// 表头设置
parseColumns
=
()
=>
{
parseColumns
=
()
=>
{
...
@@ -134,27 +214,44 @@ class QuestionManageContent extends Component {
...
@@ -134,27 +214,44 @@ class QuestionManageContent extends Component {
title
:
"题目"
,
title
:
"题目"
,
key
:
"questionStem"
,
key
:
"questionStem"
,
dataIndex
:
"questionStem"
,
dataIndex
:
"questionStem"
,
width
:
300
,
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
return
<
div
className=
"record-name"
>
{
val
}
</
div
>;
var
handleVal
=
val
;
handleVal
=
handleVal
.
replace
(
/<
(?!
img
)
.*
?
>/g
,
""
);
handleVal
=
handleVal
.
replace
(
/<
\s?
img
[^
>
]
*>/gi
,
"【图片】"
);
handleVal
=
handleVal
.
replace
(
/
\&
nbsp
\;
/gi
,
" "
);
return
(
<
Tooltip
title=
{
handleVal
}
>
<
div
className=
"record-name"
>
{
handleVal
}
</
div
>
</
Tooltip
>
);
},
},
},
},
{
{
title
:
"题型"
,
title
:
"题型"
,
key
:
"questionTypeEnum"
,
key
:
"questionTypeEnum"
,
dataIndex
:
"questionTypeEnum"
,
dataIndex
:
"questionTypeEnum"
,
render
:
(
val
)
=>
{
return
questionTypeEnum
[
val
];
},
},
},
{
{
title
:
"正确率"
,
title
:
"正确率"
,
key
:
"accuracy"
,
key
:
"accuracy"
,
dataIndex
:
"accuracy"
,
dataIndex
:
"accuracy"
,
sorter
:
true
,
sorter
:
true
,
sortDirections
:
[
"ascend"
,
"descend"
,
"ascend"
],
showSorterTooltip
:
false
,
render
:
(
val
)
=>
{
return
val
+
"%"
;
},
},
},
{
{
title
:
"更新时间"
,
title
:
"更新时间"
,
key
:
"updateTime"
,
key
:
"updateTime"
,
dataIndex
:
"updateTime"
,
dataIndex
:
"updateTime"
,
sorter
:
true
,
sorter
:
true
,
sortDirections
:
[
"ascend"
,
"descend"
,
"ascend"
],
showSorterTooltip
:
false
,
render
:
(
val
)
=>
{
render
:
(
val
)
=>
{
return
formatDate
(
"YYYY-MM-DD H:i:s"
,
val
);
return
formatDate
(
"YYYY-MM-DD H:i:s"
,
val
);
},
},
...
@@ -169,14 +266,14 @@ class QuestionManageContent extends Component {
...
@@ -169,14 +266,14 @@ class QuestionManageContent extends Component {
<
div
className=
"record-operate"
>
<
div
className=
"record-operate"
>
<
div
<
div
className=
"record-operate__item"
className=
"record-operate__item"
onClick=
{
()
=>
console
.
log
(
"预览"
)
}
onClick=
{
()
=>
this
.
previewQuestion
(
record
.
id
)
}
>
>
预览
预览
</
div
>
</
div
>
<
span
className=
"record-operate__item split"
>
|
</
span
>
<
span
className=
"record-operate__item split"
>
|
</
span
>
<
div
<
div
className=
"record-operate__item"
className=
"record-operate__item"
onClick=
{
()
=>
console
.
log
(
"预览"
)
}
onClick=
{
()
=>
this
.
toEditQuetion
(
record
.
id
,
record
.
questionTypeEnum
)
}
>
>
编辑
编辑
</
div
>
</
div
>
...
@@ -227,9 +324,9 @@ class QuestionManageContent extends Component {
...
@@ -227,9 +324,9 @@ class QuestionManageContent extends Component {
if
(
current
==
size
)
{
if
(
current
==
size
)
{
return
;
return
;
}
}
let
_query
=
this
.
props
.
query
;
let
_query
=
this
.
state
.
query
;
_query
.
size
=
size
;
_query
.
size
=
size
;
this
.
props
.
onChange
(
_query
);
this
.
setState
({
query
:
_query
},
()
=>
this
.
queryQuestionPageList
()
);
};
};
// 改变搜索条件
// 改变搜索条件
...
@@ -250,8 +347,8 @@ class QuestionManageContent extends Component {
...
@@ -250,8 +347,8 @@ class QuestionManageContent extends Component {
};
};
render
()
{
render
()
{
const
{
dataSource
=
[],
total
Count
,
query
}
=
this
.
state
;
const
{
dataSource
=
[],
total
,
query
}
=
this
.
state
;
const
{
current
,
size
,
categoryId
}
=
query
;
const
{
current
,
size
,
categoryId
,
questionName
,
questionType
}
=
query
;
return
(
return
(
<
div
className=
"question-manage-content"
>
<
div
className=
"question-manage-content"
>
<
div
className=
"question-manage-filter"
>
<
div
className=
"question-manage-filter"
>
...
@@ -261,6 +358,7 @@ class QuestionManageContent extends Component {
...
@@ -261,6 +358,7 @@ class QuestionManageContent extends Component {
<
span
className=
"search-label"
>
题目:
</
span
>
<
span
className=
"search-label"
>
题目:
</
span
>
<
Search
<
Search
placeholder=
"搜索题目名称"
placeholder=
"搜索题目名称"
value=
{
questionName
}
style=
{
{
width
:
"calc(100% - 84px)"
}
}
style=
{
{
width
:
"calc(100% - 84px)"
}
}
onChange=
{
(
e
)
=>
{
onChange=
{
(
e
)
=>
{
this
.
handleChangeQuery
(
"questionName"
,
e
.
target
.
value
);
this
.
handleChangeQuery
(
"questionName"
,
e
.
target
.
value
);
...
@@ -275,6 +373,7 @@ class QuestionManageContent extends Component {
...
@@ -275,6 +373,7 @@ class QuestionManageContent extends Component {
<
span
className=
"search-label"
>
题型:
</
span
>
<
span
className=
"search-label"
>
题型:
</
span
>
<
Select
<
Select
placeholder=
"请选择题目类型"
placeholder=
"请选择题目类型"
value=
{
questionType
}
style=
{
{
width
:
"calc(100% - 70px)"
}
}
style=
{
{
width
:
"calc(100% - 70px)"
}
}
showSearch
showSearch
allowClear
allowClear
...
@@ -282,7 +381,7 @@ class QuestionManageContent extends Component {
...
@@ -282,7 +381,7 @@ class QuestionManageContent extends Component {
option
.
props
.
children
.
includes
(
inputVal
)
option
.
props
.
children
.
includes
(
inputVal
)
}
}
onChange=
{
(
value
)
=>
{
onChange=
{
(
value
)
=>
{
if
(
_
.
isEmpty
(
value
))
{
if
(
_
.
isEmpty
(
value
))
{
this
.
handleChangeQuery
(
"questionType"
,
value
);
this
.
handleChangeQuery
(
"questionType"
,
value
);
}
}
}
}
}
}
...
@@ -333,25 +432,29 @@ class QuestionManageContent extends Component {
...
@@ -333,25 +432,29 @@ class QuestionManageContent extends Component {
rowKey=
{
(
record
)
=>
record
.
id
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
columns=
{
this
.
parseColumns
()
}
onChange=
{
this
.
handleChangeTable
}
pagination=
{
false
}
pagination=
{
false
}
bordered
bordered
onChange=
{
this
.
handleChangeTable
}
/>
/>
</
ConfigProvider
>
</
ConfigProvider
>
{
total
Count
>
0
&&
(
{
total
>
0
&&
(
<
div
className=
"box-footer"
>
<
div
className=
"box-footer"
>
<
PageControl
<
PageControl
current=
{
current
-
1
}
current=
{
current
-
1
}
pageSize=
{
size
}
pageSize=
{
size
}
total=
{
total
Count
}
total=
{
total
}
toPage=
{
(
page
)
=>
{
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
);
this
.
setState
({
query
:
_query
},
()
=>
this
.
queryQuestionPageList
()
);
}
}
}
}
showSizeChanger=
{
true
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
/>
</
div
>
</
div
>
)
}
)
}
{
this
.
state
.
QuestionPreviewModal
}
</
div
>
</
div
>
</
div
>
</
div
>
);
);
...
...
src/modules/teach-tool/components/QuestionManageContent.less
View file @
96b7a4c4
...
@@ -2,11 +2,11 @@
...
@@ -2,11 +2,11 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-25 11:26:28
* @Date: 2021-02-25 11:26:28
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 16:42:41
* @LastEditTime: 2021-03-1
5 09:42:30
* @Description: 助学工具-题库-题目管理右侧内容样式
* @Description: 助学工具-题库-题目管理右侧内容样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
.question-manage-content {
.question-manage-content {
.question-manage-filter {
.question-manage-filter {
position: relative;
position: relative;
.search-condition {
.search-condition {
...
@@ -57,12 +57,10 @@
...
@@ -57,12 +57,10 @@
cursor: pointer;
cursor: pointer;
}
}
.record-name {
.record-name {
word-break: break-all;
overflow: hidden;
overflow: hidden;
text-overflow: ellipsis;
text-overflow: ellipsis;
display: -webkit-box;
white-space: nowrap;
-webkit-line-clamp: 5;
width: 232px;
-webkit-box-orient: vertical;
}
}
.record-operate {
.record-operate {
display: flex;
display: flex;
...
...
src/modules/teach-tool/components/model.js
View file @
96b7a4c4
/*
/*
* @Author: chenjianyu
* @Author: chenjianyu
* @Date: 2020-09-12 17:00:44
* @Date: 2020-09-12 17:00:44
* @LastEditTime: 2021-03-1
3 11:19:38
* @LastEditTime: 2021-03-1
5 13:00:10
* @LastEditors: yuananting
* @LastEditors: yuananting
* @Description: 答题模式模板
* @Description: 答题模式模板
* @Copyright © 2020 杭州杰竞科技有限公司 版权所有
* @Copyright © 2020 杭州杰竞科技有限公司 版权所有
...
@@ -73,7 +73,7 @@ export function defineQuestionInfo(questionType) {
...
@@ -73,7 +73,7 @@ export function defineQuestionInfo(questionType) {
export
function
defineOptionInfo
()
{
export
function
defineOptionInfo
()
{
return
{
return
{
isCorrectAnswer
:
false
,
// 是否为正确答案选项
isCorrectAnswer
:
0
,
// 是否为正确答案选项
questionOptionContentList
:
[
// 选项内容
questionOptionContentList
:
[
// 选项内容
{
{
contentType
:
"QUESTION_OPTION"
,
// 内容类型(默认选项)
contentType
:
"QUESTION_OPTION"
,
// 内容类型(默认选项)
...
...
src/modules/teach-tool/modal/NewEditQuestionBankCategory.jsx
View file @
96b7a4c4
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-02-22 17:51:28
* @Date: 2021-02-22 17:51:28
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-03-1
3 14:26:31
* @LastEditTime: 2021-03-1
5 09:56:59
* @Description: 助学工具-题库-题库新建或编辑题库分类模态框
* @Description: 助学工具-题库-题库新建或编辑题库分类模态框
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -10,7 +10,6 @@ import React, { Component } from "react";
...
@@ -10,7 +10,6 @@ import React, { Component } from "react";
import
{
Modal
,
Form
,
Input
,
message
}
from
"antd"
;
import
{
Modal
,
Form
,
Input
,
message
}
from
"antd"
;
import
User
from
"@/common/js/user"
;
import
User
from
"@/common/js/user"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
import
{
node
}
from
"prop-types"
;
class
NewEditQuestionBankCategory
extends
Component
{
class
NewEditQuestionBankCategory
extends
Component
{
formRef
=
React
.
createRef
();
formRef
=
React
.
createRef
();
constructor
(
props
)
{
constructor
(
props
)
{
...
@@ -31,7 +30,7 @@ class NewEditQuestionBankCategory extends Component {
...
@@ -31,7 +30,7 @@ class NewEditQuestionBankCategory extends Component {
queryCategoryTree
=
()
=>
{
queryCategoryTree
=
()
=>
{
let
query
=
{
let
query
=
{
source
:
0
,
source
:
0
,
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
};
};
QuestionBankService
.
queryCategoryTree
(
query
).
then
((
res
)
=>
{
QuestionBankService
.
queryCategoryTree
(
query
).
then
((
res
)
=>
{
...
@@ -47,7 +46,7 @@ class NewEditQuestionBankCategory extends Component {
...
@@ -47,7 +46,7 @@ class NewEditQuestionBankCategory extends Component {
let
params
=
{
let
params
=
{
source
:
0
,
source
:
0
,
tenantId
:
User
.
getStoreId
(),
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
userId
:
User
.
get
Store
UserId
(),
};
};
if
(
type
===
"new"
)
{
if
(
type
===
"new"
)
{
//新增
//新增
...
...
src/modules/teach-tool/modal/QuestionPreviewModal.jsx
0 → 100644
View file @
96b7a4c4
import
React
,
{
Component
}
from
"react"
;
import
{
Modal
,
Divider
}
from
"antd"
;
import
User
from
"@/common/js/user"
;
import
QuestionBankService
from
"@/domains/question-bank-domain/QuestionBankService"
;
import
"./QuestionPreviewModal.less"
;
import
ScanFileModal
from
"@/modules/resource-disk/modal/ScanFileModal"
;
import
_
from
"underscore"
;
import
XMAudio
from
"../components/XMAudio"
;
import
{
NUM_TO_WORD_MAP
}
from
"@/common/constants/punchClock/punchClock"
;
const
questionTypeList
=
{
SINGLE_CHOICE
:
"单选题"
,
MULTI_CHOICE
:
"多选题"
,
JUDGE
:
"判断题"
,
GAP_FILLING
:
"填空题"
,
INDEFINITE_CHOICE
:
"不定项选择题"
,
};
class
QuestionPreviewModal
extends
Component
{
formRef
=
React
.
createRef
();
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
questionInfo
:
{},
};
}
componentDidMount
()
{
this
.
queryQuestionDetails
();
}
// 题目预览
queryQuestionDetails
=
()
=>
{
let
query
=
{
id
:
this
.
props
.
id
,
source
:
0
,
userId
:
User
.
getStoreUserId
(),
tenantId
:
User
.
getStoreId
(),
};
QuestionBankService
.
queryQuestionDetails
(
query
).
then
((
res
)
=>
{
const
{
result
=
[]
}
=
res
;
this
.
setState
({
questionInfo
:
result
});
});
};
handleScanFile
=
(
scanFileType
,
scanFileAddress
)
=>
{
this
.
setState
({
showScanFile
:
true
,
scanFileAddress
,
scanFileType
,
});
};
render
()
{
const
{
showScanFile
,
scanFileAddress
,
scanFileType
,
questionInfo
,
}
=
this
.
state
;
const
{
questionTypeEnum
,
questionStemList
,
optionList
,
questionAnswerDescList
,
}
=
questionInfo
;
// 查找答案选项
let
rightAnswerSort
=
[];
_
.
filter
(
optionList
,
(
optionItem
,
optionIndex
)
=>
{
if
(
optionItem
.
isCorrectAnswer
===
1
)
{
rightAnswerSort
.
push
(
optionIndex
);
}
});
const
textDescList
=
_
.
filter
(
questionAnswerDescList
,
(
descItem
)
=>
{
return
descItem
.
type
===
"RICH_TEXT"
;
});
const
pictureDescList
=
_
.
filter
(
questionAnswerDescList
,
(
descItem
)
=>
{
return
descItem
.
type
===
"PICTURE"
;
});
const
voiceDescList
=
_
.
filter
(
questionAnswerDescList
,
(
descItem
)
=>
{
return
descItem
.
type
===
"VOICE"
;
});
const
recordDescList
=
_
.
filter
(
questionAnswerDescList
,
(
descItem
)
=>
{
return
descItem
.
type
===
"RECORD"
;
});
const
videoDeacList
=
_
.
filter
(
questionAnswerDescList
,
(
descItem
)
=>
{
return
descItem
.
type
===
"VIDEO"
;
});
return
(
<
div
>
<
Modal
className=
"question-preview-modal"
visible=
{
true
}
title=
"题目预览"
width=
{
560
}
footer=
{
null
}
onCancel=
{
this
.
props
.
close
}
>
<
div
className=
"question-modal-content"
>
<
div
className=
"question-type"
>
<
div
className=
"question-type__title"
>
题型:
</
div
>
<
div
className=
"question-type__content"
>
{
questionTypeList
[
questionTypeEnum
]
}
</
div
>
</
div
>
<
div
className=
"question-stem"
>
<
div
className=
"question-stem__title"
>
题目:
</
div
>
<
div
className=
"question-stem__content"
>
{
_
.
map
(
questionStemList
,
(
item
,
index
)
=>
{
let
dom
=
""
;
let
{
type
,
content
,
size
}
=
item
;
switch
(
type
)
{
case
"RICH_TEXT"
:
dom
=
(
<
div
key=
{
index
}
className=
"input-box"
dangerouslySetInnerHTML=
{
{
__html
:
content
,
}
}
/>
);
break
;
case
"PICTURE"
:
dom
=
(
<
div
key=
{
index
}
className=
"picture-box"
>
<
img
src=
{
content
}
onClick=
{
()
=>
this
.
handleScanFile
(
"JPG"
,
content
)
}
/>
</
div
>
);
break
;
case
"VOICE"
:
dom
=
(
<
div
key=
{
index
}
className=
"voice-box"
>
<
XMAudio
forbidParse
url=
{
content
}
getDuration=
{
(
durationSize
)
=>
{
size
=
durationSize
;
this
.
setState
({});
}
}
index=
{
index
}
size=
{
size
||
1000
}
/>
</
div
>
);
break
;
}
return
dom
;
})
}
</
div
>
</
div
>
<
hr
style=
{
{
margin
:
"16px 0"
,
color
:
"#E8E8E8"
,
height
:
"1px"
}
}
/>
<
div
className=
"question-option"
>
<
div
className=
"question-option__title"
>
选项:
</
div
>
<
div
className=
"question-option__content"
>
{
_
.
map
(
optionList
,
(
optionItem
,
optionIndex
)
=>
{
const
{
questionOptionContentList
}
=
optionItem
;
const
inputcontent
=
_
.
filter
(
questionOptionContentList
,
(
optionItem
)
=>
{
return
optionItem
.
type
===
"RICH_TEXT"
;
}
);
return
(
<
div
className=
"option-box"
key=
{
optionIndex
}
>
<
div
className=
"option-box-header"
>
<
div
className=
"option-sort"
>
{
NUM_TO_WORD_MAP
[
optionIndex
]
}
.
</
div
>
<
div
className=
"input-box"
dangerouslySetInnerHTML=
{
{
__html
:
inputcontent
[
0
].
content
,
}
}
/>
</
div
>
{
_
.
map
(
questionOptionContentList
,
(
item
,
index
)
=>
{
let
dom
=
""
;
let
{
type
,
content
,
size
}
=
item
;
switch
(
type
)
{
case
"PICTURE"
:
dom
=
(
<
div
key=
{
index
+
1
}
className=
"picture-box"
>
<
img
src=
{
content
}
onClick=
{
()
=>
this
.
handleScanFile
(
"JPG"
,
content
)
}
/>
</
div
>
);
break
;
case
"VOICE"
:
dom
=
(
<
div
key=
{
index
+
1
}
className=
"voice-box"
>
<
XMAudio
forbidParse
url=
{
content
}
getDuration=
{
(
durationSize
)
=>
{
size
=
durationSize
;
this
.
setState
({});
}
}
index=
{
index
}
size=
{
size
||
1000
}
/>
</
div
>
);
break
;
}
return
dom
;
})
}
</
div
>
);
})
}
</
div
>
</
div
>
<
div
className=
"question-answer"
>
<
div
className=
"question-answer__title"
>
答案:
</
div
>
<
div
className=
"question-answer__content"
>
{
_
.
map
(
rightAnswerSort
,
(
item
,
index
)
=>
{
return
(
<
div
className=
"option-sort"
key=
{
index
}
>
{
NUM_TO_WORD_MAP
[
item
]
}
</
div
>
);
})
}
</
div
>
</
div
>
<
hr
style=
{
{
margin
:
"16px 0"
,
color
:
"#E8E8E8"
,
height
:
"1px"
}
}
/>
<
div
className=
"question-desc"
>
<
div
className=
"question-desc__title"
>
答案解析:
</
div
>
<
div
className=
"question-desc__content"
>
<
div
className=
"question-desc-box"
>
{
textDescList
.
length
>
0
&&
(
<
div
className=
"desc-input-box"
dangerouslySetInnerHTML=
{
{
__html
:
textDescList
[
0
].
content
,
}
}
/>
)
}
{
pictureDescList
.
length
>
0
&&
(
<
div
className=
"desc-picture-box"
>
{
_
.
map
(
pictureDescList
,
(
pictureItem
,
pictureIndex
)
=>
{
let
{
content
}
=
pictureItem
;
return
(
<
div
className=
"picture-box"
key=
{
pictureIndex
}
>
<
img
className=
"img-box"
src=
{
content
}
onClick=
{
()
=>
this
.
handleScanFile
(
"JPG"
,
content
)
}
/>
</
div
>
);
})
}
</
div
>
)
}
{
recordDescList
.
length
>
0
&&
(
<
div
className=
"desc-audio-box"
>
{
_
.
map
(
recordDescList
,
(
recordItem
,
recordIndex
)
=>
{
let
{
content
,
size
}
=
recordItem
;
return
(
<
div
className=
"audio-box"
key=
{
recordIndex
}
>
<
XMAudio
forbidParse
url=
{
content
}
getDuration=
{
(
durationSize
)
=>
{
size
=
durationSize
;
this
.
setState
({});
}
}
index=
{
recordIndex
}
size=
{
size
||
1000
}
/>
</
div
>
);
})
}
</
div
>
)
}
{
voiceDescList
.
length
>
0
&&
(
<
div
className=
"desc-audio-box"
>
{
_
.
map
(
voiceDescList
,
(
voiceItem
,
voiceIndex
)
=>
{
let
{
content
,
size
}
=
voiceItem
;
return
(
<
div
className=
"audio-box"
key=
{
voiceIndex
}
>
<
XMAudio
forbidParse
url=
{
content
}
getDuration=
{
(
durationSize
)
=>
{
size
=
durationSize
;
this
.
setState
({});
}
}
index=
{
voiceIndex
}
size=
{
size
||
1000
}
/>
</
div
>
);
})
}
</
div
>
)
}
{
videoDeacList
.
length
>
0
&&
(
<
div
className=
"desc-video-box"
>
{
_
.
map
(
videoDeacList
,
(
videoItem
,
videoIndex
)
=>
{
let
{
content
}
=
videoItem
;
return
(
<
div
className=
"video-box"
key=
{
videoIndex
}
>
<
img
className=
"video-box_content"
src=
{
`${content}?x-oss-process=video/snapshot,t_0,m_fast`
}
/>
<
img
className=
"video-box_btn"
src=
"https://image.xiaomaiketang.com/xm/r5H8cYm4ch.png"
onClick=
{
()
=>
this
.
handleScanFile
(
"MP4"
,
content
)
}
/>
</
div
>
);
})
}
</
div
>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
Modal
>
{
showScanFile
&&
(
<
ScanFileModal
modalTitle=
{
scanFileType
===
"MP4"
?
"视频播放"
:
"查看大图"
}
fileType=
{
scanFileType
}
item=
{
{
ossAddress
:
scanFileAddress
,
}
}
close=
{
()
=>
{
this
.
setState
({
showScanFile
:
false
});
}
}
/>
)
}
</
div
>
);
}
}
export
default
QuestionPreviewModal
;
src/modules/teach-tool/modal/QuestionPreviewModal.less
0 → 100644
View file @
96b7a4c4
.question-modal-content {
position: relative;
.question-type {
margin-bottom: 16px;
&__title {
height: 22px;
font-size: 16px;
color: #333333;
line-height: 22px;
margin-bottom: 8px;
}
&__content {
font-size: 14px;
font-weight: 400;
color: #666666;
}
}
.question-stem {
margin-bottom: 16px;
img {
max-width: 88px;
max-height: 88px;
}
&__title {
height: 22px;
font-size: 16px;
color: #333333;
line-height: 22px;
margin-bottom: 8px;
}
&__content {
font-size: 14px;
font-weight: 400;
color: #666666;
.input-box {
margin-bottom: 8px;
* {
display: inline-block;
}
}
.picture-box {
display: inline-flex;
margin: 12px 12px 0 0;
}
.voice-box {
margin-bottom: 12px;
box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1);
padding: 10px 20px;
width: 320px;
}
}
}
.question-option {
margin-bottom: 16px;
img {
max-width: 88px;
max-height: 88px;
}
&__title {
height: 22px;
font-size: 16px;
color: #333333;
line-height: 22px;
margin-bottom: 8px;
}
&__content {
font-size: 14px;
font-weight: 400;
color: #666666;
.option-box {
color: #666666;
margin-bottom: 8px;
.option-box-header {
.option-sort {
display: inline-block;
margin-right: 5px;
}
.input-box {
display: inline-block;
max-width: calc(100% - 20px);
vertical-align: top;
}
}
.picture-box {
display: inline-flex;
margin: 12px 12px 0 0;
}
.voice-box {
margin-bottom: 12px;
box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1);
padding: 10px 20px;
width: 320px;
}
}
}
}
.question-answer {
margin-bottom: 16px;
img {
max-width: 88px;
max-height: 88px;
}
&__title {
height: 22px;
font-size: 16px;
color: #333333;
line-height: 22px;
margin-bottom: 8px;
}
&__content {
font-size: 14px;
font-weight: 400;
color: #666666;
.option-sort {
display: inline-block;
margin-right: 8px;
}
}
}
.question-desc {
margin-bottom: 16px;
&__title {
height: 22px;
font-size: 16px;
color: #333333;
line-height: 22px;
margin-bottom: 8px;
}
&__content {
font-size: 14px;
font-weight: 400;
color: #666666;
.desc-input-box {
margin-bottom: 8px;
* {
display: inline-block;
}
}
.desc-picture-box {
display: inline-flex;
margin-bottom: 28px;
.picture-box {
width: 88px;
height: 88px;
border-radius: 4px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
.img-box {
max-width: 88px;
max-height: 88px;
border-radius: 4px;
}
}
}
.desc-audio-box {
margin-bottom: 28px;
.audio-box {
box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1);
padding: 10px 20px;
width: 320px;
margin-bottom: 12px;
}
}
.desc-video-box {
.video-box {
position: relative;
display: inline-block;
width: 208px;
overflow: hidden;
padding-top: 12px;
margin: 0px 12px 12px 0;
&_content {
max-width: 200px;
max-height: 200px;
border-radius: 4px;
}
&_btn {
width: 32px;
height: 32px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -8px;
margin-left: -16px;
}
}
}
}
}
}
.question-preview-modal.ant-modal {
max-height: 60% !important;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment