Files
hzdyjs/web/src/views/hq/satQuestion/index.vue
T

462 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="p-2 page-container">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<!-- <el-form-item label="删除标志" prop="deleted">
<el-select v-model="queryParams.deleted" placeholder="请选择删除标志" clearable >
<el-option v-for="dict in sys_item_delete" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item> -->
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="题目标题" prop="questionTitle">
<el-input v-model="queryParams.questionTitle" placeholder="请输入题目标题" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属分类" prop="categoryId">
<el-select v-model="queryParams.categoryId" placeholder="请选择所属分类" clearable @change="handleQuery">
<el-option v-for="category in satCategoryList" :key="category.id" :label="category.categoryName" :value="category.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="题目类型" prop="questionType">
<el-select v-model="queryParams.questionType" placeholder="请选择题目类型" clearable>
<el-option v-for="dict in sys_question_category" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<!-- <el-form-item label="是否必填" prop="isRequired">
<el-select v-model="queryParams.isRequired" placeholder="请选择是否必填" clearable>
<el-option v-for="dict in sys_item_required" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item> -->
<!-- <el-form-item label="排序" prop="sortOrder">
<el-input v-model="queryParams.sortOrder" placeholder="请输入排序" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
<el-option v-for="dict in sys_item_enable" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24" class="search-btn-container">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never" class="button-card table-card">
<template #header>
<el-row ref="toolbarRef" :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['hq:satQuestion:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['hq:satQuestion:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['hq:satQuestion:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button icon="Download" @click="handleExport" v-hasPermi="['hq:satQuestion:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<div class="table-container">
<el-table v-loading="loading" border :data="satQuestionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" v-if="true" /> -->
<!-- <el-table-column label="删除标志" align="center" prop="deleted">
<template #default="scope">
<dict-tag :options="sys_item_delete" :value="scope.row.deleted" />
</template>
</el-table-column> -->
<el-table-column label="题目标题" align="center" prop="questionTitle" width="200">
<template #default="scope">
<el-tooltip
effect="dark"
:content="scope.row.questionTitle"
placement="top"
:show-after="100"
:hide-after="100"
popper-style="max-width: 300px; max-height: 200px;"
>
<div class="text-ellipsis">
{{ scope.row.questionTitle }}
</div>
</el-tooltip>
</template>
</el-table-column>
<!-- <el-table-column label="题目内容" align="center" prop="questionContent" /> -->
<el-table-column label="所属分类" align="center" prop="categoryId">
<template #default="scope">
{{ satCategoryAllList.find((cat) => cat.id == scope.row.categoryId)?.categoryName || '--' }}
</template>
</el-table-column>
<el-table-column label="题目类型" align="center" prop="questionType">
<template #default="scope">
<dict-tag :options="sys_question_category" :value="scope.row.questionType" />
</template>
</el-table-column>
<el-table-column label="是否必填" align="center" prop="isRequired">
<template #default="scope">
<dict-tag :options="sys_item_required" :value="scope.row.isRequired" />
</template>
</el-table-column>
<!-- <el-table-column label="排序" align="center" prop="sortOrder" /> -->
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :options="sys_item_enable" :value="scope.row.status" />
</template>
</el-table-column>
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
<el-table-column label="备注" align="center" prop="remark" width="200">
<template #default="scope">
<el-tooltip
effect="dark"
:content="scope.row.remark"
placement="top"
:show-after="100"
:hide-after="100"
popper-style="max-width: 300px; max-height: 200px;"
>
<div class="text-ellipsis">
{{ scope.row.remark }}
</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['hq:satQuestion:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['hq:satQuestion:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</div>
</el-card>
<!-- 添加或修改题库对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="satQuestionFormRef" :model="form" :rules="rules" label-width="80px">
<!-- <el-form-item label="删除标志" prop="deleted">
<el-select v-model="form.deleted" placeholder="请选择删除标志">
<el-option v-for="dict in sys_item_delete" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
</el-select>
</el-form-item> -->
<el-form-item label="题目标题" prop="questionTitle">
<el-input v-model="form.questionTitle" type="textarea" resize="none" :autosize="false" :rows="4" placeholder="请输入题目标题" />
</el-form-item>
<!-- <el-form-item label="题目内容">
<editor v-model="form.questionContent" :min-height="192" />
</el-form-item> -->
<el-form-item label="所属分类" prop="categoryId">
<el-select v-model="form.categoryId" placeholder="请选择所属分类">
<el-option v-for="category in satCategoryList" :key="category.id" :label="category.categoryName" :value="category.id" />
</el-select>
</el-form-item>
<el-form-item label="题目类型" prop="questionType">
<el-select v-model="form.questionType" placeholder="请选择题目类型">
<el-option v-for="dict in sys_question_category" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="是否必填" prop="isRequired">
<el-select v-model="form.isRequired" placeholder="请选择是否必填">
<el-option v-for="dict in sys_item_required" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="排序" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请输入排序" />
</el-form-item> -->
<el-form-item label="状态" prop="status">
<el-select v-model="form.status" placeholder="请选择状态">
<el-option v-for="dict in sys_item_enable" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" resize="none" :autosize="false" :rows="4" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="SatQuestion" lang="ts">
import { listSatQuestion, getSatQuestion, delSatQuestion, addSatQuestion, updateSatQuestion } from '@/api/hq/satQuestion';
import { SatQuestionVO, SatQuestionQuery, SatQuestionForm } from '@/api/hq/satQuestion/types';
import { listSatCategory, listAllSatCategory } from '@/api/hq/satCategory';
import { SatCategoryVO } from '@/api/hq/satCategory/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_question_category, sys_item_enable, sys_item_required, sys_item_delete } = toRefs<any>(
proxy?.useDict('sys_question_category', 'sys_item_enable', 'sys_item_required', 'sys_item_delete')
);
const satQuestionList = ref<SatQuestionVO[]>([]);
const satCategoryList = ref<SatCategoryVO[]>([]);
const satCategoryAllList = ref<SatCategoryVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const satQuestionFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: SatQuestionForm = {
id: undefined,
deleted: undefined,
questionTitle: undefined,
questionContent: undefined,
categoryId: undefined,
questionType: '1', // 默认单选
isRequired: 1,
sortOrder: undefined,
status: '0',
remark: undefined
};
const data = reactive<PageData<SatQuestionForm, SatQuestionQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
deleted: undefined,
questionTitle: undefined,
questionContent: undefined,
categoryId: undefined,
questionType: undefined,
isRequired: undefined,
sortOrder: undefined,
status: undefined,
params: {}
},
rules: {
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
questionTitle: [{ required: true, message: '题目标题不能为空', trigger: 'blur' }],
categoryId: [{ required: true, message: '所属分类不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询题库列表 */
const getList = async () => {
loading.value = true;
const res = await listSatQuestion(queryParams.value);
satQuestionList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 获取分类列表 */
const getCategoryList = async () => {
const res = await listSatCategory({
pageNum: 1,
pageSize: 1000,
status: '0'
}); // 只获取启用状态的分类
satCategoryList.value = res.rows.sort((a, b) => a.sortOrder - b.sortOrder); // 按sort_order排序
};
/** 获取全部分类列表(包括已删除的) */
const getAllCategoryList = async () => {
const res = await listAllSatCategory({
pageNum: 1,
pageSize: 1000
}); // 获取所有分类,包括已删除的
satCategoryAllList.value = res.data.sort((a, b) => a.sortOrder - b.sortOrder); // 按sort_order排序
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
satQuestionFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: SatQuestionVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加题库';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: SatQuestionVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getSatQuestion(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改题库';
};
/** 提交按钮 */
const submitForm = () => {
satQuestionFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateSatQuestion(form.value).finally(() => (buttonLoading.value = false));
} else {
await addSatQuestion(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: SatQuestionVO) => {
const _ids = row?.id || ids.value;
let confirmMessage = '';
if (row) {
// 单个删除,显示题目标题
confirmMessage = `是否确认删除题目"${row.questionTitle}"?`;
} else {
// 批量删除,显示数量
confirmMessage = `是否确认删除选中的${ids.value.length}个题目?`;
}
await proxy?.$modal.confirm(confirmMessage).finally(() => (loading.value = false));
await delSatQuestion(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'hq/satQuestion/export',
{
...queryParams.value
},
`satQuestion_${new Date().getTime()}.xlsx`
);
};
const toolbarRef = ref<HTMLElement>();
const searchRef = ref<HTMLElement>();
onMounted(() => {
getList();
getCategoryList();
getAllCategoryList();
});
</script>
<style scoped>
/* 页面容器样式 */
.page-container {
padding: 8px;
}
/* 表格卡片布局 */
.table-card {
margin-top: 0;
}
.table-card :deep(.el-card__body) {
padding: 0px 20px 20px 20px !important;
}
/* 表格容器 */
.table-container {
margin-bottom: 0;
}
/* 分页容器样式 */
.pagination-container {
display: flex;
justify-content: flex-end;
padding: 16px 20px 0 0 !important;
background-color: #fff;
margin-top: 0px !important;
}
/* 移除按钮栏底部边框 */
.button-card :deep(.el-card__header) {
border-bottom: none !important;
}
/* 文字省略样式 */
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
display: inline-block;
}
/* 搜索按钮容器样式 */
.search-btn-container {
display: flex;
justify-content: flex-end;
margin-top: 10px;
.el-form-item {
margin-bottom: 0 !important;
}
}
</style>