You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

461 lines
15 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup>
/**
* name
* usersa0ChunLuyu
* date2024年10月12日 16:29:26
*/
import { ref, onMounted, nextTick } from 'vue'
import $router from '@/router'
import { onBeforeRouteUpdate } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
QuestionQuestionSelectAction,
QuestionItemSelectAction,
QuestionQuestionCreateAction,
QuestionQuestionUpdateAction,
QuestionQuestionDeleteAction,
QuestionQuestionListAction
} from '@/api/api.js'
const default_page_options = {
search: '',
page: 1
}
const page_options = ref(JSON.parse(JSON.stringify(default_page_options)))
onBeforeRouteUpdate((to) => {
routerChange(to.query)
})
const table_list = ref([])
const last_page = ref(0)
const QuestionQuestionList = async () => {
const response = await QuestionQuestionListAction(page_options.value)
if (response.status !== 'no') {
table_list.value = response.data.list.data.map((item) => {
return {
...item,
option: JSON.parse(item.option)
}
})
last_page.value = response.data.list.last_page
} else {
ElMessage.error(response.msg)
}
}
const routerChange = (query) => {
page_options.value = {
search: query.search || default_page_options.search,
page: Number(query.page) || default_page_options.page
}
QuestionQuestionList()
}
const searchClick = (page = 1) => {
page_options.value.page = page
$router.push({
query: JSON.parse(JSON.stringify(page_options.value))
})
}
const select_option = {
value: [
{ content: 'A. ', type: 'items', items: [], questions: [], score: 0 },
{ content: 'B. ', type: 'items', items: [], questions: [], score: 0 },
{ content: 'C. ', type: 'items', items: [], questions: [], score: 0 }
]
}
const input_option = {
value: '',
placeholder: '请输入选项内容'
}
const edit_data_default = {
id: 0,
question: '',
type: 'input',
option: {
input: JSON.parse(JSON.stringify(input_option)),
select: JSON.parse(JSON.stringify(select_option))
}
}
const edit_data = ref(JSON.parse(JSON.stringify(edit_data_default)))
const edit_show = ref(false)
const createClick = () => {
updateClick(edit_data_default)
}
const updateClick = (row) => {
edit_data.value = JSON.parse(JSON.stringify(row))
edit_show.value = true
}
const editDoneClick = async () => {
const $func =
edit_data.value.id !== 0 ? QuestionQuestionUpdateAction : QuestionQuestionCreateAction
const response = await $func({
...edit_data.value,
option: JSON.stringify(edit_data.value.option)
})
if (response.status !== 'no') {
edit_show.value = false
await QuestionQuestionList()
} else {
ElMessage.error(response.msg)
}
}
const QuestionQuestionDelete = async (id) => {
const response = await QuestionQuestionDeleteAction({ id })
if (response.status !== 'no') {
await QuestionQuestionList()
} else {
ElMessage.error(response.msg)
}
}
const deleteClick = (id) => {
ElMessageBox.confirm('是否确认删除该题目?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
QuestionQuestionDelete(id)
})
.catch(() => {})
}
const edit_item_data = ref({
active: 0,
items: []
})
const edit_item_show = ref(false)
const question_list = ref([])
const QuestionQuestionSelect = async () => {
const response = await QuestionQuestionSelectAction()
if (response.status !== 'no') {
question_list.value = response.data.list
} else {
ElMessage.error(response.msg)
}
}
const editItemClick = async (index) => {
const type = edit_data.value.option.select.value[index].type
if (type === 'questions') {
await QuestionQuestionSelect()
}
await nextTick(() => {
edit_item_data.value = {
active: index,
items: JSON.parse(JSON.stringify(edit_data.value.option.select.value[index][type]))
}
edit_item_show.value = true
})
}
const editItemDoneClick = () => {
const type = edit_data.value.option.select.value[edit_item_data.value.active].type
edit_data.value.option.select.value[edit_item_data.value.active][type] = JSON.parse(
JSON.stringify(edit_item_data.value.items)
)
edit_item_show.value = false
}
const filterMethod = (query, item) => {
const type = edit_data.value.option.select.value[edit_item_data.value.active].type
if (type === 'items') {
return item.name.toLowerCase().includes(query.toLowerCase())
} else {
return item.question.toLowerCase().includes(query.toLowerCase())
}
}
const item_list = ref([])
const QuestionItemSelect = async () => {
const response = await QuestionItemSelectAction()
if (response.status !== 'no') {
item_list.value = response.data.list
} else {
ElMessage.error(response.msg)
}
}
const moveQuestionClick = (index, type) => {
if (edit_data.value.option.select.value.length - 1 >= index + type) {
const question = edit_data.value.option.select.value[index]
edit_data.value.option.select.value[index] = JSON.parse(
JSON.stringify(edit_data.value.option.select.value[index + type])
)
edit_data.value.option.select.value[index + type] = JSON.parse(JSON.stringify(question))
}
}
const delQuestionClick = (index) => {
edit_data.value.option.select.value.splice(index, 1)
}
const addQuestionClick = () => {
edit_data.value.option.select.value.push({ content: '', type: 'items', items: [], questions: [] })
}
const question_type_map = {
select: '选择题',
input: '输入框'
}
onMounted(() => {
routerChange($router.currentRoute.value.query)
QuestionItemSelect()
})
</script>
<template>
<div>
<el-dialog
v-model="edit_item_show"
title="关联管理"
width="610px"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
>
<div>
<el-transfer
v-if="!!edit_item_show"
:titles="['可选', '已选']"
:props="{
key: 'id',
label:
edit_data.option.select.value[edit_item_data.active].type === 'items'
? 'name'
: 'question'
}"
v-model="edit_item_data.items"
filterable
:filter-method="filterMethod"
filter-placeholder="搜索"
:data="
edit_data.option.select.value[edit_item_data.active].type === 'items'
? item_list
: question_list
"
/>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="editItemDoneClick()" type="primary">确定</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="edit_show" :title="`${!!edit_data.id ? '编辑' : '新建'}`" width="1000px">
<div>
<el-form label-width="150">
<el-form-item label="题目">
<el-input v-model="edit_data.question" placeholder="请输入题目"></el-input>
</el-form-item>
<el-form-item label="题目类型">
<el-select v-model="edit_data.type" placeholder="请选择题目类型">
<el-option label="选择题" value="select"></el-option>
<el-option label="输入框" value="input"></el-option>
</el-select>
</el-form-item>
<template v-if="edit_data.type === 'input'">
<el-form-item label="题目配置">
<div>
<div class="select_item_wrapper">
<el-input
class="select_input_wrapper"
v-model="edit_data.option.input.value"
placeholder="请输入默认值"
></el-input>
<el-input
class="select_input_wrapper"
v-model="edit_data.option.input.placeholder"
placeholder="请输入占位符"
></el-input>
</div>
</div>
</el-form-item>
</template>
<template v-else-if="edit_data.type === 'select'">
<el-form-item label="题目配置">
<div>
<div
class="select_item_wrapper"
v-for="(_, k) in edit_data.option.select.value"
:key="k"
>
<el-input
class="select_input_wrapper"
v-model="edit_data.option.select.value[k].content"
placeholder="请输入"
></el-input>
<el-select
class="select_select_wrapper"
v-model="edit_data.option.select.value[k].type"
placeholder="请选择题目类型"
>
<el-option label="项目" value="items"></el-option>
<el-option label="题目" value="questions"></el-option>
<el-option label="分数" value="score"></el-option>
</el-select>
<template v-if="edit_data.option.select.value[k].type === 'score'">
<el-input-number
v-model="edit_data.option.select.value[k].score"
></el-input-number>
</template>
<template v-else>
<span style="margin-right: 10px"
>{{
edit_data.option.select.value[k].type === 'items'
? edit_data.option.select.value[k].items.length
: edit_data.option.select.value[k].questions.length
}}个{{
edit_data.option.select.value[k].type === 'items' ? '项目' : '题目'
}}</span
>
<el-button type="primary" size="small" @click="editItemClick(k)">
编辑{{ edit_data.option.select.value[k].type === 'items' ? '项目' : '题目' }}
</el-button>
<el-button
:disabled="k === 0"
type="primary"
size="small"
@click="moveQuestionClick(k, -1)"
>↑
</el-button>
<el-button
:disabled="k === edit_data.option.select.value.length - 1"
type="primary"
size="small"
@click="moveQuestionClick(k, 1)"
>↓
</el-button>
<el-button
:disabled="edit_data.option.select.value.length === 1"
type="primary"
size="small"
@click="delQuestionClick(k)"
>X
</el-button>
</template>
</div>
<div>
<el-button type="primary" size="small" @click="addQuestionClick()"
>添加选项</el-button
>
</div>
</div>
</el-form-item>
</template>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="edit_show = false">取消</el-button>
<el-button type="primary" @click="editDoneClick()">确定</el-button>
</span>
</template>
</el-dialog>
<div class="head">
<div class="head">
<el-row>
<el-form-item>
<el-input v-model="page_options.search" placeholder="搜索题目" />
</el-form-item>
<el-button type="primary" @click="searchClick()" style="margin-left: 10px"
>查询</el-button
>
<el-button type="success" @click="createClick()" style="margin-left: 10px"
>添加</el-button
>
</el-row>
</div>
</div>
<el-table
:data="table_list"
style="width: 100%"
row-key="id"
:tooltip-options="{
popperClass: 'popper_class_wrapper'
}"
>
<el-table-column prop="id" label="ID" width="100" />
<el-table-column prop="question" label="题目" width="200" show-overflow-tooltip />
<el-table-column label="类型" width="100">
<template #default="scope">
{{ question_type_map[scope.row.type] }}
</template>
</el-table-column>
<el-table-column label="题目配置">
<template #default="scope">
<div v-if="scope.row.type === 'input'" class="select_item_wrapper">
<span class="title_wrapper">占位符:</span
><span style="margin: 0 10px">{{ scope.row.option.input.placeholder }}</span>
<span v-if="!!scope.row.option.input.value" class="title_wrapper">默认值:</span
><span style="margin: 0 10px">{{ scope.row.option.input.value }}</span>
</div>
<div v-else-if="scope.row.type === 'select'">
<div
class="select_item_wrapper"
v-for="(i, k) in scope.row.option.select.value"
:key="k"
>
<span style="margin-right: 10px; width: 400px">{{ i.content }}</span>
<span class="title_wrapper">带出:</span>
<span v-if="scope.row.option.select.value[k].type === 'items'">项目</span>
<span v-else-if="scope.row.option.select.value[k].type === 'questions'">题目</span>
<span v-else-if="scope.row.option.select.value[k].type === 'score'">分数</span>
<span v-if="scope.row.option.select.value[k].type === 'score'" style="margin: 0 5px">{{
scope.row.option.select.value[k][scope.row.option.select.value[k].type]
}}</span>
<span v-else style="margin: 0 5px">{{
scope.row.option.select.value[k][scope.row.option.select.value[k].type].length
}}</span>
<span>{{ scope.row.option.select.value[k].type === 'score' ? '分' : '个' }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="140">
<template #default="scope">
<el-button type="primary" @click="updateClick(scope.row)" size="small">修改</el-button>
<el-button type="danger" @click="deleteClick(scope.row.id)" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination
v-if="last_page > 0"
:current-page="page_options.page"
mt-2
background
layout="prev, pager, next"
:page-count="last_page"
@update:current-page="searchClick"
/>
</div>
</div>
</template>
<style>
.popper_class_wrapper {
width: 300px;
}
</style>
<style scoped>
.title_wrapper {
font-weight: bold;
}
.select_input_wrapper {
width: 300px;
margin-right: 10px;
}
.select_select_wrapper {
width: 80px;
margin-right: 10px;
}
.select_item_wrapper {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.page {
display: flex;
justify-content: flex-end;
margin-top: 10px;
}
</style>