提交 7649fdcd authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 b8a55b7b
......@@ -6,21 +6,64 @@ export function getExperimentList(params?: { name?: string; page?: number; 'per-
return httpRequest.get('/api/resource/v1/backend/experiment/list', { params })
}
// 获取实验详情
export function getExperiment(params: { experiment_id: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/experiment/view', { params })
}
// 创建实验
export function createExperiment(data: ExperimentCreateItem) {
return httpRequest.post('/api/resource//v1/backend/experiment/create', data)
return httpRequest.post('/api/resource/v1/backend/experiment/create', data)
}
// 更新实验
export function updateExperiment(data: ExperimentCreateItem) {
return httpRequest.post('/api/resource//v1/backend/experiment/update', data)
return httpRequest.post('/api/resource/v1/backend/experiment/update', data)
}
// 获取实验课程列表
export function getExperimentCourseList(params: { organ_id?: string }) {
export function getExperimentCourseList(params: { organ_id: string }) {
return httpRequest.get('/api/resource/v1/backend/experiment/courses', { params })
}
// 获取实验指导老师列表
export function getExperimentTeacherList(params: { organ_id?: string }) {
export function getExperimentTeacherList(params: { organ_id: string }) {
return httpRequest.get('/api/resource/v1/backend/experiment/teachers', { params })
}
// 获取实验关联班级列表
export function getExperimentClassList(params: { experiment_id: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/experiment/class-add', { params })
}
// 实验关联班级
export function experimentAddClass(data: { experiment_id: string; classes_id: string; type: 'add' | 'delete' }) {
return httpRequest.post('/api/resource/v1/backend/experiment/class-add', data)
}
// 获取班级学生列表
export function getClassStudentList(params: { class_id: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/experiment/class-students', { params })
}
// 获取班级小组列表
export function getExperimentClassGroupsList(params: { experiment_id: string; class_id: string }) {
return httpRequest.get('/api/resource/v1/backend/experiment/class-teams', { params })
}
// 获取实验小组
export function getExperimentGroup(params: { team_id: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/experiment/team-view', { params })
}
// 新增实验小组
export function experimentAddClassGroup(data: { experiment_id: string; class_id: string; name: string }) {
return httpRequest.post('/api/resource/v1/backend/experiment/team-add', data)
}
// 实验小组添加学生
export function experimentGroupAddStudent(data: { team_id: string; students_id: string; type: 'add' | 'delete' }) {
return httpRequest.post('/api/resource/v1/backend/experiment/team-add-student', data)
}
// 获取实验关联班级列表
export function getExperimentGroupStudentList(params: { team_id: string; page?: number; 'per-page'?: number }) {
return httpRequest.get('/api/resource/v1/backend/experiment/team-add-student', { params })
}
<script setup lang="ts">
import type { ExperimentItem, ClassItem } from '../types'
import { ElMessage } from 'element-plus'
import { getExperimentClassList, experimentAddClass } from '../api'
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const detail = $ref<ExperimentItem>(inject('detail'))
// 列表配置
const listOptions = {
// remote: {
// httpRequest: getExperimentList,
// params: { name: '' }
// },
remote: {
httpRequest: getExperimentClassList,
params: { experiment_id: detail?.id }
},
columns: [
{ type: 'selection' },
{ label: '序号', type: 'index', width: 60 },
{ label: '学号', prop: 'name' },
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'name' },
{ label: '所属部门/学校', prop: 'name' },
{ label: '专业', prop: 'name' },
{ label: '班级', prop: 'name' }
],
data: [{}]
{ label: '班级代码', prop: 'code' },
{ label: '班级名称', prop: 'name' },
{ label: '所属部门/学校', prop: 'organ_id_name' },
{ label: '人数', prop: 'student_nums' },
{ label: '专业', prop: 'specialty_id_name' }
]
}
let multipleSelection = $ref<ClassItem[]>([])
function handleSelectionChange(selection: ClassItem[]) {
multipleSelection = selection
}
function handleSubmit() {
const classes_id = multipleSelection.map(item => item.id).join(',')
experimentAddClass({ experiment_id: detail.id, classes_id, type: 'add' }).then(() => {
ElMessage({ message: '关联成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
})
}
</script>
<template>
<el-dialog title="关联班级">
<AppList v-bind="listOptions"></AppList>
<el-dialog title="关联班级" @update:modelValue="$emit('update:modelValue')">
<p>所属机构/学校:{{ detail.organ_id_name }}</p>
<AppList v-bind="listOptions" @selection-change="handleSelectionChange"></AppList>
<el-row justify="center">
<el-button type="primary" round>关联选择班级</el-button>
<el-button type="primary" round :disabled="!multipleSelection.length" @click="handleSubmit"
>关联选择班级</el-button
>
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
</el-row>
</el-dialog>
......
<script setup lang="ts">
import type { GroupItem, StudentItem } from '../types'
import { ElMessage } from 'element-plus'
import { getExperimentGroupStudentList, experimentGroupAddStudent } from '../api'
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const detail = $ref<GroupItem>(inject('detail'))
// 列表配置
const listOptions = {
// remote: {
// httpRequest: getExperimentList,
// params: { name: '' }
// },
remote: {
httpRequest: getExperimentGroupStudentList,
params: { team_id: detail?.id }
},
columns: [
{ type: 'selection' },
{ label: '序号', type: 'index', width: 60 },
{ label: '班级代码', prop: 'name' },
{ label: '班级名称', prop: 'name' },
{ label: '所属部门/学校', prop: 'name' },
{ label: '人数', prop: 'name' },
{ label: '专业', prop: 'name' }
],
data: [{}]
{ label: '学号', prop: 'name' },
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'name' },
{ label: '部门/学校', prop: 'name' },
{ label: '专业', prop: 'name' },
{ label: '班级', prop: 'name' }
]
}
let multipleSelection = $ref<StudentItem[]>([])
function handleSelectionChange(selection: StudentItem[]) {
multipleSelection = selection
}
function handleSubmit() {
const students_id = multipleSelection.map(item => item.id).join(',')
experimentGroupAddStudent({ team_id: detail.id, students_id, type: 'add' }).then(() => {
ElMessage({ message: '添加成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
})
}
</script>
<template>
<el-dialog title="添加小组成员">
<AppList v-bind="listOptions"></AppList>
<el-dialog title="添加小组成员" @update:modelValue="$emit('update:modelValue')">
<AppList v-bind="listOptions" @selection-change="handleSelectionChange"></AppList>
<el-row justify="center">
<el-button type="primary" round>添加选择学生</el-button>
<el-button type="primary" round :disabled="!multipleSelection.length" @click="handleSubmit"
>添加选择学生</el-button
>
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
</el-row>
</el-dialog>
......
<script setup lang="ts">
import type { ExperimentItem, ClassItem, GroupItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue'
import StudentGroupFormDialog from './StudentGroupFormDialog.vue'
import AppList from '@/components/base/AppList.vue'
import { getExperimentClassGroupsList } from '../api'
interface Props {
data: ClassItem
}
const props = defineProps<Props>()
const detail = $ref<ExperimentItem>(inject('detail'))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置
const listOptions = {
// remote: {
// httpRequest: getExperimentList,
// params: { name: '' }
// },
remote: {
httpRequest: getExperimentClassGroupsList,
params: { experiment_id: detail?.id, class_id: props.data?.id },
callback(data: GroupItem[]) {
return { list: data, total: data.length }
}
},
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '小组名称', prop: 'name' },
{ label: '成员人数', prop: 'name' },
{ label: '操作', slots: 'table-x' }
],
data: [{}]
{ label: '成员人数', prop: 'student_num' },
{ label: '操作', slots: 'table-x', width: 120 }
]
}
const dialogVisible = $ref(false)
// 刷新
function handleRefetch() {
appList?.refetch()
}
</script>
<template>
<el-dialog title="学生分组">
<AppList v-bind="listOptions">
<el-descriptions :column="2">
<el-descriptions-item label="实验名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="所属机构:">{{ detail.organ_id_name }}</el-descriptions-item>
<el-descriptions-item label="班级名称:">{{ data.name }}</el-descriptions-item>
<el-descriptions-item label="学生人数:">{{ data.student_nums }}</el-descriptions-item>
</el-descriptions>
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="dialogVisible = true">新增分组</el-button>
</template>
<template #table-x>
<el-button type="primary" link>小组成员</el-button>
<template #table-x="{ row }">
<el-button type="primary" link>
<router-link :to="`/admin/system/experiment/group/${row.id}`" target="_blank">小组成员</router-link>
</el-button>
</template>
</AppList>
<StudentGroupFormDialog v-model="dialogVisible" append-to-body></StudentGroupFormDialog>
<StudentGroupFormDialog
append-to-body
v-model="dialogVisible"
:data="data"
@update="handleRefetch"
v-if="dialogVisible"
></StudentGroupFormDialog>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
// import { ElMessage } from 'element-plus'
import type { ExperimentItem, ClassItem } from '../types'
import { ElMessage } from 'element-plus'
import { experimentAddClassGroup } from '../api'
interface Props {
data?: any
data: ClassItem
}
const props = defineProps<Props>()
defineEmits<{
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const detail = $ref<ExperimentItem>(inject('detail'))
const formRef = $ref<FormInstance>()
const form = reactive({ title: '', status: 1 })
watchEffect(() => {
Object.assign(form, props.data)
})
const form = reactive({ name: '' })
const rules = ref<FormRules>({
title: [{ required: true, message: '请输入问题描述', trigger: 'blur' }],
content: [{ required: true, message: '请输入问题详情', trigger: 'blur' }]
name: [{ required: true, message: '请输入实验小组名称', trigger: 'blur' }]
})
// 提交
function handleSubmit() {
formRef?.validate().then(update)
formRef?.validate().then(handleCreate)
}
// 修改
const update = () => {
// submitSuggestion(form).then(() => {
// ElMessage({ message: '提交成功', type: 'success' })
// emit('update')
// formRef?.resetFields()
// })
// 创建
const handleCreate = () => {
const params = { ...form, experiment_id: detail.id, class_id: props.data.id }
experimentAddClassGroup(params).then(() => {
ElMessage({ message: '创建成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
})
}
</script>
<template>
<el-dialog title="新增实验分组" :close-on-click-modal="false" width="600px">
<el-dialog
title="新增实验分组"
:close-on-click-modal="false"
width="600px"
@update:modelValue="$emit('update:modelValue')"
>
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
<el-form-item label="实验名称" prop="title"></el-form-item>
<el-form-item label="实验小组名称" prop="content">
<el-input v-model="form.title"></el-input>
<el-form-item label="实验名称">{{ detail.name }}</el-form-item>
<el-form-item label="实验小组名称" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="handleSubmit">保存</el-button>
......
<script setup lang="ts">
import type { ClassItem } from '../types'
import { getClassStudentList } from '../api'
interface Props {
data: ClassItem
}
const props = defineProps<Props>()
// 列表配置
const listOptions = {
// remote: {
// httpRequest: getExperimentList,
// params: { name: '' }
// },
remote: {
httpRequest: getClassStudentList,
params: { class_id: props.data?.id }
},
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '学号', prop: 'name' },
{ label: '学号', prop: 'id_number' },
{ label: '姓名', prop: 'name' },
{ label: '性别', prop: 'name' },
{ label: '所属部门/学校', prop: 'name' },
{ label: '专业', prop: 'name' },
{ label: '班级', prop: 'name' }
],
data: [{}]
{ label: '性别', prop: 'gender_name' },
{ label: '所属部门/学校', prop: 'organ_id_name' },
{ label: '专业', prop: 'specialty_id_name' },
{ label: '班级', prop: 'class_id_name' }
]
}
</script>
<template>
......
......@@ -8,7 +8,8 @@ export const routes: Array<RouteRecordRaw> = [
redirect: '/admin/system/experiment',
children: [
{ path: 'experiment', component: () => import('./views/Index.vue') },
{ path: 'experiment/:id', component: () => import('./views/View.vue'), props: true }
{ path: 'experiment/:id', component: () => import('./views/View.vue'), props: true },
{ path: 'experiment/group/:id', component: () => import('./views/Group.vue'), props: true }
]
}
]
......@@ -40,3 +40,79 @@ export interface ExperimentCreateItem {
teachers_id: string
teachers_ids?: string[]
}
export interface ClassItem {
code: string
created_operator: string
created_operator_name: string
created_time: string
delete_time: string
id: string
name: string
organ_id: string
organ_id_name: string
project_id: string
project_id_name: string
specialty_id: string
specialty_id_name: string
start_year: string
start_year_name: string
status: string
status_name: string
student_nums: number
teacher_id: string
teacher_id_name: string
updated_operator: string
updated_operator_name: string
updated_time: string
}
export interface StudentItem {
birthday: string
city: string
city_name: string
class_id: string
class_id_name: string
county: string
county_name: string
created_operator: string
created_operator_name: string
created_time: string
delete_time: string
gender: string
gender_name: string
id: string
id_number: string
id_type: string
id_type_name: string
mobile: string
name: string
organ_id: string
organ_id_name: string
project_id: string
project_id_name: string
province: string
province_name: string
sno_number: string
specialty_id: string
specialty_id_name: string
sso_id: string
status: string
status_name: string
updated_operator: string
updated_operator_name: string
updated_time: string
}
export interface GroupItem {
class_id: string
created_operator: string
created_time: string
experiment_id: string
id: string
name: string
status: string
student_num: number
updated_operator: string
updated_time: string
}
<script setup lang="ts">
import type { GroupItem, StudentItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue'
import { getExperimentGroup, experimentGroupAddStudent } from '../api'
const SelectStudentDialog = defineAsyncComponent(() => import('../components/SelectStudentDialog.vue'))
interface Props {
id: string
}
const props = defineProps<Props>()
let detail = $ref<GroupItem | null>(null)
provide('detail', $$(detail))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置
const listOptions = {
remote: {
httpRequest: getExperimentGroup,
params: { team_id: props.id },
callback(data: { total: number; list: StudentItem[]; info: GroupItem }) {
const { total, list, info } = data
detail = info
return { list, total }
}
},
columns: [
{ label: '序号', type: 'index', width: 60 },
{
label: '小组名称',
computed() {
return detail?.name || '-'
}
},
{ label: '班级名称', prop: 'class_id_name' },
{ label: '姓名', prop: 'name' },
{ label: '学号', prop: 'id_number' },
{ label: '操作', slots: 'table-x', width: 100 }
]
}
// 刷新
function handleRefetch() {
appList?.refetch()
}
// 关联学生
const selectStudentVisible = $ref(false)
// 移除班级
function handleRemoveStudent(row: StudentItem) {
ElMessageBox.confirm('确定要移除吗?', '提示').then(() => {
experimentGroupAddStudent({ team_id: props.id, students_id: row.id, type: 'delete' }).then(() => {
ElMessage({ message: '移除成功', type: 'success' })
appList?.refetch()
})
})
}
</script>
<template>
<AppCard title="实验管理">
<el-descriptions :column="2" v-if="detail">
<el-descriptions-item label="实验名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="实验课程:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="小组名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="班级名称:">{{ detail.name }}</el-descriptions-item>
</el-descriptions>
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="selectStudentVisible = true"
>添加小组成员</el-button
>
</template>
<template #table-x="{ row }">
<el-button type="primary" round @click="handleRemoveStudent(row)">移除</el-button>
</template>
</AppList>
</AppCard>
<!-- 添加小组成员 -->
<SelectStudentDialog
v-model="selectStudentVisible"
@update="handleRefetch"
v-if="selectStudentVisible"
></SelectStudentDialog>
</template>
<script setup lang="ts">
import type { ExperimentItem, ClassItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue'
import SelectClassDialog from '../components/SelectClassDialog.vue'
import StudentGroupDialog from '../components/StudentGroupDialog.vue'
import StudentListDialog from '../components/StudentListDialog.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue'
import { getExperiment, experimentAddClass } from '../api'
const SelectClassDialog = defineAsyncComponent(() => import('../components/SelectClassDialog.vue'))
const StudentGroupDialog = defineAsyncComponent(() => import('../components/StudentGroupDialog.vue'))
const StudentListDialog = defineAsyncComponent(() => import('../components/StudentListDialog.vue'))
interface Props {
id: string
}
defineProps<Props>()
const props = defineProps<Props>()
let detail = $ref<ExperimentItem | null>(null)
provide('detail', $$(detail))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置
const listOptions = {
// remote: {
// httpRequest: getExperimentList,
// params: { name: '' }
// },
remote: {
httpRequest: getExperiment,
params: { experiment_id: props.id },
callback(data: { total: number; list: ClassItem[]; info: ExperimentItem }) {
const { total, list, info } = data
detail = info
return { list, total }
}
},
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '专业名称', prop: 'name' },
{ label: '专业名称', prop: 'specialty_id_name' },
{ label: '班级名称', prop: 'name' },
{ label: '学生人数', prop: 'name' },
{ label: '更新时间', prop: 'name' },
{ label: '学生人数', prop: 'student_nums' },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', slots: 'table-x', width: 300 }
],
data: [{}]
]
}
// 刷新
function handleRefetch() {
appList?.refetch()
}
let rowData = $ref<ClassItem | null>(null)
// 关联班级
const selectClassVisible = $ref(false)
const studentGroupVisible = $ref(false)
const studentListVisible = $ref(false)
// 查看学生
let studentListVisible = $ref(false)
function handleViewStudent(row: ClassItem) {
rowData = row
studentListVisible = true
}
// 学生分组
let studentGroupVisible = $ref(false)
function handleStudentGroup(row: ClassItem) {
rowData = row
studentGroupVisible = true
}
// 移除班级
function handleRemoveClass(row: ClassItem) {
ElMessageBox.confirm('确定要移除吗?', '提示').then(() => {
experimentAddClass({ experiment_id: props.id, classes_id: row.id, type: 'delete' }).then(() => {
ElMessage({ message: '移除成功', type: 'success' })
appList?.refetch()
})
})
}
</script>
<template>
<AppCard title="实验管理">
<el-descriptions>
<el-descriptions-item label="实验名称">kooriookami</el-descriptions-item>
<el-descriptions-item label="实验课程">18100000000</el-descriptions-item>
<el-descriptions-item label="所属机构/学校">Suzhou</el-descriptions-item>
<el-descriptions v-if="detail">
<el-descriptions-item label="实验名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="实验课程:">{{ detail.course_name }}</el-descriptions-item>
<el-descriptions-item label="所属机构/学校:">{{ detail.organ_id_name }}</el-descriptions-item>
</el-descriptions>
<AppList v-bind="listOptions">
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="selectClassVisible = true">关联班级</el-button>
</template>
<template #table-x>
<el-button type="primary" round @click="studentListVisible = true">查看学生</el-button>
<el-button type="primary" round @click="studentGroupVisible = true">学生分组</el-button>
<el-button type="primary" round>移除</el-button>
<template #table-x="{ row }">
<el-button type="primary" round @click="handleViewStudent(row)">查看学生</el-button>
<el-button type="primary" round @click="handleStudentGroup(row)">学生分组</el-button>
<el-button type="primary" round @click="handleRemoveClass(row)">移除</el-button>
</template>
</AppList>
</AppCard>
<!-- 关联班级 -->
<SelectClassDialog v-model="selectClassVisible"></SelectClassDialog>
<SelectClassDialog v-model="selectClassVisible" @update="handleRefetch" v-if="selectClassVisible"></SelectClassDialog>
<!-- 学生分组 -->
<StudentGroupDialog v-model="studentGroupVisible"></StudentGroupDialog>
<StudentGroupDialog
v-model="studentGroupVisible"
:data="rowData"
v-if="studentGroupVisible && rowData"
></StudentGroupDialog>
<!-- 查看学生 -->
<StudentListDialog v-model="studentListVisible"></StudentListDialog>
<StudentListDialog
v-model="studentListVisible"
:data="rowData"
v-if="studentListVisible && rowData"
></StudentListDialog>
</template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论