【新增】试卷任务前端分类,监控管理前端

This commit is contained in:
YOHO\20373
2025-05-05 00:05:46 +08:00
parent 7a6472d8d4
commit e8a418b9f7
134 changed files with 19516 additions and 493 deletions

View File

@@ -66,7 +66,9 @@
/>
</el-select>
</el-form-item>
<el-form-item label="试题别名" prop="quTitle">
<el-input v-model="form.quTitle" placeholder="请输入试题别名" :disabled="isUpdate" />
</el-form-item>
<!-- 数量分数 -->
<el-form-item label="试题数量" prop="quNumbers">
<el-input-number v-model="form.quNumbers" placeholder="请输入试题数量" :disabled="isUpdate" />
@@ -83,6 +85,11 @@
<el-form-item label="可用数量">
<el-text>{{ availableCount }}</el-text>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="form.sort" />
</el-form-item>
</el-form>
<template #footer>
@@ -144,11 +151,13 @@ const form = ref<{
schemeId?: string
taskId?: string
spName?: string
quTitle?: string
quLevel?: number
keyword: string[]
pointName: string[]
quNumbers?: number
quScores?: number
sort?: number
subtotalScore?: number
taskSpecialty?: string
}>({
@@ -159,6 +168,8 @@ const form = ref<{
const rules = reactive({
spName: [{ required: true, message: '请选择题型', trigger: 'change' }],
quLevel: [{ required: true, message: '请选择难度', trigger: 'change' }],
sort: [{ required: true, message: '请设置排序', trigger: 'change' }],
quTitle: [{ required: true, message: '请输入别名', trigger: 'change' }],
pointName: [{ required: true, message: '请选择知识点', trigger: 'change' }],
quNumbers: [{ required: true, message: '请输入试题数量', trigger: 'blur' }],
quScores: [{ required: true, message: '请输入每题分数', trigger: 'blur' }]
@@ -203,11 +214,13 @@ const open = async (type: 'create' | 'update', data?: any) => {
taskId: props.taskId,
spName: undefined,
quLevel: undefined,
quTitle:undefined,
keyword: [],
pointName: [],
quNumbers: undefined,
quScores: undefined,
subtotalScore: undefined,
sort: undefined,
taskSpecialty: props.taskSpecialty
}
}

View File

@@ -48,7 +48,7 @@
<span v-else>未知</span>
</template>
</el-table-column>
<el-table-column label="试题别名" align="center" prop="quTitle"/>
<!-- <el-table-column label="关键字" align="center" prop="keywords" /> -->
<el-table-column label="试题数量" align="center" prop="quNumbers"/>

View File

@@ -74,7 +74,8 @@
<!-- 多选列 -->
<el-table-column type="selection" width="55" />
<el-table-column label="试卷编号" align="center" prop="paperId" />
<el-table-column label="试卷id" align="center" prop="paperId" />
<el-table-column label="试卷编号" align="center" prop="num" />
<el-table-column label="使用次数" align="center" prop="counts" />
<el-table-column label="抽卷方式" align="center" prop="rollUp">
<template #default="scope">
@@ -199,6 +200,7 @@ interface PaperItem {
rollUp: string;
isAb: string;
status: string;
num:string;
// 你可以根据需要扩展更多字段
}

View File

@@ -3,9 +3,8 @@
<Dialog v-model="visible" :title="'试卷调整'" width="860" @open="handleOpen" center>
<div>{{rows}}</div>
<div>{{taskId}}</div>
<el-transfer v-model="value" :data="data" />
<el-transfer v-model="value" :data="data" :titles="['未选试卷', '已选试卷']" />
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" :loading="loading" @click="save">保存</el-button>
@@ -18,7 +17,7 @@ import { ref, nextTick } from 'vue';
import { useFormData } from '@/utils/use-form-data';
import { getPaperListByType } from '@/api/system/paper';
import { setSessions } from '@/api/system/session';
import type { FormInstance } from 'element-plus' // ✅ 引入 FormInstance 类型
import type { FormInstance } from 'element-plus'
const message = useMessage();
const props = defineProps({
@@ -60,11 +59,12 @@ const handleOpen = async () => {
rows: props.rows
});
data.value = (res?.paperId || []).map((item: string) => ({
key: item,
label: item,
disabled: false
}));
data.value = Object.entries(res?.paperId || {}).map(([id, name]) => ({
key: id,
label: String(name), // 👈 关键在这里
disabled: false
}));
value.value = res?.selectedIds || [];

View File

@@ -152,7 +152,7 @@ const getList = async () => {
try {
const res = await SmsChannelApi.pageSessions(queryParams)
console.log(res)
list.value = res
list.value = res.list
total.value = res.total
} finally {
loading.value = false

View File

@@ -16,32 +16,30 @@
<el-col :span="10" style="height: 100%;">
<div style="height: 100%; overflow: auto;">
<ele-card title="试卷任务列表" :body-style="{ paddingTop: '8px' }">
<ContentWrap style="overflow-x: auto;">
<ContentWrap style="overflow-x: auto;">
<el-table
table-layout="fixed"
ref="taskTableRef"
:data="mockTaskList"
highlight-current-row
@row-click="handleTaskRowClick"
style="min-width: 1000px; width: 100%; "
style="min-width: 1000px; width: 100%;"
>
<el-table-column type="index" label="#" width="50" align="center" />
<el-table-column label="考试批次" align="center" prop="batch" />
<el-table-column label="考试开始时间" align="center" prop="startTime" />
<el-table-column label="考试结束时间" align="center" prop="endTime" />
<el-table-column label="开始考试前分钟,允许入场" align="center" prop="allowEntry" />
<el-table-column label="开始考试后分钟,禁止入场" align="center" prop="endAllowEntry" />
<el-table-column label="开始考试后分钟,允许交卷" align="center" prop="allowSubmission" />
<el-table-column label="允许入场(分钟)" align="center" prop="allowEntry" />
<el-table-column label="禁止入场(分钟)" align="center" prop="endAllowEntry" />
<el-table-column label="允许交卷(分钟)" align="center" prop="allowSubmission" />
</el-table>
<Pagination
:total="taskTotal"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
</ele-card>
</div>
</el-col>
@@ -51,16 +49,11 @@
<div style="height: 100%; overflow: auto;">
<ele-card :body-style="{ paddingTop: '8px' }">
<div class="mb-2">
<el-button
type="primary"
@click="openAssignDialog()"
>
分配人员
</el-button>
<el-button type="primary" @click="openAssignDialog()">分配人员</el-button>
<el-button type="danger" @click="removeBatch()">删除</el-button>
<el-button @click="exportData()">导出</el-button>
</div>
<ContentWrap style="overflow-x: auto;">
<ContentWrap style="overflow-x: auto;">
<el-table
table-layout="fixed"
ref="personTableRef"
@@ -73,23 +66,16 @@
<el-table-column type="index" label="#" width="50" align="center" />
<el-table-column label="用户名称" align="center" prop="username" />
<el-table-column label="用户昵称" align="center" prop="nickname" />
<el-table-column label="班级名称" align="center" prop="className"/>
<el-table-column label="分配考场" align="center" prop="batch"/>
<!-- <el-table-column label="操作" align="center" width="180">
<template #default="{ row }">
<el-link type="primary" @click="openEdit(row)">修改</el-link>
<el-divider direction="vertical" />
<el-link type="danger" @click="removeBatch(row)">删除</el-link>
</template>
</el-table-column> -->
<el-table-column label="班级名称" align="center" prop="className" />
<el-table-column label="分配考场" align="center" prop="batch" />
</el-table>
<Pagination
:stutotal="stutotal"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
:total="stutotal"
v-model:page="stuQuery.pageNo"
v-model:limit="stuQuery.pageSize"
@pagination="getPersonList"
/>
</ContentWrap>
<el-empty
v-if="filteredPersonList.length === 0"
description="暂无分配人员"
@@ -99,166 +85,148 @@
</el-col>
</el-row>
</ele-page>
<PersonSearch :session-id="selectedSessionId" :session-batch="selectedSessionBanch" :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
<PersonSearch
:session-id="selectedSessionId"
:session-batch="selectedSessionBanch"
:task-id="props.taskId"
v-model="showPersonEdit"
ref="stuAddRef"
@done="reload"
/>
</el-form>
</Dialog>
</template>
<script setup>
import { ref, onMounted, nextTick, computed } from 'vue';
import PersonSearch from './person-serach.vue'
import { ref, onMounted, nextTick, reactive } from 'vue';
import PersonSearch from './person-serach.vue';
import * as SmsChannelApi from '@/api/system/session';
import * as PersonApi from '@/api/system/person'
import * as PersonApi from '@/api/system/person';
const visible = ref(true);
const selectedSessionId = ref(null);
const selectedSessionBanch = ref(null);
const selections = ref([]);
const showEdit = ref(false);
const current = ref(null);
const taskTableRef = ref();
const personTableRef = ref();
const stuAddRef = ref();
const showPersonEdit = ref(false);
const emit = defineEmits(['done']);
const props = defineProps({
taskId: {
type: String,
default: ''
}
})
});
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
status: '0',
taskId: props.taskId,
sessionId:''
})
const stuAddRef = ref();
sessionId: ''
});
const stuQuery = reactive({
pageNo: 1,
pageSize: 10
});
const mockTaskList = ref([]);
const total = ref(0);
const filteredPersonList = ref([]);
const stutotal = ref(0);
const showPersonEdit = ref(false)
const emit = defineEmits(['done'])
const openAssignDialog = () => {
if (!selectedSessionId.value) {
ElMessage.warning('请先选择左侧任务!')
return
ElMessage.warning('请先选择左侧任务!');
return;
}
showPersonEdit.value = true
showPersonEdit.value = true;
nextTick(() => {
stuAddRef.value?.open();
});
}
const submitAssign = () => {
// 提交逻辑
console.log('提交分配人员')
assignVisible.value = false
}
const mockTaskList = ref([]) ;
const filteredPersonList = ref([]) ;
};
const handleTaskRowClick = async (row) => {
selectedSessionId.value = row.sessionId;
selectedSessionBanch.value=row.batch;
selectedSessionId.value = row.sessionId;
selectedSessionBanch.value = row.batch;
queryParams.sessionId = row.sessionId;
const res = await SmsChannelApi.getSessionStu(queryParams);
stuQuery.pageNo = 1; // 重置分页
await getPersonList();
};
const getList = async () => {
const res = await SmsChannelApi.pageSessions(queryParams);
mockTaskList.value = res.list;
total.value = res.total;
};
const getPersonList = async () => {
const personParams = {
...stuQuery,
taskId: props.taskId,
sessionId: selectedSessionId.value
};
const res = await SmsChannelApi.getSessionStu(personParams);
filteredPersonList.value = res.list;
stutotal.value=res.total;
stutotal.value = res.total;
};
const openEdit = (row = null) => {
current.value = row;
showEdit.value = true;
};
const removeBatch = async (row) => {
const removeBatch = async () => {
const selectedIds = selections.value.map(item => item.id);
console.log('选中的 ID 列表:', selectedIds);
console.log('选中的 考场 id:' + selectedSessionId.value);
console.log('选中的 试卷任务id:', props.taskId);
if (selectedIds.length === 0) {
ElMessage.warning('请选择要删除的人员');
return;
}
// 弹出确认提示框
ElMessageBox.confirm(
'确定要删除选中的人员吗?',
'警告',
await ElMessageBox.confirm(
'确定要删除选中的人员吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
type: 'warning'
}
).then(async () => {
// 赋值参数
const data = {
studentIds: selectedIds,
sessionId: selectedSessionId.value,
taskId: props.taskId,
batch: selectedSessionBanch.value,
};
);
await PersonApi.removeSessionStu(data);
const data = {
studentIds: selectedIds,
sessionId: selectedSessionId.value,
taskId: props.taskId,
batch: selectedSessionBanch.value
};
// 删除选中的人员
for (const sel of selections.value) {
const index = filteredPersonList.value.findIndex(p => p.id === sel.id);
if (index !== -1) filteredPersonList.value.splice(index, 1);
}
emit('done')
ElMessage.success('删除成功');
}).catch(() => {
await PersonApi.removeSessionStu(data);
console.log('删除操作已取消');
});
await getPersonList(); // 删除后刷新右侧列表
emit('done');
ElMessage.success('删除成功');
};
const getList = async () => {
const res = await SmsChannelApi.pageSessions(queryParams)
mockTaskList.value = res
total.value = res.total
}
const reload = () => {
getList()
emit('done')
}
const exportData = () => {
console.log('导出功能触发');
};
const reloadPerson = () => {
// 模拟刷新
console.log('刷新人员列表');
};
const handleDialogClose = () => {
visible.value = false;
};
const reload = () => {
getList();
if (selectedSessionId.value) {
getPersonList();
}
emit('done');
};
onMounted(() => {
getList()
})
getList();
});
</script>