Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-qa
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-qa
Commits
7f689cd5
提交
7f689cd5
authored
2月 28, 2022
作者:
matian
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master'
上级
aaa33184
7651caa9
隐藏空白字符变更
内嵌
并排
正在显示
26 个修改的文件
包含
1687 行增加
和
1357 行删除
+1687
-1357
.eslintrc.js
.eslintrc.js
+1
-0
AppCard.vue
src/components/base/AppCard.vue
+1
-0
AppList.vue
src/components/base/AppList.vue
+1
-1
api.js
src/modules/paper/api.js
+36
-6
AddPaper.vue
src/modules/paper/components/AddPaper.vue
+168
-122
BatchSetting.vue
src/modules/paper/components/BatchSetting.vue
+1
-1
PaperQuestions.vue
src/modules/paper/components/PaperQuestions.vue
+103
-0
QuestionList.vue
src/modules/paper/components/QuestionList.vue
+20
-657
QuestionListItem.vue
src/modules/paper/components/QuestionListItem.vue
+127
-0
QuestionListItems.vue
src/modules/paper/components/QuestionListItems.vue
+0
-242
QuestionNum.vue
src/modules/paper/components/QuestionNum.vue
+30
-20
QuestionSelect.vue
src/modules/paper/components/QuestionSelect.vue
+1
-1
Detail.vue
src/modules/paper/views/Detail.vue
+542
-6
List.vue
src/modules/paper/views/List.vue
+40
-12
NewPaper.vue
src/modules/paper/views/NewPaper.vue
+1
-2
api.js
src/modules/question/api.js
+9
-92
AddChidren.vue
src/modules/question/components/AddChidren.vue
+201
-26
Detail.vue
src/modules/question/components/Detail.vue
+49
-34
QTypeCheckbox.vue
src/modules/question/components/QTypeCheckbox.vue
+9
-1
QTypeJudgment.vue
src/modules/question/components/QTypeJudgment.vue
+8
-1
QTypeRadio.vue
src/modules/question/components/QTypeRadio.vue
+9
-2
QTypeSituation.vue
src/modules/question/components/QTypeSituation.vue
+184
-46
QuestionsChidren.vue
src/modules/question/components/QuestionsChidren.vue
+69
-53
Create.vue
src/modules/question/views/Create.vue
+38
-6
List.vue
src/modules/question/views/List.vue
+39
-25
axios.js
src/utils/axios.js
+0
-1
没有找到文件。
.eslintrc.js
浏览文件 @
7f689cd5
...
...
@@ -4,6 +4,7 @@ module.exports = {
},
extends
:
[
'plugin:vue/essential'
,
'standard'
],
rules
:
{
'vue/no-mutating-props'
:
'off'
,
// 暂时关闭
'vue/comment-directive'
:
'off'
,
'vue/multi-word-component-names'
:
'off'
,
'space-before-function-paren'
:
'off'
...
...
src/components/base/AppCard.vue
浏览文件 @
7f689cd5
...
...
@@ -31,6 +31,7 @@ export default {
}
.app-card-hd
{
display
:
flex
;
align-items
:
flex-start
;
}
.app-card-hd__title
{
flex
:
1
;
...
...
src/components/base/AppList.vue
浏览文件 @
7f689cd5
...
...
@@ -147,7 +147,7 @@ export default {
// 翻页参数设置
if
(
this
.
hasPagination
)
{
params
.
page
=
this
.
page
.
currentPage
.
toString
()
params
.
page_size
=
this
.
page
.
size
.
toString
()
params
.
limit
=
this
.
page
.
size
.
toString
()
}
// 接口请求之前
if
(
beforeRequest
)
{
...
...
src/modules/paper/api.js
浏览文件 @
7f689cd5
import
httpRequest
from
'@/utils/axios'
/**
* 获取知识点/标签
*/
export
function
getKnowledge
(
params
)
{
return
httpRequest
.
get
(
'/admin/v1/knowledge-point/search/x1'
,
{
params
})
}
/**
* 获取试卷列表
*/
...
...
@@ -34,9 +28,45 @@ export function getPaper(params) {
return
httpRequest
.
get
(
`/api/qbs/admin/v1/question-paper/
${
params
.
id
}
`
,
{
params
})
}
/**
* 删除试卷
*/
export
function
batchDeletePaper
(
data
)
{
return
httpRequest
.
post
(
'/api/qbs/admin/v1/question-paper/batch-delete'
,
data
)
}
/**
* 获取试题列表
*/
export
function
getQuestionList
(
params
)
{
return
httpRequest
.
get
(
'/api/qbs/admin/v1/questions'
,
{
params
})
}
/**
* 批量获取试题列表
*/
export
function
batchGetQuestionList
(
data
)
{
return
httpRequest
.
post
(
'/api/qbs/admin/v1/questions/batch'
,
data
)
}
/**
* 设置组题规则
* 添加试题和设置试题分数
*/
export
function
updatePaperRules
(
data
)
{
return
httpRequest
.
post
(
`/api/qbs/admin/v1/question-paper/rules/
${
data
.
id
}
`
,
data
)
}
/**
* 获取试卷分类
*/
export
function
getPaperCategory
(
params
)
{
return
httpRequest
.
get
(
`/api/qbs/admin/v1/question-category/tree/
${
params
.
project_prefix
}
`
,
{
params
})
}
/**
* 获取知识点/标签
*/
export
function
getKnowledge
(
params
)
{
return
httpRequest
.
get
(
'/admin/v1/knowledge-point/search/x1'
,
{
params
})
}
src/modules/paper/components/AddPaper.vue
浏览文件 @
7f689cd5
<
template
>
<el-drawer
size=
"50%"
v-bind=
"$attrs"
v-on=
"$listeners"
>
<!-- 选题组卷添加试卷第一步 -->
<div
v-show=
"isShowFirstStep"
>
<app-list
v-bind=
"tableOptions"
ref=
"list"
style=
"padding-left: 30px"
>
</app-list>
<el-button
type=
"primary"
class=
"nextStep"
@
click=
"nextStep"
>
下一步
</el-button>
<el-drawer
title=
"添加试卷试题"
size=
"70%"
v-bind=
"$attrs"
v-on=
"$listeners"
>
<div
style=
"margin: 0 20px"
>
<!-- 选题组卷添加试卷第一步 -->
<div
v-show=
"step === 1"
>
<app-list
v-bind=
"tableOptions"
ref=
"list"
@
selection-change=
"handleSelectionChange"
></app-list>
<el-button
type=
"primary"
class=
"nextStep"
@
click=
"nextStep"
>
下一步
</el-button>
</div>
<!-- 选题组卷添加试卷第二步 -->
<div
v-show=
"step === 2"
>
<el-form
label-width=
"170px"
>
<el-form-item
label=
"试题分值设置方式:"
>
<el-radio-group
v-model=
"setMethod"
>
<el-radio
:label=
"1"
>
批量设置
</el-radio>
<el-radio
:label=
"2"
>
逐题设置
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"您此次选择的试题总数:"
>
{{
multipleSelection
.
length
}}
</el-form-item>
<el-form-item
label=
"此次试卷总分:"
>
{{
data
.
paper_total_score
}}
</el-form-item>
<el-form-item
label=
"已设置试题总分:"
>
{{
addedQuestionsScore
}}
</el-form-item>
<el-divider></el-divider>
<el-form-item
:label=
"item.question_type_name + ':'"
v-for=
"(item, index) in questionTypeGroups"
:key=
"index"
>
<span>
数量:
{{
item
.
total
}}
</span>
<span
style=
"margin-left: 20px"
>
分值:
<el-input
v-model=
"item.score"
style=
"width: 100px"
></el-input>
{{
item
.
score
}}
</span
>
<!--
<template
v-if=
"canBatchSetting(item.question_type)"
>
<el-button
type=
"primary"
class=
"settingScore"
@
click=
"batchSetting"
>
批量设置分数
</el-button>
</
template
>
<
template
v-else
>
<span
class=
"settingScore"
>
此题型只能在试卷详情页面逐一设置
</span>
</
template
>
-->
</el-form-item>
<el-button
type=
"primary"
@
click=
"prevStep"
>
上一步
</el-button>
<el-button
type=
"primary"
style=
"margin-left: 20px"
@
click=
"handleSubmit"
>
保存
</el-button>
</el-form>
</div>
<BatchSetting
:visible
.
sync=
"visible"
/>
</div>
<!-- 选题组卷添加试卷第二步 -->
<div
class=
"isShowNextStep"
style=
"padding-left: 30px"
v-show=
"isShowNextStep"
>
<el-form>
<el-form-item
label=
"试题分值设置方式:"
>
<el-radio-group>
<el-radio
label=
"批量设置"
></el-radio>
<el-radio
label=
"逐题设置"
></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"您此次选择的试题总数:"
>
25
</el-form-item>
<el-form-item
label=
"此次试卷总分:"
>
100
</el-form-item>
<el-form-item
label=
"已设置试题总分:"
>
0
</el-form-item>
<el-divider></el-divider>
<el-form-item
label=
"单选题:"
>
<span>
数量:8
</span>
<span>
分值:0
</span>
<el-button
type=
"primary"
class=
"settingScore"
@
click=
"batchSetting"
>
批量设置分数
</el-button>
</el-form-item>
<el-form-item
label=
"多选题:"
class=
"titleSetting"
>
<span>
数量:8
</span>
<span>
分值:0
</span>
<el-button
type=
"primary"
class=
"settingScore"
>
批量设置分数
</el-button>
</el-form-item>
<el-form-item
label=
"判断题:"
class=
"titleSetting"
>
<span>
数量:8
</span>
<span>
分值:0
</span>
<el-button
type=
"primary"
class=
"settingScore"
>
批量设置分数
</el-button>
</el-form-item>
<el-form-item
label=
"问答题:"
class=
"titleSetting"
>
<span>
数量:8
</span>
<span>
分值:0
</span>
<span
class=
"settingScore"
>
此题型只能在试卷详情页面逐一设置
</span>
</el-form-item>
<el-form-item
label=
"情景题:"
class=
"titleSetting"
>
<span>
数量:8
</span>
<span>
分值:0
</span>
<span
class=
"settingScore"
>
此题型只能在试卷详情页面逐一设置
</span>
</el-form-item>
<el-form-item
label=
"案例题:"
class=
"titleSetting"
>
<span>
数量:8
</span>
<span>
分值:0
</span>
<span
class=
"settingScore"
>
此题型只能在试卷详情页面逐一设置
</span>
</el-form-item>
<el-form-item
class=
"nextStep"
>
<el-button
type=
"primary"
@
click=
"lastStep"
>
上一步
</el-button>
<el-button
type=
"primary"
style=
"margin-left: 20px"
@
click=
"saveSetting"
>
保存
</el-button>
</el-form-item>
</el-form>
</div>
<BatchSetting
:visible
.
sync=
"visible"
/>
</el-drawer>
</template>
<
script
>
import
BatchSetting
from
'./BatchSetting.vue'
import
{
getQuestionList
,
batchGetQuestionList
,
updatePaperRules
}
from
'../api.js'
export
default
{
component
s
:
{
BatchSetting
prop
s
:
{
data
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
components
:
{
BatchSetting
},
data
()
{
return
{
visible
:
false
,
isShowFirstStep
:
true
,
isShowNextStep
:
false
multipleSelection
:
[],
// 选择项
setMethod
:
1
,
// 设置方式
step
:
1
,
questions
:
[],
// 试题列表
questionTypeGroups
:
{}
// 试题类型组
}
},
computed
:
{
tableOptions
()
{
return
{
// remote: { httpRequest: getAppList },
remote
:
{
httpRequest
:
getQuestionList
,
params
:
{
question_type
:
''
,
question_title
:
''
,
question_difficulty
:
''
,
question_category
:
''
}
},
filters
:
[
{
type
:
'
inpu
t'
,
prop
:
'
nam
e'
,
type
:
'
selec
t'
,
prop
:
'
question_typ
e'
,
placeholder
:
'请选择题目类型'
,
options
:
this
.
staffList
,
size
:
'small'
,
options
:
[
{
label
:
'单选题'
,
value
:
'1'
},
{
label
:
'多选题'
,
value
:
'2'
},
{
label
:
'问答题'
,
value
:
'3'
},
{
label
:
'案例题'
,
value
:
'5'
},
{
label
:
'判断题'
,
value
:
'6'
},
{
label
:
'实操题'
,
value
:
'7'
},
{
label
:
'情景题'
,
value
:
'8'
}
],
label
:
'题目类型'
},
{
type
:
'select'
,
prop
:
'
name1
'
,
prop
:
'
question_difficulty
'
,
placeholder
:
'请选择题目难度等级'
,
options
:
this
.
staffList
,
labelKey
:
'name'
,
valueKey
:
'id'
,
size
:
'small'
,
options
:
[
{
label
:
'易'
,
value
:
'1'
},
{
label
:
'中'
,
value
:
'2'
},
{
label
:
'难'
,
value
:
'3'
}
],
label
:
'难度等级'
},
{
type
:
'input'
,
prop
:
'
name2
'
,
prop
:
'
question_category
'
,
placeholder
:
'请选择试题分类'
,
options
:
this
.
staffList
,
size
:
'small'
,
label
:
'试题分类'
},
{
type
:
'select'
,
prop
:
'name3'
,
placeholder
:
'请输入题目标题内容'
,
options
:
this
.
natureList
,
labelKey
:
'name'
,
valueKey
:
'id'
,
size
:
'small'
,
label
:
'题目标题'
type
:
'input'
,
prop
:
'question_title'
,
label
:
'题目标题'
,
placeholder
:
'请输入题目标题'
},
{
type
:
'
selec
t'
,
type
:
'
inpu
t'
,
prop
:
'name4'
,
placeholder
:
'请输入题干内容'
,
options
:
this
.
natureList
,
labelKey
:
'name'
,
valueKey
:
'id'
,
size
:
'small'
,
label
:
'题干内容'
label
:
'题干内容'
,
placeholder
:
'请输入题干内容'
},
{
type
:
'
selec
t'
,
type
:
'
inpu
t'
,
prop
:
'name5'
,
placeholder
:
'请输入知识点'
,
options
:
this
.
natureList
,
labelKey
:
'name'
,
valueKey
:
'id'
,
size
:
'small'
,
label
:
'知识点'
label
:
'知识点'
,
placeholder
:
'请输入知识点'
}
],
columns
:
[
{
type
:
'selection'
,
minWidth
:
'50px'
,
fixed
:
'left'
},
{
type
:
'index'
,
label
:
'序号'
,
minWidth
:
'50px'
,
fixed
:
'left'
},
{
label
:
'题目类型'
,
prop
:
'name'
},
{
label
:
'试卷分类'
,
prop
:
'alias_name'
},
{
label
:
'题目标题'
,
prop
:
'desc'
},
{
label
:
'知识点'
,
prop
:
'desc2'
},
{
label
:
'难度等级'
,
prop
:
'desc3'
},
{
label
:
'更新人'
,
prop
:
'desc4'
}
],
data
:
[
{
type
:
'selection'
},
{
type
:
'index'
,
label
:
'序号'
},
{
index
:
1
,
name
:
'dfshfh'
label
:
'题目类型'
,
prop
:
'question_type'
,
computed
:
({
row
})
=>
{
const
map
=
{
1
:
'单选题'
,
2
:
'多选题'
,
3
:
'问答题'
,
5
:
'案例题'
,
6
:
'判断题'
,
7
:
'实操题'
,
8
:
'情景题'
}
return
map
[
row
.
question_type
]
||
row
.
question_type
}
},
{
label
:
'试卷分类'
,
prop
:
'question_category.category_name'
},
{
label
:
'题目标题'
,
prop
:
'question_title'
},
{
label
:
'知识点'
,
prop
:
'knowledge_point.title'
},
{
index
:
1
,
name
:
'dfshfh'
label
:
'难度等级'
,
prop
:
'question_difficulty'
,
computed
:
({
row
})
=>
{
const
map
=
{
1
:
'易'
,
2
:
'中'
,
3
:
'难'
}
return
map
[
row
.
question_difficulty
]
||
row
.
question_difficulty
}
},
{
index
:
1
,
name
:
'dfshfh'
}
{
label
:
'更新人'
,
prop
:
'operator.realname'
}
]
}
},
// 已添加的试题
addedQuestions
()
{
return
this
.
data
.
questions
||
[]
},
// 已添加的试题总分
addedQuestionsScore
()
{
return
this
.
addedQuestions
.
reduce
((
total
,
item
)
=>
{
return
total
+
parseInt
(
item
.
score
)
},
0
)
}
},
methods
:
{
handleSelectionChange
(
val
)
{
this
.
multipleSelection
=
val
},
// 下一步
nextStep
()
{
this
.
isShowFirstStep
=
false
this
.
isShowNextStep
=
true
if
(
!
this
.
multipleSelection
.
length
)
{
this
.
$message
.
error
(
'请选择题目'
)
return
}
this
.
step
=
2
// 获取题目列表
this
.
batchGetQuestionList
()
},
// 上一步
lastStep
()
{
this
.
isShowFirstStep
=
true
this
.
isShowNextStep
=
false
prevStep
()
{
this
.
step
=
1
},
// 保存
saveSetting
()
{
this
.
$emit
(
'update:visible'
,
false
)
// 批量获取试题列表,根据选中的试题
batchGetQuestionList
()
{
const
ids
=
this
.
multipleSelection
.
map
(
item
=>
item
.
id
)
batchGetQuestionList
({
ids
}).
then
(
res
=>
{
this
.
questions
=
res
.
data
this
.
questionTypeGroups
=
this
.
questions
.
reduce
((
result
,
item
)
=>
{
const
map
=
{
1
:
'单选题'
,
2
:
'多选题'
,
3
:
'问答题'
,
5
:
'案例题'
,
6
:
'判断题'
,
7
:
'实操题'
,
8
:
'情景题'
}
if
(
result
[
item
.
question_type
])
{
result
[
item
.
question_type
].
total
+=
1
result
[
item
.
question_type
].
questions
.
push
(
item
)
}
else
{
result
[
item
.
question_type
]
=
{
total
:
1
,
question_type
:
item
.
question_type
,
question_type_name
:
map
[
item
.
question_type
],
score
:
''
,
questions
:
[
item
]
}
}
return
result
},
{})
})
},
// 是否可以批量设置分数
canBatchSetting
(
value
)
{
return
[
1
,
2
,
6
].
includes
(
value
)
},
batchSetting
()
{
console
.
log
(
'bsdhfsjhfb'
)
this
.
visible
=
true
},
// 保存
handleSubmit
()
{
const
rules
=
[]
Object
.
values
(
this
.
questionTypeGroups
).
forEach
(
item
=>
{
item
.
questions
.
forEach
(
question
=>
{
rules
.
push
({
id
:
question
.
id
,
score
:
item
.
score
||
0
})
if
(
item
.
children
&&
item
.
children
.
length
)
{
item
.
children
.
forEach
(
question
=>
{
rules
.
push
({
id
:
question
.
id
,
score
:
item
.
score
||
0
})
})
}
})
})
const
parmas
=
{
id
:
this
.
data
.
id
,
rules
}
updatePaperRules
(
parmas
).
then
(()
=>
{
this
.
$message
.
success
(
'保存成功'
)
this
.
$emit
(
'update'
)
this
.
$emit
(
'update:visible'
,
false
)
})
}
}
}
...
...
src/modules/paper/components/BatchSetting.vue
浏览文件 @
7f689cd5
<
template
>
<el-dialog
v-bind=
"$attrs"
v-on=
"$listeners"
:modal=
"false"
width=
"20%
"
>
<el-dialog
title=
"批量设置分数"
v-bind=
"$attrs"
v-on=
"$listeners"
append-to-body
width=
"400px
"
>
<el-form>
<el-form-item>
单选题
</el-form-item>
<el-form-item>
数量:8
</el-form-item>
...
...
src/modules/paper/components/PaperQuestions.vue
0 → 100644
浏览文件 @
7f689cd5
<
template
>
<div>
<el-row
:gutter=
"20"
style=
"margin-top: 20px"
>
<!-- 试题列表 -->
<el-col
:span=
"18"
>
<app-card
title=
"试题列表"
>
<template
#
header-aside
>
<el-button
type=
"primary"
@
click=
"handleAdd"
>
添加试题
</el-button>
<el-button
type=
"primary"
@
click=
"handleRemove"
>
删除选中试题
</el-button>
</
template
>
<question-list
:list=
"questions"
>
<
template
v-slot:selection=
"item"
>
<el-checkbox
@
change=
"handleSelectionChange(arguments[0], item)"
></el-checkbox>
</
template
>
</question-list>
</app-card>
</el-col>
<!-- 试题序号 -->
<el-col
:span=
"6"
>
<question-num
:list=
"questions"
>
<
template
#
footer
>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
保存试卷
</el-button>
</
template
>
</question-num>
</el-col>
</el-row>
<!-- 选题组卷 -->
<
template
v-if=
"data.paper_type === 1"
>
<addPaper
:visible
.
sync=
"visible"
:data=
"data"
@
update=
"handelUpdate"
v-if=
"visible"
/>
</
template
>
<!-- 自动组卷 -->
<
template
v-if=
"data.paper_type === 2"
>
<AutomaticPaper
:visible
.
sync=
"visible"
:data=
"data"
@
update=
"handelUpdate"
v-if=
"visible"
/>
</
template
>
</div>
</template>
<
script
>
import
QuestionList
from
'./QuestionList.vue'
import
QuestionNum
from
'./QuestionNum.vue'
import
AddPaper
from
'./AddPaper.vue'
import
AutomaticPaper
from
'./AutomaticPaper.vue'
import
{
updatePaperRules
}
from
'../api.js'
export
default
{
props
:
{
data
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
components
:
{
QuestionList
,
QuestionNum
,
AddPaper
,
AutomaticPaper
},
data
()
{
return
{
visible
:
false
,
questions
:
[],
multipleSelection
:
[]
// 选择项
}
},
watch
:
{
data
:
{
immediate
:
true
,
handler
(
data
)
{
this
.
questions
=
data
.
questions
||
[]
}
}
},
computed
:
{},
methods
:
{
// 增加试题
handleAdd
()
{
this
.
visible
=
true
},
handleSelectionChange
(
checked
,
data
)
{
if
(
checked
)
{
this
.
multipleSelection
.
push
(
data
.
id
)
}
else
{
this
.
multipleSelection
=
this
.
multipleSelection
.
filter
(
id
=>
id
!==
data
.
id
)
}
},
// 删除选中试题
handleRemove
()
{
this
.
questions
=
this
.
questions
.
filter
(
item
=>
!
this
.
multipleSelection
.
includes
(
item
.
id
))
},
// 保存试卷
handleSubmit
()
{
const
rules
=
[]
this
.
questions
.
forEach
(
question
=>
{
rules
.
push
({
id
:
question
.
id
,
score
:
question
.
score
||
0
})
if
(
question
.
children
&&
question
.
children
.
length
)
{
question
.
children
.
forEach
(
question
=>
{
rules
.
push
({
id
:
question
.
id
,
score
:
question
.
score
||
0
})
})
}
})
const
parmas
=
{
id
:
this
.
data
.
id
,
rules
}
updatePaperRules
(
parmas
).
then
(
res
=>
{
this
.
$message
.
success
(
'保存成功'
)
})
},
// 更新详情数据
handelUpdate
()
{
this
.
$emit
(
'update'
)
}
}
}
</
script
>
src/modules/paper/components/QuestionList.vue
浏览文件 @
7f689cd5
<
template
>
<div
style=
"margin-top: 32px"
>
<el-row
:gutter=
"20"
>
<!-- 试题列表 -->
<el-col
:span=
"18"
>
<el-card
id=
"questionMain"
>
<div
slot=
"header"
class=
"clearfix"
>
<span
class=
"clearfix_tit"
>
试题列表
</span>
<el-button
class=
"clearfix_del"
type=
"primary"
@
click=
"delCheckedQuestion"
v-if=
"questionList.length > 0"
>
删除所选试题
</el-button
>
<el-button
class=
"clearfix_add"
type=
"primary"
@
click=
"addPaper"
>
添加试题
</el-button>
</div>
<!-- 题目列表 -->
<QuestionListItems
:questionList=
"getSortQuestionList()"
ref=
"listItemRef"
@
handlePosition=
"handlePosition"
@
selectSubjectsChange=
"selectSubjectsChange"
:disabled=
"selectQuestion.length === 0"
/>
<!-- 选题组卷无数据情况下显示 -->
<div
class=
"nonePaper"
v-show=
"questionList.length === 0"
>
<!--
<el-result
icon=
"info"
subTitle=
"该试卷无试题,去添加试题吧"
></el-result>
-->
</div>
</el-card>
</el-col>
<!-- 题目序号列表 -->
<el-col
:span=
"4"
v-if=
"getSortQuestionList().length > 0"
>
<el-card
style=
"position: fixed"
>
<div
class=
"titleIndex"
>
<ul>
<li
v-for=
"(item, index) in getSortQuestionList()"
:key=
"index"
@
click=
"titleClick(index)"
>
<div
id=
"subNum"
:class=
"currentIndex === index + 1 ? `titleItem` : ''"
>
{{
index
+
1
}}
</div>
<div
class=
"subType"
>
{{
subType
[
item
.
question_type
]
}}
</div>
</li>
</ul>
<div
style=
"margin-top: 10px; display: flex; justify-content: center; align-items: center"
>
<el-button
type=
"primary"
@
click=
"savePaper"
>
保存试卷
</el-button>
</div>
</div>
</el-card>
</el-col>
</el-row>
<AutomaticPaper
:visible
.
sync=
"visible"
v-if=
"paperMode === '自动组卷'"
/>
<addPaper
:visible
.
sync=
"visible"
v-else
/>
<div
class=
"question-list"
>
<template
v-for=
"(item, index) in list"
>
<question-list-item
:data=
"item"
:index=
"index + 1"
:key=
"item.id"
v-on=
"$listeners"
>
<template
v-if=
"item.children && item.children.length"
>
<question-list
:list=
"item.children"
:key=
"item.id"
v-on=
"$listeners"
>
<template
#
selection
>
<slot
name=
"selection"
v-bind=
"item"
></slot>
</
template
>
</question-list>
</template>
<
template
#
selection
>
<slot
name=
"selection"
v-bind=
"item"
></slot>
</
template
>
</question-list-item>
</template>
</div>
</template>
<
script
>
import
QuestionListItems
from
'./QuestionListItems.vue'
import
AutomaticPaper
from
'./AutomaticPaper.vue'
import
addPaper
from
'./AddPaper.vue'
import
QuestionListItem
from
'./QuestionListItem.vue'
export
default
{
components
:
{
QuestionListItems
,
addPaper
,
AutomaticPaper
},
props
:
{
paperMode
:
{
type
:
String
,
default
:
''
}
},
data
()
{
return
{
visible
:
false
,
// 控制增加试题弹框显示还是隐藏
currentIndex
:
1
,
selectQuestion
:
[],
// 选择的题
questionListed
:
[],
// 处理好排序的试题列表
subType
:
{
// 匹配类型显示
1
:
'单'
,
2
:
'多'
,
3
:
'简'
,
5
:
'案'
,
6
:
'判'
,
7
:
'实'
,
8
:
'情'
},
questionList
:
[
{
question_title
:
'单选题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
1
,
is_parent
:
1
,
child_question_type
:
1
,
question_options
:
[
{
id
:
'1'
,
options
:
'示向功能'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'示向----'
,
checked
:
false
}
],
question_answer
:
'示向功能'
,
group_id
:
'1001'
,
score
:
2
},
{
question_title
:
'多选题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
2
,
is_parent
:
1
,
child_question_type
:
0
,
score
:
2
,
question_options
:
[
{
id
:
'1'
,
options
:
'示向功能'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'示向----'
,
checked
:
true
},
{
id
:
'3'
,
options
:
'示向---12333-'
,
checked
:
false
}
],
question_answer
:
'示向功能、示向----'
,
group_id
:
'1002'
},
{
question_title
:
'判断题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
6
,
is_parent
:
1
,
child_question_type
:
0
,
score
:
2
,
question_options
:
[
{
id
:
'1'
,
options
:
'正确'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'错误'
,
checked
:
false
}
],
question_answer
:
'正确'
,
group_id
:
'1003'
},
{
question_title
:
'简答题'
,
question_content
:
'<p>复购率在金融数字化营销中是反应用户对品牌忠诚度的一个重要指标,锡盟高钙奶是一家专门生产乳制品的企业,其中脱脂牛奶的销量一直不太理想,所以想看一下过往的购买客户的订单记录,计算以下这一部分客户的复购率为多少,根据数据显示,2021年一季度华北市场的脱脂牛奶交易笔数为12000笔,4000人实现二次购买,而这4000人当中2000人实现了三次购买。</p>'
,
question_type
:
3
,
is_parent
:
1
,
child_question_type
:
0
,
question_answer
:
'2021年一季度华北市场的脱脂牛奶交易笔数为12000笔'
,
group_id
:
'1004'
,
score
:
2
},
{
question_title
:
'案例题'
,
question_content
:
'<p>平邦保险公司想通过一些建设性的方案来解决目前4个策略中所存在的问题,以下为各个策略分别所对应的问题。</p><p>① 在产品策略方面,某保险公司主要售卖两款疾病险和一款年金险产品,由于整体保险市场的产品同质化严重,与同行业其他保险公司相比没有明显优势。</p><p>② 在定价策略方面,某保险公司的产品定价整体处于中等水平,比大型保险公司定价整体相比较低,比其他小型保险公司定价略高。过去人们在比较不同保险产品时,关注的主要是经济补偿,而现在不仅包括经济补偿,还包括各类附加功能。比如保险公司与医院联网合作,不仅可以在费用阶段直接垫付客户治疗费用,还可以增加包括专家门诊、预约病床、绿色通道在内的多种特色服务,成为了公司品牌特色的一部分。</p><p>③ 在渠道策略方面,某保险公司目前营销渠道还是以个人代理制为主。目前,保险代理人队伍的整体文化素质不高,学历在高中及以下超过90%,另外由于公司对保险代理人实施以业务业绩为主的晋升机制,导致目前忽视了对整体代理人队伍文化及金融素养的培训。</p><p>④ 在促销策略方面,某保险公司的广告投入较少,投放了电视广告,但是一般在非黄金时段播放;同时,其销售方式以人员推销为主。</p>'
,
question_type
:
5
,
is_parent
:
1
,
child_question_type
:
0
,
question_answer
:
null
,
group_id
:
'1005'
,
score
:
8
},
{
question_title
:
'单选题'
,
question_content
:
'<p>根据题目描述,若按交易方法计算,则重复购买次数为?</p>'
,
question_type
:
5
,
is_parent
:
0
,
child_question_type
:
1
,
question_options
:
[
{
id
:
'1'
,
options
:
'2000'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'2000'
,
checked
:
false
}
],
question_answer
:
'2000'
,
group_id
:
'1005'
,
score
:
2
},
{
question_title
:
'多选题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
5
,
is_parent
:
0
,
child_question_type
:
2
,
question_options
:
[
{
id
:
'1'
,
options
:
'示向功能'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'示向----'
,
checked
:
true
},
{
id
:
'3'
,
options
:
'示向---12333-'
,
checked
:
false
}
],
question_answer
:
'示向功能、示向----'
,
group_id
:
'1005'
,
score
:
2
},
{
question_title
:
'判断题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
5
,
is_parent
:
0
,
child_question_type
:
6
,
question_options
:
[
{
id
:
'1'
,
options
:
'正确'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'错误'
,
checked
:
false
}
],
question_answer
:
'正确'
,
group_id
:
'1005'
,
score
:
2
},
{
question_title
:
'简答题'
,
question_content
:
'<p>复购率在金融数字化营销中是反应用户对品牌忠诚度的一个重要指标,锡盟高钙奶是一家专门生产乳制品的企业,其中脱脂牛奶的销量一直不太理想,2021年一季度华北市场的脱脂牛奶交易笔数为12000笔,4000人实现二次购买,而这4000人当中2000人实现了三次购买。</p>'
,
question_type
:
5
,
is_parent
:
0
,
child_question_type
:
3
,
question_answer
:
'2021年一季度华北市场的脱脂牛奶交易笔数为12000笔'
,
group_id
:
'1005'
,
score
:
2
},
{
question_title
:
'情景题'
,
question_content
:
'<p>平邦保险公司想通过一些建设性的方案来解决目前4个策略中所存在的问题,以下为各个策略分别所对应的问题。</p><p>① 在产品策略方面,某保险公司主要售卖两款疾病险和一款年金险产品,由于整体保险市场的产品同质化严重,与同行业其他保险公司相比没有明显优势。</p><p>② 在定价策略方面,某保险公司的产品定价整体处于中等水平,比大型保险公司定价整体相比较低,比其他小型保险公司定价略高。过去人们在比较不同保险产品时,关注的主要是经济补偿,而现在不仅包括经济补偿,还包括各类附加功能。比如保险公司与医院联网合作,不仅可以在费用阶段直接垫付客户治疗费用,还可以增加包括专家门诊、预约病床、绿色通道在内的多种特色服务,成为了公司品牌特色的一部分。</p><p>③ 在渠道策略方面,某保险公司目前营销渠道还是以个人代理制为主。目前,保险代理人队伍的整体文化素质不高,学历在高中及以下超过90%,另外由于公司对保险代理人实施以业务业绩为主的晋升机制,导致目前忽视了对整体代理人队伍文化及金融素养的培训。</p><p>④ 在促销策略方面,某保险公司的广告投入较少,投放了电视广告,但是一般在非黄金时段播放;同时,其销售方式以人员推销为主。</p>'
,
question_type
:
8
,
is_parent
:
1
,
child_question_type
:
0
,
question_answer
:
null
,
group_id
:
'1006'
,
score
:
8
},
{
question_title
:
'单选题'
,
question_content
:
'<p>根据题目描述,若按交易方法计算,则重复购买次数为?</p>'
,
question_type
:
8
,
is_parent
:
0
,
child_question_type
:
1
,
question_options
:
[
{
id
:
'1'
,
options
:
'2000'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'2000'
,
checked
:
false
}
],
question_answer
:
'2000'
,
group_id
:
'1006'
,
score
:
2
},
{
question_title
:
'多选题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
8
,
is_parent
:
0
,
child_question_type
:
2
,
question_options
:
[
{
id
:
'1'
,
options
:
'示向功能'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'示向----'
,
checked
:
true
},
{
id
:
'3'
,
options
:
'示向---12333-'
,
checked
:
false
}
],
question_answer
:
'示向功能、示向----'
,
group_id
:
'1006'
,
score
:
2
},
{
question_title
:
'判断题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
8
,
is_parent
:
0
,
child_question_type
:
6
,
question_options
:
[
{
id
:
'1'
,
options
:
'正确'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'错误'
,
checked
:
false
}
],
question_answer
:
'正确'
,
group_id
:
'1006'
,
score
:
2
},
{
question_title
:
'简答题'
,
question_content
:
'<p>复购率在金融数字化营销中是反应用户对品牌忠诚度的一个重要指标,锡盟高钙奶是一家专门生产乳制品的企业,其中脱脂牛奶的销量一直不太理想,2021年一季度华北市场的脱脂牛奶交易笔数为12000笔,4000人实现二次购买,而这4000人当中2000人实现了三次购买。</p>'
,
question_type
:
8
,
is_parent
:
0
,
child_question_type
:
3
,
question_answer
:
'2021年一季度华北市场的脱脂牛奶交易笔数为12000笔'
,
group_id
:
'1006'
,
score
:
2
},
{
question_title
:
'实操题'
,
question_content
:
'<p>平邦保险公司想通过一些建设性的方案来解决目前4个策略中所存在的问题,以下为各个策略分别所对应的问题。</p><p>① 在产品策略方面,某保险公司主要售卖两款疾病险和一款年金险产品,由于整体保险市场的产品同质化严重,与同行业其他保险公司相比没有明显优势。</p><p>② 在定价策略方面,某保险公司的产品定价整体处于中等水平,比大型保险公司定价整体相比较低,比其他小型保险公司定价略高。过去人们在比较不同保险产品时,关注的主要是经济补偿,而现在不仅包括经济补偿,还包括各类附加功能。比如保险公司与医院联网合作,不仅可以在费用阶段直接垫付客户治疗费用,还可以增加包括专家门诊、预约病床、绿色通道在内的多种特色服务,成为了公司品牌特色的一部分。</p><p>③ 在渠道策略方面,某保险公司目前营销渠道还是以个人代理制为主。目前,保险代理人队伍的整体文化素质不高,学历在高中及以下超过90%,另外由于公司对保险代理人实施以业务业绩为主的晋升机制,导致目前忽视了对整体代理人队伍文化及金融素养的培训。</p><p>④ 在促销策略方面,某保险公司的广告投入较少,投放了电视广告,但是一般在非黄金时段播放;同时,其销售方式以人员推销为主。</p>'
,
question_type
:
7
,
is_parent
:
1
,
child_question_type
:
0
,
question_answer
:
null
,
group_id
:
'1007'
,
score
:
8
},
{
question_title
:
'单选题'
,
question_content
:
'<p>根据题目描述,若按交易方法计算,则重复购买次数为?</p>'
,
question_type
:
7
,
is_parent
:
0
,
child_question_type
:
1
,
question_options
:
[
{
id
:
'1'
,
options
:
'2000'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'2000'
,
checked
:
false
}
],
question_answer
:
'2000'
,
group_id
:
'1007'
,
score
:
2
},
{
question_title
:
'多选题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
7
,
is_parent
:
0
,
child_question_type
:
2
,
question_options
:
[
{
id
:
'1'
,
options
:
'示向功能'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'示向----'
,
checked
:
true
},
{
id
:
'3'
,
options
:
'示向---12333-'
,
checked
:
false
}
],
question_answer
:
'示向功能、示向----'
,
group_id
:
'1007'
,
score
:
2
},
{
question_title
:
'判断题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
7
,
is_parent
:
0
,
child_question_type
:
6
,
question_options
:
[
{
id
:
'1'
,
options
:
'正确'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'错误'
,
checked
:
false
}
],
question_answer
:
'正确'
,
group_id
:
'1007'
,
score
:
2
},
{
question_title
:
'简答题'
,
question_content
:
'<p>复购率在金融数字化营销中是反应用户对品牌忠诚度的一个重要指标,锡盟高钙奶是一家专门生产乳制品的企业,其中脱脂牛奶的销量一直不太理想,2021年一季度华北市场的脱脂牛奶交易笔数为12000笔,4000人实现二次购买,而这4000人当中2000人实现了三次购买。</p>'
,
question_type
:
7
,
is_parent
:
0
,
child_question_type
:
3
,
question_answer
:
'2021年一季度华北市场的脱脂牛奶交易笔数为12000笔'
,
group_id
:
'1007'
,
score
:
2
},
{
question_title
:
'单选题'
,
question_content
:
'<p>市场营销通过多方面手段便利交换、便利物流,从而保障交换工能够和物流功能的实现。这主要说的是市场营销的哪一项功能?</p>'
,
question_type
:
1
,
is_parent
:
1
,
child_question_type
:
1
,
question_options
:
[
{
id
:
'1'
,
options
:
'示向功能'
,
checked
:
true
},
{
id
:
'2'
,
options
:
'示向----'
,
checked
:
false
}
],
question_answer
:
'示向功能'
,
group_id
:
'1001'
,
score
:
2
}
]
}
},
mounted
()
{
this
.
getlist
()
// 处理后端返回
},
methods
:
{
getlist
()
{
const
newQuestionList
=
[]
const
bigData
=
this
.
questionList
.
filter
(
item
=>
item
.
is_parent
===
1
)
// 大题
const
smallData
=
this
.
questionList
.
filter
(
item
=>
item
.
is_parent
===
0
)
// 小题
for
(
let
i
=
0
;
i
<
bigData
.
length
;
i
++
)
{
const
listArray
=
[]
// 存放每次外层符合条件的数据
for
(
let
j
=
0
;
j
<
smallData
.
length
;
j
++
)
{
if
(
bigData
[
i
].
group_id
===
smallData
[
j
].
group_id
)
{
// 如果大题的group_id和小题group_id相等就push listArray数组中,然后赋值给bigData[i].list 相当于加个list属性
listArray
.
push
(
smallData
[
j
])
// 符合就push listArray数组暂存
bigData
[
i
].
list
=
listArray
}
}
newQuestionList
.
push
(
bigData
[
i
])
}
this
.
questionList
=
newQuestionList
},
// 排好序数据 左侧的题号,需对后端返回的数据进行排序循环 [1,2,3,6], //简单题类型 [5,7,8], //复杂题类型
getSortQuestionList
()
{
// [1,2,3,6,5,7,8] //以这个顺序排序
const
data
=
[
...
this
.
getListBytype
(
1
),
...
this
.
getListBytype
(
2
),
...
this
.
getListBytype
(
3
),
...
this
.
getListBytype
(
6
),
...
this
.
getListBytype
(
5
),
...
this
.
getListBytype
(
7
),
...
this
.
getListBytype
(
8
)
]
// 存放排好序的试题
return
data
},
// 拿到指定类型的试题
getListBytype
(
type
)
{
return
this
.
questionList
.
filter
(
item
=>
item
.
question_type
===
type
)
},
// 增加试题
addPaper
()
{
console
.
log
(
'dfjsf'
)
this
.
visible
=
true
},
// 切换题目编号
titleClick
(
index
)
{
this
.
currentIndex
=
index
+
1
this
.
$refs
.
listItemRef
.
handleScroll
(
index
)
},
// 试题列表滑动指定位置
handlePosition
(
offsetTop
)
{
console
.
log
(
offsetTop
)
// document.getElementById('questionMain').scrollTo(0, offsetTop)
window
.
scrollTo
(
0
,
offsetTop
)
},
// 保存试卷
savePaper
()
{
// 校验分数
const
tottalScore
=
34
// 假如这套试卷的总分为 32分
const
bigScore
=
this
.
questionList
.
map
(
item
=>
item
.
score
*
1
).
reduce
((
pre
,
em
)
=>
(
pre
+=
em
),
0
)
// 大题分数
const
bigQuestionNum
=
this
.
questionList
.
filter
(
item
=>
item
?.
list
).
length
// 记录复杂题的个数
const
num
=
[]
// 保存分数正确的复杂题,准确来说 num.length 和 bigQuestionNum相等 才说明每一道复杂题的分数等于小题总分
this
.
questionList
.
forEach
(
item
=>
{
// 循环大题,如果有小题,就拿有小题的大题的分数和小题的总分比较,分数相等就push num中,之后根据复杂题的个数和num数组length相等,说明复杂题下面的小题都满足小题分总和等于大题的分
if
(
item
?.
list
?.
length
>
0
)
{
const
smallAllSore
=
item
.
list
.
map
(
v
=>
v
.
score
*
1
).
reduce
((
pre
,
em
)
=>
(
pre
+=
em
),
0
)
// 小题总分
if
(
item
.
score
===
smallAllSore
)
{
// 大题分数 === 小题总分
num
.
push
(
item
.
score
)
// 保存分数正确的复杂题
}
}
})
if
(
tottalScore
===
bigScore
&&
bigQuestionNum
===
num
.
length
)
{
// 检测分数:首先判断所有大题的总分和试卷的总分相等并且有小题的大题的总分和所有对应所有小题的总分数相等
// 在这里调接口
this
.
$message
({
message
:
'分数正确,去调接口'
,
type
:
'success'
})
}
else
{
this
.
$message
({
message
:
'分数和总分不相等,请确保分数保持一致'
,
type
:
'warning'
})
}
},
// 删除所选试题
delCheckedQuestion
()
{
console
.
log
(
'删除的题目序号'
,
this
.
selectQuestion
)
},
selectSubjectsChange
(
val
)
{
this
.
selectQuestion
=
val
}
}
name
:
'QuestionList'
,
props
:
{
list
:
{
type
:
Array
,
default
:
()
=>
[]
}
},
components
:
{
QuestionListItem
}
}
</
script
>
<
style
lang=
"scss"
>
.el-row
{
margin-bottom
:
20px
;
&
:last-child
{
margin-bottom
:
0
;
}
}
.bg-purple
{
background
:
#d3dce6
;
}
.grid-content
{
border-radius
:
4px
;
min-height
:
36px
;
}
.nonePaper
{
height
:
300px
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
#questionMain
{
// height: calc(100vh - 450px);
overflow
:
auto
;
.clearfix
{
.clearfix_tit
{
color
:
#c01c40
;
font-size
:
20px
;
font-weight
:
bold
;
}
.clearfix_del
{
float
:
right
;
padding
:
10px
5px
;
margin-right
:
20px
;
}
.clearfix_add
{
float
:
right
;
padding
:
10px
5px
;
margin-right
:
20px
;
}
}
}
.titleIndex
{
ul
{
display
:
flex
;
justify-content
:
flex-start
;
align-items
:
center
;
flex-wrap
:
wrap
;
li
{
flex
:
1
;
width
:
20%
;
min-width
:
20%
;
max-width
:
20%
;
margin-top
:
10px
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
#subNum
{
border-radius
:
50px
;
width
:
24px
;
height
:
24px
;
font-size
:
14px
;
text-align
:
center
;
border
:
2px
solid
#ccc
;
color
:
#666
;
cursor
:
pointer
;
}
.subType
{
font-size
:
14px
;
color
:
#666
;
}
}
.titleItem
{
background-color
:
rgb
(
194
,
43
,
43
);
}
}
}
</
style
>
src/modules/paper/components/QuestionListItem.vue
0 → 100644
浏览文件 @
7f689cd5
<
template
>
<el-card
style=
"margin-bottom: 20px"
shadow=
"hover"
>
<div
class=
"question-item"
>
<div
class=
"question-item-hd"
>
<div
class=
"question-item-hd-top"
>
<slot
name=
"selection"
></slot>
<div
class=
"question-index"
>
{{
index
}}
、
</div>
<div
class=
"question-type"
>
{{
questionTypeText
}}
</div>
<div
class=
"question-score"
>
<p>
分数:
</p>
<el-input
v-model=
"data.score"
style=
"width: 100px"
></el-input>
</div>
</div>
<!-- 题干 -->
<div
class=
"question-title"
v-html=
"data.question_content"
></div>
</div>
<slot>
<div
class=
"question-item-bd"
>
<!-- 单选题 -->
<template
v-if=
"questionType === 1"
>
<el-radio-group
:disabled=
"disabled"
:value=
"data.question_answer[0]"
>
<div
class=
"question-item-option"
v-for=
"item in data.question_options"
:key=
"item.id"
>
<el-radio
:label=
"item.id"
>
{{
item
.
option
}}
</el-radio>
</div>
</el-radio-group>
</
template
>
<!-- 多选题 -->
<
template
v-if=
"questionType === 2"
>
<el-checkbox-group
:disabled=
"disabled"
:value=
"data.question_answer"
>
<div
class=
"question-item-option"
v-for=
"item in data.question_options"
:key=
"item.id"
>
<el-checkbox
:label=
"item.id"
>
{{
item
.
option
}}
</el-checkbox>
</div>
</el-checkbox-group>
</
template
>
<!-- 问答题 -->
<
template
v-if=
"questionType === 3"
>
<v-editor></v-editor>
</
template
>
<!-- 判断题 -->
<
template
v-if=
"questionType === 6"
>
<el-radio-group
:disabled=
"disabled"
:value=
"data.question_answer"
>
<div
class=
"question-item-option"
v-for=
"item in data.question_options"
:key=
"item.id"
>
<el-radio
:label=
"item.id"
>
{{
item
.
option
}}
</el-radio>
</div>
</el-radio-group>
</
template
>
</div>
</slot>
<div
class=
"question-item-ft"
></div>
</div>
</el-card>
</template>
<
script
>
import
VEditor
from
'@/components/tinymce/Index.vue'
export
default
{
props
:
{
index
:
{
type
:
Number
,
default
:
1
},
disabled
:
{
type
:
Boolean
,
default
:
false
},
data
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
components
:
{
VEditor
},
data
()
{
return
{
question
:
{}
}
},
watch
:
{
data
:
{
immediate
:
true
,
handler
(
data
)
{
this
.
question
=
this
.
genQuestion
(
data
)
}
}
},
computed
:
{
// 试题类型
questionType
()
{
// 1单选,2多选,3简答,5案例题, 6判断, 7实操,8情景
return
this
.
data
.
child_question_type
||
this
.
data
.
question_type
},
// 26个英文字母
A_Z
()
{
const
result
=
[]
for
(
let
i
=
0
;
i
<
26
;
i
++
)
{
result
.
push
(
String
.
fromCharCode
(
65
+
i
))
}
return
result
},
// 选项类型
questionTypeText
()
{
const
map
=
{
1
:
'单选题'
,
2
:
'多选题'
,
3
:
'问答题'
,
5
:
'案例题'
,
6
:
'判断题'
,
7
:
'实操题'
,
8
:
'情景题'
}
return
map
[
this
.
questionType
]
}
},
methods
:
{
genQuestion
(
data
)
{}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.question-item-hd-top
{
display
:
flex
;
.question-index
{
margin-left
:
10px
;
color
:
#c01c40
;
}
.question-type
{
flex
:
1
;
color
:
#c01c40
;
}
.question-score
{
display
:
flex
;
align-items
:
center
;
p
{
white-space
:
nowrap
;
}
}
}
.question-title
{
padding
:
10px
0
;
}
.question-item-option
{
margin
:
10px
0
;
}
</
style
>
src/modules/paper/components/QuestionListItems.vue
deleted
100644 → 0
浏览文件 @
aaa33184
<
template
>
<div>
<div
v-for=
"(item, index) in questionList"
:key=
"index"
>
<!-- 简单题类型 [1,2,3,6] :根据判断题的类型渲染 -->
<el-card
class=
"boxCard"
v-if=
"signQuestionTypes.includes(item.question_type)"
:id=
"`page$
{index}`">
<div
class=
"boxHeader"
>
<div
class=
"headerLeft"
>
<div
class=
"check"
>
<input
type=
"checkbox"
class=
"checkInpt"
v-model=
"selectSubjects"
:value=
"item"
@
change=
"slectSubItem(item)"
/>
</div>
<div
class=
"title"
>
<div
class=
"titleType"
>
{{
index
+
1
}}
、
{{
item
.
question_title
}}
</div>
<div
class=
"titleDec"
v-html=
"item.question_content"
></div>
</div>
</div>
<div
class=
"pmty"
></div>
<div
class=
"headerRight"
>
<div
class=
"scoreValue"
>
<span
class=
"lableScore"
>
分数:
</span>
<el-input
v-model=
"item.score"
></el-input>
</div>
</div>
</div>
<div
class=
"boxMain"
>
<el-radio-group
class=
"options"
>
<el-radio
v-for=
"(v, index) in item.question_options"
:key=
"index"
:label=
"v.options"
class=
"option"
>
{{
v
.
options
}}
</el-radio>
</el-radio-group>
</div>
<div
class=
"boxFooter"
>
<div>
正确答案:
</div>
<div
class=
"boxAnswer"
>
{{
item
.
question_answer
}}
</div>
</div>
</el-card>
<!-- 复杂题类型 [5,7,8] :根据判断题的类型渲染 复杂利用上面的头部,内部重新写个页面渲染复杂题中的小题-->
<el-card
class=
"boxCard"
v-if=
"intricacyQuestionTypes.includes(item.question_type)"
:id=
"`page$
{index}`">
<div
class=
"boxHeader"
>
<div
class=
"headerLeft"
>
<div
class=
"check"
>
<input
type=
"checkbox"
class=
"checkInpt"
v-model=
"selectSubjects"
:value=
"item"
@
change=
"slectSubItem(item)"
/>
</div>
<div
class=
"title"
>
<div
class=
"titleType"
>
{{
index
+
1
}}
、
{{
item
.
question_title
}}
</div>
<div
class=
"titleDec"
v-html=
"item.question_content"
></div>
</div>
</div>
<div
class=
"headerRight"
>
<div
class=
"scoreValue"
>
<span
class=
"lableScore"
>
分数:
</span>
<el-input
:value=
"getSubScore(item)"
></el-input>
</div>
</div>
</div>
<div
class=
"intricacyBoxMain"
v-for=
"(v, index) in item.list"
:key=
"index"
style=
"margin-top: 20px"
>
<div
class=
"intricacyHeader"
>
<div
class=
"intricacyDsc"
>
<div
class=
"intricacyTitle"
>
{{
index
+
1
}}
、
{{
v
.
question_title
}}
</div>
<div
class=
"titleDec"
v-html=
"v.question_content"
></div>
</div>
<div
class=
"intricacyScoreValue"
>
<span
class=
"lableScore"
>
分数:
</span>
<el-input
v-model=
"v.score"
></el-input>
</div>
<div
class=
"empty"
></div>
</div>
<div
class=
"intricacyMain"
>
<el-radio-group
class=
"options"
>
<el-radio
v-for=
"(o, index) in v.question_options"
:key=
"index"
:label=
"o.options"
class=
"option"
>
{{
o
.
options
}}
</el-radio>
</el-radio-group>
</div>
<div
class=
"intricacyFooter"
>
<div>
正确答案:
</div>
<div
class=
"intricacyAnswer"
>
{{
v
.
question_answer
}}
</div>
</div>
</div>
</el-card>
</div>
</div>
</
template
>
<
script
>
export
default
{
// 问答、情景、案例
props
:
{
questionList
:
{
// 试题数据
type
:
Array
}
},
data
()
{
return
{
selectSubjects
:
[],
// 选中的题
signQuestionTypes
:
[
1
,
2
,
3
,
6
],
// 简单题类型
intricacyQuestionTypes
:
[
5
,
7
,
8
]
// 复杂题类型
}
},
methods
:
{
// 根据小题的分数计算大题的分数,以至于监听分数变化 s.score*1 是为了下次修改,返回的是字符串变成number类型才可以计算
getSubScore
(
item
)
{
return
item
?.
list
?.
map
(
s
=>
parseInt
(
s
.
score
)
*
1
).
reduce
((
pre
,
em
)
=>
pre
+
em
,
0
)
},
// 返回点击题号的offsettop
handleScroll
(
key
)
{
const
PageId
=
document
.
querySelector
(
'#page'
+
key
)
this
.
$emit
(
'handlePosition'
,
PageId
.
offsetTop
)
},
// 选中的数据回传
slectSubItem
(
item
)
{
console
.
log
(
item
)
this
.
$emit
(
'selectSubjectsChange'
,
this
.
selectSubjects
)
}
}
}
</
script
>
<
style
lang=
"scss"
>
.boxCard
{
margin-bottom
:
10px
;
.boxHeader
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
30px
;
.headerLeft
{
flex
:
0
.75
;
display
:
flex
;
.check
{
margin-right
:
20px
;
}
.title
{
justify-content
:
space-around
;
.titleType
{
width
:
200px
;
color
:
#1890ff
;
}
}
.checkInpt
.title
{
display
:
inline-block
;
}
}
.pmty
{
flex
:
0
.05
;
}
.headerRight
{
flex
:
0
.2
;
display
:
flex
;
position
:
relative
;
.scoreValue
{
position
:
absolute
;
top
:
0px
;
display
:
flex
;
align-items
:
center
;
.lableScore
{
width
:
100px
;
}
}
}
}
.boxMain
{
padding-left
:
70px
;
.options
{
display
:
flex
;
flex-direction
:
column
;
.option
{
margin-bottom
:
5px
;
}
}
}
.boxFooter
{
margin-top
:
30px
;
padding-left
:
40px
;
display
:
flex
;
align-items
:
center
;
.boxAnswer
{
color
:
#1890ff
;
font-size
:
14px
;
}
}
.intricacyBoxMain
{
padding-left
:
70px
;
padding-top
:
20px
;
.options
{
display
:
flex
;
flex-direction
:
column
;
.option
{
margin-bottom
:
5px
;
}
}
.intricacyHeader
{
display
:
flex
;
align-items
:
center
;
.intricacyDsc
{
flex
:
0
.8
;
.intricacyTitle
{
width
:
200px
;
color
:
#949091
;
}
}
.intricacyScoreValue
{
flex
:
0
.2
;
margin-left
:
50px
;
display
:
flex
;
align-items
:
center
;
.lableScore
{
width
:
80px
;
}
}
}
.intricacyMain
{
padding-left
:
30px
;
}
.intricacyFooter
{
margin-top
:
10px
;
display
:
flex
;
align-items
:
center
;
.intricacyAnswer
{
color
:
#1890ff
;
font-size
:
14px
;
}
}
}
}
</
style
>
src/modules/paper/components/QuestionNum.vue
浏览文件 @
7f689cd5
<
template
>
<el-card>
<div
class=
"titleIndex"
>
<ul>
<li
:class=
"currentIndex === index ? `dotItem` : ''"
v-for=
"(item, index) in list"
:key=
"index"
@
click=
"TitleClick(index)"
>
{{
index
+
1
}}
</li>
</ul>
<div
style=
"margin-top: 10px; display: flex; justify-content: center; align-items: center"
>
<el-button
type=
"primary"
>
保存试卷
</el-button>
<app-card
class=
"fixed"
>
<div
class=
"question-num"
>
<div
class=
"question-num-bd"
>
<ul>
<li
:class=
"className"
v-for=
"(item, index) in list"
:key=
"index"
@
click=
"handleClick(index)"
>
{{
index
+
1
}}
</li>
</ul>
</div>
<div
class=
"question-num-ft"
>
<slot
name=
"footer"
></slot>
</div>
</div>
</
el
-card>
</
app
-card>
</
template
>
<
script
>
...
...
@@ -31,8 +28,13 @@ export default {
currentIndex
:
0
// 当前点击题号
}
},
computed
:
{
className
()
{
return
{}
}
},
methods
:
{
Tit
leClick
(
index
)
{
hand
leClick
(
index
)
{
this
.
currentIndex
=
index
this
.
$emit
(
'indexClick'
,
`
${
index
+
1
}
`
)
}
...
...
@@ -40,12 +42,15 @@ export default {
}
</
script
>
<
style
lang=
"scss"
>
.titleIndex
{
<
style
lang=
"scss"
scoped
>
.fixed
{
position
:
sticky
;
top
:
0
;
}
.question-num
{
ul
{
display
:
flex
;
justify-content
:
space-around
;
align-items
:
center
;
flex-wrap
:
wrap
;
li
{
border-radius
:
50px
;
width
:
24px
;
...
...
@@ -56,10 +61,15 @@ export default {
border
:
2px
solid
#ccc
;
color
:
#666
;
cursor
:
pointer
;
margin
:
10px
5px
;
}
.dotItem
{
background-color
:
rgb
(
243
,
190
,
190
);
}
}
}
.question-num-ft
{
margin-top
:
20px
;
text-align
:
center
;
}
</
style
>
src/modules/paper/components/QuestionSelect.vue
浏览文件 @
7f689cd5
<
template
>
<
el-dialog
title=
"添加试卷试题"
v-bind=
"$attrs"
v-on=
"$listeners"
></el-dialog
>
<
app-list
v-bind=
"tableOptions"
ref=
"list"
style=
"padding-left: 30px"
>
</app-list
>
</
template
>
<
script
>
...
...
src/modules/paper/views/Detail.vue
浏览文件 @
7f689cd5
...
...
@@ -3,12 +3,12 @@
<!-- 试卷描述 -->
<app-card
title=
"试卷信息"
>
<template
#
header-aside
>
<el-button
type=
"primary"
size=
"mini"
@
click=
"handleUpdate"
>
编辑试卷
</el-button>
<el-button
type=
"primary"
@
click=
"handleUpdate"
>
编辑试卷
</el-button>
</
template
>
<el-descriptions
:column=
"2"
class=
"descriptionsCon"
>
<el-descriptions-item
label=
"试卷名称"
>
{{ detail.paper_title }}
</el-descriptions-item>
<el-descriptions-item
label=
"标签"
>
{{ detail.paper_labels }}
</el-descriptions-item>
<el-descriptions-item
label=
"试卷分类"
>
{{ detail.paper_category }}
</el-descriptions-item>
<el-descriptions-item
label=
"试卷分类"
>
{{ detail.paper_category
.category_name
}}
</el-descriptions-item>
<el-descriptions-item
label=
"组卷模式"
>
{{ detail.paper_type }}
</el-descriptions-item>
<el-descriptions-item
label=
"试卷总分"
>
{{ detail.paper_total_score }}
</el-descriptions-item>
<el-descriptions-item
label=
"及格分数"
>
{{ detail.pass_score }}
</el-descriptions-item>
...
...
@@ -20,19 +20,555 @@
</el-descriptions>
</app-card>
<!-- 试卷列表 -->
<
QuestionList
:paperMode=
"detail.paperMode"
:paperTotalScore=
"detail.paperTotalScore"
/
>
<
paper-questions
:data=
"detail"
:list=
"detail.questions"
@
update=
"getDetail"
></paper-questions
>
</div>
</template>
<
script
>
import
QuestionList
from
'../components/QuestionList.vue'
// import QuestionList from '../components/QuestionList.vue'
import
PaperQuestions
from
'../components/PaperQuestions.vue'
import
{
getPaper
}
from
'../api.js'
export
default
{
props
:
{
id
:
{
type
:
String
}
},
components
:
{
QuestionList
},
components
:
{
PaperQuestions
},
data
()
{
return
{
detail
:
{}
detail
:
{
paper_category
:
{},
questions
:
[]
}
// detail: {
// id: '355310262572814336',
// project_prefix: 'x1',
// paper_uses: 1,
// paper_title: '测试试卷',
// paper_labels: '',
// paper_type: 1,
// paper_contents: [
// {
// id: '355016409588379649',
// score: 20
// },
// {
// id: '355014384641318913',
// score: 20
// },
// {
// id: '355666309116432384',
// score: 10
// },
// {
// id: '355666267181780992',
// score: 10
// },
// {
// id: '355666228921339905',
// score: 10
// },
// {
// id: '354948368938758145',
// score: 10
// },
// {
// id: '355016685372256256',
// score: 20
// },
// {
// id: '355016686743793664',
// score: 10
// },
// {
// id: '355016685909127168',
// score: 10
// }
// ],
// paper_category: '7223',
// paper_times: 10,
// paper_total_score: 100,
// pass_score: 60,
// paper_question_order: 1,
// minimum_paper_handing_time: 1,
// is_multiple_exams: 0,
// multiple_test_score_rule: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-24 11:16:07',
// updated_at: '2022-02-25 10:57:08',
// deleted_at: null,
// questions: [
// {
// id: '354948368938758145',
// project_prefix: 'x1',
// permission: 2,
// question_type: 3,
// question_title: '问答题测试题1',
// question_content: '问答题测试题1',
// common_content: '',
// question_options: [],
// question_category: {},
// question_answer: {},
// question_analysis: '',
// question_difficulty: 3,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '0',
// question_order: 0,
// question_tag: 'test',
// is_parent: 1,
// child_question_type: 0,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-23 11:18:05',
// updated_at: '2022-02-23 11:18:05',
// score: 10,
// children: []
// },
// {
// id: '355016409588379649',
// project_prefix: 'x1',
// permission: 2,
// question_type: 1,
// question_title: '单选题测试题1',
// question_content: '单选题测试题1',
// common_content: '',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902157182012227584'
// },
// {
// option: '错误',
// checked: false,
// id: '6902157182012227585'
// }
// ],
// question_category: {},
// question_answer: ['6902157182012227584'],
// question_analysis: '',
// question_difficulty: 3,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '0',
// question_order: 0,
// question_tag: 'test',
// is_parent: 1,
// child_question_type: 0,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-23 15:48:27',
// updated_at: '2022-02-23 15:48:27',
// score: 20,
// children: []
// },
// {
// id: '355014384641318913',
// project_prefix: 'x1',
// permission: 2,
// question_type: 1,
// question_title: '单选题测试题1',
// question_content: '单选题测试题1',
// common_content: '',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902155157220360192'
// },
// {
// option: '错误',
// checked: false,
// id: '6902155157220360193'
// }
// ],
// question_category: {},
// question_answer: ['6902155157220360192'],
// question_analysis: '',
// question_difficulty: 3,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '0',
// question_order: 0,
// question_tag: 'test',
// is_parent: 1,
// child_question_type: 0,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-23 15:40:25',
// updated_at: '2022-02-23 15:40:25',
// score: 20,
// children: []
// },
// {
// id: '355666309116432384',
// project_prefix: 'x1',
// permission: 2,
// question_type: 2,
// question_title: '多选题测试题3',
// question_content: '多选题测试题3',
// common_content: '',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902807082072801280'
// },
// {
// option: '错误',
// checked: false,
// id: '6902807082072801281'
// }
// ],
// question_category: {
// id: '7223',
// category_name: '测试使用的分类',
// name: '题目分类/测试使用的分类'
// },
// question_answer: ['6902807082072801280'],
// question_analysis: '',
// question_difficulty: 3,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '0',
// question_order: 0,
// question_tag: 'test',
// is_parent: 1,
// child_question_type: 0,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-25 10:50:56',
// updated_at: '2022-02-25 10:50:56',
// score: 10,
// children: []
// },
// {
// id: '355666267181780992',
// project_prefix: 'x1',
// permission: 2,
// question_type: 2,
// question_title: '多选题测试题2',
// question_content: '多选题测试题2',
// common_content: '',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902807040146538496'
// },
// {
// option: '错误',
// checked: false,
// id: '6902807040146538497'
// }
// ],
// question_category: {
// id: '7223',
// category_name: '测试使用的分类',
// name: '题目分类/测试使用的分类'
// },
// question_answer: ['6902807040146538496'],
// question_analysis: '',
// question_difficulty: 3,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '0',
// question_order: 0,
// question_tag: 'test',
// is_parent: 1,
// child_question_type: 0,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-25 10:50:46',
// updated_at: '2022-02-25 10:50:46',
// score: 10,
// children: []
// },
// {
// id: '355666228921339905',
// project_prefix: 'x1',
// permission: 2,
// question_type: 2,
// question_title: '多选题测试题1',
// question_content: '多选题测试题1',
// common_content: '',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902807001823182848'
// },
// {
// option: '错误',
// checked: false,
// id: '6902807001823182849'
// }
// ],
// question_category: {
// id: '7223',
// category_name: '测试使用的分类',
// name: '题目分类/测试使用的分类'
// },
// question_answer: ['6902807001823182848'],
// question_analysis: '',
// question_difficulty: 3,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '0',
// question_order: 0,
// question_tag: 'test',
// is_parent: 1,
// child_question_type: 0,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-25 10:50:36',
// updated_at: '2022-02-25 10:50:36',
// score: 10,
// children: []
// },
// {
// id: '355016685372256256',
// project_prefix: 'x1',
// permission: 1,
// question_type: 5,
// question_title: '案例题测试2',
// question_content: '',
// common_content: '案例题测试2',
// question_options: [],
// question_category: {},
// question_answer: {},
// question_analysis: {},
// question_difficulty: 1,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '6902157457808687104',
// question_order: 0,
// question_tag: 'test2',
// is_parent: 1,
// child_question_type: 0,
// created_by: {},
// created_at: '2022-02-23 15:49:33',
// updated_at: '2022-02-23 15:49:33',
// score: 20,
// children: [
// {
// id: '355016686743793664',
// project_prefix: 'x1',
// permission: 1,
// question_type: 5,
// question_title: '案例-单选题测试题1',
// question_content: '案例-单选题测试题1',
// common_content: '案例题测试2',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902157458941149184'
// },
// {
// option: '错误',
// checked: false,
// id: '6902157458941149185'
// }
// ],
// question_category: {},
// question_answer: ['6902157458941149184'],
// question_analysis: '',
// question_difficulty: 1,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '6902157457808687104',
// question_order: 3,
// question_tag: 'test2',
// is_parent: 0,
// child_question_type: 1,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-23 15:49:34',
// updated_at: '2022-02-23 15:49:34',
// score: 10
// },
// {
// id: '355016685909127168',
// project_prefix: 'x1',
// permission: 1,
// question_type: 5,
// question_title: '案例-判断题测试题1',
// question_content: '案例-判断题测试题1',
// common_content: '案例题测试2',
// question_options: [
// {
// option: '正确',
// checked: true,
// id: '6902157458161008640'
// },
// {
// option: '错误',
// checked: false,
// id: '6902157458161008641'
// }
// ],
// question_category: {},
// question_answer: '6902157458161008640',
// question_analysis: '',
// question_difficulty: 1,
// status: 1,
// operator: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// group_id: '6902157457808687104',
// question_order: 1,
// question_tag: 'test2',
// is_parent: 0,
// child_question_type: 6,
// created_by: {
// id: '6653195831513972736',
// username: '王诒正',
// nickname: '王诒正',
// realname: '王诒正',
// email: 'wangyizheng@ezijing.com',
// mobile: '18435134258',
// country_code: '86'
// },
// created_at: '2022-02-23 15:49:33',
// updated_at: '2022-02-23 15:49:33',
// score: 10
// }
// ]
// }
// ]
// }
}
},
computed
:
{},
...
...
src/modules/paper/views/List.vue
浏览文件 @
7f689cd5
...
...
@@ -3,7 +3,9 @@
<app-list
v-bind=
"tableOptions"
ref=
"list"
@
selection-change=
"handleSelectionChange"
>
<div
class=
"btn_operate"
>
<el-button
type=
"primary"
icon=
"el-icon-plus"
@
click=
"handleCreate"
>
新建试卷
</el-button>
<el-button
type=
"primary"
icon=
"el-icon-delete"
@
click=
"batchDelete"
>
批量删除
</el-button>
<el-button
type=
"primary"
icon=
"el-icon-delete"
:disabled=
"!multipleSelection.length"
@
click=
"handleBatchDelete"
>
批量删除
</el-button
>
</div>
<template
v-slot:filter-category=
"
{ params }">
<question-type-cascader
v-model=
"params.paper_category"
></question-type-cascader>
...
...
@@ -18,7 +20,7 @@
</template>
<
script
>
import
{
getPaperList
}
from
'../api'
import
{
getPaperList
,
batchDeletePaper
}
from
'../api'
import
QuestionTypeCascader
from
'@/components/base/QuestionTypeCascader.vue'
const
paperType
=
[
...
...
@@ -30,9 +32,7 @@ export default {
components
:
{
QuestionTypeCascader
},
data
()
{
return
{
visible
:
false
,
multipleSelection
:
[],
// 选择项
paperCategoryList
:
[]
multipleSelection
:
[]
// 选择项
}
},
computed
:
{
...
...
@@ -85,8 +85,15 @@ export default {
columns
:
[
{
type
:
'selection'
,
width
:
'50px'
,
fixed
:
'left'
},
{
type
:
'index'
,
label
:
'序号'
,
minWidth
:
'50px'
,
fixed
:
'left'
},
{
label
:
'组卷模式'
,
prop
:
'paper_type'
},
{
label
:
'试卷分类'
,
prop
:
'paper_category'
},
{
label
:
'组卷模式'
,
prop
:
'paper_type'
,
computed
:
({
row
})
=>
{
const
map
=
{
1
:
'选题组卷'
,
2
:
'自动组卷'
}
return
map
[
row
.
paper_type
]
||
row
.
paper_type
}
},
{
label
:
'试卷分类'
,
prop
:
'paper_category.category_name'
},
{
label
:
'试卷名称'
,
prop
:
'paper_title'
},
{
label
:
'总分'
,
prop
:
'paper_total_score'
},
{
label
:
'及格分数'
,
prop
:
'pass_score'
},
...
...
@@ -113,13 +120,34 @@ export default {
handleSelectionChange
(
val
)
{
this
.
multipleSelection
=
val
},
// 批量删除
batchDelete
()
{
console
.
log
(
'111'
)
},
// 单个删除
handleDelete
(
row
)
{
// this.$refs.list.refetch()
this
.
$confirm
(
'确定删除该试卷吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(()
=>
{
const
ids
=
[
row
.
id
]
this
.
batchDeletePaper
(
ids
)
})
},
// 批量删除
handleBatchDelete
()
{
this
.
$confirm
(
'确定删除所选试卷吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(()
=>
{
const
ids
=
this
.
multipleSelection
.
map
(
item
=>
item
.
id
)
this
.
batchDeletePaper
(
ids
)
})
},
// 批量删除
batchDeletePaper
(
ids
)
{
batchDeletePaper
({
ids
}).
then
(
res
=>
{
// 刷新列表
this
.
$refs
.
list
.
refetch
()
})
}
}
}
...
...
src/modules/paper/views/NewPaper.vue
浏览文件 @
7f689cd5
...
...
@@ -131,7 +131,6 @@
<el-button
type=
"primary"
@
click=
"handleSubmitSelect"
v-if=
"hasSelectQuestionButton"
>
保存并选择试题
</el-button>
</div>
</el-form>
<question-select
:visible
.
sync=
"questionSelectVisible"
></question-select>
</app-card>
</
template
>
...
...
@@ -141,7 +140,7 @@ import QuestionTypeCascader from '@/components/base/QuestionTypeCascader.vue'
export
default
{
props
:
{
id
:
{
type
:
String
}
},
components
:
{
QuestionTypeCascader
,
QuestionSelect
:
()
=>
import
(
'../components/QuestionSelect.vue'
)
},
components
:
{
QuestionTypeCascader
},
data
()
{
return
{
form
:
{
...
...
src/modules/question/api.js
浏览文件 @
7f689cd5
...
...
@@ -38,103 +38,20 @@ export function addQuestion(data) {
}
/**
*
获取应用详情
*
删除试题
*/
export
function
getApp
(
id
,
params
)
{
return
httpRequest
.
get
(
`/api/permissions/admin/v1/
${
id
}
/application`
,
{
params
}
)
export
function
deleteQuestion
(
data
)
{
return
httpRequest
.
post
(
'/api/qbs/admin/v1/question/batch-delete'
,
data
)
}
/**
*
创建应用
*
更新试题
*/
export
function
createApp
(
data
)
{
return
httpRequest
.
p
ost
(
'/api/permissions/admin/v1/application'
,
data
)
export
function
updateQuestion
(
id
,
data
)
{
return
httpRequest
.
p
ut
(
`/api/qbs/admin/v1/question/
${
id
}
`
,
data
)
}
/**
* 更新应用
*/
export
function
updateApp
(
id
,
data
)
{
return
httpRequest
.
put
(
`/api/permissions/admin/v1/
${
id
}
/application`
,
data
)
}
/**
* 删除应用
*/
export
function
deleteApp
(
id
,
data
)
{
return
httpRequest
.
delete
(
`/api/permissions/admin/v1/
${
id
}
/application`
,
data
)
}
/**
* 更新应用签名秘钥
*/
export
function
updateAppSecretKey
(
id
,
data
)
{
return
httpRequest
.
patch
(
`/api/permissions/admin/v1/
${
id
}
/application/secret-key`
,
data
)
}
/**
* 获取应用管理员
*/
export
function
getAppAdminUsers
(
params
)
{
return
httpRequest
.
get
(
`/api/permissions/admin/v1/
${
params
.
app_id
}
/application/assign/app-users`
,
{
params
})
}
/**
* 删除应用管理员
*/
export
function
deleteAppAdminUsers
(
appid
,
data
)
{
return
httpRequest
.
post
(
`/api/permissions/admin/v1/
${
appid
}
/application/assign/remove-app-users`
,
data
)
}
/**
* 创建成员
*/
export
function
createUser
(
appid
,
data
)
{
return
httpRequest
.
post
(
`/api/permissions/admin/v1/
${
appid
}
/application/user`
,
data
)
}
/**
* 创建应用管理员
*/
export
function
createAppAdminUsers
(
appid
,
data
)
{
return
httpRequest
.
post
(
`/api/permissions/admin/v1/
${
appid
}
/application/assign/users-to-app`
,
data
)
}
/**
* 获取事件列表
*/
export
function
getEventList
(
params
)
{
return
httpRequest
.
get
(
`/api/permissions/admin/v1/
${
params
.
app_id
}
/events`
,
{
params
})
}
/**
* 创建事件
*/
export
function
createEvent
(
appid
,
data
)
{
return
httpRequest
.
post
(
`/api/permissions/admin/v1/
${
appid
}
/event/create`
,
data
)
}
/**
* 更新事件
*/
export
function
updateEvent
(
id
,
data
)
{
return
httpRequest
.
put
(
`/api/permissions/admin/v1/event/
${
id
}
/update`
,
data
)
}
/**
* 删除事件
*/
export
function
deleteEvents
(
data
)
{
return
httpRequest
.
post
(
'/api/permissions/admin/v1/event/batch-delete'
,
data
)
}
/**
* 获取事件详情
*/
export
function
getEvent
(
params
)
{
return
httpRequest
.
get
(
`/api/permissions/admin/v1/event/
${
params
.
id
}
/detail`
,
{
params
})
}
/**
* 刷新事件token
*/
export
function
refreshEventToken
(
params
)
{
return
httpRequest
.
patch
(
`/api/permissions/admin/v1/event/
${
params
.
id
}
/refresh-token`
,
{
params
})
}
/**
* 获取获取事件回调记录列表
* 试题详情
*/
export
function
getEventRecordList
(
params
)
{
return
httpRequest
.
get
(
`/api/
permissions/admin/v1/
${
params
.
app_id
}
/event/records`
,
{
params
}
)
export
function
questionDetail
(
id
)
{
return
httpRequest
.
get
(
`/api/
qbs/admin/v1/question/
${
id
}
`
)
}
src/modules/question/components/AddChidren.vue
浏览文件 @
7f689cd5
...
...
@@ -9,12 +9,19 @@
<template
v-if=
"source == 1"
>
<div
class=
"radio-box"
>
<div
class=
"tips-tit index"
>
请选择题库:
</div>
<el-radio
v-model=
"questionBank"
label=
"1"
>
我的题库
</el-radio>
<el-radio
v-model=
"questionBank"
label=
"2"
style=
"text-indent: 1.5em"
>
公共题库
</el-radio>
<el-radio
@
change=
"radioChange"
v-model=
"questionBank"
label=
"1"
>
我的题库
</el-radio>
<el-radio
@
change=
"radioChange"
v-model=
"questionBank"
label=
"2"
style=
"text-indent: 1.5em"
>
公共题库
</el-radio>
</div>
<app-list
v-bind=
"tableOptions"
ref=
"list"
class=
"app-list"
></app-list>
<app-list
v-bind=
"tableOptions"
ref=
"list"
class=
"app-list"
@
selection-change=
"handleSelectionChange"
>
<template
v-slot:input-filter
>
<div
class=
"filter-input"
>
<el-input
v-model=
"filterInput"
placeholder=
"请选择"
></el-input>
<div
class=
"pop"
@
click=
"dialogVisible = true"
></div>
</div>
</
template
>
</app-list>
<div
class=
"btn-box"
>
<el-button
type=
"primary"
>
确定
</el-button>
<el-button
type=
"primary"
@
click=
"$emit('haveQuestion', checkedList)"
>
确定
</el-button>
</div>
</template>
<
template
v-else
>
...
...
@@ -22,72 +29,236 @@
<div
class=
"tips-tit"
>
请选择子题目类型:
</div>
<el-radio
v-model=
"type"
label=
"1"
>
单选题
</el-radio>
<el-radio
v-model=
"type"
label=
"2"
>
多选题
</el-radio>
<el-radio
v-model=
"type"
label=
"3"
>
判断题
</el-radio>
<el-radio
v-model=
"type"
label=
"4"
>
问答题
</el-radio>
<el-radio
v-model=
"type"
label=
"6"
>
判断题
</el-radio>
<el-radio
v-model=
"type"
label=
"3"
>
简答题
</el-radio>
</div>
<div
class=
"btn-box"
style=
"padding-top:50px;"
>
<el-button
type=
"primary"
@
click=
"addQuestionConfirm"
>
确定
</el-button>
</div>
</
template
>
<el-dialog
title=
"提示"
:visible=
"dialogVisible"
width=
"30%"
:before-close=
"handleClose"
>
<el-tree
:data=
"treeList"
:props=
"defaultProps"
@
node-click=
"handleNodeClick"
:expand-on-click-node=
"false"
></el-tree>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"handleClose"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"dialogConfirm"
>
确 定
</el-button>
</span>
</el-dialog>
</div>
</template>
<
script
>
import
{
getAppList
}
from
'../api'
import
{
getAppList
,
getQuestionCategory
}
from
'../api'
export
default
{
data
()
{
return
{
dialogVisible
:
false
,
filterInput
:
''
,
source
:
'1'
,
questionBank
:
'1'
,
type
:
'1'
type
:
'1'
,
visible
:
false
,
treeList
:
[],
defaultProps
:
''
,
treeValue
:
{
name
:
''
,
id
:
''
},
checkedList
:
[]
}
},
computed
:
{
tableOptions
()
{
return
{
limit
:
10
,
filters
:
[
{
type
:
'select'
,
label
:
'题目类型:'
label
:
'题目类型:'
,
prop
:
'question_type'
,
options
:
[
{
label
:
'单选题'
,
value
:
1
},
{
label
:
'多选题'
,
value
:
2
},
{
label
:
'问答题'
,
value
:
3
},
{
label
:
'案例题'
,
value
:
5
},
{
label
:
'判断题'
,
value
:
6
},
{
label
:
'实操题'
,
value
:
7
},
{
label
:
'情景题'
,
value
:
8
}
]
},
{
type
:
'select'
,
label
:
'等级难度:'
prop
:
'question_title'
,
type
:
'input'
,
label
:
'题目标题:'
},
{
type
:
'select'
,
label
:
'试题分类:'
prop
:
'question_content'
,
type
:
'input'
,
label
:
'题干内容:'
},
{
type
:
'input'
,
label
:
'题目标题:'
prop
:
'question_difficulty'
,
type
:
'select'
,
label
:
'难度等级:'
,
options
:
[
{
label
:
'易'
,
value
:
'1'
},
{
label
:
'中'
,
value
:
'2'
},
{
label
:
'难'
,
value
:
'3'
}
]
},
{
slots
:
'input-filter'
,
prop
:
'question_category'
,
type
:
'input'
,
label
:
'
题干内容
:'
label
:
'
试题分类
:'
},
{
type
:
'input'
,
label
:
'知识点:'
prop
:
'question_tag'
,
label
:
'知识点/标签:'
}
],
remote
:
{
httpRequest
:
getAppList
},
remote
:
{
httpRequest
:
getAppList
,
params
:
{
permission
:
this
.
questionBank
,
project_prefix
:
'x1'
,
question_category
:
this
.
treeValue
.
id
},
callback
(
data
)
{
const
questionType
=
{
1
:
'单选题'
,
2
:
'多选题'
,
3
:
'问答题'
,
6
:
'判断题'
}
const
questionDifficulty
=
{
1
:
'易'
,
2
:
'中'
,
3
:
'难'
}
return
data
.
data
.
reduce
((
a
,
b
)
=>
{
const
type
=
b
.
question_type
b
.
question_type
=
questionType
[
b
.
question_type
]
b
.
question_difficulty
=
questionDifficulty
[
b
.
question_difficulty
]
if
(
type
!==
5
&&
type
!==
7
&&
type
!==
8
)
a
.
push
(
b
)
return
a
},
[])
}
},
columns
:
[
{
type
:
'selection'
,
minWidth
:
'50px'
,
fixed
:
'left'
},
{
label
:
'序号'
,
prop
:
'order'
},
{
label
:
'题目类型'
,
prop
:
'type'
},
{
label
:
'试题分类'
,
prop
:
'sort'
},
{
label
:
'题目目标'
,
prop
:
'title'
},
{
label
:
'知识点'
,
prop
:
'points'
},
{
label
:
'等级难度'
,
prop
:
'grade'
},
{
label
:
'更新人'
,
prop
:
'update_people'
}
{
label
:
'序号'
,
prop
:
'question_order'
},
{
label
:
'题目类型'
,
prop
:
'question_type'
},
{
label
:
'试题分类'
,
prop
:
'question_category.category_name'
},
{
label
:
'题目标题'
,
prop
:
'question_title'
},
{
label
:
'知识点'
,
prop
:
'knowledge_point.title'
},
{
label
:
'等级难度'
,
prop
:
'question_difficulty'
},
{
label
:
'更新人'
,
prop
:
'operator.nickname'
},
{
label
:
'更新时间'
,
prop
:
'updated_at'
},
{
label
:
'操作'
,
slots
:
'table-x'
,
align
:
'right'
}
]
}
}
},
mounted
()
{
this
.
getTreeList
()
},
methods
:
{
handleSelectionChange
(
data
)
{
this
.
checkedList
=
data
.
reduce
((
a
,
b
)
=>
{
const
data
=
{}
console
.
log
(
typeof
b
.
child_question_type
)
data
.
question_title
=
b
.
question_title
data
.
child_question_type
=
b
.
child_question_type
||
'1'
data
.
question_content
=
b
.
question_content
data
.
question_analysis
=
b
.
question_analysis
if
(
this
.
type
!==
'3'
)
data
.
question_options
=
b
.
question_options
a
.
push
(
data
)
return
a
},
[])
},
radioChange
()
{
this
.
$refs
.
list
.
refetch
()
},
addQuestionConfirm
()
{
const
data
=
{
question_title
:
''
,
child_question_type
:
this
.
type
,
question_content
:
''
,
question_analysis
:
''
}
let
options
=
[]
if
(
this
.
type
!==
'3'
)
{
if
(
this
.
type
===
'1'
||
this
.
type
===
'2'
)
{
options
=
[
{
option
:
''
,
checked
:
true
},
{
option
:
''
,
checked
:
false
},
{
option
:
''
,
checked
:
false
}
]
}
else
{
options
=
[
{
option
:
'正确'
,
checked
:
true
},
{
option
:
'错误'
,
checked
:
false
}
]
}
data
.
question_options
=
options
}
this
.
$emit
(
'questionList'
,
data
)
},
handleNodeClick
(
data
)
{
this
.
treeValue
.
name
=
data
.
label
this
.
treeValue
.
id
=
data
.
id
},
handleClose
()
{
this
.
treeValue
.
name
=
''
this
.
treeValue
.
id
=
''
this
.
dialogVisible
=
false
},
dialogConfirm
()
{
this
.
dialogVisible
=
false
this
.
filterInput
=
this
.
treeValue
.
name
this
.
$refs
.
list
.
refetch
()
},
// 获取tree列表
getTreeList
()
{
getQuestionCategory
(
'x1'
).
then
(
res
=>
{
if
(
Array
.
isArray
(
res
.
data
))
{
this
.
initTree
(
res
.
data
)
}
})
},
// 过滤数据 变成tree组件需要的数据
initTree
(
data
)
{
this
.
treeList
=
data
.
reduce
((
a
,
b
)
=>
{
b
.
label
=
b
.
category_name
if
(
b
.
children
.
length
)
{
setData
(
b
.
children
)
}
a
.
push
(
b
)
return
a
},
[])
function
setData
(
item
)
{
return
item
.
map
(
element
=>
{
if
(
element
.
children
.
length
)
{
setData
(
element
.
children
)
element
.
label
=
element
.
category_name
}
else
{
element
.
label
=
element
.
category_name
}
return
element
})
}
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
>
.add-chidren
{
padding
:
0
20px
;
.radio-tips
{
...
...
@@ -113,6 +284,10 @@ export default {
.btn-box
{
display
:
flex
;
justify-content
:
center
;
padding-bottom
:
30px
;
}
}
.v-modal
{
z-index
:
10
!
important
;
}
</
style
>
src/modules/question/components/Detail.vue
浏览文件 @
7f689cd5
<
template
>
<div>
<!--
<el-form
:model=
"ruleForm"
:rules=
"rules"
ref=
"ruleForm"
label-width=
"100px"
class=
"demo-ruleForm"
>
-->
<el-form
:model=
"ruleForm"
:rules=
"rules"
ref=
"ruleForm"
label-width=
"100px"
class=
"demo-ruleForm"
>
<el-form-item
label=
"题库范围"
prop=
"permission"
>
<el-radio
v-model=
"ruleForm.permission"
label=
"1"
>
我的题库
</el-radio>
<el-radio
v-model=
"ruleForm.permission"
label=
"2"
>
公共题库
</el-radio>
</el-form-item>
<el-form-item
label=
"题目类型"
prop=
"question_type"
>
<!--
<el-input
v-model=
"ruleForm.name"
></el-input>
-->
<el-select
v-model=
"ruleForm.question_type"
placeholder=
"请选择活题目类型"
@
change=
"changeQuestionType"
>
<el-select
@
change=
"questionTypeChange"
v-model=
"ruleForm.question_type"
placeholder=
"请选择活题目类型"
>
<el-option
v-for=
"(item, index) in qType"
:label=
"item.label"
:value=
"item.value"
:key=
"index"
></el-option>
</el-select>
</el-form-item>
...
...
@@ -26,13 +26,13 @@
</el-form-item>
<el-form-item
label=
"选项"
prop=
"question_options"
v-if=
"ruleForm.question_type != 3"
>
<!-- 单选题 -->
<radio
ref=
"options"
v-if=
"ruleForm.question_type == 1"
></radio>
<radio
ref=
"options"
:option=
"ruleForm.question_options"
v-if=
"ruleForm.question_type == 1"
></radio>
<!-- 多选题 -->
<checkbox
ref=
"options"
v-if=
"ruleForm.question_type == 2"
></checkbox>
<checkbox
ref=
"options"
:option=
"ruleForm.question_options"
v-if=
"ruleForm.question_type == 2"
></checkbox>
<!-- 判断题 -->
<judgment
ref=
"options"
v-if=
"ruleForm.question_type == 6"
></judgment>
<judgment
ref=
"options"
:option=
"ruleForm.question_options"
v-if=
"ruleForm.question_type == 6"
></judgment>
</el-form-item>
<el-form-item
label=
"标签"
prop=
"
type
"
>
<el-form-item
label=
"标签"
prop=
"
question_tag
"
>
<el-input
v-model=
"ruleForm.question_tag"
></el-input>
</el-form-item>
<el-form-item
label=
"题目解析"
prop=
"question_analysis"
>
...
...
@@ -53,27 +53,28 @@
remote
reserve-keyword
placeholder=
"请输入关键词"
:remote-method=
"remoteMethod"
>
<el-option
v-for=
"item in pointOptions"
:key=
"item.id"
:label=
"item.title"
:value=
"item.id"
>
</el-option>
:remote-method=
"remoteMethod"
>
<el-option
v-for=
"item in pointOptions"
:key=
"item.id"
:label=
"item.title"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"submitForm('ruleForm')"
>
立即创建
</el-button>
<template
v-if=
"$route.query.id"
>
<el-button
v-if=
"$route.query.type == 'edit'"
type=
"primary"
@
click=
"submitForm('ruleForm')"
>
确认修改
</el-button>
</
template
>
<
template
v-else
>
<el-button
type=
"primary"
@
click=
"submitForm('ruleForm')"
>
立即创建
</el-button>
</
template
>
<!-- <el-button @click="resetForm('ruleForm')">重置</el-button> -->
</el-form-item>
</el-form>
<el-dialog
title=
"提示"
:visible
.
sync=
"dialogVisible
"
width=
"30%
"
:before-close=
"handleClose
"
>
<el-tree
:data=
"treeList"
:props=
"defaultProps"
@
node-click=
"handleNodeClick"
:expand-on-click-node=
"false"
></el-tree>
<el-dialog
title=
"提示"
:visible
.
sync=
"dialogVisible"
width=
"30%"
:before-close=
"handleClose"
>
<el-tree
:data=
"treeList
"
:props=
"defaultProps
"
@
node-click=
"handleNodeClick
"
:expand-on-click-node=
"false"
></el-tree>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"handleClose"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"dialogConfirm"
>
确 定
</el-button>
...
...
@@ -86,12 +87,17 @@ import VEditor from '@/components/tinymce/Index.vue'
import
Radio
from
'../components/QTypeRadio.vue'
import
Checkbox
from
'../components/QTypeCheckbox.vue'
import
Judgment
from
'../components/QTypeJudgment.vue'
import
{
getQuestionCategory
,
searchTag
,
addQuestion
}
from
'../api'
import
{
getQuestionCategory
,
searchTag
,
addQuestion
,
updateQuestion
}
from
'../api'
export
default
{
components
:
{
VEditor
,
Radio
,
Checkbox
,
Judgment
},
props
:
{
detailData
:
{
type
:
Object
}
},
data
()
{
return
{
pointOptions
:
''
,
pointOptions
:
[]
,
treeList
:
[],
defaultProps
:
''
,
treeValue
:
{
...
...
@@ -106,7 +112,7 @@ export default {
question_difficulty
:
''
,
question_title
:
''
,
question_content
:
''
,
//
question_options: [],
question_options
:
[],
question_analysis
:
''
,
question_category
:
''
,
knowledge_point
:
''
,
...
...
@@ -115,7 +121,7 @@ export default {
qType
:
[
{
label
:
'单选题'
,
value
:
1
},
{
label
:
'多选题'
,
value
:
2
},
{
label
:
'
简
答题'
,
value
:
3
},
{
label
:
'
问
答题'
,
value
:
3
},
{
label
:
'案例题'
,
value
:
5
},
{
label
:
'判断题'
,
value
:
6
},
{
label
:
'实操题'
,
value
:
7
},
...
...
@@ -134,24 +140,34 @@ export default {
}
},
mounted
()
{
if
(
this
.
detailData
)
{
this
.
ruleForm
=
this
.
detailData
}
this
.
getTreeList
()
},
methods
:
{
submitForm
(
formName
)
{
if
(
parseInt
(
this
.
ruleForm
.
question_type
)
!==
3
)
{
console
.
log
(
this
.
$refs
.
options
.
datas
,
'123'
)
const
isValue
=
this
.
$refs
.
options
.
datas
.
find
(
item
=>
item
.
option
===
''
)
if
(
!
isValue
)
this
.
ruleForm
.
question_options
=
this
.
$refs
.
options
.
datas
}
this
.
$refs
[
formName
].
validate
(
valid
=>
{
if
(
valid
)
{
// alert('submit!')
addQuestion
(
this
.
ruleForm
).
then
(
res
=>
{
if
(
res
.
code
===
0
)
{
// console.log(JSON.stringify(this.ruleForm))
if
(
this
.
$router
.
query
.
id
)
{
updateQuestion
(
this
.
ruleForm
).
then
(
res
=>
{
this
.
$router
.
push
({
path
:
'/question/list'
})
})
}
else
{
addQuestion
(
this
.
ruleForm
).
then
(
res
=>
{
this
.
$router
.
push
({
path
:
'/question/list'
})
}
}
)
}
)
}
}
else
{
console
.
log
(
'error submit!!'
)
return
false
...
...
@@ -161,9 +177,6 @@ export default {
resetForm
(
formName
)
{
this
.
$refs
[
formName
].
resetFields
()
},
changeQuestionType
()
{
console
.
log
(
this
.
ruleForm
.
question_type
)
},
// 点击选中tree
handleNodeClick
(
data
)
{
this
.
treeValue
.
name
=
data
.
label
...
...
@@ -213,8 +226,10 @@ export default {
console
.
log
(
query
)
searchTag
({
title
:
query
}).
then
(
res
=>
{
this
.
pointOptions
=
res
.
data
.
data
console
.
log
(
res
,
'query'
)
})
},
questionTypeChange
()
{
this
.
$emit
(
'questionType'
,
this
.
ruleForm
.
question_type
)
}
}
}
...
...
src/modules/question/components/QTypeCheckbox.vue
浏览文件 @
7f689cd5
<
template
>
<div
class=
"radio-box"
>
<template
v-for=
"(item, index) in datas"
>
<template
v-for=
"(item, index) in
option ||
datas"
>
<div
class=
"opt"
:key=
"index"
>
<el-checkbox
v-model=
"checkboxValue"
:label=
"index"
@
change=
"checkboxChange"
>
<el-tag>
{{
A_Z
()[
index
]
}}
</el-tag>
...
...
@@ -15,6 +15,11 @@
<
script
>
export
default
{
props
:
{
option
:
{
type
:
Array
}
},
data
()
{
return
{
checkboxValue
:
[
0
],
...
...
@@ -38,6 +43,9 @@ export default {
]
}
},
mounted
()
{
if
(
this
.
option
)
this
.
datas
=
this
.
option
},
methods
:
{
add
()
{
this
.
datas
.
push
({
option
:
''
,
checked
:
false
})
...
...
src/modules/question/components/QTypeJudgment.vue
浏览文件 @
7f689cd5
...
...
@@ -7,6 +7,11 @@
<
script
>
export
default
{
props
:
{
option
:
{
type
:
Array
}
},
data
()
{
return
{
radio
:
'0'
,
...
...
@@ -22,6 +27,9 @@ export default {
]
}
},
mounted
()
{
if
(
this
.
option
)
this
.
datas
=
this
.
option
},
methods
:
{
radioChange
()
{
this
.
datas
.
map
(
item
=>
{
...
...
@@ -29,7 +37,6 @@ export default {
this
.
datas
[
this
.
radio
].
checked
=
true
return
item
})
console
.
log
(
this
.
datas
,
'datas'
)
}
}
}
...
...
src/modules/question/components/QTypeRadio.vue
浏览文件 @
7f689cd5
<
template
>
<div
class=
"radio-box"
>
<template
v-for=
"(item, index) in datas"
>
<template
v-for=
"(item, index) in
option ||
datas"
>
<div
class=
"opt"
:key=
"index"
>
<el-radio
v-model=
"radioValue"
:label=
"index"
@
change=
"radioChange"
>
<el-tag>
{{
A_Z
()[
index
]
}}
</el-tag>
...
...
@@ -10,12 +10,16 @@
<i
class=
"el-icon-circle-plus-outline icon-style"
v-else
@
click=
"add"
></i>
</div>
</
template
>
<!-- <el-radio v-model="radio" label="1"></el-radio> -->
</div>
</template>
<
script
>
export
default
{
props
:
{
option
:
{
type
:
Array
}
},
data
()
{
return
{
radioValue
:
0
,
...
...
@@ -36,6 +40,9 @@ export default {
ruleForm
:
''
}
},
mounted
()
{
if
(
this
.
option
)
this
.
datas
=
this
.
option
},
methods
:
{
add
()
{
this
.
datas
.
push
({
option
:
''
,
checked
:
false
})
...
...
src/modules/question/components/QTypeSituation.vue
浏览文件 @
7f689cd5
<
template
>
<div>
<div
class=
"tool-btn"
>
<el-button
type=
"primary"
@
click=
"
submitForm('ruleForm')
"
>
添加子题目
</el-button>
<el-button
type=
"primary"
@
click=
"
drawer = true
"
>
添加子题目
</el-button>
<el-button
type=
"primary"
@
click=
"resetForm('ruleForm')"
>
保存主题目
</el-button>
</div>
<el-form
:model=
"ruleForm"
:rules=
"rules"
ref=
"ruleForm"
label-width=
"100px"
class=
"demo-ruleForm"
>
<el-form-item
label=
"题目类型"
prop=
"desc"
>
<el-select
v-model=
"ruleForm.desc"
placeholder=
"请选择活动区域"
>
<el-option
label=
"单选题"
value=
"questionType1"
></el-option>
<el-option
label=
"多选题"
value=
"questionType2"
></el-option>
<el-option
label=
"判断题"
value=
"questionType3"
></el-option>
<el-option
label=
"问答题"
value=
"questionType4"
></el-option>
<el-form-item
label=
"题库范围"
prop=
"permission"
>
<el-radio
v-model=
"ruleForm.permission"
label=
"1"
>
我的题库
</el-radio>
<el-radio
v-model=
"ruleForm.permission"
label=
"2"
>
公共题库
</el-radio>
</el-form-item>
<el-form-item
label=
"题目类型"
prop=
"question_type"
>
<el-select
@
change=
"questionTypeChange"
v-model=
"ruleForm.question_type"
placeholder=
"请选择活题目类型"
>
<el-option
v-for=
"(item, index) in qType"
:label=
"item.label"
:value=
"item.value"
:key=
"index"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"难度等级"
prop=
"question_difficulty"
>
<el-select
v-model=
"ruleForm.question_difficulty"
placeholder=
"请选择活难度等级"
>
<el-option
label=
"易"
value=
"1"
></el-option>
<el-option
label=
"中"
value=
"2"
></el-option>
<el-option
label=
"难"
value=
"3"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"题目标题"
prop=
"
data2
"
>
<el-input
v-model=
"ruleForm.
data2
"
></el-input>
<el-form-item
label=
"题目标题"
prop=
"
question_title
"
>
<el-input
v-model=
"ruleForm.
question_title
"
></el-input>
</el-form-item>
<el-form-item
label=
"公共题干"
prop=
"
data2
"
>
<v-editor></v-editor>
<el-form-item
label=
"公共题干"
prop=
"
common_content
"
>
<v-editor
v-model=
"ruleForm.common_content"
></v-editor>
</el-form-item>
<el-form-item>
<!--
<el-button
type=
"primary"
@
click=
"submitForm('ruleForm')"
>
立即创建
</el-button>
-->
<!--
<el-button
@
click=
"resetForm('ruleForm')"
>
重置
</el-button>
-->
<!--
</el-form-item>
-->
<!--
<el-form-item>
-->
<el-form-item
label=
"标签"
prop=
"question_tag"
>
<el-input
v-model=
"ruleForm.question_tag"
></el-input>
</el-form-item>
<el-form-item
label=
"试题分类"
prop=
"question_category"
>
<div
class=
"filter-input"
>
<el-select
v-model=
"ruleForm.question_category"
placeholder=
"请选择试题分类"
>
<el-option
v-if=
"!dialogVisible"
:label=
"treeValue.name"
:value=
"treeValue.id"
></el-option>
</el-select>
<div
class=
"pop"
@
click=
"dialogVisible = true"
></div>
</div>
</el-form-item>
<el-dialog
title=
"提示"
:visible
.
sync=
"dialogVisible"
width=
"30%"
:before-close=
"handleClose"
>
<el-tree
:data=
"treeList"
:props=
"defaultProps"
@
node-click=
"handleNodeClick"
:expand-on-click-node=
"false"
></el-tree>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"handleClose"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"dialogConfirm"
>
确 定
</el-button>
</span>
</el-dialog>
<el-form-item
label=
"知识点"
prop=
"knowledge_point"
>
<el-select
v-model=
"ruleForm.knowledge_point"
filterable
remote
reserve-keyword
placeholder=
"请输入关键词"
:remote-method=
"remoteMethod"
>
<el-option
v-for=
"item in pointOptions"
:key=
"item.id"
:label=
"item.title"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
<questions-chidren></questions-chidren>
<!--
<questions-chidren></questions-chidren>
-->
<el-drawer
size=
"90%"
title=
"新建试题"
:visible
.
sync=
"drawer"
direction=
"rtl"
:before-close=
"handleClose"
>
<add-chidren></add-chidren>
<questions-chidren
:chidrenList=
"chidrenList"
@
submitForm=
"submitForm"
@
addChidren=
"drawer = true"
></questions-chidren>
<el-drawer
size=
"90%"
title=
"新建试题"
:visible
.
sync=
"drawer"
direction=
"rtl"
:before-close=
"handleCloseDrawer"
>
<add-chidren
@
haveQuestion=
"haveQuestion"
@
questionList=
"questionList"
:dataForm=
"ruleForm"
></add-chidren>
</el-drawer>
</div>
</
template
>
...
...
@@ -35,56 +79,150 @@
import
QuestionsChidren
from
'./QuestionsChidren.vue'
import
VEditor
from
'@/components/tinymce/Index.vue'
import
AddChidren
from
'./AddChidren.vue'
import
{
getQuestionCategory
,
searchTag
,
addQuestion
}
from
'../api'
export
default
{
components
:
{
AddChidren
,
VEditor
,
QuestionsChidren
},
props
:
{
questionTypeNumber
:
{
type
:
Number
,
default
:
1
}
},
data
()
{
return
{
pointOptions
:
[],
treeList
:
[],
defaultProps
:
''
,
treeValue
:
{
name
:
''
,
id
:
''
},
dialogVisible
:
false
,
chidrenList
:
[],
drawer
:
false
,
ruleForm
:
{
name
:
''
,
region
:
''
,
date1
:
''
,
date2
:
''
,
delivery
:
false
,
type
:
''
,
resource
:
''
,
desc
:
''
permission
:
'1'
,
question_type
:
1
,
question_title
:
''
,
common_content
:
''
,
question_category
:
''
,
question_tag
:
''
,
knowledge_point
:
''
,
question_difficulty
:
''
,
children
:
[]
},
rules
:
{
name
:
[
{
required
:
true
,
message
:
'请输入活动名称'
,
trigger
:
'blur'
},
{
min
:
3
,
max
:
5
,
message
:
'长度在 3 到 5 个字符'
,
trigger
:
'blur'
}
],
region
:
[{
required
:
true
,
message
:
'请选择活动区域'
,
trigger
:
'change'
}],
date1
:
[{
type
:
'date'
,
required
:
true
,
message
:
'请选择日期'
,
trigger
:
'change'
}],
date2
:
[{
type
:
'date'
,
required
:
true
,
message
:
'请选择时间'
,
trigger
:
'change'
}],
type
:
[{
type
:
'array'
,
required
:
true
,
message
:
'请至少选择一个活动性质'
,
trigger
:
'change'
}],
resource
:
[{
required
:
true
,
message
:
'请选择活动资源'
,
trigger
:
'change'
}],
desc
:
[{
required
:
true
,
message
:
'请填写活动形式'
,
trigger
:
'blur'
}]
}
permission
:
[{
required
:
true
,
message
:
'请选择'
,
trigger
:
'change'
}],
question_type
:
[{
required
:
true
,
message
:
'请选择'
,
trigger
:
'change'
}],
question_difficulty
:
[{
required
:
true
,
message
:
'请选择难度等级'
,
trigger
:
'change'
}],
question_title
:
[{
required
:
true
,
message
:
'请填写题目标题'
,
trigger
:
'blur'
}],
common_content
:
[{
required
:
true
,
message
:
'请填写题干内容'
,
trigger
:
'blur'
}],
question_category
:
[{
required
:
true
,
message
:
'请选择试题分类'
,
trigger
:
'blur'
}],
knowledge_point
:
[{
required
:
true
,
message
:
'请输入题目知识点内容'
,
trigger
:
'blur'
}]
},
qType
:
[
{
label
:
'单选题'
,
value
:
1
},
{
label
:
'多选题'
,
value
:
2
},
{
label
:
'简答题'
,
value
:
3
},
{
label
:
'案例题'
,
value
:
5
},
{
label
:
'判断题'
,
value
:
6
},
{
label
:
'实操题'
,
value
:
7
},
{
label
:
'情景题'
,
value
:
8
}
]
}
},
mounted
()
{
this
.
ruleForm
.
question_type
=
this
.
questionTypeNumber
this
.
getTreeList
()
},
methods
:
{
handleCloseDrawer
()
{
this
.
drawer
=
false
},
submitForm
(
formName
)
{
this
.
ruleForm
.
children
=
this
.
chidrenList
addQuestion
(
this
.
ruleForm
).
then
(
res
=>
{
// 11
this
.
$router
.
push
({
path
:
'/question/list'
})
})
},
resetForm
(
formName
)
{
this
.
$refs
[
formName
].
validate
(
valid
=>
{
if
(
valid
)
{
this
.
drawer
=
true
// alert('submit!')
console
.
log
(
this
.
chidrenList
)
}
else
{
console
.
log
(
'error submit!!'
)
return
false
}
})
},
resetForm
(
formName
)
{
this
.
$refs
[
formName
].
resetFields
()
questionTypeChange
()
{
this
.
$emit
(
'questionType'
,
this
.
ruleForm
.
question_type
)
},
// 点击选中tree
handleNodeClick
(
data
)
{
this
.
treeValue
.
name
=
data
.
label
this
.
treeValue
.
id
=
data
.
id
},
// 关闭选择tree弹窗
handleClose
()
{
this
.
dialogVisible
=
false
},
// tree确认选择
dialogConfirm
()
{
this
.
dialogVisible
=
false
this
.
ruleForm
.
question_category
=
this
.
treeValue
.
id
},
// 获取tree列表
getTreeList
()
{
getQuestionCategory
(
'x1'
).
then
(
res
=>
{
if
(
Array
.
isArray
(
res
.
data
))
{
this
.
initTree
(
res
.
data
)
}
})
},
handleClose
(
done
)
{
this
.
$confirm
(
'确认关闭?'
)
.
then
(
_
=>
{
done
()
// 过滤数据 变成tree组件需要的数据
initTree
(
data
)
{
this
.
treeList
=
data
.
reduce
((
a
,
b
)
=>
{
b
.
label
=
b
.
category_name
if
(
b
.
children
.
length
)
{
setData
(
b
.
children
)
}
a
.
push
(
b
)
return
a
},
[])
function
setData
(
item
)
{
return
item
.
map
(
element
=>
{
if
(
element
.
children
.
length
)
{
setData
(
element
.
children
)
element
.
label
=
element
.
category_name
}
else
{
element
.
label
=
element
.
category_name
}
return
element
})
.
catch
(
_
=>
{})
}
},
// 知识点搜索
remoteMethod
(
query
)
{
console
.
log
(
query
)
searchTag
({
title
:
query
}).
then
(
res
=>
{
this
.
pointOptions
=
res
.
data
.
data
})
},
// 添加子题目
questionList
(
data
)
{
this
.
chidrenList
.
push
(
data
)
this
.
drawer
=
false
console
.
log
(
this
.
chidrenList
,
'list'
)
},
haveQuestion
(
data
)
{
data
.
forEach
(
item
=>
{
this
.
chidrenList
.
push
(
item
)
})
this
.
drawer
=
false
}
}
}
...
...
src/modules/question/components/QuestionsChidren.vue
浏览文件 @
7f689cd5
<
template
>
<div>
<el-divider
content-position=
"center"
class=
"divider"
>
子题目1
</el-divider>
<el-form
:model=
"ruleForm"
:rules=
"rules"
ref=
"ruleForm"
label-width=
"100px"
class=
"demo-ruleForm"
>
<el-form-item
label=
"子题目类型"
prop=
"desc"
>
<el-select
v-model=
"ruleForm.desc"
disabled
placeholder=
"请选择活动区域"
>
<el-option
label=
"单选题"
value=
"questionType1"
></el-option>
<el-option
label=
"多选题"
value=
"questionType2"
></el-option>
<el-option
label=
"判断题"
value=
"questionType3"
></el-option>
<el-option
label=
"问答题"
value=
"questionType4"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"难度等级"
prop=
"desc"
>
<el-select
v-model=
"ruleForm.desc"
placeholder=
"请选择活动区域"
>
<el-option
label=
"单选题"
value=
"questionType1"
></el-option>
<el-option
label=
"多选题"
value=
"questionType2"
></el-option>
<el-option
label=
"判断题"
value=
"questionType3"
></el-option>
<el-option
label=
"问答题"
value=
"questionType4"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"子题目标题"
prop=
"data2"
>
<el-input
v-model=
"ruleForm.data2"
></el-input>
</el-form-item>
<el-form-item
label=
"子题目内容"
prop=
"data2"
>
<v-editor></v-editor>
</el-form-item>
<el-form-item
label=
"选项"
>
<radio></radio>
<!--
<el-button
type=
"primary"
@
click=
"submitForm('ruleForm')"
>
立即创建
</el-button>
-->
<!--
<el-button
@
click=
"resetForm('ruleForm')"
>
重置
</el-button>
-->
</el-form-item>
<el-form-item
label=
"标签"
>
<el-input
v-model=
"ruleForm.data2"
></el-input>
</el-form-item>
<el-form-item
label=
"子题目解析"
prop=
"data2"
>
<v-editor></v-editor>
</el-form-item>
<el-form-item
label=
"试题分类"
prop=
"desc"
>
<el-select
v-model=
"ruleForm.desc"
disabled
placeholder=
"请选择活动区域"
>
<el-option
label=
"单选题"
value=
"questionType1"
></el-option>
<el-option
label=
"多选题"
value=
"questionType2"
></el-option>
<el-option
label=
"判断题"
value=
"questionType3"
></el-option>
<el-option
label=
"问答题"
value=
"questionType4"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"知识点"
>
<el-input
v-model=
"ruleForm.data2"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"submitForm('ruleForm')"
>
保存子题目
</el-button>
<el-button
type=
"primary"
@
click=
"resetForm('ruleForm')"
>
删除子题目
</el-button>
<!--
<el-input
v-model=
"ruleForm.data2"
></el-input>
-->
</el-form-item>
<el-form
:model=
"data"
ref=
"ruleForm"
label-width=
"100px"
class=
"demo-ruleForm"
>
<div
v-for=
"(ruleForm, index) in dataList"
:key=
"index"
>
<el-divider
content-position=
"center"
class=
"divider"
>
子题目
{{
index
+
1
}}
</el-divider>
<el-form-item
style=
"text-align: right;"
>
<el-button
type=
"primary"
@
click=
"$emit('addChidren')"
>
添加子题目
</el-button>
<el-button
type=
"primary"
@
click=
"removeChidren(index)"
>
删除子题目
</el-button>
</el-form-item>
<el-form-item
label=
"子题目类型"
prop=
"child_question_type"
>
<el-select
v-model=
"ruleForm.child_question_type"
disabled
placeholder=
"请选择活动区域"
>
<el-option
label=
"单选题"
value=
"1"
></el-option>
<el-option
label=
"多选题"
value=
"2"
></el-option>
<el-option
label=
"判断题"
value=
"6"
></el-option>
<el-option
label=
"问答题"
value=
"3"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"子题目标题"
prop=
"question_title"
>
<el-input
v-model=
"ruleForm.question_title"
></el-input>
</el-form-item>
<el-form-item
label=
"子题目内容"
prop=
"question_content"
>
<v-editor
v-model=
"ruleForm.question_content"
></v-editor>
</el-form-item>
<el-form-item
label=
"选项"
prop=
"question_options"
v-if=
"ruleForm.child_question_type != 3"
>
<!-- 单选题 -->
<radio
ref=
"options"
:option=
"ruleForm.question_options"
v-if=
"ruleForm.child_question_type == 1"
></radio>
<!-- 多选题 -->
<checkbox
ref=
"options"
:option=
"ruleForm.question_options"
v-if=
"ruleForm.child_question_type == 2"
></checkbox>
<!-- 判断题 -->
<judgment
ref=
"options"
:option=
"ruleForm.question_options"
v-if=
"ruleForm.child_question_type == 6"
></judgment>
</el-form-item>
<el-form-item
label=
"子题目解析"
prop=
"question_analysis"
>
<v-editor
v-model=
"ruleForm.question_analysis"
></v-editor>
</el-form-item>
<el-form-item
style=
"text-align: center;"
v-if=
"index + 1 == dataList.length"
>
<el-button
type=
"primary"
@
click=
"submitForm"
>
保存
</el-button>
</el-form-item>
</div>
</el-form>
</div>
</
template
>
<
script
>
import
Radio
from
'./QTypeRadio.vue'
import
Checkbox
from
'./QTypeCheckbox.vue'
import
Judgment
from
'./QTypeJudgment.vue'
import
VEditor
from
'@/components/tinymce/Index.vue'
export
default
{
components
:
{
VEditor
,
Radio
},
components
:
{
VEditor
,
Radio
,
Checkbox
,
Judgment
},
props
:
{
data
:
{
type
:
Object
},
chidrenList
:
{
type
:
Array
}
},
data
()
{
return
{
ruleForm
:
{}
ruleForm
:
{},
dataList
:
[],
rules
:
{
child_question_type
:
[{
required
:
true
,
message
:
' '
,
trigger
:
'blur'
}],
question_difficulty
:
[{
required
:
true
,
message
:
' '
,
trigger
:
'blur'
}],
question_title
:
[{
required
:
true
,
message
:
' '
,
trigger
:
'blur'
}],
question_content
:
[{
required
:
true
,
message
:
' '
,
trigger
:
'blur'
}],
question_analysis
:
[{
required
:
true
,
message
:
' '
,
trigger
:
'blur'
}],
question_options
:
[{
required
:
true
,
message
:
' '
,
trigger
:
'blur'
}]
}
}
},
mounted
()
{
this
.
dataList
=
this
.
chidrenList
console
.
log
(
this
.
chidrenList
)
},
methods
:
{
removeChidren
(
n
)
{
this
.
dataList
.
splice
(
n
,
1
)
},
submitForm
()
{
this
.
$emit
(
'submitForm'
)
}
}
}
...
...
src/modules/question/views/Create.vue
浏览文件 @
7f689cd5
<
template
>
<app-card>
<detail></detail>
<template
v-if=
"[1, 2, 3, 6].includes(questionTypeNum)"
>
<template
v-if=
"$route.query.id"
>
<detail
v-if=
"Object.keys(detailData).length"
:detailData=
"detailData"
@
questionType=
"questionType"
></detail>
</
template
>
<detail
v-else
@
questionType=
"questionType"
></detail>
</template>
<
template
v-else
>
<template
v-if=
"$route.query.id"
>
<situation-question
v-if=
"$route.query.id && Object.keys(detailData).length"
:detailData=
"detailData"
:questionTypeNumber=
"questionTypeNum"
@
questionType=
"questionType"
></situation-question>
</
template
>
<situation-question
v-else
:questionTypeNumber=
"questionTypeNum"
@
questionType=
"questionType"
></situation-question>
</template>
</app-card>
</template>
<
script
>
import
Detail
from
'../components/Detail.vue'
// import VEditor from '@/components/tinymce/Index.vue'
// import Radio from '../components/QTypeRadio.vue'
// import Checkbox from '../components/QTypeCheckbox.vue'
// import Judgment from '../components/QTypeJudgment.vue'
import
SituationQuestion
from
'../components/QTypeSituation.vue'
import
{
questionDetail
}
from
'../api'
export
default
{
components
:
{
Detail
}
components
:
{
Detail
,
SituationQuestion
},
data
()
{
return
{
questionTypeNum
:
1
,
detailData
:
{}
}
},
mounted
()
{
if
(
this
.
$route
.
query
.
id
)
{
questionDetail
(
this
.
$route
.
query
.
id
).
then
(
res
=>
{
this
.
questionTypeNum
=
res
.
data
.
question_type
res
.
data
.
permission
=
res
.
data
.
permission
.
toString
()
res
.
data
.
question_difficulty
=
res
.
data
.
question_difficulty
.
toString
()
res
.
data
.
question_category
=
res
.
data
.
question_category
.
category_name
this
.
detailData
=
res
.
data
console
.
log
(
this
.
detailData
)
})
}
},
methods
:
{
questionType
(
n
)
{
this
.
questionTypeNum
=
n
}
}
}
</
script
>
...
...
src/modules/question/views/List.vue
浏览文件 @
7f689cd5
<
template
>
<app-card>
<app-list
v-bind=
"tableOptions"
ref=
"list"
>
<app-list
v-bind=
"tableOptions"
ref=
"list"
@
selection-change=
"handleSelectionChange"
>
<template
v-slot:radio-filter
>
<el-radio
v-model=
"radio"
label=
"1"
>
我的题库
</el-radio>
<el-radio
v-model=
"radio"
label=
"2"
>
公共题库
</el-radio>
<el-radio
@
change=
"radioChange"
v-model=
"radio"
label=
"1"
>
我的题库
</el-radio>
<el-radio
@
change=
"radioChange"
v-model=
"radio"
label=
"2"
>
公共题库
</el-radio>
</
template
>
<
template
v-slot:input-filter
>
<div
class=
"filter-input"
>
...
...
@@ -16,20 +16,20 @@
>
新建试题
</el-button
>
<el-button
type=
"primary"
icon=
"el-icon-plus"
@
click=
"visible = true"
>
批量导入试题
</el-button>
<el-button
type=
"primary"
icon=
"el-icon-plus"
@
click=
"
visible = true
"
>
批量删除
</el-button>
<el-button
type=
"primary"
icon=
"el-icon-plus"
@
click=
"
deleteQuestion()
"
>
批量删除
</el-button>
</div>
<
template
v-slot:table-x=
"{ row }"
>
<el-button
type=
"text"
@
click=
"handle
View
(row)"
>
编辑
</el-button>
<el-button
type=
"text"
@
click=
"handle
Settings
(row)"
>
查看详情
</el-button>
<el-button
type=
"text"
@
click=
"handle
Settings(row
)"
>
删除
</el-button>
<el-button
type=
"text"
@
click=
"handle
Settings
(row)"
>
编辑
</el-button>
<el-button
type=
"text"
@
click=
"handle
View
(row)"
>
查看详情
</el-button>
<el-button
type=
"text"
@
click=
"handle
Delete(row.id
)"
>
删除
</el-button>
</
template
>
<el-dialog
title=
"提示"
:visible
.
sync=
"dialogVisible
"
width=
"30%
"
:before-close=
"handleClose
"
>
<el-tree
:data=
"treeList"
:props=
"defaultProps"
@
node-click=
"handleNodeClick"
:expand-on-click-node=
"false"
></el-tree>
<el-dialog
title=
"提示"
:visible
.
sync=
"dialogVisible"
width=
"30%"
:before-close=
"handleClose"
>
<el-tree
:data=
"treeList
"
:props=
"defaultProps
"
@
node-click=
"handleNodeClick
"
:expand-on-click-node=
"false"
></el-tree>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"handleClose"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"dialogConfirm"
>
确 定
</el-button>
...
...
@@ -40,11 +40,12 @@
</template>
<
script
>
import
{
getAppList
,
getQuestionCategory
}
from
'../api'
import
{
getAppList
,
getQuestionCategory
,
deleteQuestion
}
from
'../api'
export
default
{
data
()
{
return
{
deleteQuestions
:
[],
dialogVisible
:
false
,
visible
:
false
,
radio
:
'1'
,
...
...
@@ -60,6 +61,7 @@ export default {
computed
:
{
tableOptions
()
{
return
{
limit
:
10
,
filters
:
[
{
slots
:
'radio-filter'
,
...
...
@@ -73,7 +75,7 @@ export default {
options
:
[
{
label
:
'单选题'
,
value
:
1
},
{
label
:
'多选题'
,
value
:
2
},
{
label
:
'
简
答题'
,
value
:
3
},
{
label
:
'
问
答题'
,
value
:
3
},
{
label
:
'案例题'
,
value
:
5
},
{
label
:
'判断题'
,
value
:
6
},
{
label
:
'实操题'
,
value
:
7
},
...
...
@@ -123,7 +125,7 @@ export default {
const
questionType
=
{
1
:
'单选题'
,
2
:
'多选题'
,
3
:
'
简
答题'
,
3
:
'
问
答题'
,
5
:
'案例题'
,
6
:
'判断题'
,
7
:
'实操题'
,
...
...
@@ -161,6 +163,22 @@ export default {
this
.
getTreeList
()
},
methods
:
{
// 列表选择
handleSelectionChange
(
data
)
{
this
.
deleteQuestions
=
data
.
reduce
((
a
,
b
)
=>
a
.
push
(
b
.
id
)
&&
a
,
[])
},
// 删除试题
handleDelete
(
id
)
{
console
.
log
(
id
)
const
ids
=
id
?
[
id
]
:
this
.
deleteQuestions
deleteQuestion
({
ids
:
ids
}).
then
(
res
=>
{
this
.
$message
({
message
:
'删除成功'
,
type
:
'success'
})
this
.
$refs
.
list
.
refetch
()
})
},
// 获取tree列表
getTreeList
()
{
getQuestionCategory
(
'x1'
).
then
(
res
=>
{
...
...
@@ -201,7 +219,7 @@ export default {
},
handleSettings
(
row
)
{
// tan ~~~~~
this
.
$router
.
push
({
path
:
'/
settings/users'
,
query
:
{
appid
:
row
.
id
}
})
this
.
$router
.
push
({
path
:
'/
question/create'
,
query
:
{
id
:
row
.
id
,
type
:
'edit'
}
})
},
handleNodeClick
(
data
)
{
this
.
treeValue
.
name
=
data
.
label
...
...
@@ -216,13 +234,9 @@ export default {
this
.
dialogVisible
=
false
this
.
filterInput
=
this
.
treeValue
.
name
this
.
$refs
.
list
.
refetch
()
}
},
watch
:
{
radio
:
{
handler
()
{
this
.
$refs
.
list
.
refetch
()
}
},
radioChange
()
{
this
.
$refs
.
list
.
refetch
()
}
}
}
...
...
src/utils/axios.js
浏览文件 @
7f689cd5
...
...
@@ -49,7 +49,6 @@ httpRequest.interceptors.request.use(
httpRequest
.
interceptors
.
response
.
use
(
function
(
response
)
{
const
{
data
}
=
response
console
.
log
(
response
)
// 正常返回
if
(
data
.
code
===
0
||
data
.
type
===
'application/vnd.ms-excel'
)
{
return
data
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论