|
|
<!-- src/components/Question/QuestionSearch.vue --><template> <div class="question-search-container"> <div class="top"> <h2>题库管理</h2> </div> <!-- 搜索区域容器 --> <div class="search-area"> <!-- 题目类型筛选项 --> <div class="search-item"> <h3>题目类型</h3> <select v-model="searchForm.questionType"> <option value="">全部</option> <option>股票知识</option> <option>企业文化</option> </select> </div>
<!-- 题干关键词搜索项 --> <div class="search-item"> <h3>题干查找</h3> <input type="text" placeholder="请输入题干关键词" v-model="searchForm.keyword" /> </div>
<!-- 课程推荐筛选项 --> <div class="search-item"> <h3>推荐系列</h3> <select v-model="searchForm.course"> <option value="">全部</option> <option>量能擒牛</option> <option>价格破译</option> <option>量价时空综合</option> </select> </div>
<!-- 操作按钮组 --> <div class="btn-group"> <button class="btn-red" @click="handleSearch">查找</button> <button class="btn-red" @click="showAddModal = true">新增题目</button> <button class="btn-red" @click="exportExcel">Excel导出</button> </div> </div>
<!-- 新增题目弹窗 --> <div v-if="showAddModal" class="modal-overlay"> <div class="modal-content" @click.stop> <div class="modal-header"> <h3>新增题目</h3> <button class="close-btn" @click="closeModal">×</button> </div> <div class="modal-body"> <div class="form-row"> <label>题目类型</label> <select v-model="newQuestion.questionTypeName"> <option value="股票知识">股票知识</option> <option value="企业文化">企业文化</option> </select> </div>
<div class="form-row"> <label>题干</label> <textarea v-model="newQuestion.stem" placeholder="请输入题目内容" rows="4" style="width: 545px; height: 120px;" ></textarea> </div>
<div class="form-row-options"> <div class="option-group"> <label>选项A</label> <input type="text" v-model="newQuestion.optionA" placeholder="请输入选项A" style="width: 280px; height: 40px;" /> </div> <div class="option-group"> <label>选项B</label> <input type="text" v-model="newQuestion.optionB" placeholder="请输入选项B" style="width: 280px; height: 40px;"/> </div> <div class="option-group"> <label>选项C</label> <input type="text" v-model="newQuestion.optionC" placeholder="请输入选项C" style="width: 280px; height: 40px;"/> </div> <div class="option-group"> <label>选项D</label> <input type="text" v-model="newQuestion.optionD" placeholder="请输入选项D" style="width: 280px; height: 40px;"/> </div> </div>
<div class="form-row"> <label>正确答案</label> <select v-model="newQuestion.correctAnswer"> <option value="A">A</option> <option value="B">B</option> <option value="C">C</option> <option value="D">D</option> </select> </div>
<div class="form-row"> <label>推荐系列</label> <select v-model="newQuestion.recommendedCourse"> <option value="量能擒牛">量能擒牛</option> <option value="价格破译">价格破译</option> <option value="量价时空综合">量价时空综合</option> </select> </div> </div> <div class="modal-footer"> <button class="btn-red" @click="addQuestion">确定</button> <button class="btn-red" @click="closeModal">取消</button> </div> </div> </div> </div></template>
<script>import { getQuestions } from '@/api/question.js';import axios from 'axios';// import { Message } from 'element-ui'
export default { name: 'QuestionSearch', data() { return { searchForm: { questionType: '', keyword: '', course: '' }, showAddModal: false, newQuestion: { id: 0, stem: '', optionA: '', optionB: '', optionC: '', optionD: '', correctAnswer: 'A', questionTypeName: '股票知识', recommendedCourse: '量能擒牛' }, currentPage: 1, // 当前页码
total: 0 // 总记录数
}; }, methods: { async handleSearch(page = 1) { try { this.currentPage = page; // 更新当前页码
const params = new URLSearchParams(); params.append('page', page); // 使用传入的页码
params.append('page_size', 20);
// 题目类型映射为 id
const questionTypeIdMap = { '股票知识': 1, '企业文化': 2 }; if (this.searchForm.questionType) { params.append('question_type_id', questionTypeIdMap[this.searchForm.questionType]); }
// 推荐系列映射为 id
const courseRecommendationIdMap = { '量能擒牛': 1, '价格破译': 2, '量价时空综合': 3 }; if (this.searchForm.course) { params.append('course_recommendation_id', courseRecommendationIdMap[this.searchForm.course]); }
// 题干关键词模糊查询
if (this.searchForm.keyword) { params.append('stem', this.searchForm.keyword); }
const response = await getQuestions(params);
// if (response.data.code === 200) {
// // 包装数据以便传递分页信息
// const resultData = {
// list: response.data.data.list,
// total: response.data.data.total || []
// };
// this.$emit('search-result', resultData);
// this.total = response.data.data.total || 0;
// } else {
// alert('搜索失败:' + response.data.msg);
// }
if (response.data.code === 200) { const list = response.data.data.list || [];
const totalRaw = response.data.data.total; const total = Number.isFinite(Number(totalRaw)) ? Number(totalRaw) : 1;
const resultData = { list, total };
this.$emit('search-result', resultData); this.total = total; } else { alert('搜索失败:' + response.data.msg); } } catch (error) { console.error('搜索失败:', error); alert('网络错误,请检查连接!'); } },
async addQuestion() { // 表单验证
if (!this.newQuestion.stem || !this.newQuestion.optionA || !this.newQuestion.optionB || !this.newQuestion.optionC || !this.newQuestion.optionD || !this.newQuestion.correctAnswer || !this.newQuestion.recommendedCourse) { alert('请填写所有必填项!'); return; }
try { // 构造请求参数
const params = new URLSearchParams(); params.append('id', this.newQuestion.id); params.append('stem', this.newQuestion.stem); params.append('A', this.newQuestion.optionA); params.append('B', this.newQuestion.optionB); params.append('C', this.newQuestion.optionC); params.append('D', this.newQuestion.optionD); params.append('correct_answer', this.newQuestion.correctAnswer); params.append('question_type_id', this.newQuestion.questionTypeName === '股票知识' ? 1 : 2); params.append('course_recommendation_id', this.newQuestion.recommendedCourse === '量能擒牛' ? 1 : this.newQuestion.recommendedCourse === '价格破译' ? 2 : 3 );
// 发送请求
// const response = await axios.post('/admin/questions/update', params, {
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
// }
// });
//发送请求
console.log(params); const response = await axios.post('http://192.168.40.41:8000/admin/questions/update',params, { headers: { 'Content-Type': 'application/json' } }); console.log(response.data);
if (response.data.code === 200) { this.closeModal(); console.log('第二步'); this.$emit('question-added'); console.log('第三步'); this.$message({ message: '添加题目成功!', type: 'success' }); console.log('第四步'); } else { alert('添加题目失败:' + response.data.msg); } } catch (error) { console.error('添加题目失败:', error); alert('网络错误,请检查连接!'); } },
// 新增:处理分页搜索
async handlePageChange(page) { await this.handleSearch(page); },
async exportExcel() { try{ // 构造包含筛选条件的导出参数
const exportParams = {}; // 添加题目类型筛选条件
const questionTypeIdMap = { '股票知识': 1, '企业文化': 2 }; if (this.searchForm.questionType) { exportParams.question_type_id = questionTypeIdMap[this.searchForm.questionType]; }
// 添加推荐系列筛选条件
const courseRecommendationIdMap = { '量能擒牛': 1, '价格破译': 2, '量价时空综合': 3 }; if (this.searchForm.course) { exportParams.course_recommendation_id = courseRecommendationIdMap[this.searchForm.course]; }
// 添加题干关键词筛选条件
if (this.searchForm.keyword) { exportParams.stem = this.searchForm.keyword; }
// 发送导出请求,包含筛选条件
const response = await axios.post( 'http://192.168.40.41:8000/admin/questions/export', exportParams, { responseType: 'blob' } ); const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', '题库详细数据表.xlsx'); document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); alert('导出成功!'); }catch (error) { console.error('导出 Excel 失败:', error); alert('网络错误,请检查连接!'); } }, closeModal() { this.showAddModal = false; console.log('关闭弹窗 第一步'); },
resetForm() { this.newQuestion = { id: 0, stem: '', optionA: '', optionB: '', optionC: '', optionD: '', correctAnswer: 'A', questionTypeName: '股票知识', recommendedCourse: '量能擒牛' }; } }};</script>
<style scoped>.top{ padding: 20px 0px;}/* 弹窗样式 */.modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 1000;}
.modal-content { background-color: white; border-radius: 8px; width: 620px; height: 760px; max-width: 90%; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); overflow: hidden;}
.modal-header { padding: 20px; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center;}
.modal-header h3 { margin: 0; font-size: 18px; color: #333;}
.close-btn { background: none; border: none; font-size: 24px; cursor: pointer; color: #666; padding: 5px; border-radius: 50%; transition: color 0.2s;}
.close-btn:hover { color: #e74c3c;}
.modal-body { padding: 20px; max-height: 600px; overflow-y: auto;}
.form-row { margin-bottom: 16px;}
.form-row label { display: block; margin-bottom: 8px; font-weight: 500; color: #333;}
.form-row select,.form-row input[type="text"],.form-row textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;}
.form-row textarea { resize: vertical;}
.form-row-options { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px;}
.option-group { display: flex; flex-direction: column;}
.modal-footer { padding: 20px; border-top: 1px solid #eee; display: flex; justify-content: flex-end; gap: 16px;}
/* 响应式设计 */@media (max-width: 768px) { .modal-content { width: 90%; }
.form-row-options { grid-template-columns: 1fr; }}</style>
|