提交 e9311674 authored 作者: matian's avatar matian

feat:接口对接以及页面优化

上级 1238949e
......@@ -174,13 +174,13 @@ export const menus: IMenuItem[] = [
path: '/teach/qa'
},
{
tag: 'v1-backend-lecturer-list',
tag: 'v1-teaching-paper-paper-list',
icon: EditPen,
name: '批改试卷',
path: '/teach/exam'
},
{
tag: 'v1-backend-lecturer-list',
tag: 'v1-teaching-job-list',
icon: EditPen,
name: '批改大作业',
path: '/teach/work'
......
......@@ -156,6 +156,7 @@ defineExpose({ refetch, tableRef, params })
clearable
@change="search"
v-if="item.type === 'select'"
style="width: 200px"
>
<el-option
:label="option[item.labelKey] || option.label"
......
......@@ -138,10 +138,10 @@ getProList({ name: '', 'per-page': '100' }).then((res: any) => {
<el-dialog :model-value="isShowClassDialog" draggable :before-close="handleCancel" :title="props.title" width="30%">
<el-form :model="form" label-position="right" label-width="auto" :rules="rules" ref="ruleFormRef">
<el-form-item label="班级代码:" prop="code">
<el-input v-model="form.code" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.code" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="班级名称:" prop="name">
<el-input v-model="form.name" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.name" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="所属部门/学校:" prop="organ_id">
<el-select
......
......@@ -87,8 +87,10 @@ const handleCancel = () => {
style="margin-top: 30px"
@selection-change="handleSelectChange"
>
<template #header-aside>
<el-button type="primary" round @click="handleAddStu" v-permission="'v1-learning-class-add-students'"
>关联选择学生</el-button
></template
>
</AppList>
</div>
......
......@@ -86,9 +86,11 @@ const handleRefresh = () => {
<el-descriptions-item label="入学年份:">{{ classInfo?.start_year_name }}</el-descriptions-item>
</el-descriptions>
<AppList v-bind="listOptions" ref="appList" border stripe style="margin-top: 30px">
<template #header-aside>
<el-button type="primary" round @click="handleAddStu" v-permission="'v1-learning-class-add-students'"
>添加学生</el-button
>
</template>
<template #table-operate="{ row }">
<el-space>
<el-link type="primary" plain @click="handleDetail(row)">查看</el-link>
......
<script lang="ts" setup>
import { ElMessage,ElMessageBox } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import AddTermDialog from './AddTermDialog.vue'
import AddSemester from '../../semester/components/AddSemester.vue'
......@@ -34,7 +34,6 @@ const listOptions = $computed(() => {
return { list: data.list, total: data.total }
}
},
filters: [{ type: 'input', prop: 'name', label: '学生姓名:', placeholder: '学生姓名' }],
columns: [
{ label: '序号', type: 'index', align: 'center' },
{ label: '学期名称', prop: 'name', align: 'center' },
......@@ -89,7 +88,9 @@ const handleFresh = () => {
<el-descriptions-item label="入学年份:">{{ classInfo?.start_year_name }}</el-descriptions-item>
</el-descriptions>
<AppList v-bind="listOptions" ref="appList" border stripe style="margin-top: 30px">
<template #header-aside>
<el-button type="primary" round @click="handleAddTerm">添加学期</el-button>
</template>
<template #table-operate="{ row }">
<el-space>
<el-link type="primary" plain @click="handleDetail(row)">查看</el-link>
......
......@@ -24,7 +24,7 @@ const listOptions = $computed(() => {
remote: { httpRequest: getClassList, params: { name: '', organ_id: '' } },
filters: [
{ type: 'input', prop: 'name', label: '班级名称:', placeholder: '班级名称' },
{ type: 'select', slots: 'filter-department' }
{ type: 'select', prop: 'organ_id', slots: 'filter-department' }
],
columns: [
{ label: '序号', type: 'index', align: 'center' },
......
......@@ -87,7 +87,6 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
if (props.isEdit === '2' || props.isEdit === '1') {
const params: any = { id: props.id }
getProDetail(params).then((res: any) => {
console.log(res)
Object.keys(form).forEach(key => {
form[key] = res.data[key]
})
......@@ -98,10 +97,10 @@ if (props.isEdit === '2' || props.isEdit === '1') {
<el-dialog :model-value="isShowProDialog" draggable :before-close="handleCancel" :title="props.title" width="30%">
<el-form :model="form" label-position="right" label-width="auto" :rules="rules" ref="ruleFormRef">
<el-form-item label="专业代码:" prop="code">
<el-input v-model="form.code" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.code" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="专业名称:" prop="name">
<el-input v-model="form.name" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.name" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="专业类别:" prop="category">
<el-select v-model="form.category" placeholder="请选择专业类别" :disabled="props.isEdit === '2'">
......
......@@ -36,7 +36,16 @@ const listOptions = $computed(() => {
{ label: '选课类型', prop: 'elective_type_name', align: 'center' },
{ label: '课程分类', prop: 'classification_name', align: 'center' },
{ label: '课程学分', prop: 'credit', align: 'center' },
{ label: '讲师', prop: 'enter_month', align: 'center' },
{
label: '讲师',
prop: 'lecturers_name',
align: 'center',
computed(row: any) {
if (row.row.lecturers_name.length) {
return row.row.lecturers_name.toString()
}
}
},
{ label: '更新时间', prop: 'updated_time', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center', minWidth: '200', fixed: 'right' }
]
......
......@@ -20,7 +20,7 @@ const listOptions = $computed(() => {
remote: { httpRequest: getSemList, params: { name: '', organ_id: '' } },
filters: [
{ type: 'input', prop: 'name', label: '学期名称:', placeholder: '学期名称' },
{ type: 'select', slots: 'filter-department' }
{ type: 'select', prop: 'organ_id', slots: 'filter-department' }
],
columns: [
{ label: '序号', type: 'index', align: 'center' },
......
......@@ -56,7 +56,9 @@ const rules = reactive<FormRules>({
email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
status: [{ required: true, message: '请选择生效状态', trigger: 'change' }]
})
if (userStore.roles[0].name !== '超级管理员') {
form.organ_id = userStore.organization?.id
}
// 取消
const handleCancel = () => {
emit('update:isShowStaffDialog', false)
......@@ -120,16 +122,15 @@ if (props.isEdit === '2' || props.isEdit === '1') {
<el-input :placeholder="userStore.organization?.name" v-model="form.organ_id_name" v-else disabled> </el-input>
</el-form-item>
<el-form-item label="姓名:" prop="name">
<el-input v-model="form.name" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.name" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="性别:" prop="gender">
<el-radio-group v-model="form.gender" :disabled="props.isEdit === '2'">
<el-radio v-for="(item, index) in sexList" :key="index" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="手机号:" prop="mobile">
<el-input v-model="form.mobile" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.mobile" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="角色类型:" prop="role">
<el-radio-group v-model="form.role" :disabled="props.isEdit === '2'">
......
......@@ -28,7 +28,7 @@ const listOptions = $computed(() => {
},
filters: [
{ type: 'input', prop: 'name', label: '姓名:', placeholder: '姓名' },
{ type: 'select', slots: 'filter-department' }
{ type: 'select', prop: 'organ_id', slots: 'filter-department' }
],
columns: [
{ label: '序号', type: 'index', align: 'center' },
......
......@@ -131,7 +131,6 @@ const handleClassList = () => {
const handleConfirm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(valid => {
console.log(valid)
if (valid) {
if (props.isEdit === '0') {
form.organ_id = form.organ_id || userStore.organization?.id
......@@ -166,6 +165,9 @@ if (props.isEdit === '2' || props.isEdit === '1') {
Object.keys(form).forEach(key => {
form[key] = res.data[key]
})
if (res.data.specialty_id === '0') {
form.specialty_id = ''
}
})
}
</script>
......@@ -173,10 +175,10 @@ if (props.isEdit === '2' || props.isEdit === '1') {
<el-dialog :model-value="isShowAddDialog" draggable :before-close="handleCancel" :title="props.title" width="30%">
<el-form :model="form" label-width="120px" :rules="rules" ref="ruleFormRef">
<el-form-item label="学号:" prop="sno_number">
<el-input v-model="form.sno_number" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.sno_number" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="姓名:" prop="name">
<el-input v-model="form.name" :disabled="props.isEdit === '2'"></el-input>
<el-input v-model="form.name" :disabled="props.isEdit === '2' || props.isEdit === '1'"></el-input>
</el-form-item>
<el-form-item label="性别:" prop="gender">
......
......@@ -68,8 +68,8 @@ const handleSubmitUpload = () => {
<div style="margin-bottom: 10px; text-align: center">
导入模板下载:<a
href="https://webapp-pub.ezijing.com/center_resource/%E5%AD%A6%E7%94%9F%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx"
download="教师模板"
><el-link type="primary">teacher_import.xlsx</el-link></a
download="学生模板"
><el-link type="primary">学生模板.xlsx</el-link></a
>
</div>
......
......@@ -20,14 +20,14 @@ const listOptions = {
remote: { httpRequest: getStudentList, params: { name: '', organ_id: '' } },
filters: [
{ type: 'input', prop: 'name', label: '学生姓名:', placeholder: '学生姓名' },
{ type: 'select', slots: 'filter-department' }
{ type: 'select', prop: 'organ_id', slots: 'filter-department' }
],
columns: [
{ type: 'selection' },
{ label: '序号', type: 'index', align: 'center' },
{ label: '学号', prop: 'sno_number', align: 'center' },
{ label: '姓名', prop: 'name', align: 'center' },
{ label: '性别', prop: 'gender', align: 'center' },
{ label: '性别', prop: 'gender_name', align: 'center' },
{ label: '出生年月', prop: 'birthday', align: 'center' },
{ label: '省', prop: 'province_name', align: 'center' },
{ label: '市', prop: 'city_name', align: 'center' },
......
......@@ -31,11 +31,15 @@ const id = route.query.id ? route.query.id : (route.params.courseId as string)
margin-left: 20px;
height: fit-content;
border-radius: 10px;
height: 800px;
overflow-y: auto;
&.active-black {
background: #1f1e24;
border-radius: 0px;
margin-left: 0px;
overflow-y: auto;
height: 506px;
.chapter-list {
.item {
......@@ -44,13 +48,14 @@ const id = route.query.id ? route.query.id : (route.params.courseId as string)
}
}
.title {
width: 271px;
margin: 0 auto;
font-size: 24px;
font-weight: 500;
line-height: 52px;
color: #ffffff;
text-align: center;
word-break: normal;
word-wrap: break-all;
}
.line {
width: 85%;
......@@ -59,7 +64,7 @@ const id = route.query.id ? route.query.id : (route.params.courseId as string)
}
.chapter-list {
margin: 0 auto;
padding: 0 23px 70px;
padding: 0 23px 11px;
.item:last-child {
border-bottom: none;
}
......@@ -86,8 +91,11 @@ const id = route.query.id ? route.query.id : (route.params.courseId as string)
margin-bottom: 20px;
margin-top: 6px;
cursor: pointer;
word-break: break-all;
}
.sections {
width: 100px;
font-size: 14px;
line-height: 100%;
color: #ffffff;
......
......@@ -159,13 +159,26 @@ const basicInfo = computed((): IBasicInfo[] => {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
.item:nth-child(5) {
width: 20%;
}
.item:nth-child(10) {
width: 20%;
}
.item:nth-child(1) {
width: 20%;
}
.item:nth-child(6) {
width: 20%;
}
.item {
width: 15%;
display: flex;
align-items: center;
height: fit-content;
flex-wrap: nowrap;
margin-left: 2%;
margin-bottom: 10px;
margin-bottom: 32px;
.item-right {
margin-left: 15px;
.label {
......@@ -175,10 +188,10 @@ const basicInfo = computed((): IBasicInfo[] => {
margin-bottom: 8px;
}
.value {
font-size: 16px;
font-weight: 500;
font-size: 14px;
line-height: 100%;
color: #333333;
font-family: Source Han Sans CN;
}
}
}
......
......@@ -53,7 +53,8 @@ const changeVideo = (index: number) => {
<AppVideoPlayer :options="videoOptions"></AppVideoPlayer>
</div>
</div>
<div style="margin-top: 10px">本小节视频资源:</div>
<div style="margin-top: 20px">本小节视频资源:</div>
<div class="cover-list">
<div class="cover-box">
<div
class="cover-img"
......@@ -67,19 +68,26 @@ const changeVideo = (index: number) => {
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.cover-list {
max-width: 1200px;
overflow-x: auto;
}
.cover-box {
display: flex;
justify-content: flex-start;
margin-bottom: 30px;
}
.cover-img {
width: 200px;
height: 100px;
min-width: 200px;
min-height: 100px;
background-size: cover;
margin-right: 20px;
margin-top: 20px;
margin: 20px 10px 0;
cursor: pointer;
box-sizing: border-box;
.border {
width: 100%;
height: 100%;
......@@ -93,7 +101,7 @@ const changeVideo = (index: number) => {
}
.cover-name {
width: 100%;
height: 30px;
// height: 30px;
background: #aa1941;
text-align: center;
line-height: 30px;
......
......@@ -124,7 +124,8 @@ const listOptions = computed(() => {
{ label: '试卷名称', prop: 'paper_title' },
{ label: '总分', prop: 'paper_total_score' },
{ label: '及格分数', prop: 'pass_score' },
{ label: '更新时间', prop: 'updated_at' }
{ label: '更新时间', prop: 'updated_at' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: resourceData.exam
}
......@@ -211,18 +212,28 @@ watch(
router.go(0)
}
)
const handleExamDetail = (row: any) => {
window.open(`https://qa-center.ezijing.com/paper/detail/${row.id}`)
}
</script>
<template>
<AppCard title="查阅课程">
<div class="chapter-box">
<div class="title">{{ chapterDetails?.name }}</div>
<div class="chapter-content">
<div class="content-left">
<div class="content-top">
<ViewDetailsVideo
v-if="Object.keys(resourceData.videoData).length"
:data="resourceData.videoData"
></ViewDetailsVideo>
<el-empty description="暂无数据" v-else />
<el-empty style="max-width: 900px; min-width: 900px" description="暂无数据" v-else />
<ViewCourseChapter
:isBlack="true"
:data="chapterTree"
:style="Object.keys(resourceData.videoData).length ? 'margin-left: -300px' : ''"
></ViewCourseChapter>
</div>
<div class="content-bottom">
<el-tabs :lazy="true" v-model="activeName" class="demo-tabs">
<el-tab-pane label="课件" name="1">
<PreviewFiles v-for="item in resourceData.courseware" :key="item.id" :url="item.url"></PreviewFiles>
......@@ -237,10 +248,18 @@ watch(
<el-empty description="暂无数据" v-if="!resourceData.data.length" />
</el-tab-pane>
<el-tab-pane label="作业" name="4">
<AppList v-bind="homeworkOptions"></AppList>
<AppList v-bind="homeworkOptions">
<template #table-operate="{ row }">
<el-link type="primary" @click="handleExamDetail(row)">进入</el-link>
</template>
</AppList>
</el-tab-pane>
<el-tab-pane label="考试 / 测验" name="5">
<AppList v-bind="listOptions"></AppList>
<AppList v-bind="listOptions">
<template #table-operate="{ row }">
<el-link type="primary" @click="handleExamDetail(row)">进入</el-link>
</template>
</AppList>
</el-tab-pane>
<el-tab-pane label="直播" name="6">
<AppList v-bind="liveOptions">
......@@ -251,7 +270,6 @@ watch(
</el-tab-pane>
</el-tabs>
</div>
<ViewCourseChapter :isBlack="true" :data="chapterTree"></ViewCourseChapter>
</div>
</div>
</AppCard>
......@@ -264,9 +282,11 @@ watch(
color: #333333;
}
.chapter-content {
.content-top {
display: flex;
.content-left {
width: 900px;
}
.content-bottom {
max-width: 1200px;
}
}
}
......
import httpRequest from '@/utils/axios'
// 获取学生列表
export function getProList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
// 获取试卷列表
export function getPaperList(params?: { course_id?: string; paper_name?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/resource/v1/teaching/paper/paper-list', { params })
}
// 搜索条件
export function getSearchList(params?: { type: string; search_id?: string }) {
return httpRequest.get('/api/resource/v1/teaching/paper/search-list', { params })
}
// 学员试卷列表
export function getPaperStuList(params?: {
course_id?: string
paper_id?: string
paper_use?: string
class_id?: string
student_id?: string
page?: number
page_size?: number
}) {
return httpRequest.get('/api/resource/v1/teaching/paper/list', { params })
}
// /**
// * 获取试卷详情
// */
......
<script setup lang="ts">
// import { getProList } from '../api'
import { getPaperList, getSearchList } from '../api'
// import { useMapStore } from '@/stores/map'
// const store = useMapStore()
const router = useRouter()
const appList = ref()
const courseListCategory: any = ref([])
const listOptions = $computed(() => {
return {
// remote: { httpRequest: getProList, params: { name: '' } },
remote: { httpRequest: getPaperList, params: { course_id: '', paper_name: '' } },
filters: [
{ type: 'select', prop: 'course', label: '所属课程:', placeholder: '所属课程' },
{
type: 'select',
prop: 'course_id',
label: '所属课程:',
placeholder: '所属课程',
options: courseListCategory.value,
labelKey: 'name',
valueKey: 'id',
filterable: true,
remote: true
},
{ type: 'input', prop: 'paper_name', label: '试卷名称:', placeholder: '试卷名称' }
],
columns: [
{ label: '序号', type: 'index', align: 'center' },
{ label: '所属课程', prop: 'course', align: 'center' },
{ label: '试卷用途', prop: 'use', align: 'center' },
{ label: '组卷模式', prop: 'class', align: 'center' },
{ label: '试卷名称', prop: 'paper_name', align: 'center' },
{ label: '总分', prop: 'score', align: 'center' },
{ label: '及格分数', prop: 'correct', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{ label: '所属课程', prop: 'course_name', align: 'center' },
{ label: '试卷用途', prop: 'paper_use_name', align: 'center' },
{
course: 111,
exam_id: '6952903190949920768',
student_id: '6953256575158976512'
label: '组卷模式',
prop: 'paper_type',
align: 'center',
computed(row: any) {
if (row.row.paper_type === '1') {
return '选题组卷'
} else {
return '自动组卷'
}
}
},
{ label: '试卷名称', prop: 'paper_name', align: 'center' },
{ label: '总分', prop: 'paper_total_score', align: 'center' },
{ label: '及格分数', prop: 'pass_score', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
]
}
})
const handleCheckPaper = (row: any) => {
console.log(row)
router.push({ path: '/teach/stuList', query: { eid: row.exam_id } })
// router.push({ path: '/teach/stuList', query: { eid: row.exam_id } })
router.push({
path: '/teach/stuList',
query: {
course_id: row.course_id,
paper_id: row.paper_id,
paper_use: row.paper_use
}
})
}
getSearchList({ type: 'course', search_id: '' }).then((res: any) => {
courseListCategory.value = res.data
})
</script>
<template>
......@@ -41,7 +66,9 @@ const handleCheckPaper = (row: any) => {
<AppList v-bind="listOptions" ref="appList" border stripe>
<template #table-operate="{ row }">
<el-space>
<el-link type="primary" plain @click="handleCheckPaper(row)">批改试卷</el-link>
<el-link type="primary" plain @click="handleCheckPaper(row)" v-permission="'v1-teaching-paper-list'"
>批改试卷</el-link
>
</el-space>
</template>
</AppList>
......
<script setup lang="ts">
// import { getProList } from '../api'
// import { useMapStore } from '@/stores/map'
// const store = useMapStore()
import { checkPermission } from '@/utils/permission'
import { getPaperStuList, getSearchList } from '../api'
const router = useRouter()
const route = useRoute()
const appList = ref()
const classId = ref('')
const classList: any = ref([])
const stuList: any = ref([])
const listOptions = $computed(() => {
return {
// remote: { httpRequest: getProList, params: { name: '' } },
remote: {
httpRequest: getPaperStuList,
params: {
course_id: route.query.course_id,
paper_id: route.query.paper_id,
paper_use: route.query.paper_use,
class_id: '',
student_id: ''
},
beforeRequest(params: any) {
if (params.class_id !== '') {
classId.value = params.class_id
}
return params
}
},
filters: [
{ type: 'input', prop: 'class', label: '所属班级:', placeholder: '所属班级' },
{ type: 'input', prop: 'name', label: '所属学生:', placeholder: '所属学生' }
{
type: 'select',
prop: 'class_id',
label: '所属班级:',
placeholder: '所属班级',
options: classList.value,
labelKey: 'name',
valueKey: 'id',
filterable: true,
remote: true
},
{
type: 'select',
prop: 'student_id',
label: '所属学生:',
placeholder: '所属学生',
options: stuList.value,
labelKey: 'name',
valueKey: 'id',
filterable: true,
remote: true
}
],
columns: [
{ label: '序号', type: 'index', align: 'center' },
{ label: '所属课程', prop: 'course', align: 'center' },
{ label: '所属班级', prop: 'class', align: 'center' },
{ label: '学生姓名', prop: 'name', align: 'center' },
{ label: '所属课程', prop: 'course_name', align: 'center' },
{ label: '所属班级', prop: 'class_name', align: 'center' },
{ label: '学生姓名', prop: 'student_name', align: 'center' },
{ label: '试卷名称', prop: 'paper_name', align: 'center' },
{ label: '得分', prop: 'score', align: 'center' },
{ label: '是否批改', prop: 'correct', align: 'center' },
{ label: '更新时间', prop: 'update_time', align: 'center' },
{ label: '是否批改', prop: 'status_name', align: 'center' },
{ label: '更新时间', prop: 'updated_at', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{
name: 111,
exam_id: '6952903190949920768',
student_id: '6953256575158976512'
}
]
}
})
const handleCheckPaper = (row: any) => {
console.log(row)
router.push({ path: '/teach/view', query: { eid: row.exam_id, sid: row.student_id } })
}
onMounted(() => {
checkPermission('v1-teaching-paper-search-list') && handleGetSearchList()
})
const handleGetSearchList = () => {
const params: any = { type: 'class', search_id: classId }
getSearchList(params).then((res: any) => {
stuList.value = res.data
})
}
// 获取学生列表
const handleGetStuList = () => {
const params: any = { type: 'class', search_id: classId.value }
getSearchList(params).then((res: any) => {
classList.value = res.data
})
}
if (classId.value !== '') {
checkPermission('v1-teaching-paper-search-list') && handleGetStuList()
}
</script>
<template>
......@@ -42,7 +92,13 @@ const handleCheckPaper = (row: any) => {
<AppList v-bind="listOptions" ref="appList" border stripe>
<template #table-operate="{ row }">
<el-space>
<el-link type="primary" plain @click="handleCheckPaper(row)">批改试卷</el-link>
<el-link
type="primary"
plain
@click="handleCheckPaper(row)"
v-permission="'v1-teaching-paper-update' || 'v1-teaching-paper-view'"
>批改试卷</el-link
>
</el-space>
</template>
</AppList>
......
import httpRequest from '@/utils/axios'
// 获取学生列表
export function getProList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
// 获取大作业列表
export function getWorkList(params?: { course_id: string; title?: string; page?: string; page_size?: string }) {
return httpRequest.get('/api/resource/v1/teaching/job/list', { params })
}
// 搜索条件
export function getSearchList(params?: { type: string; search_id?: string }) {
return httpRequest.get('/api/resource/v1/teaching/job/search-list', { params })
}
// 大作业详情
export function getWorkDetail(params?: { id: string }) {
return httpRequest.get('/api/resource/v1/teaching/job/view', { params })
}
//大作业批改
export function updateWork(data: { id: string; score: string }) {
return httpRequest.post('/api/resource/v1/teaching/job/update', data)
}
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { getWorkDetail, updateWork } from '../api'
const emit = defineEmits<Emits>()
const ruleFormRef = ref<FormInstance>()
// 封面类型
// 封面状态
const form = reactive({
desc: '',
detail: '',
answer: ''
const form: any = reactive({
course_name: '',
student_name: '',
student_sno_number: '',
score: '',
title: '',
content: '',
attachments: [],
is_critiqued: ''
})
defineProps({
const rules = reactive<FormRules>({
score: [{ required: true, message: '请输入得分', trigger: 'blur' }]
})
const props = defineProps({
isShowCheckDialog: {
type: Boolean,
required: true
},
id: {
type: String,
required: true
}
})
interface Emits {
(e: 'update:isShowCheckDialog', isShowCheckDialog: boolean): void
(e: 'create'): void
}
// 取消
const handleCancel = () => {
emit('update:isShowCheckDialog', false)
}
// 确定
const handleConfirm = () => {
// 确认
const handleConfirm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(valid => {
if (valid) {
updateWork({ id: props.id, score: form.score }).then(() => {
emit('update:isShowCheckDialog', false)
emit('create')
})
}
})
}
onMounted(() => {
handleGetWorkDetail()
})
const handleGetWorkDetail = () => {
getWorkDetail({ id: props.id }).then(res => {
Object.keys(form).forEach(key => {
form[key] = res.data[key]
})
form.attachments = JSON.parse(form.attachments)
})
}
</script>
<template>
<el-dialog :model-value="isShowCheckDialog" draggable :before-close="handleCancel" width="50%" title="批改大作业">
<el-form :model="form" ref="ruleFormRef" label-width="100px">
<el-dialog :model-value="isShowCheckDialog" draggable :before-close="handleCancel" width="30%" title="批改大作业">
<el-form :model="form" label-width="110px" :rules="rules" ref="ruleFormRef">
<el-row>
<el-col :span="10"> <el-form-item label="课程名称:" prop="type"> 投诉建议人:lisi </el-form-item></el-col>
<el-col :span="12">
<el-form-item label="课程名称:" prop="type"> {{ form?.course_name }} </el-form-item></el-col
>
</el-row>
<el-row>
<el-col :span="10"> <el-form-item label="学生姓名:" prop="type"> 投诉建议人:lisi </el-form-item></el-col>
<el-col :span="10"> <el-form-item label="学号:" prop="type"> 提交时间:2022-07-19 </el-form-item></el-col>
<el-col :span="12">
<el-form-item label="学生姓名:" prop="type"> {{ form.student_name }}</el-form-item></el-col
>
<el-col :span="12">
<el-form-item label="学号:" prop="type"> {{ form.student_sno_number }} </el-form-item></el-col
>
</el-row>
<el-form-item label="得分:" prop="desc">
<el-input v-model="form.desc" autosize type="textarea" placeholder="Please input" disabled />
<el-form-item label="得分:" prop="score">
<el-input-number
v-model="form.score"
:min="1"
:max="100"
:controls="false"
:disabled="form.is_critiqued === '1'"
/>
</el-form-item>
<el-divider border-style="desdashedc" />
<el-form-item label="大作业标题:" prop="desc">
<el-input v-model="form.desc" autosize type="textarea" placeholder="Please input" disabled />
<el-form-item label="大作业标题:" prop="title">
<el-input v-model="form.title" autosize type="textarea" placeholder="Please input" disabled />
</el-form-item>
<el-form-item label="大作业正文:" prop="detail">
<el-input v-model="form.detail" autosize type="textarea" placeholder="Please input" disabled />
<el-form-item label="大作业正文:" prop="content">
<el-input v-model="form.content" autosize type="textarea" placeholder="Please input" disabled />
</el-form-item>
<el-form-item label="相关附件:" prop="type">
<a href="1">11</a>
<el-form-item label="相关附件:" prop="attachments">
<div v-for="(item, index) in form.attachments" :key="index">
<a :href="item.url" style="color: #aa1941" target="_blank">{{ item.name }}</a>
</div>
</el-form-item>
</el-form>
<template #footer>
<template #footer v-if="form.is_critiqued !== '1'">
<span>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
<el-button type="primary" @click="handleConfirm(ruleFormRef)">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<style>
.el-input-number:placeholder {
text-align: left;
}
</style>
<script setup lang="ts">
// import { getProList } from '../api'
import { checkPermission } from '@/utils/permission'
import CheckWork from '../components/CheckWork.vue'
import { getWorkList, getSearchList } from '../api'
const appList = ref()
const isShowCheckDialog = ref(false)
const id = ref('')
const searchList: any = ref([])
const listOptions = $computed(() => {
return {
// remote: { httpRequest: getProList, params: { name: '' } },
remote: { httpRequest: getWorkList, params: { course_id: '', title: '' } },
filters: [
{ type: 'select', prop: 'course', label: '所属课程:', placeholder: '所属课程' },
{ type: 'input', prop: 'paper_name', label: '大作业名称:', placeholder: '大作业名称' }
{
type: 'select',
prop: 'course_id',
label: '所属课程:',
placeholder: '所属课程',
options: searchList.value,
labelKey: 'name',
valueKey: 'id',
filterable: true,
remote: true
}
],
columns: [
{ label: '序号', type: 'index', align: 'center' },
{ label: '所属课程', prop: 'course', align: 'center' },
{ label: '所属课程', prop: 'course_name', align: 'center' },
{ label: '学生姓名', prop: 'name', align: 'center' },
{ label: '学号', prop: 'sno_number', align: 'center' },
{ label: '提交时间', prop: 'created_time', align: 'center' },
{ label: '批改人', prop: 'operator_name', align: 'center' },
{ label: '批改时间', prop: 'update_time', align: 'center' },
{ label: '得分', prop: 'score', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{
name: 111,
exam_id: '6952903190949920768',
student_id: '6953256575158976512'
label: '提交时间',
prop: 'created_at',
align: 'center',
computed(row: any) {
return row.row.created_at || '-'
}
},
{
label: '批改人',
prop: 'checker_id_name',
align: 'center',
computed(row: any) {
return row.row.checker_id_name || '-'
}
},
{
label: '批改时间',
prop: 'marking_time',
align: 'center',
computed(row: any) {
return row.row.marking_time || '-'
}
},
{
label: '得分',
prop: 'score',
align: 'center',
computed(row: any) {
return row.row.score || '-'
}
},
{ label: '操作', slots: 'table-operate', align: 'center' }
]
}
})
const handleCheckPaper = (row: any) => {
console.log(row)
id.value = row.job_id
isShowCheckDialog.value = true
console.log(isShowCheckDialog.value)
}
onMounted(() => {
checkPermission('v1-teaching-job-search-list') && handleGetSearchList()
})
const handleGetSearchList = () => {
getSearchList({ type: 'course', search_id: '' }).then(res => {
searchList.value = res.data
})
}
const handleFresh = () => {
appList.value.refetch()
}
</script>
<template>
<AppCard title="批改试卷">
<AppCard title="批改大作业">
<AppList v-bind="listOptions" ref="appList" border stripe>
<template #table-operate="{ row }">
<el-space>
<el-link type="primary" plain @click="handleCheckPaper(row)">批改</el-link>
<el-link
type="primary"
plain
@click="handleCheckPaper(row)"
v-if="row.created_at !== null"
v-permission="'v1-teaching-job-update' || 'v1-teaching-job-view'"
>批改</el-link
>
<div v-else>-</div>
</el-space>
</template>
</AppList>
</AppCard>
<CheckWork v-if="isShowCheckDialog === true" v-model:isShowCheckDialog="isShowCheckDialog" />
<CheckWork
v-if="isShowCheckDialog === true"
v-model:isShowCheckDialog="isShowCheckDialog"
:id="id"
@create="handleFresh"
/>
</template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论