Browse Source

题库更改,抽题规则

zjq 1 month ago
parent
commit
df36eb3b56

+ 71 - 0
src/api/examTrain/extractRule.ts

@@ -0,0 +1,71 @@
+/*
+ * @Author: zjq
+ * @description 抽题规则
+ */
+import request from '@/utils/request';
+
+/**
+ * @description 新增抽题规则
+ * @param {object} data
+ */
+export const addExtractRule = (data: object) => {
+    return request({
+        url: '/api/v1/ExtractRule/Add',
+        method: 'post',
+        data,
+    });
+};
+/**
+ * @description 编辑抽题规则
+ * @param {object} data
+ */
+export const editExtractRule = (data: object) => {
+    return request({
+        url: '/api/v1/ExtractRule/Update',
+        method: 'put',
+        data,
+    });
+};
+/**
+ * @description 删除抽题规则
+ * @param {object} data
+ */
+export const deleteExtractRule = (data: object) => {
+    return request({
+        url: '/api/v1/ExtractRule/Delete',
+        method: 'delete',
+        data,
+    });
+};
+/**
+ * @description 获取抽题规则列表
+ * @param {object} params
+ */
+export const getExtractRuleData = (params?: object) => {
+    return request({
+        url: '/api/v1/ExtractRule/GetPagedList',
+        method: 'post',
+        data: params,
+    });
+};
+/**
+ * @description 查询抽题规则详情
+ * @param {object} Id
+ */
+export const getExtractRuleDetail = (Id: string) => {
+    return request({
+        url: `/api/v1/ExtractRule/Get?id=${Id}`,
+        method: 'get',
+    });
+};
+/**
+ * @description 获取标签题库
+ * @param {object} data
+ */
+export const getTagQuestionCount = (data: object) => {
+    return request({
+        url: '/api/v1/ExtractRule/GetTagQuestionCount',
+        method: 'post',
+        data,
+    });
+};

+ 1 - 1
src/api/examTrain/questionBank.ts

