新增培训:实现开班计划P0能力

This commit is contained in:
wangzhibiao committed 2026-09-14 12:07:57 +08:00
1 parent 7fcaea29b8
commit eff048874d
21 files changed
+1561 -526

No files matched your search

+9 -9
View File
@@ -3,7 +3,7 @@ import request from '@/utils/request'
// 查询开班计划列表
export function listPlan(query) {
return request({
url: '/train/plan/list',
url: '/train/plans',
method: 'get',
params: query
})
@@ -12,7 +12,7 @@ export function listPlan(query) {
// 查询开班计划详细
export function getPlan(planId) {
return request({
url: '/train/plan/' + planId,
url: '/train/plans/' + planId,
method: 'get'
})
}
@@ -20,25 +20,25 @@ export function getPlan(planId) {
// 新增开班计划
export function addPlan(data) {
return request({
url: '/train/plan',
url: '/train/plans',
method: 'post',
data: data
})
}
// 修改开班计划
export function updatePlan(data) {
export function updatePlan(planId, data) {
return request({
url: '/train/plan',
url: '/train/plans/' + planId,
method: 'put',
data: data
})
}
// 删除开班计划
export function delPlan(planId) {
// 结束培训计划
export function completePlan(planId) {
return request({
url: '/train/plan/' + planId,
method: 'delete'
url: '/train/plans/' + planId + '/complete',
method: 'post'
})
}
+155 -261
View File
@@ -1,68 +1,30 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="开班名称" prop="planName">
<el-input
v-model="queryParams.planName"
placeholder="请输入开班名称"
<el-form
v-show="showSearch"
ref="queryForm"
:model="queryParams"
size="small"
:inline="true"
label-width="88px"
>
<el-form-item label="培训班名称" prop="planName">
<el-input v-model="queryParams.planName" placeholder="请输入培训班名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="计划状态" prop="planStatus">
<el-select v-model="queryParams.planStatus" placeholder="全部状态" clearable>
<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="开班时间">
<el-date-picker
v-model="startTimeRange"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="所属课程编号,关联train_course.c_id" prop="cId">
<el-input
v-model="queryParams.cId"
placeholder="请输入所属课程编号,关联train_course.c_id"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="开班时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择开班时间">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker clearable
v-model="queryParams.endTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="培训地点" prop="trainAddress">
<el-input
v-model="queryParams.trainAddress"
placeholder="请输入培训地点"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="授课教师工号,关联train_teacher.t_id" prop="tId">
<el-input
v-model="queryParams.tId"
placeholder="请输入授课教师工号,关联train_teacher.t_id"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="招生人数" prop="recruitNum">
<el-input
v-model="queryParams.recruitNum"
placeholder="请输入招生人数"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建管理员账号" prop="createUser">
<el-input
v-model="queryParams.createUser"
placeholder="请输入创建管理员账号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
@@ -74,141 +36,99 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['train:plan:add']"
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['train:plan:add']"
>新增</el-button>
>新增计划</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['train:plan:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['train:plan:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['train:plan:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
</el-row>
<el-table v-loading="loading" :data="planList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="开班计划ID主键" align="center" prop="planId" />
<el-table-column label="开班名称" align="center" prop="planName" />
<el-table-column label="所属课程编号,关联train_course.c_id" align="center" prop="cId" />
<el-table-column label="开班时间" align="center" prop="startTime" width="180">
<el-table v-loading="loading" :data="planList">
<el-table-column label="计划编号" align="center" prop="planId" min-width="220" show-overflow-tooltip />
<el-table-column label="培训班名称" align="left" prop="planName" min-width="230" show-overflow-tooltip />
<el-table-column label="状态" align="center" prop="planStatus" width="100">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
<el-tag :type="statusTagType(scope.row.planStatus)">{{ statusLabel(scope.row.planStatus) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="结束时间" align="center" prop="endTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="培训地点" align="center" prop="trainAddress" />
<el-table-column label="授课教师工号,关联train_teacher.t_id" align="center" prop="tId" />
<el-table-column label="招生人数" align="center" prop="recruitNum" />
<el-table-column label="报名条件" align="center" prop="applyCondition" />
<el-table-column label="0 未开始 1 进行中 2 已结束 3 已取消" align="center" prop="planStatus" />
<el-table-column label="创建管理员账号" align="center" prop="createUser" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="开班时间" align="center" prop="startTime" width="165" />
<el-table-column label="结束时间" align="center" prop="endTime" width="165" />
<el-table-column label="报到截止" align="center" prop="reportDeadline" width="165" />
<el-table-column label="培训地点" align="left" prop="trainAddress" min-width="180" show-overflow-tooltip />
<el-table-column label="计划人数" align="center" prop="recruitNum" width="90" />
<el-table-column label="课程数" align="center" prop="courseCount" width="80" />
<el-table-column label="参训人数" align="center" prop="enrolledCount" width="90" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="170" fixed="right">
<template slot-scope="scope">
<el-button
v-hasPermi="['train:plan:edit']"
size="mini"
type="text"
icon="el-icon-edit"
:disabled="isLocked(scope.row.planStatus)"
@click="handleUpdate(scope.row)"
v-hasPermi="['train:plan:edit']"
>修改</el-button>
<el-button
v-hasPermi="['train:plan:complete']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['train:plan:remove']"
>删除</el-button>
icon="el-icon-finished"
:disabled="isLocked(scope.row.planStatus)"
@click="handleComplete(scope.row)"
>结束计划</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改开班计划对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="开班名称" prop="planName">
<el-input v-model="form.planName" placeholder="请输入开班名称" />
</el-form-item>
<el-form-item label="所属课程编号,关联train_course.c_id" prop="cId">
<el-input v-model="form.cId" placeholder="请输入所属课程编号,关联train_course.c_id" />
</el-form-item>
<el-form-item label="开班时间" prop="startTime">
<el-date-picker clearable
v-model="form.startTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择开班时间">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker clearable
v-model="form.endTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择结束时间">
</el-date-picker>
<el-dialog :title="title" :visible.sync="open" width="660px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="110px">
<el-form-item label="培训班名称" prop="planName">
<el-input v-model="form.planName" maxlength="150" show-word-limit placeholder="请输入培训班名称" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="开班时间" prop="startTime">
<el-date-picker v-model="form.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择开班时间" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束时间" prop="endTime">
<el-date-picker v-model="form.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择结束时间" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="报到截止" prop="reportDeadline">
<el-date-picker v-model="form.reportDeadline" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择报到截止时间" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划人数" prop="recruitNum">
<el-input-number v-model="form.recruitNum" :min="1" :precision="0" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="培训地点" prop="trainAddress">
<el-input v-model="form.trainAddress" placeholder="请输入培训地点" />
</el-form-item>
<el-form-item label="授课教师工号,关联train_teacher.t_id" prop="tId">
<el-input v-model="form.tId" placeholder="请输入授课教师工号,关联train_teacher.t_id" />
</el-form-item>
<el-form-item label="招生人数" prop="recruitNum">
<el-input v-model="form.recruitNum" placeholder="请输入招生人数" />
<el-input v-model="form.trainAddress" maxlength="200" show-word-limit placeholder="请输入培训地点" />
</el-form-item>
<el-form-item label="报名条件" prop="applyCondition">
<el-input v-model="form.applyCondition" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="创建管理员账号" prop="createUser">
<el-input v-model="form.createUser" placeholder="请输入创建管理员账号" />
<el-input v-model="form.applyCondition" type="textarea" :rows="3" placeholder="请输入报名条件" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
<el-input v-model="form.remark" type="textarea" :rows="2" maxlength="500" show-word-limit placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -220,67 +140,38 @@
</template>
<script>
import { listPlan, getPlan, delPlan, addPlan, updatePlan } from "@/api/train/plan"
import { addPlan, completePlan, getPlan, listPlan, updatePlan } from '@/api/train/plan'
export default {
name: "Plan",
name: 'Plan',
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 开班计划表格数据
planList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
startTimeRange: [],
title: '',
open: false,
// 查询参数
statusOptions: [
{ value: 0, label: '未开始' },
{ value: 1, label: '进行中' },
{ value: 2, label: '已结束' },
{ value: 3, label: '已取消' }
],
queryParams: {
pageNum: 1,
pageSize: 10,
planName: null,
cId: null,
startTime: null,
endTime: null,
trainAddress: null,
tId: null,
recruitNum: null,
applyCondition: null,
planStatus: null,
createUser: null,
planStatus: null
},
// 表单参数
form: {},
// 表单校验
rules: {
planName: [
{ required: true, message: "开班名称不能为空", trigger: "blur" }
],
cId: [
{ required: true, message: "所属课程编号,关联train_course.c_id不能为空", trigger: "blur" }
],
startTime: [
{ required: true, message: "开班时间不能为空", trigger: "blur" }
],
endTime: [
{ required: true, message: "结束时间不能为空", trigger: "blur" }
],
tId: [
{ required: true, message: "授课教师工号,关联train_teacher.t_id不能为空", trigger: "blur" }
],
createUser: [
{ required: true, message: "创建管理员账号不能为空", trigger: "blur" }
],
planName: [{ required: true, message: '培训班名称不能为空', trigger: 'blur' }],
startTime: [{ required: true, message: '开班时间不能为空', trigger: 'change' }],
endTime: [{ required: true, message: '结束时间不能为空', trigger: 'change' }],
reportDeadline: [{ required: true, message: '报到截止时间不能为空', trigger: 'change' }],
recruitNum: [{ required: true, message: '计划人数不能为空', trigger: 'change' }]
}
}
},
@@ -288,107 +179,110 @@ export default {
this.getList()
},
methods: {
/** 查询开班计划列表 */
getList() {
this.loading = true
listPlan(this.queryParams).then(response => {
const query = { ...this.queryParams }
if (this.startTimeRange && this.startTimeRange.length === 2) {
query.startTimeBegin = this.startTimeRange[0]
query.startTimeEnd = this.startTimeRange[1]
}
listPlan(query).then(response => {
this.planList = response.rows
this.total = response.total
}).finally(() => {
this.loading = false
})
},
// 取消按钮
statusLabel(status) {
const option = this.statusOptions.find(item => item.value === status)
return option ? option.label : '未知'
},
statusTagType(status) {
return { 0: 'info', 1: 'primary', 2: 'success', 3: 'danger' }[status] || 'info'
},
isLocked(status) {
return status === 2 || status === 3
},
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
planId: null,
planName: null,
cId: null,
startTime: null,
endTime: null,
reportDeadline: null,
trainAddress: null,
tId: null,
recruitNum: null,
recruitNum: 1,
applyCondition: null,
planStatus: null,
createUser: null,
createTime: null,
updateTime: null,
remark: null
}
this.resetForm("form")
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.startTimeRange = []
this.resetForm('queryForm')
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.planId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加开班计划"
this.title = '创建培训计划'
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const planId = row.planId || this.ids
getPlan(planId).then(response => {
getPlan(row.planId).then(response => {
this.form = response.data
this.open = true
this.title = "修改开班计划"
this.title = '编辑培训计划'
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.planId != null) {
updatePlan(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addPlan(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
this.$refs.form.validate(valid => {
if (!valid) return
if (this.form.startTime >= this.form.endTime) {
this.$modal.msgError('结束时间必须晚于开班时间')
return
}
if (this.form.reportDeadline > this.form.startTime) {
this.$modal.msgError('报到截止时间不得晚于开班时间')
return
}
const request = this.form.planId
? updatePlan(this.form.planId, this.planPayload())
: addPlan(this.planPayload())
request.then(() => {
this.$modal.msgSuccess(this.form.planId ? '修改成功' : '创建成功')
this.open = false
this.getList()
})
})
},
/** 删除按钮操作 */
handleDelete(row) {
const planIds = row.planId || this.ids
this.$modal.confirm('是否确认删除开班计划编号为"' + planIds + '"的数据项?').then(function() {
return delPlan(planIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
planPayload() {
return {
planName: this.form.planName,
startTime: this.form.startTime,
endTime: this.form.endTime,
reportDeadline: this.form.reportDeadline,
trainAddress: this.form.trainAddress,
recruitNum: this.form.recruitNum,
applyCondition: this.form.applyCondition,
remark: this.form.remark
}
},
/** 导出按钮操作 */
handleExport() {
this.download('train/plan/export', {
...this.queryParams
}, `plan_${new Date().getTime()}.xlsx`)
handleComplete(row) {
this.$modal.confirm('结束计划后将锁定计划信息并保留全部历史记录,是否继续?').then(() => {
return completePlan(row.planId)
}).then(() => {
this.$modal.msgSuccess('计划已结束')
this.getList()
}).catch(() => {})
}
}
}