提交 c8401632 authored 作者: 王鹏飞's avatar 王鹏飞

updates

上级 9fe2e086
......@@ -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'
......
......@@ -31,6 +31,7 @@ export default {
}
.app-card-hd {
display: flex;
align-items: flex-start;
}
.app-card-hd__title {
flex: 1;
......
......@@ -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) {
......
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 })
}
<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 {
components: {
BatchSetting
props: {
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: 'input',
prop: 'name',
type: 'select',
prop: 'question_type',
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: 'select',
type: 'input',
prop: 'name4',
placeholder: '请输入题干内容',
options: this.natureList,
labelKey: 'name',
valueKey: 'id',
size: 'small',
label: '题干内容'
label: '题干内容',
placeholder: '请输入题干内容'
},
{
type: 'select',
type: 'input',
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)
})
}
}
}
......
<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>
......
<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>
<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>
<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>
<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>
<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: {
TitleClick(index) {
handleClick(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>
<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>
......
......@@ -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: {},
......
......@@ -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()
})
}
}
}
......
......@@ -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: {
......
......@@ -53,13 +53,9 @@
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>
......@@ -67,13 +63,13 @@
<!-- <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>
......@@ -115,7 +111,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 },
......
......@@ -23,13 +23,13 @@
<el-button type="text" @click="handleSettings(row)">查看详情</el-button>
<el-button type="text" @click="handleSettings(row)">删除</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>
......@@ -73,7 +73,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 +123,7 @@ export default {
const questionType = {
1: '单选题',
2: '多选题',
3: '答题',
3: '答题',
5: '案例题',
6: '判断题',
7: '实操题',
......
......@@ -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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论