@@ -52,7 +52,7 @@ export const getQuestionData = (params?: object) => {
  * @description 查询试题详情
  * @param {object} Id
  */
-export const getQuestionDetail = (Id: string) => {
+export const getQuestionDetail = (Id: any) => {
     return request({
         url: `/api/v1/Question/Get?id=${Id}`,
         method: 'get',

+ 240 - 0
src/views/examTrain/exam/extractRule/components/ExtractRule-add.vue

@@ -0,0 +1,240 @@
+<template>
+	<el-dialog title="新增抽题规则" v-model="state.dialogVisible" draggable append-to-body destroy-on-close @close="close" width="800px">
+		<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="80px" v-loading="state.loading">
+			<el-row :gutter="10">
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="规则编号" prop="code" :rules="[{ required: true, message: '请填写规则编号', trigger: 'blur' }]">
+						<el-input v-model="state.ruleForm.code" placeholder="请填写规则编号" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="规则名称" prop="name" :rules="[{ required: true, message: '请填写规则名称', trigger: 'blur' }]">
+						<el-input v-model="state.ruleForm.name" placeholder="请填写规则名称" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="规则类型" prop="ruleType" :rules="[{ required: true, message: '请选择规则类型', trigger: 'change' }]">
+						<el-radio-group v-model="state.ruleForm.ruleType">
+							<el-radio :value="0">正式</el-radio>
+							<el-radio :value="1">模拟</el-radio>
+						</el-radio-group>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="抽题标签" prop="questionTagIds" :rules="[{ required: true, message: '请选择抽题标签', trigger: 'change' }]">
+						<el-tree-select
+							v-model="state.ruleForm.questionTagIds"
+							:data="state.tagData"
+							node-key="id"
+							:props="{ label: 'name' }"
+							filterable
+							multiple
+							collapse-tags
+							collapse-tags-tooltip
+							:max-collapse-tags="2"
+							:render-after-expand="false"
+							style="width: 100%"
+							ref="treeSelectRef"
+							@change="selQuestionTag"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="抽题设置" class="w100 tableFormItem">
+						<vxe-table
+							border
+							:loading="state.tableLoading"
+							:data="state.ruleForm.tagQuestionDtos"
+							:column-config="{ resizable: true }"
+							:row-config="{ height: 50, useKey: true }"
+							ref="tableRef"
+							height="300"
+							auto-resize
+							show-overflow
+							:print-config="{}"
+							:scrollY="{ enabled: true, gt: 100 }"
+							id="extractRule"
+							:custom-config="{ storage: true }"
+							showHeaderOverflow
+							:merge-cells=mergeCells
+						>
+							<vxe-column field="tag" title="标签名称" width="200"></vxe-column>
+							<vxe-column title="试题类型" min-width="250">
+								<template #default="scope">
+									<el-form-item :label="scope.row.questionTypeDes">
+									<!-- <el-form-item :label="scope.row.questionTypeDes" :prop="`tagQuestionDtos.` + scope.$rowIndex+ `.count`" :rules="[{ validator: vaildateTable, trigger: 'blur', totalCount: scope.row.totalCount }]">
+										<el-input type="number" v-model="scope.row.count" placeholder="请填写" clearable></el-input>
+										<template #append>共{{scope.row.totalCount}}题</template> -->
+										<el-input-number v-model="scope.row.count" :min="0" :max="scope.row.totalCount" >
+											<template #suffix>
+												<span>共{{scope.row.totalCount}}题</span>
+											</template>
+										</el-input-number>
+									</el-form-item>
+								</template>
+							</vxe-column>
+						</vxe-table>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="备注" prop="remark">
+						<el-input type="textarea" :rows="3" v-model="state.ruleForm.remark" placeholder="请输入备注" clearable></el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="closeDialog" class="default-button">取 消</el-button>
+				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading">确 定 </el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from 'vue';
+import { ElMessage, FormInstance } from 'element-plus';
+import Other from '@/utils/other';
+import { examTagTreeList } from '@/api/examTrain/tag';
+import {addExtractRule, getTagQuestionCount} from '@/api/examTrain/extractRule';
+
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+
+// 定义变量内容
+const state = reactive<any>({
+	dialogVisible: false, // 弹窗
+	ruleForm: {
+		code: '', // 规则编号
+		name: '', // 规则名称
+		ruleType: null, // 规则类型
+		questionTagIds: '', // 抽题标签ids
+		ruleTagDtos: [], // 规则标签
+		tagQuestionDtos: [], // 标签试题数
+		remark: '', // 备注
+	},
+	tagData: [], // 标签数据
+	loading: false, // 加载
+	tableLoading: false, // 表格加载
+});
+// 打开弹窗
+const ruleFormRef = ref<any>(); // 表单ref
+// 打开弹窗
+const openDialog = async () => {
+	state.dialogVisible = true;
+	try {
+		getTagData();
+	} catch (error) {
+		console.log(error);
+		state.loading = false;
+	}
+};
+const close = () => {
+	ruleFormRef.value?.clearValidate();
+	ruleFormRef.value?.resetFields();
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.dialogVisible = false;
+};
+// 选择标签
+const treeSelectRef = ref<RefType>();
+const mergeCells = ref<any>(); // 行合并
+const selQuestionTag = async (value: any) => {
+	state.tableLoading = true;
+	state.ruleForm.ruleTagDtos = [];
+	mergeCells.value = [];
+	try {
+		const { result } = await getTagQuestionCount({tagIds: state.ruleForm.questionTagIds});
+		state.ruleForm.questionTagIds.forEach(item => {
+			let tagObj = Other.deepClone(treeSelectRef.value.getNode(item).data);
+			state.ruleForm.ruleTagDtos.push({tagId: tagObj.id});
+			result.forEach(it => {if (it.tagId == tagObj.id) it.tag = tagObj.name} )
+			let arrResult = Other.deepClone(result);
+			let rowNum = result.findIndex(it => it.tagId == tagObj.id);
+			let rowspanNum = arrResult.filter(it => it.tagId == tagObj.id).length;
+			mergeCells.value.push({ row: rowNum, col: 0, rowspan: rowspanNum, colspan: 1 })
+		});
+		result.forEach(item => {
+			let obj = state.ruleForm.tagQuestionDtos.find(it => (item.tagId == it.tagId && item.questionType == it.questionType))
+			if (obj){
+				item.count = obj.count;
+			} else {
+				item.count = 0;
+			}
+			switch(item.questionType){
+				case 0: item.questionTypeDes = '单选题'; break;
+				case 1: item.questionTypeDes = '多选题'; break;
+				case 2: item.questionTypeDes = '判断题'; break;
+				case 3: item.questionTypeDes = '填空题'; break;
+				case 4: item.questionTypeDes = '问答题'; break;
+				default: break;
+			}
+		});
+		state.ruleForm.tagQuestionDtos = result ?? [];
+		state.tableLoading = false;
+	} catch (error) {
+		state.tableLoading = false;
+	}
+}
+// 验证表格input值
+// const vaildateTable = (rule: any, value: any, callback: any) => {
+// 	if (value > rule.totalCount) {
+//     callback(new Error('填写的数字不能大于标签题型最大数量'))
+//   } else {
+//     callback()
+//   }
+// };
+// 新增
+const onSubmit = async (formEl: FormInstance | undefined) => {
+	console.log(state.ruleForm);
+	if (!formEl) return;
+	// 表单额外验证
+	let blog = false;
+	state.ruleForm.tagQuestionDtos.forEach(it => {
+		if (it.count > 0){
+			blog = true;
+		}
+	});
+	if (!blog){
+		ElMessage.warning('请至少选择一道题!')
+		return;
+	}
+	await formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		addExtractRule(state.ruleForm)
+			.then(() => {
+				emit('updateList');
+				closeDialog(); // 关闭弹窗
+				ElMessage.success('操作成功');
+				state.loading = false;
+			})
+			.catch(() => {
+				state.loading = false;
+			});
+	});
+};
+// 获取标签下拉数据
+const getTagData = async () => {
+	state.loading = true;
+	try {
+		const { result } = await examTagTreeList();
+		state.tagData = result ?? [];
+		state.loading = false;
+	} catch (error) {
+		state.loading = false;
+	}
+};
+// 暴露变量
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>
+<style lang="scss">
+	.tableFormItem .el-form-item__content{
+		display: block;
+	}
+</style>

+ 243 - 0
src/views/examTrain/exam/extractRule/components/ExtractRule-edit.vue

@@ -0,0 +1,243 @@
+<template>
+	<el-dialog title="编辑抽题规则" v-model="state.dialogVisible" draggable append-to-body destroy-on-close @close="close" width="800px">
+		<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="80px" v-loading="state.loading">
+			<el-row :gutter="10">
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="规则编号" prop="code" :rules="[{ required: true, message: '请填写规则编号', trigger: 'blur' }]">
+						<el-input v-model="state.ruleForm.code" placeholder="请填写规则编号" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="规则名称" prop="name" :rules="[{ required: true, message: '请填写规则名称', trigger: 'blur' }]">
+						<el-input v-model="state.ruleForm.name" placeholder="请填写规则名称" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="规则类型" prop="ruleType" :rules="[{ required: true, message: '请选择规则类型', trigger: 'change' }]">
+						<el-radio-group v-model="state.ruleForm.ruleType">
+							<el-radio :value="0">正式</el-radio>
+							<el-radio :value="1">模拟</el-radio>
+						</el-radio-group>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="抽题标签" prop="questionTagIds" :rules="[{ required: true, message: '请选择抽题标签', trigger: 'change' }]">
+						<el-tree-select
+							v-model="state.ruleForm.questionTagIds"
+							:data="state.tagData"
+							node-key="id"
+							:props="{ label: 'name' }"
+							filterable
+							multiple
+							collapse-tags
+							collapse-tags-tooltip
+							:max-collapse-tags="2"
+							:render-after-expand="false"
+							style="width: 100%"
+							ref="treeSelectRef"
+							@change="selQuestionTag"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="抽题设置" class="w100 tableFormItem">
+						<vxe-table
+							border
+							:loading="state.tableLoading"
+							:data="state.ruleForm.tagQuestionDtos"
+							:column-config="{ resizable: true }"
+							:row-config="{ height: 50, useKey: true }"
+							ref="tableRef"
+							height="300"
+							auto-resize
+							show-overflow
+							:print-config="{}"
+							:scrollY="{ enabled: true, gt: 100 }"
+							id="extractRule"
+							:custom-config="{ storage: true }"
+							showHeaderOverflow
+							:merge-cells=mergeCells
+						>
+							<vxe-column field="tag" title="标签名称" width="200"></vxe-column>
+							<vxe-column title="试题类型" min-width="250">
+								<template #default="scope">
+									<el-form-item :label="scope.row.questionTypeDes">
+									<!-- <el-form-item :label="scope.row.questionTypeDes" :prop="`tagQuestionDtos.` + scope.$rowIndex+ `.count`" :rules="[{ validator: vaildateTable, trigger: 'blur', totalCount: scope.row.totalCount }]">
+										<el-input type="number" v-model="scope.row.count" placeholder="请填写" clearable></el-input>
+										<template #append>共{{scope.row.totalCount}}题</template> -->
+										<el-input-number v-model="scope.row.count" :min="0" :max="scope.row.totalCount" >
+											<template #suffix>
+												<span>共{{scope.row.totalCount}}题</span>
+											</template>
+										</el-input-number>
+									</el-form-item>
+								</template>
+							</vxe-column>
+						</vxe-table>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-form-item label="备注" prop="remark">
+						<el-input type="textarea" :rows="3" v-model="state.ruleForm.remark" placeholder="请输入备注" clearable></el-input>
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="closeDialog" class="default-button">取 消</el-button>
+				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading">确 定 </el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from 'vue';
+import { ElMessage, FormInstance } from 'element-plus';
+import Other from '@/utils/other';
+import { examTagTreeList } from '@/api/examTrain/tag';
+import {editExtractRule, getTagQuestionCount, getExtractRuleDetail} from '@/api/examTrain/extractRule';
+
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+
+// 定义变量内容
+const state = reactive<any>({
+	dialogVisible: false, // 弹窗
+	ruleForm: {
+		code: '', // 规则编号
+		name: '', // 规则名称
+		ruleType: null, // 规则类型
+		questionTagIds: '', // 抽题标签ids
+		ruleTagDtos: [], // 规则标签
+		tagQuestionDtos: [], // 标签试题数
+		remark: '', // 备注
+	},
+	tagData: [], // 标签数据
+	loading: false, // 加载
+	tableLoading: false, // 表格加载
+});
+// 打开弹窗
+const ruleFormRef = ref<any>(); // 表单ref
+// 打开弹窗
+const openDialog = async (row: any) => {
+	state.dialogVisible = true;
+	try {
+		getTagData();
+		const { result } = await getExtractRuleDetail(row.id);
+		state.ruleForm = result;
+		state.ruleForm.questionTagIds = state.ruleForm.ruleTagDtos.map(it => it.tagId);
+	} catch (error) {
+		console.log(error);
+		state.loading = false;
+	}
+};
+const close = () => {
+	ruleFormRef.value?.clearValidate();
+	ruleFormRef.value?.resetFields();
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.dialogVisible = false;
+};
+// 选择标签
+const treeSelectRef = ref<RefType>();
+const mergeCells = ref<any>(); // 行合并
+const selQuestionTag = async (value: any) => {
+	state.tableLoading = true;
+	state.ruleForm.ruleTagDtos = [];
+	mergeCells.value = [];
+	try {
+		const { result } = await getTagQuestionCount({tagIds: state.ruleForm.questionTagIds});
+		state.ruleForm.questionTagIds.forEach(item => {
+			let tagObj = Other.deepClone(treeSelectRef.value.getNode(item).data);
+			state.ruleForm.ruleTagDtos.push({tagId: tagObj.id});
+			result.forEach(it => {if (it.tagId == tagObj.id) it.tag = tagObj.name} )
+			let arrResult = Other.deepClone(result);
+			let rowNum = result.findIndex(it => it.tagId == tagObj.id);
+			let rowspanNum = arrResult.filter(it => it.tagId == tagObj.id).length;
+			mergeCells.value.push({ row: rowNum, col: 0, rowspan: rowspanNum, colspan: 1 })
+		});
+		result.forEach(item => {
+			let obj = state.ruleForm.tagQuestionDtos.find(it => (item.tagId == it.tagId && item.questionType == it.questionType))
+			if (obj){
+				item.count = obj.count;
+			} else {
+				item.count = 0;
+			}
+			switch(item.questionType){
+				case 0: item.questionTypeDes = '单选题'; break;
+				case 1: item.questionTypeDes = '多选题'; break;
+				case 2: item.questionTypeDes = '判断题'; break;
+				case 3: item.questionTypeDes = '填空题'; break;
+				case 4: item.questionTypeDes = '问答题'; break;
+				default: break;
+			}
+		});
+		state.ruleForm.tagQuestionDtos = result ?? [];
+		state.tableLoading = false;
+	} catch (error) {
+		state.tableLoading = false;
+	}
+}
+// 验证表格input值
+// const vaildateTable = (rule: any, value: any, callback: any) => {
+// 	if (value > rule.totalCount) {
+//     callback(new Error('填写的数字不能大于标签题型最大数量'))
+//   } else {
+//     callback()
+//   }
+// };
+// 新增
+const onSubmit = async (formEl: FormInstance | undefined) => {
+	console.log(state.ruleForm);
+	if (!formEl) return;
+	// 表单额外验证
+	let blog = false;
+	state.ruleForm.tagQuestionDtos.forEach(it => {
+		if (it.count > 0){
+			blog = true;
+		}
+	});
+	if (!blog){
+		ElMessage.warning('请至少选择一道题!')
+		return;
+	}
+	await formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		editExtractRule(state.ruleForm)
+			.then(() => {
+				emit('updateList');
+				closeDialog(); // 关闭弹窗
+				ElMessage.success('操作成功');
+				state.loading = false;
+			})
+			.catch(() => {
+				state.loading = false;
+			});
+	});
+};
+// 获取标签下拉数据
+const getTagData = async () => {
+	state.loading = true;
+	try {
+		const { result } = await examTagTreeList();
+		state.tagData = result ?? [];
+		state.loading = false;
+	} catch (error) {
+		state.loading = false;
+	}
+};
+// 暴露变量
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>
+<style lang="scss">
+	.tableFormItem .el-form-item__content{
+		display: block;
+	}
+</style>

+ 181 - 0
src/views/examTrain/exam/extractRule/index.vue

@@ -0,0 +1,181 @@
+<template>
+	<div class="plan-index-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent :disabled="state.tableLoading">
+                <el-form-item label="编号" prop="code">
+                    <el-input v-model="state.queryParams.code" placeholder="编号" clearable @keyup.enter="handleQuery" class="keyword-input" />
+                </el-form-item>
+                <el-form-item label="标题" prop="name">
+                    <el-input v-model="state.queryParams.name" placeholder="标题" clearable @keyup.enter="handleQuery" class="keyword-input" />
+                </el-form-item>
+                <el-form-item label="状态" prop="status">
+                    <el-select v-model="state.queryParams.status" clearable placeholder="请选择" @change="handleQuery" :disabled="state.tableLoading">
+                        <el-option key='0' label="停用" :value="0" />
+                        <el-option key='1' label="启用" :value="1" />
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="handleQuery" :loading="state.tableLoading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+                    <el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置</el-button>
+                </el-form-item>
+            </el-form>
+            <vxe-toolbar
+                ref="toolbarRef"
+                :loading="state.tableLoading"
+                custom
+                :refresh="{
+                    queryMethod: handleQuery,
+                }"
+            >
+                <template #buttons>
+                    <el-button type="primary" @click="onOpenAdd" v-auth="'extractRule:index:add'" :loading="state.tableLoading">
+                        <SvgIcon name="ele-Plus" class="mr10" />新增
+                    </el-button>
+                </template>
+            </vxe-toolbar>
+            <div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+                <vxe-table
+                    border
+                    :loading="state.tableLoading"
+                    :data="state.tableData"
+                    :column-config="{ resizable: true }"
+                    :row-config="{ isCurrent: true, isHover: true, height: 30, useKey: true }"
+                    ref="tableRef"
+                    height="auto"
+                    auto-resize
+                    show-overflow
+                    :print-config="{}"
+                    :scrollY="{ enabled: true, gt: 100 }"
+                    id="extractRule"
+                    :custom-config="{ storage: true }"
+                    showHeaderOverflow
+                >
+                    <vxe-column field="code" title="规则编号" width="250"></vxe-column>
+                    <vxe-column field="name" title="规则标题" width="250"></vxe-column>
+                    <vxe-column field="status" title="状态" width="160">
+                        <template #default="{ row }">
+                            <el-switch v-model="row.status" />
+                        </template>
+                    </vxe-column>
+                    <vxe-column field="remark" title="备注" min-width="200"></vxe-column>
+                    <vxe-column title="操作" fixed="right" width="120" align="center" :show-overflow="false">
+                        <template #default="{ row }">
+                            <el-button link type="primary" @click="onOpenEdit(row)" title="编辑" v-auth="'extractRule:index:edit'">
+                                编辑
+                            </el-button>
+                            <el-button link type="danger" @click="onRowDel(row)" title="删除" v-auth="'extractRule:index:delete'">
+                                删除
+                            </el-button>
+                        </template>
+                    </vxe-column>
+                </vxe-table>
+            </div>
+            <pagination
+                @pagination="queryList"
+                :total="state.total"
+                v-model:current-page="state.queryParams.PageIndex"
+                v-model:page-size="state.queryParams.PageSize"
+                :disabled="state.tableLoading"
+            />
+		</div>
+
+        <extractRule-add ref="extractRuleAddRef" @updateList="queryList" />
+		<extractRule-edit ref="extractRuleEditRef" @updateList="queryList" />
+	</div>
+</template>
+
+<script lang="tsx" setup name="extractRule">
+import { ref, reactive, onMounted, defineAsyncComponent, computed } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { formatDate } from '@/utils/formatTime';
+import 'splitpanes/dist/splitpanes.css';
+import Other from '@/utils/other';
+import { downloadFileByStream } from '@/utils/tools';
+import {deleteExtractRule, getExtractRuleData} from '@/api/examTrain/extractRule';
+
+// 引入组件
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+const ExtractRuleAdd = defineAsyncComponent(() => import('@/views/examTrain/exam/extractRule/components/ExtractRule-add.vue')); // 新增组件
+const ExtractRuleEdit = defineAsyncComponent(() => import('@/views/examTrain/exam/extractRule/components/ExtractRule-edit.vue')); // 修改组件
+
+const router = useRouter(); //路由
+
+// 定义变量内容
+const state = reactive<any>({
+	queryParams: {
+		PageIndex: 1, //页码
+		PageSize: 20, //每页条数
+        code: null, // 编号
+        name: null, // 名称
+		status: null, // 状态
+	},
+	tableData: [], //表格数据
+	total: 0, //总条数
+	tableLoading: false, //表格loading
+});
+/** 搜索按钮操作 节流操作 */
+const handleQuery = () => {
+	state.queryParams.PageIndex = 1;
+	queryList();
+};
+/** 获取试题列表 */
+const requestParams = ref<EmptyObjectType>({});
+const queryList = () => {
+	state.tableLoading = true;
+    requestParams.value = Other.deepClone(state.queryParams);
+	getExtractRuleData(requestParams.value)
+		.then((response: any) => {
+            console.log(response)
+			state.tableData = response?.result.items ?? [];
+			state.total = response?.result.pagination.totalCount;
+			state.tableLoading = false;
+		})
+		.catch(() => {
+			state.tableLoading = false;
+		});
+};
+/** 重置按钮操作 */
+const ruleFormRef = ref<RefType>(); // 表单ref
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	ruleFormRef.value?.resetFields();
+	handleQuery();
+};
+// 打开新增弹窗
+const extractRuleAddRef = ref<RefType>(); // 新增ref
+const onOpenAdd = () => {
+	extractRuleAddRef.value.openDialog();
+};
+// 打开编辑弹窗
+const extractRuleEditRef = ref<RefType>(); // 修改ref
+const onOpenEdit = (row: any) => {
+	extractRuleEditRef.value.openDialog(row, state.tableData);
+};
+// 删除当前行
+const onRowDel = (row: any) => {
+	ElMessageBox.confirm(`是否确认删除当前抽题规则?删除后不可恢复`, '提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+        .then(() => {
+			deleteExtractRule({id: row.id}).then(() => {
+				ElMessage.success('删除成功');
+				queryList();
+			});
+		})
+		.catch(() => {});
+};
+
+const tableRef = ref<RefType>();
+const toolbarRef = ref<RefType>();
+onMounted(() => {
+	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
+});
+</script>

+ 1 - 1
src/views/examTrain/questionBank/components/Question-course.vue

@@ -43,7 +43,7 @@
 	</el-dialog>
 </template>
 
-<script lang="tsx" setup>
+<script lang="ts" setup>
 import { defineAsyncComponent, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';

+ 1 - 1
src/views/examTrain/questionBank/components/Question-knowledge.vue

@@ -48,7 +48,7 @@
 	</el-dialog>
 </template>
 
-<script lang="tsx" setup>
+<script lang="ts" setup>
 import { defineAsyncComponent, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';

+ 1 - 1
src/views/examTrain/questionBank/edit.vue

@@ -511,7 +511,7 @@ const getDetail = async () => {
 			});
 		}
 	}else {
-		for(let num:number = ref(0); num.value < 3; num.value++){
+		for(let num = ref(0); num.value < 3; num.value++){
 			state.ruleForm.questionOptionsDtos.push({temp: guid(), content: '', isAnswer: false});
 		}
 	}