forked from liweijie/education
Compare commits
44 Commits
14d4fa7c7c
...
215a48446d
| Author | SHA1 | Date | |
|---|---|---|---|
| 215a48446d | |||
| 3ac8c9496e | |||
| a5cd5eab44 | |||
| 5e3217dc8f | |||
| ee25e06680 | |||
| 137528beb2 | |||
| a29c357ed2 | |||
| c2098878b1 | |||
| 08b1ea4606 | |||
| 43f1aab297 | |||
| 71257bdce0 | |||
| 526b9082df | |||
| 499518a2a6 | |||
| 18bbfd71ba | |||
| ec448a1977 | |||
| 0a25dac2c1 | |||
| a8aba532e2 | |||
| 8bf726a745 | |||
| 26fe8ea334 | |||
| 5fb95ae476 | |||
| 2d3150c566 | |||
| 0c3de2809e | |||
| 24ca73ffa5 | |||
| 24907a7621 | |||
| 4b952280b3 | |||
| 12214a326f | |||
| c7f334ed53 | |||
| 088a35c9e8 | |||
| 18f1faba5f | |||
| 0ea410ffec | |||
| 29387b3193 | |||
| 001a264f16 | |||
| 1abadfb3ff | |||
| cc623d5fdb | |||
| 370cb615d0 | |||
| 97562579dc | |||
| 7a453e4ac3 | |||
| a4b3c241a2 | |||
| fe008ce383 | |||
| 657774e1b1 | |||
| 4efb84e5d2 | |||
| 776ffaac4f | |||
| 8a8aa0c7ca | |||
| 61ef0c1214 |
+2
-11
@@ -1,20 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<router-view />
|
<router-view />
|
||||||
<theme-picker />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ThemePicker from "@/components/ThemePicker"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App"
|
||||||
components: { ThemePicker }
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
|
||||||
#app .theme-picker {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 课时补助核算:课时统计 / 课时费统计 ========================
|
||||||
|
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks;返回行为 HourStatisticsVO。
|
||||||
|
|
||||||
|
// 分页查询课时统计(支持 nd 年度、xq 学期序号、jyxm 教员姓名)
|
||||||
|
export function listHourStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/hour-stat/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出课时统计 Excel(返回 Blob,文件名 课时统计.xlsx)
|
||||||
|
export function exportHourStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/hour-stat/export',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页查询课时费统计(支持 nd、xq、jyxm、ksfbzbh 课时费标准编号)
|
||||||
|
export function listFeeStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-stat/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出课时费统计 Excel(返回 Blob,文件名 课时费统计.xlsx)
|
||||||
|
export function exportFeeStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-stat/export',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 联教联训管理(课时补助项目) ========================
|
||||||
|
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks;后端实体为 KSBZXM。
|
||||||
|
|
||||||
|
// 新增联教联训(编号为空时后端自动生成 UUID)
|
||||||
|
export function addJointTraining(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除联教联训
|
||||||
|
export function deleteJointTraining(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改联教联训
|
||||||
|
export function updateJointTraining(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按编号查询联教联训详情
|
||||||
|
export function getJointTraining(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页查询联教联训列表(支持名称模糊)
|
||||||
|
export function listJointTraining(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入联教联训 Excel(multipart,字段名 file)
|
||||||
|
export function importJointTraining(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/import',
|
||||||
|
method: 'post',
|
||||||
|
data: formData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出联教联训到 Excel(返回 Blob)
|
||||||
|
export function exportJointTraining() {
|
||||||
|
return request({
|
||||||
|
url: '/ks/yjlx/export',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 方案管理:课时费方案 / 课时方案 ========================
|
||||||
|
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks。
|
||||||
|
|
||||||
|
// ---------- 课时费方案(KSFBZ) ----------
|
||||||
|
// 分页列表(名称模糊)
|
||||||
|
export function listFeeStandard(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-standard/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
export function getFeeStandard(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-standard/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增(编号为空时后端自动生成 UUID)
|
||||||
|
export function addFeeStandard(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-standard/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑(编号必传)
|
||||||
|
export function updateFeeStandard(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-standard/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
export function deleteFeeStandard(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-standard/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 课时方案(KSXSFA) ----------
|
||||||
|
// 分页列表(名称模糊)
|
||||||
|
export function listCoefficientPlan(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/coefficient-plan/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
export function getCoefficientPlan(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/coefficient-plan/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增(编号为空时后端自动生成 UUID)
|
||||||
|
export function addCoefficientPlan(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/coefficient-plan/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑(编号必传)
|
||||||
|
export function updateCoefficientPlan(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/coefficient-plan/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
+39
-43
@@ -1,10 +1,9 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// ======================== 教学日志核心 ========================
|
// ======================== 教学日志核心(以 api.txt 为准) ========================
|
||||||
// 说明:以下接口均已与实际运行的后端 LogController 逐一核对(前缀 /log,
|
// 接口前缀 /log,经 vue.config.js 代理转发为 /api/log(axios baseURL 为 /api)。
|
||||||
// 经 vue.config.js 代理转发为 /api/log)。axios baseURL 为 /api(.env.development)。
|
|
||||||
|
|
||||||
// 分页条件查询教学日志列表(待上报 / 待审核视图)
|
// 分页条件查询教学日志列表(待上报视图)
|
||||||
// 支持参数:pageNum pageSize ksrq jsrq kcmc jys jxff skjy rzzt pxqb gdqk gdxxqk rwlb
|
// 支持参数:pageNum pageSize ksrq jsrq kcmc jys jxff skjy rzzt pxqb gdqk gdxxqk rwlb
|
||||||
export function getTeachingLogList(query) {
|
export function getTeachingLogList(query) {
|
||||||
return request({
|
return request({
|
||||||
@@ -32,7 +31,7 @@ export function getAuditedTeachingLogList(query) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增教学日志
|
// 新增教学日志(请求体为 SSKCB_RZ 实体)
|
||||||
export function addTeachingLog(data) {
|
export function addTeachingLog(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/log/teaching-log/add',
|
url: '/log/teaching-log/add',
|
||||||
@@ -41,21 +40,39 @@ export function addTeachingLog(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量上报教学日志(入参为 bh 编号数组,Content-Type: application/json)
|
// 编辑教学日志(请求体为 SSKCB_RZ 实体,bh 必传)
|
||||||
export function batchReportTeachingLog(bhList) {
|
export function updateTeachingLog(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/log/teaching-log/batch-report',
|
url: '/log/teaching-log/update',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: bhList
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量审核教学日志(入参为 bh 编号数组)
|
// 根据编号查询教学日志详情
|
||||||
export function batchAuditTeachingLog(bhList) {
|
export function getTeachingLogByBh(bh) {
|
||||||
return request({
|
return request({
|
||||||
url: '/log/teaching-log/batch-audit',
|
url: '/log/teaching-log/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交教学日志审核,接口形态:POST /log/teaching-log/submit?bh=&targetStatus=
|
||||||
|
export function submitTeachingLog(bh, targetStatus) {
|
||||||
|
return request({
|
||||||
|
url: '/log/teaching-log/submit',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: bhList
|
params: { bh: bh, targetStatus: targetStatus }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核通过教学日志,接口形态:GET /log/teaching-log/approve?bh=&feedback=
|
||||||
|
export function approveTeachingLog(bh, feedback) {
|
||||||
|
return request({
|
||||||
|
url: '/log/teaching-log/approve',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh, feedback: feedback }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +85,15 @@ export function rejectTeachingLog(bh, thyj) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据课表自动创建教学日志,接口形态:POST /log/teaching-log/auto-create?tybh=
|
||||||
|
export function autoCreateTeachingLog(tybh) {
|
||||||
|
return request({
|
||||||
|
url: '/log/teaching-log/auto-create',
|
||||||
|
method: 'post',
|
||||||
|
params: { tybh: tybh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 批量导入教学日志 Excel,接口形态:POST /log/teaching-log/import-excel(multipart,字段名 file)
|
// 批量导入教学日志 Excel,接口形态:POST /log/teaching-log/import-excel(multipart,字段名 file)
|
||||||
export function importTeachingLogExcel(file) {
|
export function importTeachingLogExcel(file) {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
@@ -97,33 +123,3 @@ export function downloadTeachingLogTemplate() {
|
|||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== TODO:后端暂未提供,保留占位待接 ========================
|
|
||||||
|
|
||||||
// TODO(后端缺接口):批量删除教学日志 —— 当前后端 LogController 无 delete 接口,
|
|
||||||
// 待后端提供后确认入参与请求方式。
|
|
||||||
export function deleteTeachingLog(bhList) {
|
|
||||||
return request({
|
|
||||||
url: '/log/teaching-log/delete',
|
|
||||||
method: 'post',
|
|
||||||
data: bhList
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(后端缺接口):重新检查通报变更情况 —— 当前后端无 recheck 接口,待后端提供后确认。
|
|
||||||
export function recheckTeachingLog() {
|
|
||||||
return request({
|
|
||||||
url: '/log/teaching-log/recheck',
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(后端缺接口):根据编号查询教学日志详情 —— 当前后端无 teaching-log/get 接口。
|
|
||||||
// 列表接口已含完整字段,组件以行数据兜底展示;待后端提供 get 接口后再联调。
|
|
||||||
export function getTeachingLogByBh(bh) {
|
|
||||||
return request({
|
|
||||||
url: '/log/teaching-log/get',
|
|
||||||
method: 'get',
|
|
||||||
params: { bh: bh }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 教学实施计划导入 ========================
|
||||||
|
// 接口前缀 /teachingPlan,经 vue.config.js 代理转发为 /api/teachingPlan。
|
||||||
|
|
||||||
|
// 分页查询教学实施计划列表
|
||||||
|
// 支持参数:pageNum pageSize nd kcmc bc zrdw skjy ytgjc ybdr(与后端 Mapper 一致)
|
||||||
|
export function listTeachingPlan(query) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingPlan/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入教学实施计划 Excel(multipart,字段名 file),返回导入条数
|
||||||
|
export function importTeachingPlan(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
return request({
|
||||||
|
url: '/teachingPlan/import',
|
||||||
|
method: 'post',
|
||||||
|
data: formData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载教学实施计划导入模板(返回 Blob)
|
||||||
|
export function downloadTeachingPlanTemplate() {
|
||||||
|
return request({
|
||||||
|
url: '/teachingPlan/template',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 学员学籍异动申请(实体 XYXJYDSQB) ========================
|
||||||
|
// 列表查询仅支持 bh / xybh / sqlx / zt 四个等值筛选。
|
||||||
|
|
||||||
|
// 分页查询学籍异动申请列表
|
||||||
|
export function listApplication(query) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/application/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询学籍异动申请详情(bh 异动申请编号)
|
||||||
|
export function getApplication(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/application/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增学籍异动申请(请求体 XYXJYDSQB 实体;bh 需前端传入,创建/修改时间后端自动维护)
|
||||||
|
export function addApplication(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/application/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑学籍异动申请(bh 异动申请编号必传,请求体 XYXJYDSQB 实体)
|
||||||
|
export function updateApplication(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/application/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学籍异动申请(bh 异动申请编号)
|
||||||
|
export function delApplication(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/application/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 班历管理(实体 XYDRWB 学员队任务表) ========================
|
||||||
|
// 接口依据:api2.txt「班次学期日历(班历)」分组 + StudentTeamTaskController
|
||||||
|
// 每个班次学期(xydxqbh)下挂若干条课程任务记录:
|
||||||
|
// bh 编号、nd 年度、xydbh 学员队编号、kbh 课编号、xqdc 学期第次、jybh 教员编号、kcxh 课次序号、
|
||||||
|
// jsbh 教室编号、rs 人数、zks 周课时、xs 学时、klx 课类型、jc 简称、ksdd 考试地点、ksbh 考试编号、
|
||||||
|
// jysdh 教研室代号、jysjhjybh 教研室计划教员编号、jysjhbz 教研室计划备注、jhkcxh 计划课次序号、
|
||||||
|
// xhbs 序号标识、xydxqbh 学员队学期编号、bz 备注、xf 学分、cjsj/bdsj/kbbdsj 时间、
|
||||||
|
// ksks 考试课时、bz2 编组、cjfz 成绩分制、bjrxypjf 不计入学员平均分、llxs 理论学时、sjxs 实践学时、
|
||||||
|
// ksksbxs 考试课时不显示、pdxh 配档序号、pdqsz 配档起始周、pdaz 配档按周、pdzzksj 配档占正课时间、
|
||||||
|
// pdbz 配档编组、pdtbykxxbz 配当同班异课选修编组、pdzdyxsfbsj 配档自定义学时分布数据、
|
||||||
|
// pdqyzdyxs 配档启用自定义学时
|
||||||
|
|
||||||
|
// 查询某班次学期下的全部班历记录(xydxqbh 学员队学期编号)
|
||||||
|
export function listClassCalendar(xydxqbh) {
|
||||||
|
return request({
|
||||||
|
url: '/classCalendar/all',
|
||||||
|
method: 'get',
|
||||||
|
params: { xydxqbh: xydxqbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据主键查询班历记录
|
||||||
|
export function getClassCalendar(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/classCalendar/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新班历记录(请求体 XYDRWB,bh 必传)
|
||||||
|
export function updateClassCalendar(data) {
|
||||||
|
return request({
|
||||||
|
url: '/classCalendar/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选定区域设置应用于其它班次(请求体 { sourceBhList: 源记录编号, targetBhList: 目标班次学期编号 })
|
||||||
|
export function batchCopyCalendar(data) {
|
||||||
|
return request({
|
||||||
|
url: '/classCalendar/batchCopy',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 整个班历应用于其它班次(请求体 { sourceXydxqbh: 源班次学期编号, targetBhList: 目标班次学期编号 })
|
||||||
|
export function batchCopyCalendarBySemester(data) {
|
||||||
|
return request({
|
||||||
|
url: '/classCalendar/batchCopyBySemester',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 学员队任务表操作(/studentTeamTask) ========================
|
||||||
|
|
||||||
|
// 新增班历记录(请求体 XYDRWB;bh 留空后端生成 UUID)
|
||||||
|
export function addTeamTask(data) {
|
||||||
|
return request({
|
||||||
|
url: '/studentTeamTask/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除班历记录(bh 编号)
|
||||||
|
export function delTeamTask(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/studentTeamTask/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量预设合班(请求体 { bhList },按年度排序生成统一课次序号)
|
||||||
|
export function batchPresetMerge(bhList) {
|
||||||
|
return request({
|
||||||
|
url: '/studentTeamTask/batchPresetMerge',
|
||||||
|
method: 'post',
|
||||||
|
data: { bhList: bhList }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量预设拆班(请求体 { bhList },清空课次序号)
|
||||||
|
export function batchPresetSplit(bhList) {
|
||||||
|
return request({
|
||||||
|
url: '/studentTeamTask/batchPresetSplit',
|
||||||
|
method: 'post',
|
||||||
|
data: { bhList: bhList }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动生成必修课程(按学员队+学期第次从专业教学计划生成班历记录)
|
||||||
|
export function autoGenerateRequiredCourses(xydbh, xqdc) {
|
||||||
|
return request({
|
||||||
|
url: '/studentTeamTask/autoGenerateRequiredCourses',
|
||||||
|
method: 'post',
|
||||||
|
params: { xydbh: xydbh, xqdc: xqdc }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 班次学期管理(实体 XYDNDXQJBXXB 学员队年度学期基本信息表) ========================
|
||||||
|
// 接口依据:api1.txt「班次学期」分组,实际后端位于 StudentRecordsController (/student-records/semester/*)
|
||||||
|
// 列表仅支持 xydbh(学员队编号)模糊筛选,无年度筛选,前端需本地过滤
|
||||||
|
// 新增 bh 留空由后端生成 UUID;字段 nd 年度、xydbh 学员队编号、kxrq 开学日期、jsrq 结束日期、
|
||||||
|
// xqdc 学期第次、zyjsbh 专用教室编号、jxrwbh 教学任务编号、bdsj 变动时间、bz 备注、
|
||||||
|
// xhbs 序号标识、ysbbh 预设编班号、jclb 节次类别、xtms 系统模式、kfjypk 开放教员排课(0/1)、
|
||||||
|
// jsonzd、fxbgscsj 分析报告生成时间、fxbgwd1bh/fxbgwd2bh/fxbgwd3bh 分析报告文档编号
|
||||||
|
|
||||||
|
// 分页查询班次学期列表(支持 xydbh 模糊)
|
||||||
|
export function listSemester(query) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有有效班次学期(DEL_FLAG = 0)
|
||||||
|
export function allSemester() {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/all',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询班次学期详情(bh 编号)
|
||||||
|
export function getSemester(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增班次学期(请求体 XYDNDXQJBXXB;bh 留空后端生成 UUID,delFlag 后端置 0)
|
||||||
|
export function addSemester(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑班次学期(bh 编号必传,请求体 XYDNDXQJBXXB)
|
||||||
|
export function updateSemester(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除班次学期(逻辑删除并级联删除其班历记录)
|
||||||
|
export function delSemester(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量删除班次学期(请求体为编号数组)
|
||||||
|
export function batchDeleteSemester(bhList) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/batchDelete',
|
||||||
|
method: 'post',
|
||||||
|
data: bhList
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量设定学期日期(请求体 { bhList, xqkssj, xqjssj })
|
||||||
|
export function batchUpdateDateRange(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/batchUpdateDateRange',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量修改开放教员排课状态(请求体 { bhList, kfjypk },0-否 1-是)
|
||||||
|
export function batchUpdateKfjypk(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/batchUpdateKfjypk',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量修改学期第次(请求体 { bhList, xqdc })
|
||||||
|
export function batchUpdateXqdc(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/batchUpdateXqdc',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量设置教学任务(请求体 { bhList, jxrwbh })
|
||||||
|
export function batchUpdateJxrwbh(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/batchUpdateJxrwbh',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量创建班次学期(按时间范围筛选可建班的学员队;xqdc 传 春季学期/夏季学期/秋季学期)
|
||||||
|
// 参数:startTime 起始日、endTime 截止日、nd 年度、xqdc 学期
|
||||||
|
export function batchAddFromElective(params) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/semester/batchAddFromElective',
|
||||||
|
method: 'post',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 班次(学员队)管理(实体 XYDB) ========================
|
||||||
|
// 分页列表查询条件为 XYDB 实体字段。
|
||||||
|
|
||||||
|
// 分页查询学员队列表
|
||||||
|
export function listTeam(query) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询学员队详情(xydbh 学员队编号)
|
||||||
|
export function getTeam(xydbh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { xydbh: xydbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增学员队(请求体 XYDB)
|
||||||
|
export function addTeam(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑学员队(xydbh 学员队编号必传,请求体 XYDB)
|
||||||
|
export function updateTeam(data) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学员队(xydbh 学员队编号)
|
||||||
|
export function delTeam(xydbh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { xydbh: xydbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入学员队 Excel(multipart,字段名 file)
|
||||||
|
export function importTeam(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/import',
|
||||||
|
method: 'post',
|
||||||
|
data: formData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出学员队 Excel(查询条件为 XYDB 实体)
|
||||||
|
export function exportTeam(query) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/team/export',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 学员学籍预警结果(实体 XYXJYJGJG,查询:实体类) ========================
|
||||||
|
|
||||||
|
// 分页查询预警结果列表
|
||||||
|
export function listWarningResult(query) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/warning-result/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询预警结果详情(bh 预警结果编号)
|
||||||
|
export function getWarningResult(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/student-records/warning-result/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh: bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 分页查询学科专业列表
|
||||||
|
export function listDiscipline(query) {
|
||||||
|
return request({
|
||||||
|
url: '/discipline/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询学科专业详情
|
||||||
|
export function getDiscipline(bsh) {
|
||||||
|
return request({
|
||||||
|
url: '/discipline/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bsh: bsh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增学科专业
|
||||||
|
export function addDiscipline(data) {
|
||||||
|
return request({
|
||||||
|
url: '/discipline/add',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑学科专业
|
||||||
|
export function updateDiscipline(data) {
|
||||||
|
return request({
|
||||||
|
url: '/discipline/update',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停用学科专业
|
||||||
|
export function disableDiscipline(bsh) {
|
||||||
|
return request({
|
||||||
|
url: '/discipline/disable',
|
||||||
|
method: 'post',
|
||||||
|
params: { bsh: bsh }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 教学场地/教室管理(JSB 教室表 /classroom)
|
||||||
|
// 接口依据:classroom 控制器(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增教室
|
||||||
|
* POST /classroom/add
|
||||||
|
* 请求体(JSB):id/jsbh/jsmc 必填,其余字段可空;ty/xslx 为 Boolean
|
||||||
|
*/
|
||||||
|
export function addClassroom(data) {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除教室(不提供批量删除接口)
|
||||||
|
* POST /classroom/delete
|
||||||
|
* @param id 教室编号(主键,必填)
|
||||||
|
*/
|
||||||
|
export function deleteClassroom(id) {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新教室
|
||||||
|
* POST /classroom/update
|
||||||
|
* 请求体(JSB):id 必传
|
||||||
|
*/
|
||||||
|
export function updateClassroom(data) {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编号查询教室详情
|
||||||
|
* GET /classroom/get
|
||||||
|
* @param id 教室编号
|
||||||
|
*/
|
||||||
|
export function getClassroom(id) {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询教室列表
|
||||||
|
* GET /classroom/list
|
||||||
|
* 查询参数:jsbh(模糊)、jsmc(模糊)、jxldh(等值)、jxcdlx(等值)、ty(等值)、pageNum、pageSize
|
||||||
|
* 返回:PageResult<JSB>(records/total)
|
||||||
|
*/
|
||||||
|
export function listClassroom(params) {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询全部教室
|
||||||
|
* GET /classroom/all
|
||||||
|
* 返回:List<JSB>(无分页)
|
||||||
|
*/
|
||||||
|
export function listAllClassroom() {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/all',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据教学楼代号查询教室
|
||||||
|
* GET /classroom/listByJxldh
|
||||||
|
* @param jxldh 教学楼代号(必填)
|
||||||
|
*/
|
||||||
|
export function listClassroomByJxldh(jxldh) {
|
||||||
|
return request({
|
||||||
|
url: '/classroom/listByJxldh',
|
||||||
|
method: 'get',
|
||||||
|
params: { jxldh }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 课程教学运行管理(CourseRunningController /course-running)
|
||||||
|
// 接口依据:course-running 控制器(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询教学实施计划课次列表
|
||||||
|
* GET /course-running/plan/list
|
||||||
|
* 查询参数(TeachingPlanQueryDTO):
|
||||||
|
* sskcbh 实施_课程编号、nd 年度、jxff 教学方法、
|
||||||
|
* rqStart 日期范围开始、rqEnd 日期范围结束(均传 ISO 格式,如 2026-08-23T00:00:00)、
|
||||||
|
* txzt 填写状态(0-未填写 1-已填写 2-已提交)、pageNum、pageSize
|
||||||
|
* 返回:PageResult<TeachingPlanLessonVO>(records/total)
|
||||||
|
*/
|
||||||
|
export function listTeachingPlan(params) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/plan/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 调课申请管理 /course-running/adjust ====================
|
||||||
|
// 接口依据:CourseRunningController(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询调课申请列表
|
||||||
|
* GET /adjust/list
|
||||||
|
* 查询参数(ScheduleAdjustQueryDTO):sskcbbh 课次编号、sqjybh 申请教员编号、nd 年度、
|
||||||
|
* jyspzzt 教研室审批状态、jyscszt 教研室查收状态、jgspzt 机关审批状态、sczt 删除状态、
|
||||||
|
* cjsjStart/cjsjEnd 申请日期范围(ISO 格式)、pageNum、pageSize
|
||||||
|
* 返回:PageResult<ScheduleAdjustApplyVO>(records/total)
|
||||||
|
*/
|
||||||
|
export function listScheduleAdjust(params) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询可供调课课次
|
||||||
|
* GET /adjust/lessons
|
||||||
|
* 查询参数:nd 学期年度
|
||||||
|
* 返回:List<AdjustableLessonVO>
|
||||||
|
* 注意:后端当前未实现该接口,调用会报错(页面已做兜底提示)
|
||||||
|
*/
|
||||||
|
export function listAdjustableLessons(params) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/lessons',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询调课申请详情
|
||||||
|
* GET /adjust/detail
|
||||||
|
* @param ssdksqbh 调课申请编号
|
||||||
|
* 返回:ScheduleAdjustDetailVO
|
||||||
|
*/
|
||||||
|
export function getScheduleAdjustDetail(ssdksqbh) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/detail',
|
||||||
|
method: 'get',
|
||||||
|
params: { ssdksqbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交调课申请
|
||||||
|
* POST /adjust/submit
|
||||||
|
* 请求体(ScheduleAdjustApplyDTO):sskcbbh 课次编号、sy 调课事由、rq 新日期、jc 新节次、
|
||||||
|
* nd 年度、sqjybh 申请教员编号、jxnr 教学内容、jxyd 教学要点、jxff 教学方法、
|
||||||
|
* jxbzbz 教学保障备注、ycxx 用车信息、bz 备注、roomList/teacherList/teamList/supportList
|
||||||
|
*/
|
||||||
|
export function submitScheduleAdjust(data) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/submit',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教研室审批调课申请
|
||||||
|
* POST /adjust/audit/jys
|
||||||
|
* 请求体(ScheduleAdjustAuditDTO):ssdksqbh、auditRole=jys、spzt(1同意/2发回/3拒绝)、fhyj、sprbh
|
||||||
|
*/
|
||||||
|
export function auditByTeachingOffice(data) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/audit/jys',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教研室查收调课申请
|
||||||
|
* POST /adjust/receive/jys
|
||||||
|
* @param ssdksqbh 调课申请编号
|
||||||
|
* @param csrbh 查收人编号
|
||||||
|
*/
|
||||||
|
export function receiveByTeachingOffice(params) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/receive/jys',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教学系审批调课申请
|
||||||
|
* POST /adjust/audit/jxx
|
||||||
|
* 请求体(ScheduleAdjustAuditDTO):ssdksqbh、auditRole=jxx、spzt、fhyj、sprbh
|
||||||
|
*/
|
||||||
|
export function auditByTeachingDepartment(data) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/audit/jxx',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机关审批调课申请
|
||||||
|
* POST /adjust/audit/jg
|
||||||
|
* 请求体(ScheduleAdjustAuditDTO):ssdksqbh、auditRole=jg、spzt、fhyj、sprbh、jgbh(机关编号必填)
|
||||||
|
*/
|
||||||
|
export function auditByAuthority(data) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/audit/jg',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机关查收调课申请
|
||||||
|
* POST /adjust/receive/jg
|
||||||
|
* @param ssdksqbh 调课申请编号
|
||||||
|
* @param jgbh 机关编号
|
||||||
|
* @param csrbh 查收人编号
|
||||||
|
*/
|
||||||
|
export function receiveByAuthority(params) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/receive/jg',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤销调课申请
|
||||||
|
* DELETE /adjust/cancel
|
||||||
|
* @param ssdksqbh 调课申请编号
|
||||||
|
* @param sqjybh 申请教员编号(权限校验)
|
||||||
|
*/
|
||||||
|
export function cancelScheduleAdjust(params) {
|
||||||
|
return request({
|
||||||
|
url: '/course-running/adjust/cancel',
|
||||||
|
method: 'delete',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -9,6 +9,14 @@ export function listSemester(query) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询所有学期列表(年度下拉数据源,返回全部学期含 nd/dqxq,按年度倒序)
|
||||||
|
export function listAllSemester() {
|
||||||
|
return request({
|
||||||
|
url: '/semester/all',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 根据主键查询学期
|
// 根据主键查询学期
|
||||||
export function getSemester(nd) {
|
export function getSemester(nd) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 学员队任务表(StudentTeamTaskController /studentTeamTask)
|
||||||
|
// 接口依据:studentTeamTask 控制器(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询学员队任务表(按班次/年度)
|
||||||
|
* GET /studentTeamTask/list
|
||||||
|
* 查询参数(XYDRWB 实体字段):xydbh 学员队编号、nd 年度、kcxh 课次序号、jhkcxh 计划课次序号、xs 学时等
|
||||||
|
* 返回:Page<XYDRWB>(records/total)
|
||||||
|
*/
|
||||||
|
export function listStudentTeamTask(params) {
|
||||||
|
return request({
|
||||||
|
url: '/studentTeamTask/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 专业教学计划(教学大纲 ZYJXJHB)
|
||||||
|
// 接口依据:/zyjxjhb/*(前端 baseURL 为 '/api',此处不再加前缀)
|
||||||
|
|
||||||
|
// 新增(bh 留空后端自动生成 UUID,ty 默认 0,qysj 默认当前时间)
|
||||||
|
export function addSyllabus(data) {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除(软删:置 ty=1 并写 tysj)
|
||||||
|
export function deleteSyllabus(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量删除(软删)
|
||||||
|
export function batchDeleteSyllabus(bhList) {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/batchDelete',
|
||||||
|
method: 'post',
|
||||||
|
data: bhList
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新(bh 必传)
|
||||||
|
export function updateSyllabus(data) {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据编号查询
|
||||||
|
export function getSyllabus(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有(返回 List,无分页,前端本地分页)
|
||||||
|
export function listSyllabus() {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/list',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据专业代号和停用标识查询(zydh、ty 均必填,等值匹配)
|
||||||
|
export function listSyllabusByZydhAndTy(zydh, ty) {
|
||||||
|
return request({
|
||||||
|
url: '/zyjxjhb/listByZydhAndTy',
|
||||||
|
method: 'get',
|
||||||
|
params: { zydh, ty }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 教学任务管理(TeachingTaskController /teachingTask)
|
||||||
|
// 接口依据:api.txt「教学任务管理」分组(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
// 实体:JXRW(bh 编号、rwmc 任务名称、nd 年度、zt 状态、
|
||||||
|
// fbsj 发布时间、cjsj 创建时间、jssj 结束时间、jcxqscsj 教材需求生成时间)
|
||||||
|
// 新增时 bh 留空由后端生成(api.txt 新增示例未传 bh),编辑/更新时 bh 必传
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询教学任务列表
|
||||||
|
* GET /teachingTask/list
|
||||||
|
* 查询参数(JXRW):rwmc 任务名称(模糊)、nd 年度(等值)、zt 状态(等值)、
|
||||||
|
* pageNum、pageSize
|
||||||
|
* 返回:PageResult<JXRW>(records/total)
|
||||||
|
*/
|
||||||
|
export function listTeachingTask(params) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingTask/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编号查询教学任务
|
||||||
|
* GET /teachingTask/get?bh=
|
||||||
|
* @param bh 编号
|
||||||
|
* 返回:JXRW
|
||||||
|
*/
|
||||||
|
export function getTeachingTask(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingTask/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增教学任务
|
||||||
|
* POST /teachingTask/add
|
||||||
|
* 请求体(JXRW):rwmc 任务名称(必填)、nd 年度(必填)、zt 状态、fbsj/jssj/jcxqscsj
|
||||||
|
* 说明:bh 不传由后端自动生成;cjsj 创建时间由后端自动维护
|
||||||
|
*/
|
||||||
|
export function addTeachingTask(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingTask/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新教学任务(根据主键)
|
||||||
|
* POST /teachingTask/update
|
||||||
|
* 请求体(JXRW):bh 编号(必填)、rwmc、nd、zt
|
||||||
|
*/
|
||||||
|
export function updateTeachingTask(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingTask/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 级联删除教学任务和教研室任务书
|
||||||
|
* POST /teachingTask/delete?bh=
|
||||||
|
* @param bh 编号
|
||||||
|
*/
|
||||||
|
export function deleteTeachingTask(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingTask/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教学任务发布(需要先填写教研室任务书)
|
||||||
|
* POST /teachingTask/batchPublish?bh=
|
||||||
|
* @param bh 教学任务编号
|
||||||
|
* 返回:更新数量
|
||||||
|
*/
|
||||||
|
export function publishTeachingTask(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingTask/batchPublish',
|
||||||
|
method: 'post',
|
||||||
|
params: { bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 课表(课程表 KCB)管理(KCBController /kcb)
|
||||||
|
// 接口依据:KCBController + KCBServiceImpl
|
||||||
|
// 说明:KCB 实体主键为 bh(编号,IdType.INPUT);新增时后端强制 setBh(UUID) 覆盖、cjsj/bdsj 自动生成;
|
||||||
|
// delete/get/update 中的 URL 参数 kbh 实为 bh(编号)值;list 无分页返回全部记录
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增课程表
|
||||||
|
* POST /kcb/add
|
||||||
|
* body 为 KCB 实体;bh 可留空(后端自动生成 UUID),cjsj/bdsj 后端自动维护
|
||||||
|
*/
|
||||||
|
export function addKcb(data) {
|
||||||
|
return request({
|
||||||
|
url: '/kcb/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除课程表
|
||||||
|
* POST /kcb/delete?kbh= (kbh 实为 bh 编号值)
|
||||||
|
*/
|
||||||
|
export function deleteKcb(kbh) {
|
||||||
|
return request({
|
||||||
|
url: '/kcb/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { kbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除课程表
|
||||||
|
* POST /kcb/batchDelete
|
||||||
|
* body 为 bh(编号)字符串数组
|
||||||
|
*/
|
||||||
|
export function batchDeleteKcb(kbhList) {
|
||||||
|
return request({
|
||||||
|
url: '/kcb/batchDelete',
|
||||||
|
method: 'post',
|
||||||
|
data: kbhList
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新课程表
|
||||||
|
* POST /kcb/update
|
||||||
|
* body 为 KCB 实体,bh 编号必传
|
||||||
|
*/
|
||||||
|
export function updateKcb(data) {
|
||||||
|
return request({
|
||||||
|
url: '/kcb/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编号查询课程表详情
|
||||||
|
* GET /kcb/get?kbh= (kbh 实为 bh 编号值)
|
||||||
|
*/
|
||||||
|
export function getKcb(kbh) {
|
||||||
|
return request({
|
||||||
|
url: '/kcb/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { kbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有课程表数据
|
||||||
|
* GET /kcb/list
|
||||||
|
* 返回 List<KCB>,无分页,页面做本地过滤与本地分页
|
||||||
|
*/
|
||||||
|
export function listKcb() {
|
||||||
|
return request({
|
||||||
|
url: '/kcb/list',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 课表冲突检查:单维度检查(POST /timetable-conflict/check)
|
||||||
|
// body: { nd 年度(必填), dimensionCode 维度编码(必填), writeToDb?(落库), jcpch?(批次号) }
|
||||||
|
// 返回 TimetableConflictCardVO { dimensionCode, title, description, checked, conflictCount }
|
||||||
|
export function checkConflict(data) {
|
||||||
|
return request({
|
||||||
|
url: '/timetable-conflict/check',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 课表冲突检查:执行全部维度检查(POST /timetable-conflict/check-all)
|
||||||
|
// body: { nd 年度(必填), writeToDb? }
|
||||||
|
// 返回 TimetableConflictSummaryVO { nd, cards[], totalConflictCount, fullyChecked }
|
||||||
|
export function checkAllConflict(data) {
|
||||||
|
return request({
|
||||||
|
url: '/timetable-conflict/check-all',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 课表冲突检查:重置检查结果(POST /timetable-conflict/reset)
|
||||||
|
// body: { nd 年度(必填), clearDb? 是否同时清空落库表 }
|
||||||
|
// 返回 TimetableConflictSummaryVO(所有卡片未检查状态)
|
||||||
|
export function resetConflict(data) {
|
||||||
|
return request({
|
||||||
|
url: '/timetable-conflict/reset',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 课表冲突检查:分页查询冲突明细(GET /timetable-conflict/details)
|
||||||
|
// params: { nd 年度(必填), dimensionCode? 维度编码, pageNum?, pageSize?, useDb?, jcpch? }
|
||||||
|
// 返回 PageResult<TimetableConflictDetailVO>
|
||||||
|
export function getConflictDetails(params) {
|
||||||
|
return request({
|
||||||
|
url: '/timetable-conflict/details',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 人才培养方案(专业表 ZYB /training)
|
||||||
|
// 接口依据:TrainingProgramController(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增培养方案(专业)
|
||||||
|
* POST /training/add
|
||||||
|
* 请求体(ZYB):zydh/zymc/zydm/pxcc/pxlx 必填;
|
||||||
|
* 主键 zydh 需手动传入(留空时后端自动生成 UUID,后端同时置 ty=false、qysj=当前时间)
|
||||||
|
*/
|
||||||
|
export function addTraining(data) {
|
||||||
|
return request({
|
||||||
|
url: '/training/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停用(逻辑删除)培养方案
|
||||||
|
* POST /training/disable?zydh=
|
||||||
|
* @param zydh 专业代号(必填)
|
||||||
|
*/
|
||||||
|
export function disableTraining(zydh) {
|
||||||
|
return request({
|
||||||
|
url: '/training/disable',
|
||||||
|
method: 'post',
|
||||||
|
params: { zydh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新培养方案
|
||||||
|
* POST /training/update
|
||||||
|
* 请求体(ZYB):zydh 必传
|
||||||
|
*/
|
||||||
|
export function updateTraining(data) {
|
||||||
|
return request({
|
||||||
|
url: '/training/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据专业代号查询培养方案详情
|
||||||
|
* GET /training/get?zydh=
|
||||||
|
* @param zydh 专业代号
|
||||||
|
*/
|
||||||
|
export function getTraining(zydh) {
|
||||||
|
return request({
|
||||||
|
url: '/training/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { zydh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页条件查询培养方案列表
|
||||||
|
* GET /training/list
|
||||||
|
* 查询参数:zymc(模糊)、zydm(模糊)、pxlx(精确)、pxcc(精确)、pageNum、pageSize
|
||||||
|
* 返回:PageResult<ZYB>(records/total)
|
||||||
|
*/
|
||||||
|
export function listTraining(params) {
|
||||||
|
return request({
|
||||||
|
url: '/training/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 课程科目(课标 KB)管理(JYSController /jys/kb)
|
||||||
|
// 接口依据:JYSController 控制器(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
// 实体 KB 主键为 kbh(课编号);新增时 kbh 留空由后端生成 UUID;xhbs 字段无需传递(后端 NEVER)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增课程科目
|
||||||
|
* POST /jys/kb/add
|
||||||
|
* body 为 KB 实体;kbh 可留空(后端生成 UUID)
|
||||||
|
*/
|
||||||
|
export function addSubject(data) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/kb/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除课程科目
|
||||||
|
* POST /jys/kb/delete?kbh=
|
||||||
|
*/
|
||||||
|
export function deleteSubject(kbh) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/kb/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { kbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑课程科目
|
||||||
|
* POST /jys/kb/update
|
||||||
|
* body 为 KB 实体,kbh 课编号必传
|
||||||
|
*/
|
||||||
|
export function updateSubject(data) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/kb/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询课程科目详情
|
||||||
|
* GET /jys/kb/get?kbh=
|
||||||
|
*/
|
||||||
|
export function getSubject(kbh) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/kb/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { kbh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询课程科目(课标 KB)
|
||||||
|
* GET /jys/kb/list
|
||||||
|
* 查询参数:pageNum、pageSize、kmc 课名称(模糊)、jc 简称(模糊)、kmdm 科目代码(模糊)、
|
||||||
|
* jysdh 教研室代号(等值)、kclx 课程类型、pxlx 培训类型、pxcc 培训层次
|
||||||
|
* 返回:PageResult<KB>(records/total)
|
||||||
|
*/
|
||||||
|
export function listSubject(params) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/kb/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 教员管理:教员(JYB)+ 教员属性(JYSX)
|
||||||
|
// 接口依据:/jys/teacher/*(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询教员列表
|
||||||
|
* GET /jys/teacher/list
|
||||||
|
* 查询参数(JYBMapper.xml 支持):jyxm 模糊、jysdh 等值、zc 模糊、jylb 等值
|
||||||
|
*/
|
||||||
|
export function listTeacher(params) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据教员编号查询教员详情 GET /jys/teacher/get?jybh= */
|
||||||
|
export function getTeacher(jybh) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { jybh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增教员 POST /jys/teacher/add
|
||||||
|
* body 为 AddTeacherDTO:{ teacher: JYB, attributes: JYSX }
|
||||||
|
* lzzt 前端不传,后端自动置 0
|
||||||
|
*/
|
||||||
|
export function addTeacher(data) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新教员基本信息 POST /jys/teacher/update(body 为 JYB,jybh 必传) */
|
||||||
|
export function updateTeacher(data) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 教员离职(逻辑删除)POST /jys/teacher/disable?jybh= */
|
||||||
|
export function disableTeacher(jybh) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/disable',
|
||||||
|
method: 'post',
|
||||||
|
params: { jybh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询教员属性 GET /jys/teacher/attribute/get?jybh= */
|
||||||
|
export function getTeacherAttribute(jybh) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/attribute/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { jybh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新教员属性 POST /jys/teacher/attribute/update(body 为 JYSX,jybh 必传) */
|
||||||
|
export function updateTeacherAttribute(data) {
|
||||||
|
return request({
|
||||||
|
url: '/jys/teacher/attribute/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 教材管理:教材信息(JCXX 实体)
|
||||||
|
// 接口依据 api.txt:/teachingMaterial/*(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教材信息分页查询
|
||||||
|
* GET /teachingMaterial/list
|
||||||
|
* 查询参数(TeachingMaterialMapper.xml 支持):bh/mc/isbn/cbs/zz 模糊,jcfl/jclx 等值,ty 等值
|
||||||
|
*/
|
||||||
|
export function listTeachingMaterial(params) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据编号查询 GET /teachingMaterial/getByBh?bh= */
|
||||||
|
export function getTeachingMaterialByBh(bh) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/getByBh',
|
||||||
|
method: 'get',
|
||||||
|
params: { bh }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据ID查询 GET /teachingMaterial/getById?id= */
|
||||||
|
export function getTeachingMaterialById(id) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/getById',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增教材信息 POST /teachingMaterial/add */
|
||||||
|
export function addTeachingMaterial(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据ID修改 POST /teachingMaterial/update(body 需携带 id) */
|
||||||
|
export function updateTeachingMaterial(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除 POST /teachingMaterial/delete?id= */
|
||||||
|
export function deleteTeachingMaterial(id) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 教材导入模板下载 GET /teachingMaterial/template */
|
||||||
|
export function downloadTeachingMaterialTemplate() {
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/template',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 教材导入 POST /teachingMaterial/import(form-data,字段名 file) */
|
||||||
|
export function importTeachingMaterial(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
return request({
|
||||||
|
url: '/teachingMaterial/import',
|
||||||
|
method: 'post',
|
||||||
|
data: formData,
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 教材库存:库存单(JCKCD)+ 库存明细项(JCKCMXX)
|
||||||
|
// 接口依据 api.txt:/teachingStock/*(前端 baseURL 为 /api,此处不重复 /api 前缀)
|
||||||
|
|
||||||
|
// ==================== 教材库存单(JCKCD) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询库存单
|
||||||
|
* GET /teachingStock/list
|
||||||
|
* 查询参数(TeachingStockMapper.xml 支持):bh/mc 模糊,lb/zb/zt 等值
|
||||||
|
*/
|
||||||
|
export function listTeachingStock(params) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据ID查询库存单 GET /teachingStock/get?id= */
|
||||||
|
export function getTeachingStock(id) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增库存单 POST /teachingStock/add(bh 留空由后端自动生成) */
|
||||||
|
export function addTeachingStock(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改库存单 POST /teachingStock/update(body 需携带 id) */
|
||||||
|
export function updateTeachingStock(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除库存单 POST /teachingStock/delete?id= */
|
||||||
|
export function deleteTeachingStock(id) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 教材库存明细项(JCKCMXX) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询库存明细项
|
||||||
|
* GET /teachingStock/detail/list
|
||||||
|
* 查询参数(TeachingStockDetailMapper.xml 支持):bh 模糊,jckcdbbh 等值,jcxxbh 模糊,hwbw 等值
|
||||||
|
*/
|
||||||
|
export function listTeachingStockDetail(params) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/detail/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据ID查询库存明细项 GET /teachingStock/detail/get?id= */
|
||||||
|
export function getTeachingStockDetail(id) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/detail/get',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增库存明细项 POST /teachingStock/detail/add(bh 留空由后端自动生成) */
|
||||||
|
export function addTeachingStockDetail(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/detail/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改库存明细项 POST /teachingStock/detail/update(body 需携带 id) */
|
||||||
|
export function updateTeachingStockDetail(data) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/detail/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除库存明细项 POST /teachingStock/detail/delete?id= */
|
||||||
|
export function deleteTeachingStockDetail(id) {
|
||||||
|
return request({
|
||||||
|
url: '/teachingStock/detail/delete',
|
||||||
|
method: 'post',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
@import './variables.scss';
|
@import './variables.scss';
|
||||||
@import './mixin.scss';
|
@import './mixin.scss';
|
||||||
@import './transition.scss';
|
@import './transition.scss';
|
||||||
@import './element-ui.scss';
|
@import './element-ui.scss';
|
||||||
@@ -41,6 +41,60 @@ html {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================= 全局自适应加固 =================
|
||||||
|
与 src/utils/adaptive.js 的视口等比缩放配合,
|
||||||
|
兜底避免极端情况下出现页面级横向溢出与内容崩塌。 */
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
/* 禁止页面级横向滚动,防止因个别固定宽度元素把整页撑破;
|
||||||
|
表格自身的横向滚动由 el-table 内部滚动容器承担,不受影响 */
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹性布局子项允许收缩,避免 flex 容器被子项固有宽度撑破 */
|
||||||
|
#app,
|
||||||
|
.app-wrapper,
|
||||||
|
.main-container,
|
||||||
|
.lower-container {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Element 浮层逆缩放(配合 adaptive.js) =====
|
||||||
|
挂到 body 的浮层(下拉/气泡/日期/对话框/消息等)基于 getBoundingClientRect 定位,
|
||||||
|
该值受 html 的 zoom 缩放影响;若浮层自身也继承同一 zoom,坐标会被“重复缩放”而错位。
|
||||||
|
这里用 adaptive.js 注入的 --adaptive-scale-inv(= 1/当前缩放倍数)把这些浮层还原为 1:1,
|
||||||
|
使其与触发元素在视觉坐标上正确对齐。缩放=1 时该变量为 1,不产生任何影响。 */
|
||||||
|
:root {
|
||||||
|
--adaptive-scale: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-popper,
|
||||||
|
.el-select-dropdown,
|
||||||
|
.el-dropdown-menu,
|
||||||
|
.el-picker-panel,
|
||||||
|
.el-cascader__dropdown,
|
||||||
|
.el-message-box__wrapper,
|
||||||
|
.el-dialog__wrapper,
|
||||||
|
.el-message,
|
||||||
|
.el-notification,
|
||||||
|
.el-loading-mask,
|
||||||
|
.v-modal {
|
||||||
|
zoom: var(--adaptive-scale-inv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 通用长文本换行,避免 url/数字/英文长串将布局撑破 */
|
||||||
|
a,
|
||||||
|
.el-button,
|
||||||
|
.el-table .cell,
|
||||||
|
.el-form-item__content,
|
||||||
|
.el-form-item__label {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
*,
|
*,
|
||||||
*:before,
|
*:before,
|
||||||
*:after {
|
*:after {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* 通用css样式布局处理
|
* 通用css样式布局处理
|
||||||
* Copyright (c) 2019 roomroot
|
* Copyright (c) 2019 roomroot
|
||||||
*/
|
*/
|
||||||
@@ -93,6 +93,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-table {
|
.el-table {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||||
th {
|
th {
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
@@ -108,6 +113,20 @@
|
|||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 表格横向拖拽滚动:拖拽过程中保持默认光标,不显示“抓手”,避免干扰操作手感
|
||||||
|
.el-table__body-wrapper.is-dragging,
|
||||||
|
.el-table__fixed-body-wrapper.is-dragging {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 原生表格同样禁止选中文本,避免横向滑动/滚动时误触发复制前的文本选中 */
|
||||||
|
table {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 表单布局 **/
|
/** 表单布局 **/
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* 通用css样式布局处理
|
* 通用css样式布局处理
|
||||||
* Copyright (c) 2019 roomroot
|
* Copyright (c) 2019 roomroot
|
||||||
*/
|
*/
|
||||||
@@ -93,13 +93,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-table {
|
.el-table {
|
||||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
th {
|
||||||
th {
|
word-break: break-word;
|
||||||
word-break: break-word;
|
background-color: #f8f8f9;
|
||||||
background-color: #f8f8f9;
|
color: #515a6e;
|
||||||
color: #515a6e;
|
height: 40px;
|
||||||
height: 40px;
|
font-size: 13px;
|
||||||
font-size: 13px;
|
text-align: center;
|
||||||
|
|
||||||
|
.cell {
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,9 +92,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
routes() {
|
routes() {
|
||||||
return this.$store.getters.defaultRoutes
|
return this.$store.getters.defaultRoutes
|
||||||
}
|
}
|
||||||
@@ -213,7 +210,7 @@ export default {
|
|||||||
activeStyle(index) {
|
activeStyle(index) {
|
||||||
if (index !== this.activeIndex) return {}
|
if (index !== this.activeIndex) return {}
|
||||||
return {
|
return {
|
||||||
'background-color': this.theme,
|
'background-color': '#00875A',
|
||||||
'color': '#fff'
|
'color': '#fff'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-color-picker
|
|
||||||
v-model="theme"
|
|
||||||
:predefine="['#00875A', '#006B47', '#007F4F', '#11a983', '#13c2c2', '#6959CD', '#f5222d', '#212121', ]"
|
|
||||||
class="theme-picker"
|
|
||||||
popper-class="theme-picker-dropdown"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const ORIGINAL_THEME = '#00875A' // default color
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chalk: '', // content of theme-chalk css
|
|
||||||
theme: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
defaultTheme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
defaultTheme: {
|
|
||||||
handler: function(val, oldVal) {
|
|
||||||
this.theme = val
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
},
|
|
||||||
async theme(val) {
|
|
||||||
await this.setTheme(val)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (this.defaultTheme !== ORIGINAL_THEME) {
|
|
||||||
this.setTheme(this.defaultTheme)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async setTheme(val) {
|
|
||||||
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
|
|
||||||
if (typeof val !== 'string') return
|
|
||||||
const themeCluster = this.getThemeCluster(val.replace('#', ''))
|
|
||||||
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
|
|
||||||
|
|
||||||
const getHandler = (variable, id) => {
|
|
||||||
return () => {
|
|
||||||
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
|
|
||||||
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
|
|
||||||
|
|
||||||
let styleTag = document.getElementById(id)
|
|
||||||
if (!styleTag) {
|
|
||||||
styleTag = document.createElement('style')
|
|
||||||
styleTag.setAttribute('id', id)
|
|
||||||
document.head.appendChild(styleTag)
|
|
||||||
}
|
|
||||||
styleTag.innerText = newStyle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.chalk) {
|
|
||||||
const url = `/styles/theme-chalk/index.css`
|
|
||||||
await this.getCSSString(url, 'chalk')
|
|
||||||
}
|
|
||||||
|
|
||||||
const chalkHandler = getHandler('chalk', 'chalk-style')
|
|
||||||
chalkHandler()
|
|
||||||
|
|
||||||
const styles = [].slice.call(document.querySelectorAll('style'))
|
|
||||||
.filter(style => {
|
|
||||||
const text = style.innerText
|
|
||||||
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
|
|
||||||
})
|
|
||||||
styles.forEach(style => {
|
|
||||||
const { innerText } = style
|
|
||||||
if (typeof innerText !== 'string') return
|
|
||||||
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$emit('change', val)
|
|
||||||
},
|
|
||||||
|
|
||||||
updateStyle(style, oldCluster, newCluster) {
|
|
||||||
let newStyle = style
|
|
||||||
oldCluster.forEach((color, index) => {
|
|
||||||
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
|
|
||||||
})
|
|
||||||
return newStyle
|
|
||||||
},
|
|
||||||
|
|
||||||
getCSSString(url, variable) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const xhr = new XMLHttpRequest()
|
|
||||||
xhr.onreadystatechange = () => {
|
|
||||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
||||||
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xhr.open('GET', url)
|
|
||||||
xhr.send()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
getThemeCluster(theme) {
|
|
||||||
const tintColor = (color, tint) => {
|
|
||||||
let red = parseInt(color.slice(0, 2), 16)
|
|
||||||
let green = parseInt(color.slice(2, 4), 16)
|
|
||||||
let blue = parseInt(color.slice(4, 6), 16)
|
|
||||||
|
|
||||||
if (tint === 0) { // when primary color is in its rgb space
|
|
||||||
return [red, green, blue].join(',')
|
|
||||||
} else {
|
|
||||||
red += Math.round(tint * (255 - red))
|
|
||||||
green += Math.round(tint * (255 - green))
|
|
||||||
blue += Math.round(tint * (255 - blue))
|
|
||||||
|
|
||||||
red = red.toString(16)
|
|
||||||
green = green.toString(16)
|
|
||||||
blue = blue.toString(16)
|
|
||||||
|
|
||||||
return `#${red}${green}${blue}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const shadeColor = (color, shade) => {
|
|
||||||
let red = parseInt(color.slice(0, 2), 16)
|
|
||||||
let green = parseInt(color.slice(2, 4), 16)
|
|
||||||
let blue = parseInt(color.slice(4, 6), 16)
|
|
||||||
|
|
||||||
red = Math.round((1 - shade) * red)
|
|
||||||
green = Math.round((1 - shade) * green)
|
|
||||||
blue = Math.round((1 - shade) * blue)
|
|
||||||
|
|
||||||
red = red.toString(16)
|
|
||||||
green = green.toString(16)
|
|
||||||
blue = blue.toString(16)
|
|
||||||
|
|
||||||
return `#${red}${green}${blue}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const clusters = [theme]
|
|
||||||
for (let i = 0; i <= 9; i++) {
|
|
||||||
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
|
|
||||||
}
|
|
||||||
clusters.push(shadeColor(theme, 0.1))
|
|
||||||
return clusters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.theme-message,
|
|
||||||
.theme-picker-dropdown {
|
|
||||||
z-index: 99999 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-picker .el-color-picker__trigger {
|
|
||||||
height: 26px !important;
|
|
||||||
width: 26px !important;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-picker-dropdown .el-color-dropdown__link-btn {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import hasRole from './permission/hasRole'
|
import hasRole from './permission/hasRole'
|
||||||
import hasPermi from './permission/hasPermi'
|
import hasPermi from './permission/hasPermi'
|
||||||
import dialogDrag from './dialog/drag'
|
import dialogDrag from './dialog/drag'
|
||||||
import dialogDragWidth from './dialog/dragWidth'
|
import dialogDragWidth from './dialog/dragWidth'
|
||||||
import dialogDragHeight from './dialog/dragHeight'
|
import dialogDragHeight from './dialog/dragHeight'
|
||||||
import clipboard from './module/clipboard'
|
import clipboard from './module/clipboard'
|
||||||
|
import tableDrag from './tableDrag'
|
||||||
|
|
||||||
const install = function(Vue) {
|
const install = function(Vue) {
|
||||||
Vue.directive('hasRole', hasRole)
|
Vue.directive('hasRole', hasRole)
|
||||||
@@ -12,6 +13,8 @@ const install = function(Vue) {
|
|||||||
Vue.directive('dialogDrag', dialogDrag)
|
Vue.directive('dialogDrag', dialogDrag)
|
||||||
Vue.directive('dialogDragWidth', dialogDragWidth)
|
Vue.directive('dialogDragWidth', dialogDragWidth)
|
||||||
Vue.directive('dialogDragHeight', dialogDragHeight)
|
Vue.directive('dialogDragHeight', dialogDragHeight)
|
||||||
|
// 全局表格横向拖拽滚动:通过 document 事件委托自动作用于所有 el-table
|
||||||
|
tableDrag()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.Vue) {
|
if (window.Vue) {
|
||||||
|
|||||||
@@ -6,17 +6,15 @@
|
|||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
<iframe-toggle />
|
<iframe-toggle />
|
||||||
<copyright />
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import copyright from "./Copyright/index"
|
|
||||||
import iframeToggle from "./IframeToggle/index"
|
import iframeToggle from "./IframeToggle/index"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppMain',
|
name: 'AppMain',
|
||||||
components: { iframeToggle, copyright },
|
components: { iframeToggle },
|
||||||
computed: {
|
computed: {
|
||||||
cachedViews() {
|
cachedViews() {
|
||||||
return this.$store.state.tagsView.cachedViews
|
return this.$store.state.tagsView.cachedViews
|
||||||
@@ -64,10 +62,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-main:has(.copyright) {
|
|
||||||
padding-bottom: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hasTagsView {
|
.hasTagsView {
|
||||||
.app-main {
|
.app-main {
|
||||||
/* tags-view 高度 34px,AppMain 在 flex 列中由父容器约束高度 */
|
/* tags-view 高度 34px,AppMain 在 flex 列中由父容器约束高度 */
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
<template>
|
|
||||||
<footer v-if="visible" class="copyright">
|
|
||||||
<span>{{ content }}</span>
|
|
||||||
</footer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
computed: {
|
|
||||||
visible() {
|
|
||||||
return this.$store.state.settings.footerVisible
|
|
||||||
},
|
|
||||||
content() {
|
|
||||||
return this.$store.state.settings.footerContent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.copyright {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 36px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
text-align: right;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
color: #666;
|
|
||||||
font-size: 14px;
|
|
||||||
border-top: 1px solid #e7e7e7;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="navbar" :class="['nav' + navType, { 'header-mode': headerMode }]">
|
<div class="navbar" :class="[{ 'header-mode': headerMode }]">
|
||||||
<hamburger v-if="!headerMode" id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
<hamburger v-if="!headerMode" id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||||
|
|
||||||
<breadcrumb v-if="!headerMode && navType == 1" id="breadcrumb-container" class="breadcrumb-container" />
|
<breadcrumb v-if="!headerMode" id="breadcrumb-container" class="breadcrumb-container" />
|
||||||
<top-nav v-if="!headerMode && navType == 2" id="topmenu-container" class="topmenu-container" />
|
|
||||||
<div class="right-menu">
|
<div class="right-menu">
|
||||||
<template v-if="device!=='mobile'">
|
<template v-if="device!=='mobile'">
|
||||||
<el-tooltip content="菜单搜索" effect="dark" placement="bottom">
|
<el-tooltip content="菜单搜索" effect="dark" placement="bottom">
|
||||||
@@ -34,9 +33,6 @@
|
|||||||
<router-link to="/user/profile">
|
<router-link to="/user/profile">
|
||||||
<el-dropdown-item icon="el-icon-user">个人中心</el-dropdown-item>
|
<el-dropdown-item icon="el-icon-user">个人中心</el-dropdown-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
<el-dropdown-item v-if="setting" icon="el-icon-s-tools" @click.native="setLayout">
|
|
||||||
<span>布局设置</span>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item icon="el-icon-lock" @click.native="lockScreen">
|
<el-dropdown-item icon="el-icon-lock" @click.native="lockScreen">
|
||||||
<span>锁定屏幕</span>
|
<span>锁定屏幕</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
@@ -52,7 +48,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import Breadcrumb from '@/components/Breadcrumb'
|
import Breadcrumb from '@/components/Breadcrumb'
|
||||||
import TopNav from './TopNav'
|
|
||||||
import Hamburger from '@/components/Hamburger'
|
import Hamburger from '@/components/Hamburger'
|
||||||
import Screenfull from '@/components/Screenfull'
|
import Screenfull from '@/components/Screenfull'
|
||||||
import Search from '@/components/HeaderSearch'
|
import Search from '@/components/HeaderSearch'
|
||||||
@@ -61,7 +56,6 @@ import HeaderNotice from './HeaderNotice'
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
TopNav,
|
|
||||||
Hamburger,
|
Hamburger,
|
||||||
Screenfull,
|
Screenfull,
|
||||||
Search,
|
Search,
|
||||||
@@ -85,16 +79,6 @@ export default {
|
|||||||
'nickName',
|
'nickName',
|
||||||
'roles'
|
'roles'
|
||||||
]),
|
]),
|
||||||
setting: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.showSettings
|
|
||||||
}
|
|
||||||
},
|
|
||||||
navType: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.navType
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 用户角色标签:根据 roles 数组智能映射为友好文本
|
// 用户角色标签:根据 roles 数组智能映射为友好文本
|
||||||
userRoleLabel() {
|
userRoleLabel() {
|
||||||
const roleMap = {
|
const roleMap = {
|
||||||
@@ -112,9 +96,6 @@ export default {
|
|||||||
toggleSideBar() {
|
toggleSideBar() {
|
||||||
this.$store.dispatch('app/toggleSideBar')
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
},
|
},
|
||||||
setLayout(event) {
|
|
||||||
this.$emit('setLayout')
|
|
||||||
},
|
|
||||||
handleCommand(command) {
|
handleCommand(command) {
|
||||||
// 预留:下拉菜单 command 事件入口
|
// 预留:下拉菜单 command 事件入口
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,219 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
:visible.sync="visible"
|
|
||||||
direction="rtl"
|
|
||||||
size="280px"
|
|
||||||
:title="'布局设置'"
|
|
||||||
class="drawer-setting"
|
|
||||||
:with-header="false"
|
|
||||||
:modal-append-to-body="false"
|
|
||||||
>
|
|
||||||
<div class="setting-drawer-index">
|
|
||||||
<div class="setting-drawer-index__title">主题色</div>
|
|
||||||
<div class="setting-drawer-index__main-color theme-color">
|
|
||||||
<ul class="ul-color">
|
|
||||||
<li
|
|
||||||
v-for="item in colorList"
|
|
||||||
:key="item.color"
|
|
||||||
class="li-theme"
|
|
||||||
:class="{ active: item.color === theme }"
|
|
||||||
:style="{ background: item.color }"
|
|
||||||
@click="changeTheme(item.color)"
|
|
||||||
>
|
|
||||||
<i v-show="item.color === theme" class="icon-check el-icon-check" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-drawer-index__title">界面功能</div>
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label">侧边栏颜色</span>
|
|
||||||
<el-dropdown trigger="click" @command="handleSideTheme">
|
|
||||||
<span class="setting-item__value">
|
|
||||||
{{ sideThemeLabel }}
|
|
||||||
<i class="el-icon-arrow-down" />
|
|
||||||
</span>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="theme-dark">深色主题</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="theme-light">浅色主题</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label">导航栏模式</span>
|
|
||||||
<el-dropdown trigger="click" @command="handleNavType">
|
|
||||||
<span class="setting-item__value">
|
|
||||||
{{ navTypeLabel }}
|
|
||||||
<i class="el-icon-arrow-down" />
|
|
||||||
</span>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="1">侧边栏模式</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="2">顶部导航模式</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="3">侧栏+顶栏</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label"> TagsView 标签栏</span>
|
|
||||||
<el-switch
|
|
||||||
:value="tagsView"
|
|
||||||
@change="changeSetting({ key: 'tagsView', value: !tagsView })"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label"> 侧边栏 Logo</span>
|
|
||||||
<el-switch
|
|
||||||
:value="sidebarLogo"
|
|
||||||
@change="changeSetting({ key: 'sidebarLogo', value: !sidebarLogo })"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label"> 固定 Header</span>
|
|
||||||
<el-switch
|
|
||||||
:value="fixedHeader"
|
|
||||||
@change="changeSetting({ key: 'fixedHeader', value: !fixedHeader })"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Settings',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
visible: false,
|
|
||||||
/**
|
|
||||||
* 主题色列表
|
|
||||||
*/
|
|
||||||
colorList: [
|
|
||||||
{ color: '#00875A', title: '教育绿' },
|
|
||||||
{ color: '#304156', title: '深蓝' },
|
|
||||||
{ color: '#409EFF', title: '亮蓝' },
|
|
||||||
{ color: '#626AEF', title: '亮紫' },
|
|
||||||
{ color: '#EB2F96', title: '粉红' },
|
|
||||||
{ color: '#F8721F', title: '橙色' },
|
|
||||||
{ color: '#CD201F', title: '红色' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
theme: state => state.settings.theme,
|
|
||||||
sideTheme: state => state.settings.sideTheme,
|
|
||||||
navType: state => state.settings.navType,
|
|
||||||
tagsView: state => state.settings.tagsView,
|
|
||||||
sidebarLogo: state => state.settings.sidebarLogo,
|
|
||||||
fixedHeader: state => state.settings.fixedHeader
|
|
||||||
}),
|
|
||||||
sideThemeLabel() {
|
|
||||||
return this.sideTheme === 'theme-dark' ? '深色主题' : '浅色主题'
|
|
||||||
},
|
|
||||||
navTypeLabel() {
|
|
||||||
const map = { 1: '侧边栏模式', 2: '顶部导航模式', 3: '侧栏+顶栏' }
|
|
||||||
return map[this.navType] || '侧边栏模式'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
openSetting() {
|
|
||||||
this.visible = true
|
|
||||||
},
|
|
||||||
closeSetting() {
|
|
||||||
this.visible = false
|
|
||||||
},
|
|
||||||
// 修改主题色
|
|
||||||
changeTheme(color) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', { key: 'theme', value: color })
|
|
||||||
},
|
|
||||||
handleSideTheme(command) {
|
|
||||||
this.changeSetting({ key: 'sideTheme', value: command })
|
|
||||||
},
|
|
||||||
handleNavType(command) {
|
|
||||||
this.changeSetting({ key: 'navType', value: Number(command) })
|
|
||||||
},
|
|
||||||
// 修改布局设置,并持久化到本地存储
|
|
||||||
changeSetting(data) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', data)
|
|
||||||
const setting = JSON.parse(localStorage.getItem('layout-setting') || '{}')
|
|
||||||
setting[data.key] = data.value
|
|
||||||
localStorage.setItem('layout-setting', JSON.stringify(setting))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.setting-drawer-index {
|
|
||||||
padding: 0 20px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&__title {
|
|
||||||
margin-top: 26px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__main-color {
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-color {
|
|
||||||
.ul-color {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.li-theme {
|
|
||||||
list-style: none;
|
|
||||||
display: inline-block;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
margin-right: 6px;
|
|
||||||
border-radius: 50%;
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
box-shadow: 0 0 0 2px #fff, 0 0 0 4px currentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-check {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #606266;
|
|
||||||
|
|
||||||
&__value {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
padding: 0 12px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-drawer size="280px" :visible="showSettings" :with-header="false" :append-to-body="true" :before-close="closeSetting" :lock-scroll="false">
|
|
||||||
<div class="drawer-container">
|
|
||||||
<div>
|
|
||||||
<div class="setting-drawer-content">
|
|
||||||
<div class="setting-drawer-title">
|
|
||||||
<h3 class="drawer-title">菜单导航设置</h3>
|
|
||||||
</div>
|
|
||||||
<div class="nav-wrap">
|
|
||||||
<el-tooltip content="左侧菜单" placement="bottom">
|
|
||||||
<div class="item left" @click="handleNavType(1)" :style="{'--theme': theme}" :class="{ activeItem: navType == 1 }">
|
|
||||||
<b></b><b></b>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
|
|
||||||
<el-tooltip content="混合菜单" placement="bottom">
|
|
||||||
<div class="item mix" @click="handleNavType(2)" :style="{'--theme': theme}" :class="{ activeItem: navType == 2 }">
|
|
||||||
<b></b><b></b>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="顶部菜单" placement="bottom">
|
|
||||||
<div class="item top" @click="handleNavType(3)" :style="{'--theme': theme}" :class="{ activeItem: navType == 3 }">
|
|
||||||
<b></b><b></b>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-title">
|
|
||||||
<h3 class="drawer-title">主题风格设置</h3>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-block-checbox">
|
|
||||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
|
||||||
<img src="@/assets/images/dark.svg" alt="dark">
|
|
||||||
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
|
||||||
<i aria-label="图标: check" class="anticon anticon-check">
|
|
||||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
|
|
||||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
|
||||||
</svg>
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
|
||||||
<img src="@/assets/images/light.svg" alt="light">
|
|
||||||
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
|
||||||
<i aria-label="图标: check" class="anticon anticon-check">
|
|
||||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
|
|
||||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
|
||||||
</svg>
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>主题颜色</span>
|
|
||||||
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider/>
|
|
||||||
|
|
||||||
<h3 class="drawer-title">系统布局配置</h3>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>开启页签</span>
|
|
||||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>持久化标签页</span>
|
|
||||||
<el-switch v-model="tagsViewPersist" :disabled="!tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>显示页签图标</span>
|
|
||||||
<el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>标签页样式</span>
|
|
||||||
<el-radio-group v-model="tagsViewStyle" :disabled="!tagsView" size="mini" class="drawer-switch">
|
|
||||||
<el-radio-button label="card">卡片</el-radio-button>
|
|
||||||
<el-radio-button label="chrome">谷歌</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>固定 Header</span>
|
|
||||||
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>显示 Logo</span>
|
|
||||||
<el-switch v-model="sidebarLogo" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>动态标题</span>
|
|
||||||
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>底部版权</span>
|
|
||||||
<el-switch v-model="footerVisible" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider/>
|
|
||||||
|
|
||||||
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
|
||||||
<el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ThemePicker from '@/components/ThemePicker'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { ThemePicker },
|
|
||||||
expose: ['openSetting'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
theme: this.$store.state.settings.theme,
|
|
||||||
sideTheme: this.$store.state.settings.sideTheme,
|
|
||||||
navType: this.$store.state.settings.navType,
|
|
||||||
showSettings: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
fixedHeader: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.fixedHeader
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'fixedHeader',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsViewPersist: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsViewPersist
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsViewPersist',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsView: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsView
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsView',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsIcon: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsIcon
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsIcon',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsViewStyle: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsViewStyle
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsViewStyle',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sidebarLogo: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.sidebarLogo
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'sidebarLogo',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dynamicTitle: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.dynamicTitle
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'dynamicTitle',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.$store.dispatch('settings/setTitle', this.$store.state.settings.title)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
footerVisible: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.footerVisible
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'footerVisible',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
navType: {
|
|
||||||
handler(val) {
|
|
||||||
if (val == 1) {
|
|
||||||
this.$store.dispatch("app/toggleSideBarHide", false)
|
|
||||||
}
|
|
||||||
if (val == 2) {
|
|
||||||
}
|
|
||||||
if (val == 3) {
|
|
||||||
this.$store.dispatch("app/toggleSideBarHide", true)
|
|
||||||
}
|
|
||||||
if ([1, 3].includes(val)) {
|
|
||||||
this.$store.commit("SET_SIDEBAR_ROUTERS",this.$store.state.permission.defaultRoutes)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
themeChange(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'theme',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.theme = val
|
|
||||||
},
|
|
||||||
handleTheme(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'sideTheme',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.sideTheme = val
|
|
||||||
},
|
|
||||||
handleNavType(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'navType',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.navType = val
|
|
||||||
},
|
|
||||||
openSetting() {
|
|
||||||
this.showSettings = true
|
|
||||||
},
|
|
||||||
closeSetting(){
|
|
||||||
this.showSettings = false
|
|
||||||
},
|
|
||||||
saveSetting() {
|
|
||||||
this.$modal.loading("正在保存到本地,请稍候...")
|
|
||||||
if (!this.tagsViewPersist) {
|
|
||||||
this.$cache.local.remove('tags-view-visited')
|
|
||||||
}
|
|
||||||
this.$cache.local.set(
|
|
||||||
"layout-setting",
|
|
||||||
`{
|
|
||||||
"navType":${this.navType},
|
|
||||||
"tagsView":${this.tagsView},
|
|
||||||
"tagsIcon":${this.tagsIcon},
|
|
||||||
"tagsViewStyle":"${this.tagsViewStyle}",
|
|
||||||
"tagsViewPersist":${this.tagsViewPersist},
|
|
||||||
"fixedHeader":${this.fixedHeader},
|
|
||||||
"sidebarLogo":${this.sidebarLogo},
|
|
||||||
"dynamicTitle":${this.dynamicTitle},
|
|
||||||
"footerVisible":${this.footerVisible},
|
|
||||||
"sideTheme":"${this.sideTheme}",
|
|
||||||
"theme":"${this.theme}"
|
|
||||||
}`
|
|
||||||
)
|
|
||||||
setTimeout(this.$modal.closeLoading(), 1000)
|
|
||||||
},
|
|
||||||
resetSetting() {
|
|
||||||
this.$modal.loading("正在清除设置缓存并刷新,请稍候...")
|
|
||||||
this.$cache.local.remove('tags-view-visited')
|
|
||||||
this.$cache.local.remove("layout-setting")
|
|
||||||
setTimeout("window.location.reload()", 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.setting-drawer-content {
|
|
||||||
.setting-drawer-title {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
color: rgba(0, 0, 0, .85);
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-drawer-block-checbox {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.setting-drawer-block-checbox-item {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 16px;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-drawer-block-checbox-selectIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-left: 24px;
|
|
||||||
color: #00875A;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-container {
|
|
||||||
padding: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
word-wrap: break-word;
|
|
||||||
|
|
||||||
.drawer-title {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
color: rgba(0, 0, 0, .85);
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-item {
|
|
||||||
color: rgba(0, 0, 0, .65);
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 12px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-switch {
|
|
||||||
float: right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导航模式
|
|
||||||
.nav-wrap {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.activeItem {
|
|
||||||
border: 2px solid #{'var(--theme)'} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 56px;
|
|
||||||
height: 48px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #f0f2f5;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
b:first-child {
|
|
||||||
display: block;
|
|
||||||
height: 30%;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
b:last-child {
|
|
||||||
width: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
border-radius: 4px 0 0 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.mix {
|
|
||||||
b:first-child {
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
display: block;
|
|
||||||
height: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
}
|
|
||||||
b:last-child {
|
|
||||||
width: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
position: absolute;
|
|
||||||
height: 70%;
|
|
||||||
border-radius: 0 0 0 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.top {
|
|
||||||
b:first-child {
|
|
||||||
display: block;
|
|
||||||
height: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['sidebar-theme-wrapper', settings.sideTheme]" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
|
<div :class="['sidebar-theme-wrapper', 'theme-dark']" :style="{ backgroundColor: variables.menuBackground }">
|
||||||
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
<el-scrollbar class="theme-dark" wrap-class="scrollbar-wrapper">
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
:collapse="isCollapse"
|
:collapse="isCollapse"
|
||||||
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
|
:background-color="variables.menuBackground"
|
||||||
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
:text-color="variables.menuColor"
|
||||||
:unique-opened="true"
|
:unique-opened="true"
|
||||||
:active-text-color="settings.sideTheme === 'theme-dark' ? '#ffffff' : settings.theme"
|
:active-text-color="'#ffffff'"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="tags-view-container" class="tags-view-container" :class="{ 'tags-view-container--chrome': tagsViewStyle === 'chrome' }" :style="chromeVars">
|
<div id="tags-view-container" class="tags-view-container">
|
||||||
<!-- 左切换箭头 -->
|
<!-- 左切换箭头 -->
|
||||||
<span class="tags-nav-btn tags-nav-btn--left" :class="{ disabled: !canScrollLeft }" @click="scrollLeft">
|
<span class="tags-nav-btn tags-nav-btn--left" :class="{ disabled: !canScrollLeft }" @click="scrollLeft">
|
||||||
<i class="el-icon-arrow-left" />
|
<i class="el-icon-arrow-left" />
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
v-for="tag in visitedViews"
|
v-for="tag in visitedViews"
|
||||||
ref="tag"
|
ref="tag"
|
||||||
:key="tag.path"
|
:key="tag.path"
|
||||||
:class="{ 'active': isActive(tag), 'has-icon': tagsIcon }"
|
:class="{ 'active': isActive(tag) }"
|
||||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||||
tag="span"
|
tag="span"
|
||||||
class="tags-view-item"
|
class="tags-view-item"
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
@click.middle.native="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
@click.middle.native="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
||||||
@contextmenu.prevent.native="openMenu(tag, $event)"
|
@contextmenu.prevent.native="openMenu(tag, $event)"
|
||||||
>
|
>
|
||||||
<svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon" style="margin-right: 3px;" />
|
|
||||||
{{ tag.title }}
|
{{ tag.title }}
|
||||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -91,26 +90,8 @@ export default {
|
|||||||
routes() {
|
routes() {
|
||||||
return this.$store.state.permission.routes
|
return this.$store.state.permission.routes
|
||||||
},
|
},
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
tagsIcon() {
|
|
||||||
return this.$store.state.settings.tagsIcon
|
|
||||||
},
|
|
||||||
tagsViewStyle() {
|
|
||||||
return this.$store.state.settings.tagsViewStyle
|
|
||||||
},
|
|
||||||
selectedDropdownTag() {
|
selectedDropdownTag() {
|
||||||
return this.visitedViews.find(v => this.isActive(v)) || {}
|
return this.visitedViews.find(v => this.isActive(v)) || {}
|
||||||
},
|
|
||||||
chromeVars() {
|
|
||||||
if (this.tagsViewStyle !== 'chrome') return {}
|
|
||||||
const primary = this.theme || '#00875A'
|
|
||||||
return {
|
|
||||||
'--chrome-tab-active-bg': this.mixHexWithWhite(primary, 0.15),
|
|
||||||
'--chrome-tab-text-active': primary,
|
|
||||||
'--chrome-wing-r': '10px'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -148,24 +129,14 @@ export default {
|
|||||||
this.toggleFullscreen()
|
this.toggleFullscreen()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixHexWithWhite(hex, ratio) {
|
|
||||||
const clean = hex.replace('#', '')
|
|
||||||
const r = parseInt(clean.substring(0, 2), 16)
|
|
||||||
const g = parseInt(clean.substring(2, 4), 16)
|
|
||||||
const b = parseInt(clean.substring(4, 6), 16)
|
|
||||||
const mr = Math.round(r * ratio + 255 * (1 - ratio))
|
|
||||||
const mg = Math.round(g * ratio + 255 * (1 - ratio))
|
|
||||||
const mb = Math.round(b * ratio + 255 * (1 - ratio))
|
|
||||||
return `rgb(${mr}, ${mg}, ${mb})`
|
|
||||||
},
|
|
||||||
isActive(route) {
|
isActive(route) {
|
||||||
return route.path === this.$route.path
|
return route.path === this.$route.path
|
||||||
},
|
},
|
||||||
tagActiveStyle(tag) {
|
tagActiveStyle(tag) {
|
||||||
if (!this.isActive(tag) || this.tagsViewStyle !== 'card') return {}
|
if (!this.isActive(tag)) return {}
|
||||||
return {
|
return {
|
||||||
"background-color": this.theme,
|
"background-color": "#00875A",
|
||||||
"border-color": this.theme
|
"border-color": "#00875A"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isAffix(tag) {
|
isAffix(tag) {
|
||||||
@@ -209,9 +180,6 @@ export default {
|
|||||||
return tags
|
return tags
|
||||||
},
|
},
|
||||||
initTags() {
|
initTags() {
|
||||||
if (this.$store.state.settings.tagsViewPersist) {
|
|
||||||
this.$store.dispatch('tagsView/loadPersistedViews')
|
|
||||||
}
|
|
||||||
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
||||||
for (const tag of affixTags) {
|
for (const tag of affixTags) {
|
||||||
if (tag.name) {
|
if (tag.name) {
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-menu
|
|
||||||
:default-active="activeMenu"
|
|
||||||
mode="horizontal"
|
|
||||||
@select="handleSelect"
|
|
||||||
>
|
|
||||||
<template v-for="(item, index) in topMenus">
|
|
||||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
|
|
||||||
<svg-icon
|
|
||||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
|
||||||
:icon-class="item.meta.icon"/>
|
|
||||||
{{ item.meta.title }}
|
|
||||||
</el-menu-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 顶部菜单超出数量折叠 -->
|
|
||||||
<el-submenu :style="{'--theme': theme}" index="more" :key="visibleNumber" v-if="topMenus.length > visibleNumber">
|
|
||||||
<template slot="title">更多菜单</template>
|
|
||||||
<template v-for="(item, index) in topMenus">
|
|
||||||
<el-menu-item
|
|
||||||
:index="item.path"
|
|
||||||
:key="index"
|
|
||||||
v-if="index >= visibleNumber">
|
|
||||||
<svg-icon
|
|
||||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
|
||||||
:icon-class="item.meta.icon"/>
|
|
||||||
{{ item.meta.title }}
|
|
||||||
</el-menu-item>
|
|
||||||
</template>
|
|
||||||
</el-submenu>
|
|
||||||
</el-menu>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { constantRoutes } from "@/router"
|
|
||||||
import { isHttp } from "@/utils/validate"
|
|
||||||
|
|
||||||
// 隐藏侧边栏路由
|
|
||||||
const hideList = ['/index', '/user/profile']
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 顶部栏初始数
|
|
||||||
visibleNumber: 5,
|
|
||||||
// 当前激活菜单的 index
|
|
||||||
currentIndex: undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
// 顶部显示菜单
|
|
||||||
topMenus() {
|
|
||||||
let topMenus = []
|
|
||||||
this.routers.map((menu) => {
|
|
||||||
if (menu.hidden !== true) {
|
|
||||||
// 兼容顶部栏一级菜单内部跳转
|
|
||||||
if (menu.path === '/' && menu.children) {
|
|
||||||
topMenus.push(menu.children[0])
|
|
||||||
} else {
|
|
||||||
topMenus.push(menu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return topMenus
|
|
||||||
},
|
|
||||||
// 所有的路由信息
|
|
||||||
routers() {
|
|
||||||
return this.$store.state.permission.topbarRouters
|
|
||||||
},
|
|
||||||
// 设置子路由
|
|
||||||
childrenMenus() {
|
|
||||||
var childrenMenus = []
|
|
||||||
this.routers.map((router) => {
|
|
||||||
for (var item in router.children) {
|
|
||||||
if (router.children[item].parentPath === undefined) {
|
|
||||||
if (router.path === "/") {
|
|
||||||
router.children[item].path = "/" + router.children[item].path
|
|
||||||
} else {
|
|
||||||
if (!isHttp(router.children[item].path)) {
|
|
||||||
router.children[item].path = router.path + "/" + router.children[item].path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
router.children[item].parentPath = router.path
|
|
||||||
}
|
|
||||||
childrenMenus.push(router.children[item])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return constantRoutes.concat(childrenMenus)
|
|
||||||
},
|
|
||||||
// 默认激活的菜单
|
|
||||||
activeMenu() {
|
|
||||||
const path = this.$route.path
|
|
||||||
let activePath = path
|
|
||||||
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
|
|
||||||
const tmpPath = path.substring(1, path.length)
|
|
||||||
if (!this.$route.meta.link) {
|
|
||||||
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"))
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false)
|
|
||||||
}
|
|
||||||
} else if (!this.$route.children) {
|
|
||||||
activePath = path
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
|
||||||
}
|
|
||||||
this.activeRoutes(activePath)
|
|
||||||
return activePath
|
|
||||||
},
|
|
||||||
},
|
|
||||||
beforeMount() {
|
|
||||||
window.addEventListener('resize', this.setVisibleNumber)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
window.removeEventListener('resize', this.setVisibleNumber)
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.setVisibleNumber()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 根据宽度计算设置显示栏数
|
|
||||||
setVisibleNumber() {
|
|
||||||
const width = document.body.getBoundingClientRect().width / 3
|
|
||||||
this.visibleNumber = parseInt(width / 85)
|
|
||||||
},
|
|
||||||
// 菜单选择事件
|
|
||||||
handleSelect(key, keyPath) {
|
|
||||||
this.currentIndex = key
|
|
||||||
const route = this.routers.find(item => item.path === key)
|
|
||||||
if (isHttp(key)) {
|
|
||||||
// http(s):// 路径新窗口打开
|
|
||||||
window.open(key, "_blank")
|
|
||||||
} else if (!route || !route.children) {
|
|
||||||
// 没有子路由路径内部打开
|
|
||||||
const routeMenu = this.childrenMenus.find(item => item.path === key)
|
|
||||||
if (routeMenu && routeMenu.query) {
|
|
||||||
let query = JSON.parse(routeMenu.query)
|
|
||||||
this.$router.push({ path: key, query: query })
|
|
||||||
} else {
|
|
||||||
this.$router.push({ path: key })
|
|
||||||
}
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
|
||||||
} else {
|
|
||||||
// 显示左侧联动菜单
|
|
||||||
this.activeRoutes(key)
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 当前激活的路由
|
|
||||||
activeRoutes(key) {
|
|
||||||
var routes = []
|
|
||||||
if (this.childrenMenus && this.childrenMenus.length > 0) {
|
|
||||||
this.childrenMenus.map((item) => {
|
|
||||||
if (key == item.parentPath || (key == "index" && "" == item.path)) {
|
|
||||||
routes.push(item)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (routes.length > 0) {
|
|
||||||
this.$store.commit("SET_SIDEBAR_ROUTERS", routes)
|
|
||||||
} else {
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.topmenu-container.el-menu--horizontal > .el-menu-item {
|
|
||||||
float: left;
|
|
||||||
height: 50px !important;
|
|
||||||
line-height: 50px !important;
|
|
||||||
color: #303133 !important;
|
|
||||||
padding: 0 5px !important;
|
|
||||||
margin: 0 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
|
|
||||||
border-bottom: 2px solid #{'var(--theme)'} !important;
|
|
||||||
color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* submenu item */
|
|
||||||
.topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
|
|
||||||
float: left;
|
|
||||||
height: 50px !important;
|
|
||||||
line-height: 50px !important;
|
|
||||||
color: #303133 !important;
|
|
||||||
padding: 0 5px !important;
|
|
||||||
margin: 0 10px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
export { default as AppMain } from './AppMain'
|
export { default as AppMain } from './AppMain'
|
||||||
export { default as Navbar } from './Navbar'
|
export { default as Navbar } from './Navbar'
|
||||||
export { default as Settings } from './Settings'
|
|
||||||
export { default as Sidebar } from './Sidebar/index.vue'
|
export { default as Sidebar } from './Sidebar/index.vue'
|
||||||
export { default as TagsView } from './TagsView/index.vue'
|
export { default as TagsView } from './TagsView/index.vue'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme, '--current-color-light': theme + '1a', '--current-color-dark-bg': theme + '33'}">
|
<div :class="classObj" class="app-wrapper" :style="{'--current-color': '#00875A', '--current-color-light': '#00875A1a', '--current-color-dark-bg': '#00875A33'}">
|
||||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||||
|
|
||||||
<!-- 顶部全宽 Header -->
|
<!-- 顶部全宽 Header -->
|
||||||
@@ -12,26 +12,25 @@
|
|||||||
class="mobile-hamburger"
|
class="mobile-hamburger"
|
||||||
@toggleClick="toggleSideBar"
|
@toggleClick="toggleSideBar"
|
||||||
/>
|
/>
|
||||||
<span class="sys-title">教学管理信息系统</span>
|
<span class="sys-title" title="关闭所有已打开的页签" @click="handleCloseAllTabs">教学管理信息系统</span>
|
||||||
</div>
|
</div>
|
||||||
<semester-bar class="top-header__center" />
|
<semester-bar class="top-header__center" />
|
||||||
<navbar class="top-header__right" @setLayout="setLayout" :header-mode="true" />
|
<navbar class="top-header__right" :header-mode="true" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 下方:侧边栏 + 主内容 -->
|
<!-- 下方:侧边栏 + 主内容 -->
|
||||||
<div class="lower-container" :class="{sidebarHide:sidebar.hide}">
|
<div class="lower-container" :class="{sidebarHide:sidebar.hide}">
|
||||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
<div :class="{hasTagsView:true,sidebarHide:sidebar.hide}" class="main-container">
|
||||||
<tags-view v-if="needTagsView"/>
|
<tags-view/>
|
||||||
<app-main/>
|
<app-main/>
|
||||||
<settings ref="settingRef"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
import { AppMain, Navbar, Sidebar, TagsView } from './components'
|
||||||
import SemesterBar from './components/SemesterBar'
|
import SemesterBar from './components/SemesterBar'
|
||||||
import Hamburger from '@/components/Hamburger'
|
import Hamburger from '@/components/Hamburger'
|
||||||
import ResizeMixin from './mixin/ResizeHandler'
|
import ResizeMixin from './mixin/ResizeHandler'
|
||||||
@@ -43,7 +42,6 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
AppMain,
|
AppMain,
|
||||||
Navbar,
|
Navbar,
|
||||||
Settings,
|
|
||||||
Sidebar,
|
Sidebar,
|
||||||
TagsView,
|
TagsView,
|
||||||
SemesterBar,
|
SemesterBar,
|
||||||
@@ -52,11 +50,8 @@ export default {
|
|||||||
mixins: [ResizeMixin],
|
mixins: [ResizeMixin],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
theme: state => state.settings.theme,
|
|
||||||
sideTheme: state => state.settings.sideTheme,
|
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device
|
||||||
needTagsView: state => state.settings.tagsView
|
|
||||||
}),
|
}),
|
||||||
classObj() {
|
classObj() {
|
||||||
return {
|
return {
|
||||||
@@ -75,8 +70,15 @@ export default {
|
|||||||
toggleSideBar() {
|
toggleSideBar() {
|
||||||
this.$store.dispatch('app/toggleSideBar')
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
},
|
},
|
||||||
setLayout() {
|
handleCloseAllTabs() {
|
||||||
this.$refs.settingRef.openSetting()
|
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
||||||
|
const last = visitedViews[visitedViews.length - 1]
|
||||||
|
if (last) {
|
||||||
|
this.$router.push(last.fullPath).catch(() => {})
|
||||||
|
} else {
|
||||||
|
this.$router.push('/').catch(() => {})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,6 +139,14 @@ export default {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
letter-spacing: 1.5px;
|
letter-spacing: 1.5px;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
transition: background 0.25s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
@@ -13,6 +13,10 @@ import router from './router'
|
|||||||
import directive from './directive' // directive
|
import directive from './directive' // directive
|
||||||
import plugins from './plugins' // plugins
|
import plugins from './plugins' // plugins
|
||||||
import { download } from '@/utils/request'
|
import { download } from '@/utils/request'
|
||||||
|
import { initAdaptive } from '@/utils/adaptive' // 全局视口等比缩放自适应
|
||||||
|
|
||||||
|
// 初始化全局自适应,保障不同大小屏幕下页面布局不崩塌
|
||||||
|
initAdaptive()
|
||||||
|
|
||||||
import './assets/icons' // icon
|
import './assets/icons' // icon
|
||||||
import './permission' // permission control
|
import './permission' // permission control
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
@@ -18,7 +18,6 @@ const isWhiteList = (path) => {
|
|||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
if (getToken()) {
|
if (getToken()) {
|
||||||
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
|
|
||||||
const isLock = store.getters.isLock
|
const isLock = store.getters.isLock
|
||||||
/* has token*/
|
/* has token*/
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* 网页标题
|
|
||||||
*/
|
|
||||||
title: process.env.VUE_APP_TITLE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
|
||||||
*/
|
|
||||||
sideTheme: 'theme-dark',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统布局配置
|
|
||||||
*/
|
|
||||||
showSettings: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
|
|
||||||
*/
|
|
||||||
navType: 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示 tagsView
|
|
||||||
*/
|
|
||||||
tagsView: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 持久化标签页
|
|
||||||
*/
|
|
||||||
tagsViewPersist: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示页签图标
|
|
||||||
*/
|
|
||||||
tagsIcon: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标签页样式:card 卡片(默认)、chrome 谷歌浏览器风格
|
|
||||||
*/
|
|
||||||
tagsViewStyle: 'card',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否固定头部
|
|
||||||
*/
|
|
||||||
fixedHeader: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示logo
|
|
||||||
*/
|
|
||||||
sidebarLogo: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示动态标题
|
|
||||||
*/
|
|
||||||
dynamicTitle: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示底部版权
|
|
||||||
*/
|
|
||||||
footerVisible: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 底部版权文本内容
|
|
||||||
*/
|
|
||||||
footerContent: 'Copyright © 2018-2026 roomroot. All Rights Reserved.'
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import app from './modules/app'
|
import app from './modules/app'
|
||||||
import lock from './modules/lock'
|
import lock from './modules/lock'
|
||||||
@@ -6,7 +6,6 @@ import dict from './modules/dict'
|
|||||||
import user from './modules/user'
|
import user from './modules/user'
|
||||||
import tagsView from './modules/tagsView'
|
import tagsView from './modules/tagsView'
|
||||||
import permission from './modules/permission'
|
import permission from './modules/permission'
|
||||||
import settings from './modules/settings'
|
|
||||||
import getters from './getters'
|
import getters from './getters'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
@@ -18,8 +17,7 @@ const store = new Vuex.Store({
|
|||||||
dict,
|
dict,
|
||||||
user,
|
user,
|
||||||
tagsView,
|
tagsView,
|
||||||
permission,
|
permission
|
||||||
settings
|
|
||||||
},
|
},
|
||||||
getters
|
getters
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
import defaultSettings from '@/settings'
|
|
||||||
import { useDynamicTitle } from '@/utils/dynamicTitle'
|
|
||||||
|
|
||||||
const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
|
|
||||||
|
|
||||||
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
|
||||||
const state = {
|
|
||||||
title: '',
|
|
||||||
theme: storageSetting.theme || '#00875A',
|
|
||||||
sideTheme: storageSetting.sideTheme || sideTheme,
|
|
||||||
showSettings: showSettings,
|
|
||||||
navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
|
|
||||||
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
|
|
||||||
tagsViewPersist: storageSetting.tagsViewPersist === undefined ? tagsViewPersist : storageSetting.tagsViewPersist,
|
|
||||||
tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
|
|
||||||
tagsViewStyle: storageSetting.tagsViewStyle === undefined ? tagsViewStyle : storageSetting.tagsViewStyle,
|
|
||||||
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
|
|
||||||
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
|
|
||||||
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
|
|
||||||
footerVisible: storageSetting.footerVisible === undefined ? footerVisible : storageSetting.footerVisible,
|
|
||||||
footerContent: footerContent
|
|
||||||
}
|
|
||||||
const mutations = {
|
|
||||||
CHANGE_SETTING: (state, { key, value }) => {
|
|
||||||
if (state.hasOwnProperty(key)) {
|
|
||||||
state[key] = value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
SET_TITLE: (state, title) => {
|
|
||||||
state.title = title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
// 修改布局设置
|
|
||||||
changeSetting({ commit }, data) {
|
|
||||||
commit('CHANGE_SETTING', data)
|
|
||||||
},
|
|
||||||
// 设置网页标题
|
|
||||||
setTitle({ commit }, title) {
|
|
||||||
commit('SET_TITLE', title)
|
|
||||||
useDynamicTitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
mutations,
|
|
||||||
actions
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import store from '@/store'
|
|
||||||
import cache from '@/plugins/cache'
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const PERSIST_KEY = 'tags-view-visited'
|
const PERSIST_KEY = 'tags-view-visited'
|
||||||
|
|
||||||
|
// 布局已固定,不启用标签页持久化
|
||||||
function isPersistEnabled() {
|
function isPersistEnabled() {
|
||||||
return store.state.settings.tagsViewPersist
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveVisitedViews(views) {
|
function saveVisitedViews(views) {
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/**
|
||||||
|
* 全局视口等比缩放 —— 让整个系统在不同大小屏幕(桌面 1280~4K)下布局不崩塌。
|
||||||
|
*
|
||||||
|
* 原理:
|
||||||
|
* 以 DESIGN_WIDTH(1920)为设计基准宽度。将视口宽度与设计宽的比值作为缩放倍数,
|
||||||
|
* 作用到文档根节点 <html> 的 zoom 上:
|
||||||
|
* - 视口 < 设计宽(如 1280):zoom < 1,整体等比缩小,避免窄屏布局被撑破;
|
||||||
|
* - 视口 = 设计宽(1920):zoom = 1,原生 1:1 显示;
|
||||||
|
* - 视口 > 设计宽(如 4K 3840):zoom = 2,整体等比放大,大屏不再留白/字小。
|
||||||
|
* 缩放倍数被限制在 MIN_SCALE ~ MAX_SCALE 之间,MAX_SCALE=2 恰好覆盖 4K(3840/1920)。
|
||||||
|
*
|
||||||
|
* 采用 zoom 挂在 documentElement 上,可覆盖包括 Element UI 挂载到 body 的
|
||||||
|
* 弹窗/提示/下拉选择在内的所有内容,保证整套界面一致缩放、不塌陷。
|
||||||
|
*
|
||||||
|
* 兼容性:
|
||||||
|
* - zoom:Chrome/Edge/Safari/Opera 全系、Firefox 126+(2024-05 起)、
|
||||||
|
* 以及国内常见 Chromium 内核浏览器(360/QQ/微信等)均支持;
|
||||||
|
* - 本方案对不支持 zoom 的旧浏览器(如 2024 前的 Firefox)做能力探测,
|
||||||
|
* 自动降级为 transform: scale() 回退,保证不崩塌、可正常使用。
|
||||||
|
*/
|
||||||
|
|
||||||
|
let initialized = false
|
||||||
|
|
||||||
|
export const DEFAULT_DESIGN_WIDTH = 1920
|
||||||
|
// 最小缩放倍数:极窄视口的安全下限,避免文字过小/布局异常
|
||||||
|
export const MIN_SCALE = 0.5
|
||||||
|
// 最大缩放倍数:2 对应 4K(3840/1920=2),更高分辨率也封顶在此,避免过度放大
|
||||||
|
export const MAX_SCALE = 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 探测当前浏览器是否支持 CSS zoom 属性。
|
||||||
|
* 现代 Chromium/Safari/Firefox(≥126) 返回 true;旧 Firefox(<126) 返回 false。
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isZoomSupported() {
|
||||||
|
const el = document.createElement('div')
|
||||||
|
el.style.zoom = '0.5'
|
||||||
|
// 能读回 "0.5" 说明浏览器真正支持
|
||||||
|
return el.style.zoom === '0.5'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化全局自适应。可在任意入口调用,重复调用幂等。
|
||||||
|
* @param {number} [designWidth] 设计基准宽度,默认 1920
|
||||||
|
*/
|
||||||
|
export function initAdaptive(designWidth = DEFAULT_DESIGN_WIDTH) {
|
||||||
|
if (initialized) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
initialized = true
|
||||||
|
|
||||||
|
const useZoom = isZoomSupported()
|
||||||
|
|
||||||
|
// rAF 帧对齐节流:把同一帧内多次 resize 合并为一次
|
||||||
|
let rafId = null
|
||||||
|
// 真实写入节流 + 尾随兜底:拖拽/设备模拟期间 resize 高频触发,
|
||||||
|
// 若每帧都写 html.zoom 会强制整页重排+重绘导致卡顿,因此限制真实写入频率
|
||||||
|
let lastAppliedScale = -1
|
||||||
|
let lastWriteAt = 0
|
||||||
|
let trailingTimer = null
|
||||||
|
const WRITE_MIN_INTERVAL = 100 // ms
|
||||||
|
|
||||||
|
function computeScale() {
|
||||||
|
const root = document.documentElement
|
||||||
|
const width = window.innerWidth || (root && root.clientWidth) || designWidth
|
||||||
|
const ratio = width / designWidth
|
||||||
|
// 收敛到 [MIN_SCALE, MAX_SCALE],规避极端宽高的异常比例
|
||||||
|
return Math.min(MAX_SCALE, Math.max(MIN_SCALE, ratio))
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeScale(scale) {
|
||||||
|
const root = document.documentElement
|
||||||
|
if (!root) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 值未变化:跳过,避免冗余的样式失效/整页重排
|
||||||
|
if (Math.abs(scale - lastAppliedScale) < 1e-4) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastAppliedScale = scale
|
||||||
|
|
||||||
|
if (scale === 1) {
|
||||||
|
clearScale(root)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useZoom) {
|
||||||
|
// 首选:zoom 参与布局计算,视觉与占位一致,最平滑
|
||||||
|
root.style.zoom = String(scale)
|
||||||
|
// 注入缩放与逆缩放变量:逆缩放用于把挂到 body 的 Element 浮层还原为 1:1,
|
||||||
|
// 以抵消 zoom 对 getBoundingClientRect 坐标造成的二次缩放(否则下拉框位置错乱)
|
||||||
|
root.style.setProperty('--adaptive-scale', String(scale))
|
||||||
|
root.style.setProperty('--adaptive-scale-inv', String(1 / scale))
|
||||||
|
} else {
|
||||||
|
// 回退:transform 仅影响视觉;将布局宽度固定为设计宽并从左上角缩放,
|
||||||
|
// 使其铺满视口且不改变内部结构,旧浏览器也能正常使用
|
||||||
|
root.style.transformOrigin = 'top left'
|
||||||
|
root.style.width = `${designWidth}px`
|
||||||
|
root.style.transform = `scale(${scale})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearScale(root) {
|
||||||
|
if (useZoom) {
|
||||||
|
root.style.zoom = ''
|
||||||
|
root.style.removeProperty('--adaptive-scale')
|
||||||
|
root.style.removeProperty('--adaptive-scale-inv')
|
||||||
|
} else {
|
||||||
|
root.style.transform = ''
|
||||||
|
root.style.transformOrigin = ''
|
||||||
|
root.style.width = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 立即计算并写入一次(带值变化守卫) */
|
||||||
|
function applyNow() {
|
||||||
|
lastWriteAt = Date.now()
|
||||||
|
writeScale(computeScale())
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize() {
|
||||||
|
if (document.hidden) {
|
||||||
|
return // 后台标签不执行,避免无谓开销
|
||||||
|
}
|
||||||
|
if (rafId) {
|
||||||
|
return // 本帧内已有待执行任务,合并
|
||||||
|
}
|
||||||
|
rafId = window.requestAnimationFrame(() => {
|
||||||
|
rafId = null
|
||||||
|
if (document.hidden) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const now = Date.now()
|
||||||
|
if (trailingTimer) {
|
||||||
|
clearTimeout(trailingTimer)
|
||||||
|
}
|
||||||
|
// 距上次真实写入已超过阈值才立即写入,其余情况靠尾随兜底,避免满帧整页重排
|
||||||
|
if (now - lastWriteAt >= WRITE_MIN_INTERVAL) {
|
||||||
|
applyNow()
|
||||||
|
}
|
||||||
|
// 尾随:拖拽/改变尺寸停下后,确保落到最终窗口尺寸
|
||||||
|
trailingTimer = setTimeout(applyNow, WRITE_MIN_INTERVAL)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onVisibilityChange() {
|
||||||
|
if (!document.hidden) {
|
||||||
|
// 从后台切回时补算一次
|
||||||
|
if (trailingTimer) {
|
||||||
|
clearTimeout(trailingTimer)
|
||||||
|
}
|
||||||
|
applyNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首次:渲染前同步应用一次,避免首帧闪烁
|
||||||
|
applyNow()
|
||||||
|
window.addEventListener('resize', onResize)
|
||||||
|
// 从后台标签切回来时,若期间窗口尺寸变化(因 hidden 被跳过)需补算一次
|
||||||
|
document.addEventListener('visibilitychange', onVisibilityChange)
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import store from '@/store'
|
|
||||||
import defaultSettings from '@/settings'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态修改标题
|
|
||||||
*/
|
|
||||||
export function useDynamicTitle() {
|
|
||||||
if (store.state.settings.dynamicTitle) {
|
|
||||||
document.title = store.state.settings.title + ' - ' + defaultSettings.title
|
|
||||||
} else {
|
|
||||||
document.title = defaultSettings.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,881 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="app-container assessment-page">
|
|
||||||
<el-tabs v-model="activeTab" type="border-card" class="assessment-tabs">
|
|
||||||
<!-- ==================== Tab1:课程表信息列表 ==================== -->
|
|
||||||
<el-tab-pane label="课程表信息列表" name="schedule">
|
|
||||||
<!-- 查询条件 -->
|
|
||||||
<el-card shadow="never" class="search-card">
|
|
||||||
<el-form :model="scheduleSearchForm" label-width="130px" class="search-form">
|
|
||||||
<!-- 考核日期:独立整行 -->
|
|
||||||
<el-row :gutter="0">
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.examDateEnabled">考核日期</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<div class="date-block">
|
|
||||||
<div class="date-range">
|
|
||||||
<span>从</span>
|
|
||||||
<el-date-picker
|
|
||||||
v-model="scheduleSearchForm.examDateFrom"
|
|
||||||
type="date"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
:disabled="!scheduleSearchForm.examDateEnabled"
|
|
||||||
/>
|
|
||||||
<span>到</span>
|
|
||||||
<el-date-picker
|
|
||||||
v-model="scheduleSearchForm.examDateTo"
|
|
||||||
type="date"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
:disabled="!scheduleSearchForm.examDateEnabled"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="quick-row">
|
|
||||||
<el-select v-model="scheduleSearchForm.semester" class="quick-select">
|
|
||||||
<el-option v-for="item in semesterOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
<el-button size="small" @click="handleQuickDate('semester')">确定</el-button>
|
|
||||||
<el-select v-model="scheduleSearchForm.week" class="quick-select">
|
|
||||||
<el-option v-for="item in weekOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
<el-button size="small" @click="handleQuickDate('week')">确定</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="0">
|
|
||||||
<!-- 左栏 -->
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.deptEnabled">教研室</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.dept" class="w-full" :disabled="!scheduleSearchForm.deptEnabled">
|
|
||||||
<el-option v-for="item in deptOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.buildingEnabled">教学楼</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.building" class="w-full" :disabled="!scheduleSearchForm.buildingEnabled">
|
|
||||||
<el-option v-for="item in buildingOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="培训层次">
|
|
||||||
<el-select v-model="scheduleSearchForm.trainLevel" placeholder="请选择" clearable class="w-full">
|
|
||||||
<el-option v-for="item in trainLevelOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.deptSystemEnabled">监考教员所属院部系</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.deptSystem" class="w-full" :disabled="!scheduleSearchForm.deptSystemEnabled">
|
|
||||||
<el-option v-for="item in deptOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.resourceTypeEnabled">保障资源类别</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.resourceType" class="w-full" :disabled="!scheduleSearchForm.resourceTypeEnabled">
|
|
||||||
<el-option v-for="item in resourceTypeOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.periodEnabled">节次</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.period" class="w-full" :disabled="!scheduleSearchForm.periodEnabled">
|
|
||||||
<el-option v-for="item in periodOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.combineEnabled">合堂选项</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.combineChange" :disabled="!scheduleSearchForm.combineEnabled">合堂变动</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专业名称">
|
|
||||||
<el-input v-model="scheduleSearchForm.majorName" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="监考教员姓名">
|
|
||||||
<el-input v-model="scheduleSearchForm.invigilatorName" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="考核场地名称">
|
|
||||||
<el-input v-model="scheduleSearchForm.examPlaceName" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<!-- 右栏 -->
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.invigilatorEnabled">监考教员</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.invigilator" class="w-full" :disabled="!scheduleSearchForm.invigilatorEnabled">
|
|
||||||
<el-option v-for="item in invigilatorOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.examSubjectEnabled">考核科目</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.examSubject" class="w-full" :disabled="!scheduleSearchForm.examSubjectEnabled">
|
|
||||||
<el-option v-for="item in subjectOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.placeEnabled">教学场地</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.place" class="w-full" :disabled="!scheduleSearchForm.placeEnabled">
|
|
||||||
<el-option v-for="item in placeOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.teamEnabled">班次</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<div class="team-field">
|
|
||||||
<el-select v-model="scheduleSearchForm.team" placeholder="请选择" :disabled="!scheduleSearchForm.teamEnabled">
|
|
||||||
<el-option v-for="item in teamOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.showElective" class="elective-check">显示选修课临时班</el-checkbox>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.teamCategoryEnabled">队别</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.teamCategory" class="w-full" :disabled="!scheduleSearchForm.teamCategoryEnabled">
|
|
||||||
<el-option v-for="item in teamCategoryOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.resourceEnabled">保障资源</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.resource" class="w-full" :disabled="!scheduleSearchForm.resourceEnabled">
|
|
||||||
<el-option v-for="item in resourceOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.manageOrgEnabled">管理机构</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="scheduleSearchForm.manageOrg" class="w-full" :disabled="!scheduleSearchForm.manageOrgEnabled">
|
|
||||||
<el-option v-for="item in manageOrgOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="scheduleSearchForm.logOptionEnabled">日志填写选项</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-radio-group v-model="scheduleSearchForm.logOption" :disabled="!scheduleSearchForm.logOptionEnabled">
|
|
||||||
<el-radio :label="'已填写'">已填写</el-radio>
|
|
||||||
<el-radio :label="'未填写'">未填写</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="年级">
|
|
||||||
<el-input v-model="scheduleSearchForm.gradeInput" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="队别班次名称">
|
|
||||||
<el-input v-model="scheduleSearchForm.teamClassName" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="科目名称">
|
|
||||||
<el-input v-model="scheduleSearchForm.subjectName" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<div class="search-tip">注意:勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
<div class="search-actions">
|
|
||||||
<el-button type="primary" @click="handleScheduleQuery">查询</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 操作与列表区域 -->
|
|
||||||
<el-card shadow="never" class="table-card">
|
|
||||||
<div class="table-title">课程表信息列表</div>
|
|
||||||
<div class="action-bar">
|
|
||||||
<div class="action-row">
|
|
||||||
<el-button type="primary" size="small" @click="handleScheduleBatch('批量设置备注信息')">批量设置备注信息</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleScheduleBatch('批量变更时间')">批量变更时间</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleScheduleBatch('批量平移时间')">批量平移时间</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleScheduleBatch('批量变更授课教员')">批量变更授课教员</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleScheduleBatch('批量变更授课场地')">批量变更授课场地</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleExport('班次课程课时汇总')">班次课程课时汇总另存</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleExport('教学实施计划概要')">教学实施计划概要另存</el-button>
|
|
||||||
<el-button type="primary" size="small" @click="handleExport('教学实施计划')">教学实施计划另存</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="action-row">
|
|
||||||
<el-button type="danger" size="small" @click="handleScheduleBatchDelete">批量删除</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-table v-loading="scheduleLoading" :data="schedulePagedData" border stripe class="main-table" @selection-change="handleScheduleSelectionChange">
|
|
||||||
<el-table-column type="selection" width="50" />
|
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
||||||
<el-table-column prop="time" label="上课时间" width="150" align="center" />
|
|
||||||
<el-table-column prop="course" label="课程" width="110" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="deptUnit" label="责任单位" width="120" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="teamCategory" label="队别" width="90" align="center" />
|
|
||||||
<el-table-column prop="teamClass" label="班次" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="grade" label="年级" width="90" align="center" />
|
|
||||||
<el-table-column prop="major" label="专业" width="100" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="teacher" label="教员" width="80" align="center" />
|
|
||||||
<el-table-column prop="countPlace" label="人数/场地" width="110" align="center" />
|
|
||||||
<el-table-column prop="contentMethod" label="教学内容方法" width="110" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="keyPoints" label="教学要点" width="100" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="guarantee" label="保障明细" width="110" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="remark" label="备注" width="90" show-overflow-tooltip />
|
|
||||||
</el-table>
|
|
||||||
<div class="pagination-wrap">
|
|
||||||
<el-pagination
|
|
||||||
background
|
|
||||||
layout="total, prev, pager, next, jumper"
|
|
||||||
:total="scheduleData.length"
|
|
||||||
:page-size="schedulePageSize"
|
|
||||||
:current-page="scheduleCurrentPage"
|
|
||||||
@current-change="handleSchedulePageChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-tab-pane>
|
|
||||||
|
|
||||||
<!-- ==================== Tab2:课程检索 ==================== -->
|
|
||||||
<el-tab-pane label="课程检索" name="search">
|
|
||||||
<div v-if="statusTip" class="status-tip">{{ statusTip }}</div>
|
|
||||||
<div class="big-title">2026年秋季学期-课程检索</div>
|
|
||||||
|
|
||||||
<div class="export-bar">
|
|
||||||
<el-button type="primary" @click="handleExport('另存Excel(成绩五级制)')">另存Excel(成绩五级制)</el-button>
|
|
||||||
<el-button type="primary" @click="handleExport('另存Excel(成绩四级制)')">另存Excel(成绩四级制)</el-button>
|
|
||||||
<el-button type="primary" @click="handleExport('课程学员名单')">课程学员名单</el-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 查询条件 -->
|
|
||||||
<el-card shadow="never" class="search-card">
|
|
||||||
<el-form :model="courseSearchForm" label-width="130px" class="search-form">
|
|
||||||
<el-row :gutter="0">
|
|
||||||
<!-- 左栏 -->
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.deptEnabled">责任教研室</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.dept" class="w-full" :disabled="!courseSearchForm.deptEnabled">
|
|
||||||
<el-option v-for="item in deptOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.courseTypeEnabled">课类型</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.courseType" class="w-full" :disabled="!courseSearchForm.courseTypeEnabled">
|
|
||||||
<el-option v-for="item in courseTypeOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="培训层次">
|
|
||||||
<el-select v-model="courseSearchForm.trainLevel" placeholder="请选择" clearable class="w-full">
|
|
||||||
<el-option v-for="item in trainLevelOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.teamEnabled">队别(班次)</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.team" class="w-full" :disabled="!courseSearchForm.teamEnabled">
|
|
||||||
<el-option v-for="item in teamOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学分">
|
|
||||||
<div class="range-control">
|
|
||||||
<el-input v-model="courseSearchForm.creditMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="courseSearchForm.creditMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="计划学时">
|
|
||||||
<div class="range-control">
|
|
||||||
<el-input v-model="courseSearchForm.planHoursMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="courseSearchForm.planHoursMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.arrangeStatusEnabled">考核安排状态</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-radio-group v-model="courseSearchForm.arrangeStatus" :disabled="!courseSearchForm.arrangeStatusEnabled">
|
|
||||||
<el-radio :label="'已安排'">已安排</el-radio>
|
|
||||||
<el-radio :label="'未安排'">未安排</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="教员">
|
|
||||||
<el-input v-model="courseSearchForm.teacher" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="队别班次">
|
|
||||||
<el-input v-model="courseSearchForm.teamClass" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.scoreStatusEnabled">成绩录入状态</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.scoreStatus" class="w-full" :disabled="!courseSearchForm.scoreStatusEnabled">
|
|
||||||
<el-option v-for="item in scoreStatusOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="形成性成绩比例">
|
|
||||||
<div class="range-control">
|
|
||||||
<el-input v-model="courseSearchForm.formaScoreMin" placeholder="0" />
|
|
||||||
<span class="range-suffix">%</span>
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="courseSearchForm.formaScoreMax" placeholder="0" />
|
|
||||||
<span class="range-suffix">%</span>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<!-- 右栏 -->
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.implTeacherEnabled">实施教员</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.implTeacher" class="w-full" :disabled="!courseSearchForm.implTeacherEnabled">
|
|
||||||
<el-option v-for="item in implTeacherOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.courseSubjectEnabled">课程科目</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.courseSubject" class="w-full" :disabled="!courseSearchForm.courseSubjectEnabled">
|
|
||||||
<el-option v-for="item in subjectOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="教学楼">
|
|
||||||
<el-select v-model="courseSearchForm.building" class="w-full">
|
|
||||||
<el-option v-for="item in buildingOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.placeEnabled">教学场地</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.place" class="w-full" :disabled="!courseSearchForm.placeEnabled">
|
|
||||||
<el-option v-for="item in placeOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.startDateEnabled">开课日期</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<div class="range-control">
|
|
||||||
<el-date-picker v-model="courseSearchForm.startDateStart" type="date" value-format="yyyy-MM-dd" :disabled="!courseSearchForm.startDateEnabled" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-date-picker v-model="courseSearchForm.startDateEnd" type="date" value-format="yyyy-MM-dd" :disabled="!courseSearchForm.startDateEnabled" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.endDateEnabled">结课日期</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<div class="range-control">
|
|
||||||
<el-date-picker v-model="courseSearchForm.endDateStart" type="date" value-format="yyyy-MM-dd" :disabled="!courseSearchForm.endDateEnabled" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-date-picker v-model="courseSearchForm.endDateEnd" type="date" value-format="yyyy-MM-dd" :disabled="!courseSearchForm.endDateEnabled" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.examDateEnabled">考试日期</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<div class="range-control">
|
|
||||||
<el-date-picker v-model="courseSearchForm.examDateStart" type="date" value-format="yyyy-MM-dd" :disabled="!courseSearchForm.examDateEnabled" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-date-picker v-model="courseSearchForm.examDateEnd" type="date" value-format="yyyy-MM-dd" :disabled="!courseSearchForm.examDateEnabled" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="课程科目">
|
|
||||||
<el-input v-model="courseSearchForm.courseSubjectInput" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="教学场地">
|
|
||||||
<el-input v-model="courseSearchForm.placeInput" placeholder="请输入" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.finalStrategyEnabled">终结性成绩策略</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-checkbox v-model="courseSearchForm.finalPassEnabled">终结性成绩定及格</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="courseSearchForm.manageOrgEnabled">管理机构</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="courseSearchForm.manageOrg" class="w-full" :disabled="!courseSearchForm.manageOrgEnabled">
|
|
||||||
<el-option v-for="item in manageOrgOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<div class="search-tip">注意:勾选"选择框"表示启用该项对应的查询条件,输入框非空表示启用查询条件。</div>
|
|
||||||
<div class="search-actions">
|
|
||||||
<el-button type="primary" @click="handleCourseQuery">查询</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
|
||||||
<el-card shadow="never" class="table-card">
|
|
||||||
<el-table v-loading="courseLoading" :data="coursePagedData" border stripe class="main-table">
|
|
||||||
<el-table-column type="index" label="序号" width="50" align="center" />
|
|
||||||
<el-table-column label="课程名称/课时系数" width="150" align="center">
|
|
||||||
<template slot="header">
|
|
||||||
<div class="two-line-header">
|
|
||||||
<span>课程名称</span>
|
|
||||||
<span>课时系数</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<div class="two-line-cell">
|
|
||||||
<span>{{ row.courseName }}</span>
|
|
||||||
<span>{{ row.coeff }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="teacherTimes" label="责任教员&课次" width="120" align="center" />
|
|
||||||
<el-table-column prop="teamClass" label="班次" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="grade" label="年级" width="90" align="center" />
|
|
||||||
<el-table-column prop="major" label="专业" width="120" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="planHours" label="计划学时" width="90" align="center" />
|
|
||||||
<el-table-column prop="runHours" label="运行学时" width="90" align="center" />
|
|
||||||
<el-table-column prop="examType" label="考核类型方式" width="110" align="center" />
|
|
||||||
<el-table-column prop="implTeacher" label="实施教员" width="90" align="center" />
|
|
||||||
<el-table-column prop="countPlace" label="人数/场地" width="110" align="center" />
|
|
||||||
<el-table-column prop="courseLecture" label="课程讲座" width="90" align="center" />
|
|
||||||
<el-table-column prop="planChange" label="实施计划变" width="90" align="center" />
|
|
||||||
</el-table>
|
|
||||||
<div class="pagination-wrap">
|
|
||||||
<el-pagination
|
|
||||||
background
|
|
||||||
layout="total, prev, pager, next, jumper"
|
|
||||||
:total="courseData.length"
|
|
||||||
:page-size="coursePageSize"
|
|
||||||
:current-page="courseCurrentPage"
|
|
||||||
@current-change="handleCoursePageChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'AssessmentIndex',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
activeTab: 'schedule',
|
|
||||||
|
|
||||||
// ==================== 下拉选项(两页共用) ====================
|
|
||||||
deptOptions: ['教务处', '政治工作教研室', '军事基础教研室', '装备保障教研室'],
|
|
||||||
trainLevelOptions: ['本科', '研究生', '大专'],
|
|
||||||
buildingOptions: ['校内', '教学楼A', '教学楼B'],
|
|
||||||
placeOptions: ['操场', '教室101', '实验室203'],
|
|
||||||
subjectOptions: ['英语(补课)', '高等数学', '军事理论', '战术基础'],
|
|
||||||
teamOptions: ['2025级炮兵装备运用(线膛炮)专业学员54队5区队', '2024级学员32队', '研究生1队'],
|
|
||||||
manageOrgOptions: ['教务处', '教务科', '教研室'],
|
|
||||||
|
|
||||||
// Tab1 专属选项
|
|
||||||
semesterOptions: ['2026年春季学期', '2026年秋季学期', '2025年秋季学期'],
|
|
||||||
weekOptions: ['第20周2026-07-06', '第19周2026-06-29', '第21周2026-07-13'],
|
|
||||||
resourceTypeOptions: ['弹药', '器材', '场地'],
|
|
||||||
periodOptions: ['1-2', '3-4', '5-6', '7-8'],
|
|
||||||
invigilatorOptions: ['教务处', '张三', '李四', '王五'],
|
|
||||||
teamCategoryOptions: ['学员大队', '学员一队', '学员二队'],
|
|
||||||
resourceOptions: ['92式手榴弹', '模拟器材', '靶场'],
|
|
||||||
|
|
||||||
// Tab2 专属选项
|
|
||||||
courseTypeOptions: ['讲座', '讲授', '研讨', '实操'],
|
|
||||||
scoreStatusOptions: ['未填写', '已填写'],
|
|
||||||
implTeacherOptions: ['教务处', '张三', '李四', '王五', '赵六'],
|
|
||||||
|
|
||||||
// ==================== Tab1 查询条件 ====================
|
|
||||||
scheduleSearchForm: {
|
|
||||||
examDateEnabled: true,
|
|
||||||
examDateFrom: '2026-07-06',
|
|
||||||
examDateTo: '2026-07-12',
|
|
||||||
semester: '2026年春季学期',
|
|
||||||
week: '第20周2026-07-06',
|
|
||||||
deptEnabled: false,
|
|
||||||
dept: '教务处',
|
|
||||||
buildingEnabled: true,
|
|
||||||
building: '校内',
|
|
||||||
trainLevel: '',
|
|
||||||
deptSystemEnabled: false,
|
|
||||||
deptSystem: '教务处',
|
|
||||||
resourceTypeEnabled: false,
|
|
||||||
resourceType: '弹药',
|
|
||||||
periodEnabled: false,
|
|
||||||
period: '1-2',
|
|
||||||
combineEnabled: false,
|
|
||||||
combineChange: false,
|
|
||||||
majorName: '',
|
|
||||||
invigilatorName: '',
|
|
||||||
examPlaceName: '',
|
|
||||||
invigilatorEnabled: false,
|
|
||||||
invigilator: '教务处',
|
|
||||||
examSubjectEnabled: false,
|
|
||||||
examSubject: '英语(补课)',
|
|
||||||
placeEnabled: false,
|
|
||||||
place: '操场',
|
|
||||||
teamEnabled: false,
|
|
||||||
team: '',
|
|
||||||
showElective: true,
|
|
||||||
teamCategoryEnabled: false,
|
|
||||||
teamCategory: '学员大队',
|
|
||||||
resourceEnabled: false,
|
|
||||||
resource: '92式手榴弹',
|
|
||||||
manageOrgEnabled: false,
|
|
||||||
manageOrg: '教务处',
|
|
||||||
logOptionEnabled: false,
|
|
||||||
logOption: '未填写',
|
|
||||||
gradeInput: '',
|
|
||||||
teamClassName: '',
|
|
||||||
subjectName: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== Tab2 查询条件 ====================
|
|
||||||
statusTip: '',
|
|
||||||
courseSearchForm: {
|
|
||||||
deptEnabled: false,
|
|
||||||
dept: '教务处',
|
|
||||||
courseTypeEnabled: false,
|
|
||||||
courseType: '讲座',
|
|
||||||
trainLevel: '',
|
|
||||||
teamEnabled: false,
|
|
||||||
team: '2025级炮兵装备运用(线膛炮)专业学员54队5区队',
|
|
||||||
creditMin: '',
|
|
||||||
creditMax: '',
|
|
||||||
planHoursMin: '',
|
|
||||||
planHoursMax: '',
|
|
||||||
arrangeStatusEnabled: true,
|
|
||||||
arrangeStatus: '已安排',
|
|
||||||
teacher: '',
|
|
||||||
teamClass: '',
|
|
||||||
scoreStatusEnabled: false,
|
|
||||||
scoreStatus: '未填写',
|
|
||||||
formaScoreMin: '',
|
|
||||||
formaScoreMax: '',
|
|
||||||
implTeacherEnabled: false,
|
|
||||||
implTeacher: '教务处',
|
|
||||||
courseSubjectEnabled: false,
|
|
||||||
courseSubject: '英语(补课)',
|
|
||||||
building: '校内',
|
|
||||||
placeEnabled: false,
|
|
||||||
place: '操场',
|
|
||||||
startDateEnabled: false,
|
|
||||||
startDateStart: '2026-08-21',
|
|
||||||
startDateEnd: '2027-01-23',
|
|
||||||
endDateEnabled: false,
|
|
||||||
endDateStart: '2026-08-21',
|
|
||||||
endDateEnd: '2027-01-23',
|
|
||||||
examDateEnabled: false,
|
|
||||||
examDateStart: '2026-08-21',
|
|
||||||
examDateEnd: '2027-01-23',
|
|
||||||
courseSubjectInput: '',
|
|
||||||
placeInput: '',
|
|
||||||
finalStrategyEnabled: false,
|
|
||||||
finalPassEnabled: false,
|
|
||||||
manageOrgEnabled: false,
|
|
||||||
manageOrg: '教务处'
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== Tab1 表格数据(mock) ====================
|
|
||||||
scheduleLoading: false,
|
|
||||||
scheduleData: [
|
|
||||||
{ id: 1, time: '2026-07-06 08:00-09:40', course: '高等数学', deptUnit: '教务处', teamCategory: '学员大队', teamClass: '2025级本科1班', grade: '2025级', major: '数学', teacher: '张三', countPlace: '45/教室101', contentMethod: '理论讲授', keyPoints: '微积分基础', guarantee: '无', remark: '第1次课' },
|
|
||||||
{ id: 2, time: '2026-07-06 10:00-11:40', course: '军事理论', deptUnit: '政治工作教研室', teamCategory: '学员大队', teamClass: '2024级本科2班', grade: '2024级', major: '军事', teacher: '李四', countPlace: '38/教室203', contentMethod: '案例教学', keyPoints: '战争理论', guarantee: '多媒体', remark: '' },
|
|
||||||
{ id: 3, time: '2026-07-07 14:30-16:10', course: '英语(补课)', deptUnit: '军事基础教研室', teamCategory: '学员一队', teamClass: '研究生1班', grade: '2026级', major: '英语', teacher: '王五', countPlace: '30/教室102', contentMethod: '研讨教学', keyPoints: '口语训练', guarantee: '无', remark: '补课' },
|
|
||||||
{ id: 4, time: '2026-07-07 08:00-09:40', course: '战术基础', deptUnit: '教务处', teamCategory: '学员大队', teamClass: '2023级本科3班', grade: '2023级', major: '战术', teacher: '赵六', countPlace: '50/操场', contentMethod: '实操演练', keyPoints: '战术动作', guarantee: '器材', remark: '' },
|
|
||||||
{ id: 5, time: '2026-07-08 10:00-11:40', course: '装备保障', deptUnit: '装备保障教研室', teamCategory: '学员二队', teamClass: '研究生2班', grade: '2026级', major: '装备', teacher: '孙七', countPlace: '20/实验室203', contentMethod: '实践教学', keyPoints: '装备维护', guarantee: '模拟器材', remark: '分组' },
|
|
||||||
{ id: 6, time: '2026-07-08 14:30-16:10', course: '联合作战指挥', deptUnit: '教务处', teamCategory: '学员大队', teamClass: '2025级本科1班', grade: '2025级', major: '指挥', teacher: '李四', countPlace: '45/教室B301', contentMethod: '案例教学', keyPoints: '联合作战', guarantee: '多媒体', remark: '' },
|
|
||||||
{ id: 7, time: '2026-07-09 08:00-09:40', course: '大学英语', deptUnit: '军事基础教研室', teamCategory: '学员一队', teamClass: '2024级本科2班', grade: '2024级', major: '英语', teacher: '王五', countPlace: '38/教室105', contentMethod: '理论讲授', keyPoints: '语法', guarantee: '无', remark: '' },
|
|
||||||
{ id: 8, time: '2026-07-09 10:00-11:40', course: '政治理论', deptUnit: '政治工作教研室', teamCategory: '学员大队', teamClass: '研究生1班', grade: '2026级', major: '政治', teacher: '张三', countPlace: '30/教室204', contentMethod: '理论讲授', keyPoints: '形势政策', guarantee: '无', remark: '' },
|
|
||||||
{ id: 9, time: '2026-07-10 14:30-16:10', course: '装备操作', deptUnit: '装备保障教研室', teamCategory: '学员二队', teamClass: '2023级本科3班', grade: '2023级', major: '装备', teacher: '赵六', countPlace: '45/实验室101', contentMethod: '实操演练', keyPoints: '操作规范', guarantee: '器材', remark: '安全注意' },
|
|
||||||
{ id: 10, time: '2026-07-10 16:20-18:00', course: '军事地形学', deptUnit: '教务处', teamCategory: '学员大队', teamClass: '2025级本科1班', grade: '2025级', major: '地形', teacher: '孙七', countPlace: '50/操场', contentMethod: '实操演练', keyPoints: '地形判读', guarantee: '地图', remark: '' }
|
|
||||||
],
|
|
||||||
selectedRows: [],
|
|
||||||
scheduleCurrentPage: 1,
|
|
||||||
schedulePageSize: 20,
|
|
||||||
|
|
||||||
// ==================== Tab2 表格数据(mock) ====================
|
|
||||||
courseLoading: false,
|
|
||||||
courseData: [
|
|
||||||
{ id: 1, courseName: '高等数学', coeff: '1.0', teacherTimes: '张三×48', teamClass: '2025级炮兵装备运用(线膛炮)专业学员54队5区队', grade: '2025级', major: '炮兵装备运用', planHours: 96, runHours: 96, examType: '闭卷考试', implTeacher: '张三', countPlace: '45/教室101', courseLecture: '讲座', planChange: '否' },
|
|
||||||
{ id: 2, courseName: '军事理论', coeff: '1.2', teacherTimes: '李四×32', teamClass: '2024级学员32队', grade: '2024级', major: '军事指挥', planHours: 64, runHours: 62, examType: '开卷考试', implTeacher: '李四', countPlace: '38/教室203', courseLecture: '讲授', planChange: '是' },
|
|
||||||
{ id: 3, courseName: '英语(补课)', coeff: '0.8', teacherTimes: '王五×40', teamClass: '研究生1队', grade: '2026级', major: '英语', planHours: 80, runHours: 78, examType: '口语测试', implTeacher: '王五', countPlace: '30/教室102', courseLecture: '讲座', planChange: '否' },
|
|
||||||
{ id: 4, courseName: '战术基础', coeff: '1.0', teacherTimes: '赵六×56', teamClass: '2023级学员51队', grade: '2023级', major: '战术指挥', planHours: 112, runHours: 110, examType: '实操考核', implTeacher: '赵六', countPlace: '50/操场', courseLecture: '实操', planChange: '是' },
|
|
||||||
{ id: 5, courseName: '装备保障', coeff: '1.1', teacherTimes: '张三×24', teamClass: '研究生2队', grade: '2026级', major: '装备保障', planHours: 48, runHours: 48, examType: '闭卷考试', implTeacher: '孙七', countPlace: '20/实验室203', courseLecture: '讲授', planChange: '否' },
|
|
||||||
{ id: 6, courseName: '联合作战指挥', coeff: '1.3', teacherTimes: '李四×60', teamClass: '2025级炮兵装备运用(线膛炮)专业学员54队5区队', grade: '2025级', major: '联合作战', planHours: 120, runHours: 118, examType: '综合考核', implTeacher: '李四', countPlace: '45/教室B301', courseLecture: '讲座', planChange: '是' },
|
|
||||||
{ id: 7, courseName: '大学英语', coeff: '0.8', teacherTimes: '王五×36', teamClass: '2024级学员32队', grade: '2024级', major: '英语', planHours: 72, runHours: 72, examType: '四级制考试', implTeacher: '王五', countPlace: '38/教室105', courseLecture: '讲授', planChange: '否' },
|
|
||||||
{ id: 8, courseName: '军事地形学', coeff: '1.0', teacherTimes: '赵六×40', teamClass: '2023级学员51队', grade: '2023级', major: '军事指挥', planHours: 80, runHours: 76, examType: '实操考核', implTeacher: '赵六', countPlace: '50/操场', courseLecture: '实操', planChange: '是' },
|
|
||||||
{ id: 9, courseName: '政治理论', coeff: '1.0', teacherTimes: '张三×48', teamClass: '研究生1队', grade: '2026级', major: '政治学', planHours: 96, runHours: 96, examType: '开卷考试', implTeacher: '孙七', countPlace: '30/教室204', courseLecture: '讲座', planChange: '否' },
|
|
||||||
{ id: 10, courseName: '装备操作', coeff: '1.2', teacherTimes: '李四×32', teamClass: '2025级炮兵装备运用(线膛炮)专业学员54队5区队', grade: '2025级', major: '炮兵装备运用', planHours: 64, runHours: 62, examType: '实操考核', implTeacher: '李四', countPlace: '45/实验室101', courseLecture: '实操', planChange: '是' }
|
|
||||||
],
|
|
||||||
courseCurrentPage: 1,
|
|
||||||
coursePageSize: 20
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
schedulePagedData() {
|
|
||||||
const start = (this.scheduleCurrentPage - 1) * this.schedulePageSize
|
|
||||||
return this.scheduleData.slice(start, start + this.schedulePageSize)
|
|
||||||
},
|
|
||||||
coursePagedData() {
|
|
||||||
const start = (this.courseCurrentPage - 1) * this.coursePageSize
|
|
||||||
return this.courseData.slice(start, start + this.coursePageSize)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// ==================== Tab1 查询 ====================
|
|
||||||
// TODO: 后端接口未提供,以下操作均为前端模拟;接口就绪后替换为对应接口
|
|
||||||
handleScheduleQuery() {
|
|
||||||
this.$message.success('查询完成(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 学期/周次「确定」快速填充日期范围 */
|
|
||||||
handleQuickDate(type) {
|
|
||||||
if (type === 'semester') {
|
|
||||||
this.$message.success(`已按「${this.scheduleSearchForm.semester}」确定考核日期范围(前端模拟)`)
|
|
||||||
} else {
|
|
||||||
this.$message.success(`已按「${this.scheduleSearchForm.week}」确定考核日期范围(前端模拟)`)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 导出按钮 ====================
|
|
||||||
handleExport(type) {
|
|
||||||
this.$message.success(`已导出 ${type}(前端模拟)`)
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== Tab1 多选与批量操作 ====================
|
|
||||||
handleScheduleSelectionChange(rows) {
|
|
||||||
this.selectedRows = rows
|
|
||||||
},
|
|
||||||
|
|
||||||
handleScheduleBatch(action) {
|
|
||||||
if (this.selectedRows.length === 0) {
|
|
||||||
this.$message.warning('请先选择记录')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$message.success(`已对所选 ${this.selectedRows.length} 条记录执行「${action}」(前端模拟)`)
|
|
||||||
},
|
|
||||||
|
|
||||||
handleScheduleBatchDelete() {
|
|
||||||
if (this.selectedRows.length === 0) {
|
|
||||||
this.$message.warning('请先选择要删除的记录')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const ids = this.selectedRows.map((r) => r.id)
|
|
||||||
this.scheduleData = this.scheduleData.filter((r) => ids.indexOf(r.id) === -1)
|
|
||||||
this.$message.success(`已删除所选 ${ids.length} 条记录(前端模拟)`)
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSchedulePageChange(page) {
|
|
||||||
this.scheduleCurrentPage = page
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== Tab2 查询 ====================
|
|
||||||
handleCourseQuery() {
|
|
||||||
const now = new Date()
|
|
||||||
const hh = String(now.getHours()).padStart(2, '0')
|
|
||||||
const mm = String(now.getMinutes()).padStart(2, '0')
|
|
||||||
const ss = String(now.getSeconds()).padStart(2, '0')
|
|
||||||
const count = this.courseData.length
|
|
||||||
this.statusTip = `[${hh}:${mm}:${ss}]查询成功! 共检索到${count}条记录。`
|
|
||||||
this.$message.success(`查询成功,共检索到${count}条记录(前端模拟)`)
|
|
||||||
},
|
|
||||||
|
|
||||||
handleCoursePageChange(page) {
|
|
||||||
this.courseCurrentPage = page
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.app-container {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.assessment-page {
|
|
||||||
.assessment-tabs {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 查询条件区域 ====================
|
|
||||||
.search-card {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
.search-form {
|
|
||||||
.w-full {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-block {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 16px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.date-range {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.quick-select {
|
|
||||||
width: 170px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.team-field {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
.el-select {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.elective-check {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.range-control {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
|
|
||||||
.el-input {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-date-editor {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.range-sep,
|
|
||||||
.range-suffix {
|
|
||||||
flex-shrink: 0;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-tip {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #f56c6c;
|
|
||||||
margin-top: 4px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-top: 8px;
|
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== Tab2 顶部提示 / 标题 / 导出 ====================
|
|
||||||
.status-tip {
|
|
||||||
display: inline-block;
|
|
||||||
background: #dc3545;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 3px 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.big-title {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #303133;
|
|
||||||
margin: 8px 0 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.export-bar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 数据表格区域 ====================
|
|
||||||
.table-card {
|
|
||||||
.table-title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-bar {
|
|
||||||
.action-row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-table {
|
|
||||||
::v-deep(.cell) {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.two-line-header,
|
|
||||||
.two-line-cell {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination-wrap {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -4,47 +4,35 @@
|
|||||||
|
|
||||||
<!-- ==================== 1. 查询条件区域 ==================== -->
|
<!-- ==================== 1. 查询条件区域 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form :model="searchForm" label-width="110px" class="search-form">
|
<el-form :model="searchForm" label-width="40px" class="search-form">
|
||||||
<el-row :gutter="0">
|
<el-row :gutter="6">
|
||||||
<el-col :span="12">
|
<el-col :span="4">
|
||||||
<el-form-item label="名称">
|
<el-form-item label="名称">
|
||||||
<el-input v-model="searchForm.mc" placeholder="请输入名称" clearable />
|
<el-input v-model="searchForm.mc" placeholder="请输入名称" clearable @keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="年度">
|
|
||||||
<el-input v-model="searchForm.nd" placeholder="如 2026" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="2">
|
||||||
<el-form-item label="教员编号">
|
<div class="search-actions">
|
||||||
<el-input v-model="searchForm.jybh" placeholder="如 JY00128" clearable />
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
</el-form-item>
|
</div>
|
||||||
<el-form-item label="合班类型">
|
|
||||||
<el-select v-model="searchForm.hflx" placeholder="请选择" clearable class="w-full">
|
|
||||||
<el-option v-for="item in hflxOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="search-actions">
|
|
||||||
<el-button type="primary" @click="handleQuery">查询</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 2. 文件操作区域 ==================== -->
|
<!-- ==================== 2. 操作区域 ==================== -->
|
||||||
<el-card shadow="never" class="upload-card">
|
<el-card shadow="never" class="upload-card">
|
||||||
<div class="upload-row">
|
<div class="upload-row">
|
||||||
<div class="upload-left">
|
<div class="upload-left">
|
||||||
<el-button type="primary" @click="handleDownloadTemplate">【联教联训数据文件模板】下载</el-button>
|
<el-button type="primary" @click="handleAdd">新增联教联训</el-button>
|
||||||
<el-button type="primary" plain @click="handleChooseFile">选择文件</el-button>
|
<el-button type="primary" plain @click="handleExport">导出 Excel</el-button>
|
||||||
|
<el-button @click="handleDownloadTemplate">【联教联训数据文件模板】下载</el-button>
|
||||||
|
<el-button plain @click="handleChooseFile">选择文件</el-button>
|
||||||
<span class="file-name" :class="{ 'has-file': selectedFile }">{{ fileName }}</span>
|
<span class="file-name" :class="{ 'has-file': selectedFile }">{{ fileName }}</span>
|
||||||
<input ref="fileInputRef" type="file" style="display: none" @change="handleFileChange" />
|
<input ref="fileInputRef" type="file" accept=".xls,.xlsx" style="display: none" @change="handleFileChange" />
|
||||||
</div>
|
<el-button type="success" :loading="uploading" @click="handleUpload">上传数据</el-button>
|
||||||
<div class="upload-right">
|
|
||||||
<el-button type="primary" @click="handleUpload">上传数据</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="upload-tip">您还没建立 联教联训证明。</div>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 3. 数据表格 ==================== -->
|
<!-- ==================== 3. 数据表格 ==================== -->
|
||||||
@@ -52,20 +40,25 @@
|
|||||||
<div class="table-title">联教联训记录列表</div>
|
<div class="table-title">联教联训记录列表</div>
|
||||||
<el-table v-loading="tableLoading" :data="tableData" border stripe style="width: 100%">
|
<el-table v-loading="tableLoading" :data="tableData" border stripe style="width: 100%">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="bh" label="任务编号" width="150" align="center" show-overflow-tooltip />
|
<el-table-column prop="bh" label="编号" width="150" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="mc" label="名称" min-width="160" show-overflow-tooltip />
|
<el-table-column prop="mc" label="名称" min-width="140" show-overflow-tooltip />
|
||||||
<el-table-column prop="jybh" label="教员编号" width="100" align="center" />
|
<el-table-column prop="xz" label="性质" width="80" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="rwlb" label="任务类别" width="110" align="center" show-overflow-tooltip />
|
<el-table-column prop="yj" label="依据" width="110" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="ksl" label="课时量" width="80" align="center" />
|
<el-table-column prop="ksrq" label="开始日期" width="110" align="center" :formatter="fmtDateTime" />
|
||||||
<el-table-column label="合班类型" width="90" align="center">
|
<el-table-column prop="jsrq" label="结束日期" width="110" align="center" :formatter="fmtDateTime" />
|
||||||
<template slot-scope="{ row }">{{ formatHflx(row.hflx) }}</template>
|
<el-table-column prop="ts" label="天数" width="70" align="center" />
|
||||||
|
<el-table-column prop="jbksl" label="基本课时量" width="90" align="center" />
|
||||||
|
<el-table-column prop="kslx" label="课时类型" width="80" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="xmlx" label="项目类型" width="80" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="sm" label="说明" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="bz" label="备注" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="160" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button type="text" size="small" @click="handleEdit(row)">修改</el-button>
|
||||||
|
<el-button type="text" size="small" class="text-danger" @click="handleDelete(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="是否评优" width="90" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ formatSfpy(row.sfpy) }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="nd" label="年度" width="80" align="center" />
|
|
||||||
<el-table-column prop="xq" label="学期" width="110" align="center" />
|
|
||||||
<el-table-column prop="sm" label="说明" min-width="180" show-overflow-tooltip />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-pagination
|
<el-pagination
|
||||||
@@ -80,67 +73,122 @@
|
|||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 4. 新增联教联训记录区域 ==================== -->
|
<!-- ==================== 4. 新增/修改对话框 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-dialog
|
||||||
<div class="form-title">新增联教联训记录</div>
|
:visible="dialogVisible"
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" class="search-form">
|
:title="dialogTitle"
|
||||||
<el-row :gutter="0">
|
width="720px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => dialogVisible = val"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px" class="add-form">
|
||||||
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="任务编号" prop="bh">
|
<el-form-item label="编号">
|
||||||
<el-input v-model="form.bh" placeholder="如 RW20260810001" clearable />
|
<el-input v-model="form.bh" placeholder="留空则自动生成" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
<el-form-item label="名称" prop="mc">
|
<el-form-item label="名称" prop="mc">
|
||||||
<el-input v-model="form.mc" placeholder="请输入名称" clearable />
|
<el-input v-model="form.mc" placeholder="请输入名称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="教员编号" prop="jybh">
|
</el-col>
|
||||||
<el-input v-model="form.jybh" placeholder="如 JY00128" clearable />
|
</el-row>
|
||||||
</el-form-item>
|
<el-row :gutter="16">
|
||||||
<el-form-item label="任务类别" prop="rwlb">
|
<el-col :span="12">
|
||||||
<el-input v-model="form.rwlb" placeholder="如 理论授课" clearable />
|
<el-form-item label="性质">
|
||||||
</el-form-item>
|
<el-input v-model="form.xz" placeholder="请输入性质" clearable />
|
||||||
<el-form-item label="课时量" prop="ksl">
|
|
||||||
<el-input v-model="form.ksl" placeholder="如 16.5" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="合班类型">
|
<el-form-item label="依据">
|
||||||
<el-radio-group v-model="form.hflx">
|
<el-input v-model="form.yj" placeholder="请输入依据" clearable />
|
||||||
<el-radio :label="0">未合班</el-radio>
|
|
||||||
<el-radio :label="1">合班</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="是否评优">
|
|
||||||
<el-radio-group v-model="form.sfpy">
|
|
||||||
<el-radio :label="0">否</el-radio>
|
|
||||||
<el-radio :label="1">是</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="年度" prop="nd">
|
|
||||||
<el-input v-model="form.nd" placeholder="如 2026" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学期" prop="xq">
|
|
||||||
<el-input v-model="form.xq" placeholder="如 2026-2027-1" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="说明" prop="sm">
|
|
||||||
<el-input v-model="form.sm" type="textarea" :rows="3" placeholder="请输入说明" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="search-actions">
|
<el-row :gutter="16">
|
||||||
<el-button type="primary" :loading="addLoading" @click="handleAdd">添加</el-button>
|
<el-col :span="12">
|
||||||
</div>
|
<el-form-item label="开始日期">
|
||||||
|
<el-date-picker v-model="form.ksrq" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择开始日期" clearable class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="结束日期">
|
||||||
|
<el-date-picker v-model="form.jsrq" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择结束日期" clearable class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="天数">
|
||||||
|
<el-input-number v-model="form.ts" :min="0" :precision="1" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="基本课时量">
|
||||||
|
<el-input-number v-model="form.jbksl" :min="0" :precision="1" :step="0.5" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="课时类型">
|
||||||
|
<el-input v-model="form.kslx" placeholder="请输入课时类型" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="项目类型">
|
||||||
|
<el-input v-model="form.xmlx" placeholder="请输入项目类型" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="说明">
|
||||||
|
<el-input v-model="form.sm" type="textarea" :rows="2" placeholder="请输入说明" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="form.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
<div slot="footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="saving" @click="handleSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ==================== 5. 详情对话框 ==================== -->
|
||||||
|
<el-dialog :visible="detailVisible" title="联教联训详情" width="640px" @update:visible="val => detailVisible = val">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailData.bh }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="名称">{{ detailData.mc }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="性质">{{ fmtEmpty(detailData.xz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="依据">{{ fmtEmpty(detailData.yj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="开始日期">{{ fmtDateTime(null, null, detailData.ksrq) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="结束日期">{{ fmtDateTime(null, null, detailData.jsrq) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="天数">{{ fmtValue(detailData.ts) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="基本课时量">{{ fmtValue(detailData.jbksl) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="课时类型">{{ fmtEmpty(detailData.kslx) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="项目类型">{{ fmtEmpty(detailData.xmlx) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="说明" :span="2">{{ fmtEmpty(detailData.sm) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ fmtEmpty(detailData.bz) }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="detailVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟列表数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import { saveAs } from 'file-saver'
|
||||||
const mockTableData = [
|
import {
|
||||||
{ bh: 'RW20260810001', mc: '某型装备联合训练', jybh: 'JY00128', rwlb: '理论授课', ksl: 16.5, hflx: 1, sfpy: 1, nd: '2026', xq: '2026-2027-1', sm: '' },
|
listJointTraining,
|
||||||
{ bh: 'RW20260810002', mc: '通信保障联合演练', jybh: 'JY00302', rwlb: '实践教学', ksl: 24, hflx: 0, sfpy: 0, nd: '2026', xq: '2026-2027-1', sm: '跨单位合练' },
|
addJointTraining,
|
||||||
{ bh: 'RW20260721003', mc: '联合教学研讨', jybh: 'JY00511', rwlb: '教学研究', ksl: 8, hflx: 1, sfpy: 1, nd: '2025', xq: '2025-2026-2', sm: '' }
|
updateJointTraining,
|
||||||
]
|
deleteJointTraining,
|
||||||
|
getJointTraining,
|
||||||
|
importJointTraining,
|
||||||
|
exportJointTraining
|
||||||
|
} from '@/api/classHour/jointTraining'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JointTrainingIndex',
|
name: 'JointTrainingIndex',
|
||||||
@@ -148,49 +196,32 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// ==================== 1. 查询条件 ====================
|
// ==================== 1. 查询条件 ====================
|
||||||
searchForm: {
|
searchForm: {
|
||||||
mc: '',
|
mc: ''
|
||||||
jybh: '',
|
|
||||||
nd: '',
|
|
||||||
hflx: ''
|
|
||||||
},
|
},
|
||||||
hflxOptions: [
|
|
||||||
{ label: '未合班', value: '0' },
|
|
||||||
{ label: '合班', value: '1' }
|
|
||||||
],
|
|
||||||
|
|
||||||
// ==================== 2. 文件操作 ====================
|
// ==================== 2. 文件操作 ====================
|
||||||
selectedFile: null,
|
selectedFile: null,
|
||||||
|
uploading: false,
|
||||||
|
|
||||||
// ==================== 3. 表格数据 ====================
|
// ==================== 3. 表格数据 ====================
|
||||||
tableLoading: false,
|
tableLoading: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
allData: [],
|
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
|
|
||||||
// ==================== 4. 新增联教联训记录表单 ====================
|
// ==================== 4. 新增/修改表单 ====================
|
||||||
form: {
|
dialogVisible: false,
|
||||||
bh: this.genBh(),
|
dialogTitle: '新增联教联训',
|
||||||
mc: '',
|
saving: false,
|
||||||
jybh: '',
|
form: this.createEmptyForm(),
|
||||||
rwlb: '',
|
|
||||||
ksl: '',
|
|
||||||
hflx: 0,
|
|
||||||
sfpy: 0,
|
|
||||||
nd: '2026',
|
|
||||||
xq: '2026-2027-1',
|
|
||||||
sm: ''
|
|
||||||
},
|
|
||||||
rules: {
|
rules: {
|
||||||
bh: [{ required: true, message: '请输入任务编号', trigger: 'blur' }],
|
mc: [{ required: true, message: '请输入名称', trigger: 'blur' }]
|
||||||
mc: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
||||||
jybh: [{ required: true, message: '请输入教员编号', trigger: 'blur' }],
|
|
||||||
rwlb: [{ required: true, message: '请输入任务类别', trigger: 'blur' }],
|
|
||||||
ksl: [{ required: true, message: '请输入课时量', trigger: 'blur' }],
|
|
||||||
nd: [{ required: true, message: '请输入年度', trigger: 'blur' }]
|
|
||||||
},
|
},
|
||||||
addLoading: false
|
|
||||||
|
// ==================== 5. 详情 ====================
|
||||||
|
detailVisible: false,
|
||||||
|
detailData: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -199,73 +230,177 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.handleQuery()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 生成任务编号(RW+日期+序号) */
|
createEmptyForm() {
|
||||||
genBh() {
|
return {
|
||||||
const d = new Date()
|
bh: '',
|
||||||
const ymd = '' + d.getFullYear() + (d.getMonth() + 1 < 10 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1) + (d.getDate() < 10 ? '0' + d.getDate() : d.getDate())
|
mc: '',
|
||||||
const seq = String(Math.floor(Math.random() * 900) + 100)
|
xz: '',
|
||||||
return `RW${ymd}${seq}`
|
yj: '',
|
||||||
|
ksrq: '',
|
||||||
|
jsrq: '',
|
||||||
|
ts: null,
|
||||||
|
jbksl: null,
|
||||||
|
kslx: '',
|
||||||
|
xmlx: '',
|
||||||
|
sm: '',
|
||||||
|
bz: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 把后端 LocalDateTime(含 T/毫秒)规范为表单可回显的格式 */
|
||||||
|
normalizeDateTime(val) {
|
||||||
|
if (!val) return ''
|
||||||
|
return String(val).replace('T', ' ').replace(/\.\d+$/, '').slice(0, 19)
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询 ====================
|
// ==================== 查询 ====================
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 getJointTrainingList
|
fetchList() {
|
||||||
handleQuery() {
|
|
||||||
this.tableLoading = true
|
this.tableLoading = true
|
||||||
setTimeout(() => {
|
const params = { pageNum: this.pageNum, pageSize: this.pageSize }
|
||||||
let records = mockTableData.slice()
|
if (this.searchForm.mc && this.searchForm.mc.trim()) params.mc = this.searchForm.mc.trim()
|
||||||
if (this.searchForm.mc.trim()) {
|
listJointTraining(params).then(res => {
|
||||||
records = records.filter((item) => (item.mc || '').includes(this.searchForm.mc.trim()))
|
const data = (res && res.data) || {}
|
||||||
}
|
this.tableData = data.records || []
|
||||||
if (this.searchForm.jybh.trim()) {
|
this.total = data.total || 0
|
||||||
records = records.filter((item) => (item.jybh || '').includes(this.searchForm.jybh.trim()))
|
|
||||||
}
|
|
||||||
if (this.searchForm.nd.trim()) {
|
|
||||||
records = records.filter((item) => String(item.nd || '').includes(this.searchForm.nd.trim()))
|
|
||||||
}
|
|
||||||
if (this.searchForm.hflx !== '') {
|
|
||||||
records = records.filter((item) => String(item.hflx) === this.searchForm.hflx)
|
|
||||||
}
|
|
||||||
this.allData = records
|
|
||||||
this.total = records.length
|
|
||||||
this.pageNum = 1
|
|
||||||
this.applyPage()
|
|
||||||
this.$message.success(`查询完成,共 ${records.length} 条记录(前端模拟)`)
|
|
||||||
this.tableLoading = false
|
this.tableLoading = false
|
||||||
}, 200)
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.tableLoading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
applyPage() {
|
handleQuery() {
|
||||||
const start = (this.pageNum - 1) * this.pageSize
|
this.pageNum = 1
|
||||||
this.tableData = this.allData.slice(start, start + this.pageSize)
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handlePageChange(page) {
|
handlePageChange(page) {
|
||||||
this.pageNum = page
|
this.pageNum = page
|
||||||
this.applyPage()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSizeChange(size) {
|
handleSizeChange(size) {
|
||||||
this.pageSize = size
|
this.pageSize = size
|
||||||
this.pageNum = 1
|
this.pageNum = 1
|
||||||
this.applyPage()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 合班类型显示 */
|
/** 日期时间显示(去掉 T、截断到分钟) */
|
||||||
formatHflx(val) {
|
fmtDateTime(row, column, cellValue) {
|
||||||
if (val === undefined || val === null || val === '') return '-'
|
if (cellValue === null || cellValue === undefined || cellValue === '') return '-'
|
||||||
return String(val) === '1' ? '合班' : '未合班'
|
return String(cellValue).replace('T', ' ').slice(0, 16)
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 是否评优显示 */
|
/** 空值显示为 '-' */
|
||||||
formatSfpy(val) {
|
fmtEmpty(val) {
|
||||||
if (val === undefined || val === null || val === '') return '-'
|
return val === null || val === undefined || val === '' ? '-' : val
|
||||||
return String(val) === '1' ? '是' : '否'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 2. 文件操作 ====================
|
/** 数值空值显示为 '-'(保留 0) */
|
||||||
|
fmtValue(val) {
|
||||||
|
return val === null || val === undefined ? '-' : val
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 新增 / 修改 ====================
|
||||||
|
handleAdd() {
|
||||||
|
this.form = this.createEmptyForm()
|
||||||
|
this.dialogTitle = '新增联教联训'
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEdit(row) {
|
||||||
|
getJointTraining(row.bh).then(res => {
|
||||||
|
const d = (res && res.data) || {}
|
||||||
|
this.form = {
|
||||||
|
bh: d.bh || '',
|
||||||
|
mc: d.mc || '',
|
||||||
|
xz: d.xz || '',
|
||||||
|
yj: d.yj || '',
|
||||||
|
ksrq: this.normalizeDateTime(d.ksrq),
|
||||||
|
jsrq: this.normalizeDateTime(d.jsrq),
|
||||||
|
ts: d.ts === null || d.ts === undefined ? null : d.ts,
|
||||||
|
jbksl: d.jbksl === null || d.jbksl === undefined ? null : d.jbksl,
|
||||||
|
kslx: d.kslx || '',
|
||||||
|
xmlx: d.xmlx || '',
|
||||||
|
sm: d.sm || '',
|
||||||
|
bz: d.bz || ''
|
||||||
|
}
|
||||||
|
this.dialogTitle = '修改联教联训'
|
||||||
|
this.dialogVisible = true
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.formRef.validate(valid => {
|
||||||
|
if (!valid) {
|
||||||
|
this.$message.warning('请完善必填项后再提交')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const payload = this.buildPayload()
|
||||||
|
this.saving = true
|
||||||
|
const req = payload.bh ? updateJointTraining(payload) : addJointTraining(payload)
|
||||||
|
req.then(() => {
|
||||||
|
this.$message.success(this.dialogTitle === '修改联教联训' ? '修改成功' : '新增成功')
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 构建请求体,仅含实体非空字段(创建/修改时间为后端自动维护,不传) */
|
||||||
|
buildPayload() {
|
||||||
|
const f = this.form
|
||||||
|
const payload = {}
|
||||||
|
if (f.bh && f.bh.trim()) payload.bh = f.bh.trim()
|
||||||
|
if (f.mc && f.mc.trim()) payload.mc = f.mc.trim()
|
||||||
|
if (f.xz && f.xz.trim()) payload.xz = f.xz.trim()
|
||||||
|
if (f.yj && f.yj.trim()) payload.yj = f.yj.trim()
|
||||||
|
if (f.ksrq) payload.ksrq = f.ksrq
|
||||||
|
if (f.jsrq) payload.jsrq = f.jsrq
|
||||||
|
if (f.ts !== null && f.ts !== undefined) payload.ts = f.ts
|
||||||
|
if (f.jbksl !== null && f.jbksl !== undefined) payload.jbksl = f.jbksl
|
||||||
|
if (f.kslx && f.kslx.trim()) payload.kslx = f.kslx.trim()
|
||||||
|
if (f.xmlx && f.xmlx.trim()) payload.xmlx = f.xmlx.trim()
|
||||||
|
if (f.sm && f.sm.trim()) payload.sm = f.sm.trim()
|
||||||
|
if (f.bz && f.bz.trim()) payload.bz = f.bz.trim()
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 删除 ====================
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm(`确定要删除「${row.mc || row.bh || '该记录'}」吗?`, '系统提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => deleteJointTraining(row.bh)).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
handleDetail(row) {
|
||||||
|
getJointTraining(row.bh).then(res => {
|
||||||
|
this.detailData = (res && res.data) || {}
|
||||||
|
this.detailVisible = true
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 导出 ====================
|
||||||
|
handleExport() {
|
||||||
|
exportJointTraining().then(blob => {
|
||||||
|
saveAs(blob, '联教联训管理.xlsx')
|
||||||
|
this.$message.success('导出成功')
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 文件选择与导入 ====================
|
||||||
handleChooseFile() {
|
handleChooseFile() {
|
||||||
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
||||||
},
|
},
|
||||||
@@ -275,48 +410,31 @@ export default {
|
|||||||
this.selectedFile = (input.files && input.files[0]) || null
|
this.selectedFile = (input.files && input.files[0]) || null
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 下载模板(生成 CSV 模板文件,字段对齐后端接口) */
|
|
||||||
handleDownloadTemplate() {
|
|
||||||
const csvContent = '\uFEFF' + '任务编号,名称,教员编号,任务类别,课时量,合班类型,是否评优,年度,学期,说明\n'
|
|
||||||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
|
|
||||||
const link = document.createElement('a')
|
|
||||||
link.href = URL.createObjectURL(blob)
|
|
||||||
link.download = '联教联训数据文件模板.csv'
|
|
||||||
link.click()
|
|
||||||
URL.revokeObjectURL(link.href)
|
|
||||||
this.$message.success('已下载联教联训数据文件模板')
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO: 后端接口未提供,上传为前端模拟;接口就绪后替换为 /log/joint-training/import-excel
|
|
||||||
handleUpload() {
|
handleUpload() {
|
||||||
if (!this.selectedFile) {
|
if (!this.selectedFile) {
|
||||||
this.$message.warning('请先选择文件')
|
this.$message.warning('请先选择文件')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$message.success(`文件「${this.selectedFile.name}」上传成功(前端模拟)`)
|
this.uploading = true
|
||||||
this.selectedFile = null
|
importJointTraining(this.selectedFile).then(res => {
|
||||||
this.handleQuery()
|
const count = res && res.data
|
||||||
|
if (count !== null && count !== undefined) {
|
||||||
|
this.$message.success(`导入成功,共 ${count} 条记录`)
|
||||||
|
} else {
|
||||||
|
this.$message.success((res && res.msg) || '导入成功')
|
||||||
|
}
|
||||||
|
this.selectedFile = null
|
||||||
|
this.$refs.fileInputRef && (this.$refs.fileInputRef.value = '')
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.uploading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 4. 添加 ====================
|
handleDownloadTemplate() {
|
||||||
// TODO: 后端接口未提供,提交为前端模拟;接口就绪后替换为 addJointTraining
|
// 后端暂未提供模板下载接口,仅作提示
|
||||||
handleAdd() {
|
this.$message.info('后端暂未提供该接口')
|
||||||
this.$refs.formRef.validate((valid) => {
|
|
||||||
if (!valid) {
|
|
||||||
this.$message.warning('请完善必填项后再提交')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.addLoading = true
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$message.success('添加成功(前端模拟)')
|
|
||||||
Object.assign(this.form, {
|
|
||||||
bh: this.genBh(), mc: '', jybh: '', rwlb: '', ksl: '',
|
|
||||||
hflx: 0, sfpy: 0, nd: '2026', xq: '2026-2027-1', sm: ''
|
|
||||||
})
|
|
||||||
this.handleQuery()
|
|
||||||
this.addLoading = false
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,30 +465,19 @@ export default {
|
|||||||
.search-actions {
|
.search-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-top: 8px;
|
align-items: center;
|
||||||
padding-top: 12px;
|
height: 40px;
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-title {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 2. 文件操作区域 ====================
|
// ==================== 2. 操作区域 ====================
|
||||||
.upload-card {
|
.upload-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
.upload-row {
|
.upload-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
|
||||||
@@ -390,12 +497,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-tip {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #f56c6c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 3. 数据表格 ====================
|
// ==================== 3. 数据表格 ====================
|
||||||
@@ -414,6 +515,17 @@ export default {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 4. 新增/修改表单 ====================
|
||||||
|
.add-form {
|
||||||
|
max-height: 62vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,15 +1,679 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container plan-page">
|
||||||
<placeholder-page title="方案管理" icon="documentation"
|
|
||||||
description="用于维护课时的各类方案信息,如教学方案的配置、启用与调整,支持查询与维护。" />
|
<!-- ==================== Tab 切换 ==================== -->
|
||||||
|
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||||
|
<el-tab-pane label="课时费方案" name="fee" />
|
||||||
|
<el-tab-pane label="课时方案" name="coeff" />
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
<!-- ==================== 1. 查询与新增 ==================== -->
|
||||||
|
<el-card shadow="never" class="search-card">
|
||||||
|
<el-form :inline="true" class="search-form" @submit.native.prevent>
|
||||||
|
<el-form-item label="名称">
|
||||||
|
<el-input v-model="currentForm.mc" placeholder="请输入名称" clearable style="width: 220px" @keyup.enter.native="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleAdd">新增{{ currentTitle }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- ==================== 2. 数据表格 ==================== -->
|
||||||
|
<el-card shadow="never" class="table-card">
|
||||||
|
<!-- 课时费方案 -->
|
||||||
|
<el-table v-if="activeTab === 'fee'" v-loading="feeState.loading" :data="feeState.list" border stripe style="width: 100%">
|
||||||
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
|
<el-table-column prop="bh" label="编号" width="150" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="mc" label="名称" min-width="130" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="mrbzksl" label="默认标准课时量" width="120" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.mrbzksl) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="mrksfbz" label="默认课时费标准" width="120" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.mrksfbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="mrclksfbz" label="默认超量课时费标准" width="150" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.mrclksfbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="xgjxbzksfbz" label="相关教学补助课时费标准" width="180" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.xgjxbzksfbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="jxyxbz" label="绩效优秀补助" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.jxyxbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="jxlhbz" label="绩效良好补助" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.jxlhbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="jxzdbz" label="绩效中等补助" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.jxzdbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="jxjgbz" label="绩效及格补助" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.jxjgbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="jxbjgbz" label="绩效不及格补助" width="120" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.jxbjgbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="sm" label="说明" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="160" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button type="text" size="small" @click="handleEdit(row)">修改</el-button>
|
||||||
|
<el-button type="text" size="small" class="text-danger" @click="handleDelete(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 课时方案 -->
|
||||||
|
<el-table v-else v-loading="coeffState.loading" :data="coeffState.list" border stripe style="width: 100%">
|
||||||
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
|
<el-table-column prop="bh" label="编号" width="150" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="mc" label="名称" min-width="130" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="zjksxs" label="主讲课时系数" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.zjksxs) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="fjksxs" label="辅讲课时系数" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.fjksxs) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="mbxyrs" label="满班学员人数" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.mbxyrs) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="dz10xybjxs" label="递增10学员班级系数" width="150" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.dz10xybjxs) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="bjxssx" label="班级系数上限" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.bjxssx) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="d78jksl" label="第78节课时量" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.d78jksl) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="yjksl" label="夜间课时量" width="100" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.yjksl) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="mrktjxffxs" label="默认课堂教法系数" width="130" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.mrktjxffxs) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="hbxszl" label="合班系数增量" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.hbxszl) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="hbxssx" label="合班系数上限" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.hbxssx) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="sm" label="说明" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button type="text" size="small" @click="handleEdit(row)">修改</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
:current-page="currentState.pageNum"
|
||||||
|
:page-size="currentState.pageSize"
|
||||||
|
:total="currentState.total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- ==================== 3. 新增/修改对话框 ==================== -->
|
||||||
|
<el-dialog
|
||||||
|
:visible="dialogVisible"
|
||||||
|
:title="dialogTitle"
|
||||||
|
width="760px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => dialogVisible = val"
|
||||||
|
>
|
||||||
|
<!-- 课时费方案表单 -->
|
||||||
|
<el-form v-if="activeTab === 'fee'" ref="feeFormRef" :model="feeForm" :rules="feeRules" label-width="160px" class="add-form">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="编号">
|
||||||
|
<el-input v-model="feeForm.bh" placeholder="留空则自动生成" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="名称" prop="mc">
|
||||||
|
<el-input v-model="feeForm.mc" placeholder="请输入名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="默认标准课时量" prop="mrbzksl">
|
||||||
|
<el-input-number v-model="feeForm.mrbzksl" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="默认课时费标准" prop="mrksfbz">
|
||||||
|
<el-input-number v-model="feeForm.mrksfbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="默认超量课时费标准" prop="mrclksfbz">
|
||||||
|
<el-input-number v-model="feeForm.mrclksfbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="相关教学补助课时费标准" prop="xgjxbzksfbz">
|
||||||
|
<el-input-number v-model="feeForm.xgjxbzksfbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绩效优秀补助" prop="jxyxbz">
|
||||||
|
<el-input-number v-model="feeForm.jxyxbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绩效良好补助" prop="jxlhbz">
|
||||||
|
<el-input-number v-model="feeForm.jxlhbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绩效中等补助" prop="jxzdbz">
|
||||||
|
<el-input-number v-model="feeForm.jxzdbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绩效及格补助" prop="jxjgbz">
|
||||||
|
<el-input-number v-model="feeForm.jxjgbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绩效不及格补助" prop="jxbjgbz">
|
||||||
|
<el-input-number v-model="feeForm.jxbjgbz" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="说明">
|
||||||
|
<el-input v-model="feeForm.sm" type="textarea" :rows="2" placeholder="请输入说明" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="feeForm.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 课时方案表单 -->
|
||||||
|
<el-form v-else ref="coeffFormRef" :model="coeffForm" :rules="coeffRules" label-width="160px" class="add-form">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="编号">
|
||||||
|
<el-input v-model="coeffForm.bh" placeholder="留空则自动生成" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="名称" prop="mc">
|
||||||
|
<el-input v-model="coeffForm.mc" placeholder="请输入名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="主讲课时系数">
|
||||||
|
<el-input-number v-model="coeffForm.zjksxs" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="辅讲课时系数">
|
||||||
|
<el-input-number v-model="coeffForm.fjksxs" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="满班学员人数">
|
||||||
|
<el-input-number v-model="coeffForm.mbxyrs" :min="0" :precision="0" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="递增10学员班级系数">
|
||||||
|
<el-input-number v-model="coeffForm.dz10xybjxs" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="班级系数上限">
|
||||||
|
<el-input-number v-model="coeffForm.bjxssx" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="第78节课时量">
|
||||||
|
<el-input-number v-model="coeffForm.d78jksl" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="夜间课时量">
|
||||||
|
<el-input-number v-model="coeffForm.yjksl" :min="0" :precision="2" :step="1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="默认课堂教学方法系数">
|
||||||
|
<el-input-number v-model="coeffForm.mrktjxffxs" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="合班系数增量">
|
||||||
|
<el-input-number v-model="coeffForm.hbxszl" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="合班系数上限">
|
||||||
|
<el-input-number v-model="coeffForm.hbxssx" :min="0" :precision="2" :step="0.1" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="说明">
|
||||||
|
<el-input v-model="coeffForm.sm" type="textarea" :rows="2" placeholder="请输入说明" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="coeffForm.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="saving" @click="handleSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ==================== 4. 详情对话框 ==================== -->
|
||||||
|
<el-dialog :visible="detailVisible" :title="`${currentTitle}详情`" width="680px" @update:visible="val => detailVisible = val">
|
||||||
|
<el-descriptions v-if="activeTab === 'fee'" :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailData.bh }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="名称">{{ detailData.mc }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="默认标准课时量">{{ fmtValue(detailData.mrbzksl) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="默认课时费标准">{{ fmtValue(detailData.mrksfbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="默认超量课时费标准">{{ fmtValue(detailData.mrclksfbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="相关教学补助课时费标准">{{ fmtValue(detailData.xgjxbzksfbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="绩效优秀补助">{{ fmtValue(detailData.jxyxbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="绩效良好补助">{{ fmtValue(detailData.jxlhbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="绩效中等补助">{{ fmtValue(detailData.jxzdbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="绩效及格补助">{{ fmtValue(detailData.jxjgbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="绩效不及格补助">{{ fmtValue(detailData.jxbjgbz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ fmtEmpty(detailData.cjsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="说明" :span="2">{{ fmtEmpty(detailData.sm) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ fmtEmpty(detailData.bz) }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<el-descriptions v-else :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailData.bh }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="名称">{{ detailData.mc }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="主讲课时系数">{{ fmtValue(detailData.zjksxs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="辅讲课时系数">{{ fmtValue(detailData.fjksxs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="满班学员人数">{{ fmtValue(detailData.mbxyrs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="递增10学员班级系数">{{ fmtValue(detailData.dz10xybjxs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="班级系数上限">{{ fmtValue(detailData.bjxssx) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="第78节课时量">{{ fmtValue(detailData.d78jksl) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="夜间课时量">{{ fmtValue(detailData.yjksl) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="默认课堂教学方法系数">{{ fmtValue(detailData.mrktjxffxs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合班系数增量">{{ fmtValue(detailData.hbxszl) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合班系数上限">{{ fmtValue(detailData.hbxssx) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ fmtEmpty(detailData.cjsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="说明" :span="2">{{ fmtEmpty(detailData.sm) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ fmtEmpty(detailData.bz) }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="detailVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PlaceholderPage from "@/components/PlaceholderPage"
|
import {
|
||||||
|
listFeeStandard,
|
||||||
|
getFeeStandard,
|
||||||
|
addFeeStandard,
|
||||||
|
updateFeeStandard,
|
||||||
|
deleteFeeStandard,
|
||||||
|
listCoefficientPlan,
|
||||||
|
getCoefficientPlan,
|
||||||
|
addCoefficientPlan,
|
||||||
|
updateCoefficientPlan
|
||||||
|
} from '@/api/classHour/plan'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ClassHourPlan",
|
name: 'ClassHourPlan',
|
||||||
components: { PlaceholderPage }
|
data() {
|
||||||
|
return {
|
||||||
|
// ==================== Tab ====================
|
||||||
|
activeTab: 'fee',
|
||||||
|
|
||||||
|
// ==================== 查询条件 ====================
|
||||||
|
feeSearch: { mc: '' },
|
||||||
|
coeffSearch: { mc: '' },
|
||||||
|
|
||||||
|
// ==================== 列表状态 ====================
|
||||||
|
feeState: this.createEmptyState(),
|
||||||
|
coeffState: this.createEmptyState(),
|
||||||
|
|
||||||
|
// ==================== 新增/修改 ====================
|
||||||
|
dialogVisible: false,
|
||||||
|
dialogTitle: '',
|
||||||
|
saving: false,
|
||||||
|
feeForm: this.createEmptyFeeForm(),
|
||||||
|
coeffForm: this.createEmptyCoeffForm(),
|
||||||
|
feeRules: {
|
||||||
|
mc: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
||||||
|
mrbzksl: [{ required: true, message: '请输入默认标准课时量', trigger: 'blur' }],
|
||||||
|
mrksfbz: [{ required: true, message: '请输入默认课时费标准', trigger: 'blur' }],
|
||||||
|
mrclksfbz: [{ required: true, message: '请输入默认超量课时费标准', trigger: 'blur' }],
|
||||||
|
xgjxbzksfbz: [{ required: true, message: '请输入相关教学补助课时费标准', trigger: 'blur' }],
|
||||||
|
jxyxbz: [{ required: true, message: '请输入绩效优秀补助', trigger: 'blur' }],
|
||||||
|
jxlhbz: [{ required: true, message: '请输入绩效良好补助', trigger: 'blur' }],
|
||||||
|
jxzdbz: [{ required: true, message: '请输入绩效中等补助', trigger: 'blur' }],
|
||||||
|
jxjgbz: [{ required: true, message: '请输入绩效及格补助', trigger: 'blur' }],
|
||||||
|
jxbjgbz: [{ required: true, message: '请输入绩效不及格补助', trigger: 'blur' }]
|
||||||
|
},
|
||||||
|
coeffRules: {
|
||||||
|
mc: [{ required: true, message: '请输入名称', trigger: 'blur' }]
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
detailVisible: false,
|
||||||
|
detailData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentForm() {
|
||||||
|
return this.activeTab === 'fee' ? this.feeSearch : this.coeffSearch
|
||||||
|
},
|
||||||
|
currentState() {
|
||||||
|
return this.activeTab === 'fee' ? this.feeState : this.coeffState
|
||||||
|
},
|
||||||
|
currentTitle() {
|
||||||
|
return this.activeTab === 'fee' ? '课时费方案' : '课时方案'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
createEmptyState() {
|
||||||
|
return { list: [], loading: false, pageNum: 1, pageSize: 10, total: 0 }
|
||||||
|
},
|
||||||
|
|
||||||
|
createEmptyFeeForm() {
|
||||||
|
return {
|
||||||
|
bh: '',
|
||||||
|
mc: '',
|
||||||
|
mrbzksl: null,
|
||||||
|
mrksfbz: null,
|
||||||
|
mrclksfbz: null,
|
||||||
|
xgjxbzksfbz: null,
|
||||||
|
jxyxbz: null,
|
||||||
|
jxlhbz: null,
|
||||||
|
jxzdbz: null,
|
||||||
|
jxjgbz: null,
|
||||||
|
jxbjgbz: null,
|
||||||
|
sm: '',
|
||||||
|
bz: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createEmptyCoeffForm() {
|
||||||
|
return {
|
||||||
|
bh: '',
|
||||||
|
mc: '',
|
||||||
|
zjksxs: null,
|
||||||
|
fjksxs: null,
|
||||||
|
mbxyrs: null,
|
||||||
|
dz10xybjxs: null,
|
||||||
|
bjxssx: null,
|
||||||
|
d78jksl: null,
|
||||||
|
yjksl: null,
|
||||||
|
mrktjxffxs: null,
|
||||||
|
hbxszl: null,
|
||||||
|
hbxssx: null,
|
||||||
|
sm: '',
|
||||||
|
bz: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 查询 ====================
|
||||||
|
fetchList() {
|
||||||
|
const state = this.currentState
|
||||||
|
const params = { pageNum: state.pageNum, pageSize: state.pageSize }
|
||||||
|
if (this.currentForm.mc && this.currentForm.mc.trim()) params.mc = this.currentForm.mc.trim()
|
||||||
|
state.loading = true
|
||||||
|
const req = this.activeTab === 'fee' ? listFeeStandard(params) : listCoefficientPlan(params)
|
||||||
|
req.then(res => {
|
||||||
|
const data = (res && res.data) || {}
|
||||||
|
state.list = data.records || []
|
||||||
|
state.total = data.total || 0
|
||||||
|
}).catch(() => {
|
||||||
|
state.list = []
|
||||||
|
state.total = 0
|
||||||
|
}).finally(() => {
|
||||||
|
state.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTabClick() {
|
||||||
|
this.currentState.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleQuery() {
|
||||||
|
this.currentState.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.currentState.pageNum = page
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.currentState.pageSize = size
|
||||||
|
this.currentState.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 新增 / 修改 ====================
|
||||||
|
handleAdd() {
|
||||||
|
this.feeForm = this.createEmptyFeeForm()
|
||||||
|
this.coeffForm = this.createEmptyCoeffForm()
|
||||||
|
this.dialogTitle = `新增${this.currentTitle}`
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEdit(row) {
|
||||||
|
const req = this.activeTab === 'fee' ? getFeeStandard(row.bh) : getCoefficientPlan(row.bh)
|
||||||
|
req.then(res => {
|
||||||
|
const d = (res && res.data) || {}
|
||||||
|
if (this.activeTab === 'fee') {
|
||||||
|
this.feeForm = {
|
||||||
|
bh: d.bh || '',
|
||||||
|
mc: d.mc || '',
|
||||||
|
mrbzksl: this.toNull(d.mrbzksl),
|
||||||
|
mrksfbz: this.toNull(d.mrksfbz),
|
||||||
|
mrclksfbz: this.toNull(d.mrclksfbz),
|
||||||
|
xgjxbzksfbz: this.toNull(d.xgjxbzksfbz),
|
||||||
|
jxyxbz: this.toNull(d.jxyxbz),
|
||||||
|
jxlhbz: this.toNull(d.jxlhbz),
|
||||||
|
jxzdbz: this.toNull(d.jxzdbz),
|
||||||
|
jxjgbz: this.toNull(d.jxjgbz),
|
||||||
|
jxbjgbz: this.toNull(d.jxbjgbz),
|
||||||
|
sm: d.sm || '',
|
||||||
|
bz: d.bz || ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.coeffForm = {
|
||||||
|
bh: d.bh || '',
|
||||||
|
mc: d.mc || '',
|
||||||
|
zjksxs: this.toNull(d.zjksxs),
|
||||||
|
fjksxs: this.toNull(d.fjksxs),
|
||||||
|
mbxyrs: this.toNull(d.mbxyrs),
|
||||||
|
dz10xybjxs: this.toNull(d.dz10xybjxs),
|
||||||
|
bjxssx: this.toNull(d.bjxssx),
|
||||||
|
d78jksl: this.toNull(d.d78jksl),
|
||||||
|
yjksl: this.toNull(d.yjksl),
|
||||||
|
mrktjxffxs: this.toNull(d.mrktjxffxs),
|
||||||
|
hbxszl: this.toNull(d.hbxszl),
|
||||||
|
hbxssx: this.toNull(d.hbxssx),
|
||||||
|
sm: d.sm || '',
|
||||||
|
bz: d.bz || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dialogTitle = `修改${this.currentTitle}`
|
||||||
|
this.dialogVisible = true
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit() {
|
||||||
|
const isFee = this.activeTab === 'fee'
|
||||||
|
const formRef = isFee ? this.$refs.feeFormRef : this.$refs.coeffFormRef
|
||||||
|
formRef.validate(valid => {
|
||||||
|
if (!valid) {
|
||||||
|
this.$message.warning('请完善必填项后再提交')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const payload = isFee ? this.buildFeePayload() : this.buildCoeffPayload()
|
||||||
|
this.saving = true
|
||||||
|
const req = payload.bh
|
||||||
|
? (isFee ? updateFeeStandard(payload) : updateCoefficientPlan(payload))
|
||||||
|
: (isFee ? addFeeStandard(payload) : addCoefficientPlan(payload))
|
||||||
|
req.then(() => {
|
||||||
|
this.$message.success(this.dialogTitle.indexOf('修改') === 0 ? '修改成功' : '新增成功')
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toNull(val) {
|
||||||
|
return val === null || val === undefined ? null : val
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 课时费方案请求体:仅含实体非空字段(创建/修改时间后端自动维护) */
|
||||||
|
buildFeePayload() {
|
||||||
|
const f = this.feeForm
|
||||||
|
const p = {}
|
||||||
|
if (f.bh && f.bh.trim()) p.bh = f.bh.trim()
|
||||||
|
if (f.mc && f.mc.trim()) p.mc = f.mc.trim()
|
||||||
|
;['mrbzksl', 'mrksfbz', 'mrclksfbz', 'xgjxbzksfbz', 'jxyxbz', 'jxlhbz', 'jxzdbz', 'jxjgbz', 'jxbjgbz'].forEach(k => {
|
||||||
|
if (f[k] !== null && f[k] !== undefined) p[k] = f[k]
|
||||||
|
})
|
||||||
|
if (f.sm && f.sm.trim()) p.sm = f.sm.trim()
|
||||||
|
if (f.bz && f.bz.trim()) p.bz = f.bz.trim()
|
||||||
|
return p
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 课时方案请求体:仅含实体非空字段 */
|
||||||
|
buildCoeffPayload() {
|
||||||
|
const f = this.coeffForm
|
||||||
|
const p = {}
|
||||||
|
if (f.bh && f.bh.trim()) p.bh = f.bh.trim()
|
||||||
|
if (f.mc && f.mc.trim()) p.mc = f.mc.trim()
|
||||||
|
;['zjksxs', 'fjksxs', 'mbxyrs', 'dz10xybjxs', 'bjxssx', 'd78jksl', 'yjksl', 'mrktjxffxs', 'hbxszl', 'hbxssx'].forEach(k => {
|
||||||
|
if (f[k] !== null && f[k] !== undefined) p[k] = f[k]
|
||||||
|
})
|
||||||
|
if (f.sm && f.sm.trim()) p.sm = f.sm.trim()
|
||||||
|
if (f.bz && f.bz.trim()) p.bz = f.bz.trim()
|
||||||
|
return p
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 删除(仅课时费方案有删除接口) ====================
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm(`确定要删除「${row.mc || row.bh || '该方案'}」吗?`, '系统提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => deleteFeeStandard(row.bh)).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
handleDetail(row) {
|
||||||
|
const req = this.activeTab === 'fee' ? getFeeStandard(row.bh) : getCoefficientPlan(row.bh)
|
||||||
|
req.then(res => {
|
||||||
|
this.detailData = (res && res.data) || {}
|
||||||
|
this.detailVisible = true
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数值空值显示为 '-'(保留 0) */
|
||||||
|
fmtValue(val) {
|
||||||
|
return val === null || val === undefined ? '-' : val
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 空值显示为 '-' */
|
||||||
|
fmtEmpty(val) {
|
||||||
|
return val === null || val === undefined || val === '' ? '-' : val
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.app-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-page {
|
||||||
|
.list-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 1. 查询区域 ====================
|
||||||
|
.search-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 2. 数据表格 ====================
|
||||||
|
.table-card {
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 3. 新增/修改表单 ====================
|
||||||
|
.add-form {
|
||||||
|
max-height: 62vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 4px;
|
||||||
|
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,223 +1,250 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container subsidy-page">
|
<div class="app-container subsidy-page">
|
||||||
<div class="list-title">课时补助核算</div>
|
<div class="list-title">课时补助核算</div>
|
||||||
<div class="top-tip">{{ tipText }}</div>
|
|
||||||
|
|
||||||
<!-- ==================== 1. 新增核算区域 ==================== -->
|
<!-- ==================== Tab 切换 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||||
<div class="form-title">新增</div>
|
<el-tab-pane label="课时统计" name="hour" />
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="search-form">
|
<el-tab-pane label="课时费统计" name="fee" />
|
||||||
<el-row :gutter="0">
|
</el-tabs>
|
||||||
<!-- 左栏 -->
|
|
||||||
<el-col :span="12">
|
<!-- ==================== 1. 查询条件 ==================== -->
|
||||||
<el-form-item label="学期名称" prop="semesterName">
|
<!-- 课时统计 -->
|
||||||
<el-input v-model="form.semesterName" placeholder="请输入学期名称" clearable />
|
<el-card v-if="activeTab === 'hour'" shadow="never" class="search-card">
|
||||||
</el-form-item>
|
<el-form :model="hourForm" label-width="100px" class="search-form" @submit.native.prevent>
|
||||||
<el-form-item label="开始日期" prop="startDate">
|
<el-row :gutter="24">
|
||||||
<el-input v-model="form.startDate" placeholder="如:2016-03-01" clearable />
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
</el-form-item>
|
<el-form-item label="学期年度">
|
||||||
<el-form-item label="课时补助标准">
|
<el-input v-model="hourForm.nd" placeholder="如 2026" clearable />
|
||||||
<el-select v-model="form.subsidyStandard" placeholder="请选择" class="w-full">
|
|
||||||
<el-option v-for="item in subsidyStandardOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
<!-- 右栏 -->
|
<el-form-item label="学期序号">
|
||||||
<el-col :span="12">
|
<el-input v-model="hourForm.xq" placeholder="如 1" clearable />
|
||||||
<el-form-item label="任务类别">
|
|
||||||
<el-radio-group v-model="form.taskCategory">
|
|
||||||
<el-radio v-for="item in taskCategoryOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="结束日期" prop="endDate">
|
</el-col>
|
||||||
<el-input v-model="form.endDate" placeholder="如:2016-08-31" clearable />
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
</el-form-item>
|
<el-form-item label="教员姓名">
|
||||||
<el-form-item label="课时核算标准">
|
<el-input v-model="hourForm.jyxm" placeholder="请输入教员姓名" clearable @keyup.enter.native="handleQuery" />
|
||||||
<el-select v-model="form.accountStandard" placeholder="请选择" class="w-full">
|
|
||||||
<el-option v-for="item in accountStandardOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="6" class="search-actions-col">
|
||||||
|
<div class="search-actions">
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleExport">导出 Excel</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 课时费统计 -->
|
||||||
|
<el-card v-else shadow="never" class="search-card">
|
||||||
|
<el-form :model="feeForm" label-width="100px" class="search-form" @submit.native.prevent>
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
|
<el-form-item label="学期年度">
|
||||||
|
<el-input v-model="feeForm.nd" placeholder="如 2026" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
|
<el-form-item label="学期序号">
|
||||||
|
<el-input v-model="feeForm.xq" placeholder="如 1" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
|
<el-form-item label="教员姓名">
|
||||||
|
<el-input v-model="feeForm.jyxm" placeholder="请输入教员姓名" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
|
<el-form-item label="标准编号">
|
||||||
|
<el-input v-model="feeForm.ksfbzbh" placeholder="课时费标准编号" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24" class="search-actions-col">
|
||||||
|
<div class="search-actions">
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleExport">导出 Excel</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="search-actions">
|
|
||||||
<el-button type="primary" :loading="addLoading" @click="handleAdd">添加</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 2. 数据表格 ==================== -->
|
<!-- ==================== 2. 数据表格 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table v-loading="queryLoading" :data="tableData" border stripe style="width: 100%">
|
<div class="table-title">{{ activeTab === 'hour' ? '课时统计列表' : '课时费统计列表' }}</div>
|
||||||
<el-table-column label="详细" width="80" fixed align="center">
|
<el-table v-loading="currentState.loading" :data="currentState.list" border stripe style="width: 100%">
|
||||||
<template slot-scope="{ row }">
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-button type="text" @click="handleDetail(row)">详细</el-button>
|
<el-table-column prop="jysdh" label="教研室代号" width="100" align="center" show-overflow-tooltip />
|
||||||
</template>
|
<el-table-column prop="jysmc" label="教研室名称" width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="jybh" label="教员编号" width="110" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="jyxm" label="教员姓名" width="100" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="zc" label="职称" width="90" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="nf" label="年份" width="70" align="center" />
|
||||||
|
<el-table-column prop="sbn" label="上半年" width="90" align="right" header-align="center">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.sbn) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="semesterName" label="学期名称" width="120" />
|
<el-table-column prop="xbn" label="下半年" width="90" align="right" header-align="center">
|
||||||
<el-table-column prop="taskCategory" label="任务类别" width="180" />
|
<template slot-scope="{ row }">{{ fmtValue(row.xbn) }}</template>
|
||||||
<el-table-column prop="startDate" label="核算开始日期" width="120" />
|
</el-table-column>
|
||||||
<el-table-column prop="endDate" label="核算结束日期" width="120" />
|
<el-table-column prop="zj" label="总计" width="90" align="right" header-align="center">
|
||||||
<el-table-column prop="totalHours" label="总课时量" width="100" align="right" />
|
<template slot-scope="{ row }">{{ fmtValue(row.zj) }}</template>
|
||||||
<el-table-column prop="qualityHours" label="优质课时量" width="100" align="right" />
|
</el-table-column>
|
||||||
<el-table-column prop="qualityRatio" label="优质课时量比例" width="120" align="right" />
|
<el-table-column prop="bzksl" label="标准课时量" width="100" align="right" header-align="center">
|
||||||
<el-table-column prop="totalSubsidy" label="总补助金额" width="120" align="right" />
|
<template slot-scope="{ row }">{{ fmtValue(row.bzksl) }}</template>
|
||||||
<el-table-column prop="accountStandard" label="课时核算标准" show-overflow-tooltip />
|
</el-table-column>
|
||||||
<el-table-column prop="subsidyStandard" label="课时补助标准" width="180" show-overflow-tooltip />
|
<el-table-column prop="cks" label="超课时" width="90" align="right" header-align="center">
|
||||||
<el-table-column prop="status" label="状态" width="100" align="center">
|
<template slot-scope="{ row }">{{ fmtValue(row.cks) }}</template>
|
||||||
<template slot-scope="{ row }">
|
</el-table-column>
|
||||||
<span :class="row.status === '已核算' ? 'status-done' : 'status-doing'">
|
<el-table-column prop="jsgs" label="计算过程" min-width="140" show-overflow-tooltip />
|
||||||
{{ row.status }}
|
<el-table-column prop="jg" label="结果" width="90" align="right" header-align="center">
|
||||||
</span>
|
<template slot-scope="{ row }">{{ fmtValue(row.jg) }}</template>
|
||||||
</template>
|
</el-table-column>
|
||||||
|
<el-table-column prop="ksfbzmc" label="课时费标准" width="110" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="ksfbz" label="课时费单价" width="100" align="right" header-align="center">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.ksfbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="clksfbz" label="超量课时费单价" width="110" align="right" header-align="center">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.clksfbz) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="table-footer">
|
<el-pagination
|
||||||
<span>总记录数:{{ tableData.length }} 条</span>
|
:current-page="currentState.pageNum"
|
||||||
<span>总课时量:{{ totalHours }}</span>
|
:page-size="currentState.pageSize"
|
||||||
<span>优质课时量:{{ totalQualityHours }}</span>
|
:total="currentState.total"
|
||||||
<span>总补助金额:{{ totalSubsidy }} 元</span>
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
</div>
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 3. 详情对话框 ==================== -->
|
|
||||||
<el-dialog
|
|
||||||
:visible="detailVisible"
|
|
||||||
title="课时补助核算详情"
|
|
||||||
width="560px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
@update:visible="val => detailVisible = val"
|
|
||||||
>
|
|
||||||
<el-descriptions v-if="detailRow" :column="1" border>
|
|
||||||
<el-descriptions-item label="学期名称">{{ detailRow.semesterName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="任务类别">{{ detailRow.taskCategory }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="核算开始日期">{{ detailRow.startDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="核算结束日期">{{ detailRow.endDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="总课时量">{{ detailRow.totalHours }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="优质课时量">{{ detailRow.qualityHours }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="优质课时量比例">{{ detailRow.qualityRatio }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="总补助金额">{{ detailRow.totalSubsidy }} 元</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="课时核算标准">{{ detailRow.accountStandard }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="课时补助标准">{{ detailRow.subsidyStandard }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="状态">{{ detailRow.status }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
<div slot="footer">
|
|
||||||
<el-button @click="detailVisible = false">关闭</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟核算列表数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import { saveAs } from 'file-saver'
|
||||||
const mockSummaryData = [
|
import {
|
||||||
{ bh: 'H001', mc: '2022年秋季学期课时补助核算', rwlb: '全军院校训练规划内任务', hsksrq: '2022-09-01T00:00:00', hsjsrq: '2023-01-15T00:00:00', zksl: 1200, yzksl: 800, yzkslbl: 0.6667, zbzje: 24000, zt: '已核算' },
|
listHourStatistics,
|
||||||
{ bh: 'H002', mc: '2022年春季学期课时补助核算', rwlb: '其他任务(含研究生导师指导)', hsksrq: '2022-03-01T00:00:00', hsjsrq: '2022-08-31T00:00:00', zksl: 900, yzksl: 540, yzkslbl: 0.6, zbzje: 18000, zt: '核算中' },
|
exportHourStatistics,
|
||||||
{ bh: 'H003', mc: '2021年秋季学期课时补助核算', rwlb: '全军院校训练规划内任务', hsksrq: '2021-09-01T00:00:00', hsjsrq: '2022-01-15T00:00:00', zksl: 1100, yzksl: 770, yzkslbl: 0.7, zbzje: 22000, zt: '已核算' }
|
listFeeStatistics,
|
||||||
]
|
exportFeeStatistics
|
||||||
|
} from '@/api/classHour/hourStat'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SubsidyIndex',
|
name: 'SubsidyIndex',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 顶部提示条 ====================
|
// ==================== Tab ====================
|
||||||
tipText: '提示:"课时核算"和"补助核算"要花费稍微长一点时间,操作后请耐心等待系统"操作成功"的提示!',
|
activeTab: 'hour',
|
||||||
|
|
||||||
// ==================== 下拉选项 ====================
|
// ==================== 课时统计查询条件 ====================
|
||||||
subsidyStandardOptions: ['2022年秋季学期', '2022年春季学期', '2021年秋季学期', '2021年春季学期'],
|
hourForm: {
|
||||||
accountStandardOptions: ['2022年秋季学期课时补助核算', '2022年春季学期课时补助核算', '2021年秋季学期课时补助核算', '2021年春季学期课时补助核算'],
|
nd: '',
|
||||||
taskCategoryOptions: [
|
xq: '',
|
||||||
{ label: '全军院校训练规划内任务', value: '全军院校训练规划内任务' },
|
jyxm: ''
|
||||||
{ label: '其他任务(含研究生导师指导)', value: '其他任务(含研究生导师指导)' }
|
|
||||||
],
|
|
||||||
|
|
||||||
// ==================== 新增表单 ====================
|
|
||||||
form: {
|
|
||||||
semesterName: '',
|
|
||||||
taskCategory: '全军院校训练规划内任务',
|
|
||||||
startDate: '',
|
|
||||||
endDate: '',
|
|
||||||
subsidyStandard: '2022年秋季学期',
|
|
||||||
accountStandard: '2022年秋季学期课时补助核算'
|
|
||||||
},
|
},
|
||||||
rules: {
|
|
||||||
semesterName: [{ required: true, message: '请输入学期名称', trigger: 'blur' }],
|
// ==================== 课时费统计查询条件 ====================
|
||||||
startDate: [{ required: true, message: '请输入开始日期', trigger: 'blur' }],
|
feeForm: {
|
||||||
endDate: [{ required: true, message: '请输入结束日期', trigger: 'blur' }]
|
nd: '',
|
||||||
|
xq: '',
|
||||||
|
jyxm: '',
|
||||||
|
ksfbzbh: ''
|
||||||
},
|
},
|
||||||
addLoading: false,
|
|
||||||
|
|
||||||
// ==================== 表格数据 ====================
|
// ==================== 各 Tab 列表状态 ====================
|
||||||
tableData: [],
|
hourState: this.createEmptyState(),
|
||||||
queryLoading: false,
|
feeState: this.createEmptyState()
|
||||||
|
|
||||||
// ==================== 详情对话框 ====================
|
|
||||||
detailVisible: false,
|
|
||||||
detailRow: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
totalHours() {
|
currentForm() {
|
||||||
return this.tableData.reduce((sum, r) => sum + Number(r.totalHours || 0), 0)
|
return this.activeTab === 'hour' ? this.hourForm : this.feeForm
|
||||||
},
|
},
|
||||||
totalQualityHours() {
|
currentState() {
|
||||||
return this.tableData.reduce((sum, r) => sum + Number(r.qualityHours || 0), 0)
|
return this.activeTab === 'hour' ? this.hourState : this.feeState
|
||||||
},
|
|
||||||
totalSubsidy() {
|
|
||||||
return this.tableData.reduce((sum, r) => sum + Number(r.totalSubsidy || 0), 0)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.handleQuery()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 查询核算列表 ====================
|
createEmptyState() {
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 /log/summary/list
|
return { list: [], loading: false, pageNum: 1, pageSize: 20, total: 0 }
|
||||||
handleQuery() {
|
|
||||||
this.queryLoading = true
|
|
||||||
setTimeout(() => {
|
|
||||||
this.tableData = mockSummaryData.map((item, idx) => ({
|
|
||||||
id: idx + 1,
|
|
||||||
_bh: item.bh || '',
|
|
||||||
semesterName: item.mc || '-',
|
|
||||||
taskCategory: item.rwlb || '-',
|
|
||||||
startDate: (item.hsksrq || '').substring(0, 10) || '-',
|
|
||||||
endDate: (item.hsjsrq || '').substring(0, 10) || '-',
|
|
||||||
totalHours: item.zksl || 0,
|
|
||||||
qualityHours: item.yzksl || 0,
|
|
||||||
qualityRatio: item.zksl > 0 ? ((item.yzkslbl || 0) * 100).toFixed(2) + '%' : '0.00%',
|
|
||||||
totalSubsidy: item.zbzje || 0,
|
|
||||||
accountStandard: item.mc || '-',
|
|
||||||
subsidyStandard: '-',
|
|
||||||
status: item.zt || '-'
|
|
||||||
}))
|
|
||||||
this.$message.success(`查询完成,共 ${this.tableData.length} 条记录(前端模拟)`)
|
|
||||||
this.queryLoading = false
|
|
||||||
}, 200)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 添加 ====================
|
/** 构建查询参数,仅传非空字段(与后端 Query 字段一致) */
|
||||||
// TODO: 后端接口未提供,提交为前端模拟;接口就绪后替换为 /log/subsidy-project/add
|
buildParams(form) {
|
||||||
handleAdd() {
|
const params = {}
|
||||||
this.$refs.formRef.validate((valid) => {
|
if (form.nd && form.nd.trim()) params.nd = form.nd.trim()
|
||||||
if (!valid) {
|
if (form.xq && form.xq.trim()) params.xq = form.xq.trim()
|
||||||
this.$message.warning('请完善必填项后再提交')
|
if (form.jyxm && form.jyxm.trim()) params.jyxm = form.jyxm.trim()
|
||||||
return
|
if (form.ksfbzbh && form.ksfbzbh.trim()) params.ksfbzbh = form.ksfbzbh.trim()
|
||||||
}
|
return params
|
||||||
this.addLoading = true
|
},
|
||||||
setTimeout(() => {
|
|
||||||
this.$message.success('核算提交成功(前端模拟)')
|
// ==================== 查询 ====================
|
||||||
this.handleQuery()
|
fetchList() {
|
||||||
this.addLoading = false
|
const state = this.currentState
|
||||||
}, 300)
|
const form = this.currentForm
|
||||||
|
const params = Object.assign(
|
||||||
|
{ pageNum: state.pageNum, pageSize: state.pageSize },
|
||||||
|
this.buildParams(form)
|
||||||
|
)
|
||||||
|
state.loading = true
|
||||||
|
const req = this.activeTab === 'hour' ? listHourStatistics(params) : listFeeStatistics(params)
|
||||||
|
req.then(res => {
|
||||||
|
const data = (res && res.data) || {}
|
||||||
|
state.list = data.records || []
|
||||||
|
state.total = data.total || 0
|
||||||
|
}).catch(() => {
|
||||||
|
state.list = []
|
||||||
|
state.total = 0
|
||||||
|
}).finally(() => {
|
||||||
|
state.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 详情对话框 ====================
|
handleTabClick() {
|
||||||
handleDetail(row) {
|
this.currentState.pageNum = 1
|
||||||
this.detailRow = row
|
this.fetchList()
|
||||||
this.detailVisible = true
|
},
|
||||||
|
|
||||||
|
handleQuery() {
|
||||||
|
this.currentState.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.currentState.pageNum = page
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.currentState.pageSize = size
|
||||||
|
this.currentState.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 导出 ====================
|
||||||
|
handleExport() {
|
||||||
|
const clean = this.buildParams(this.currentForm)
|
||||||
|
const isHour = this.activeTab === 'hour'
|
||||||
|
const req = isHour ? exportHourStatistics(clean) : exportFeeStatistics(clean)
|
||||||
|
const fileName = isHour ? '课时统计.xlsx' : '课时费统计.xlsx'
|
||||||
|
req.then(blob => {
|
||||||
|
saveAs(blob, fileName)
|
||||||
|
this.$message.success('导出成功')
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数值空值显示为 '-'(保留 0) */
|
||||||
|
fmtValue(val) {
|
||||||
|
return val === null || val === undefined ? '-' : val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,63 +263,37 @@ export default {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-tip {
|
// ==================== 1. 查询条件区域 ====================
|
||||||
color: #f56c6c;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
.form-title {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
.w-full {
|
.search-actions-col {
|
||||||
width: 100%;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-actions {
|
.search-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
gap: 12px;
|
||||||
margin-top: 8px;
|
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 2. 数据表格 ====================
|
||||||
.table-card {
|
.table-card {
|
||||||
.el-table {
|
.table-title {
|
||||||
width: 100%;
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-footer {
|
.pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
justify-content: flex-end;
|
||||||
gap: 24px;
|
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-done {
|
|
||||||
color: #67c23a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-doing {
|
|
||||||
color: #e6a23c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,89 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container home">
|
<div class="app-container home">
|
||||||
<!-- 第一行:信息/日志/公告 -->
|
<!-- 通知公告 -->
|
||||||
<el-row :gutter="20" class="bottom-row">
|
<el-row :gutter="20" class="bottom-row">
|
||||||
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24">
|
||||||
<el-card class="module-card info-card" shadow="hover">
|
|
||||||
<div slot="header" class="card-header">
|
|
||||||
<span><i class="el-icon-phone-outline card-icon"></i> 联系信息</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon"><i class="el-icon-s-promotion"></i></div>
|
|
||||||
<div class="contact-text">
|
|
||||||
<div class="label">官网</div>
|
|
||||||
<el-link href="http://www.roomroot.vip" target="_blank">http://www.roomroot.vip</el-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon"><i class="el-icon-user-solid"></i></div>
|
|
||||||
<div class="contact-text">
|
|
||||||
<div class="label">QQ群</div>
|
|
||||||
<a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=M9y5NjAl44lAL_Vh2crmEehZU_PMU6KS&authKey=ZSDz8hEREWSaPuxQV3gEwqGIaGjfRNnkB4rJjf0IvXhrSUGSGwQFmBA%2Boe8HFxyl&noverify=0&group_code=127358632" target="_blank">127358632</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon"><i class="el-icon-chat-dot-round"></i></div>
|
|
||||||
<div class="contact-text">
|
|
||||||
<div class="label">微信</div>
|
|
||||||
<span>风影随行</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon"><i class="el-icon-money"></i></div>
|
|
||||||
<div class="contact-text">
|
|
||||||
<div class="label">支付宝</div>
|
|
||||||
<span>风影随行</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
|
||||||
<el-card class="module-card log-card" shadow="hover">
|
|
||||||
<div slot="header" class="card-header">
|
|
||||||
<span><i class="el-icon-time card-icon"></i> 登录日志</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body" v-loading="loginLogLoading">
|
|
||||||
<table v-if="loginLogList.length > 0" class="data-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>登录人</th>
|
|
||||||
<th>登录时间</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="item in loginLogList" :key="item.infoId">
|
|
||||||
<td>
|
|
||||||
<i class="el-icon-user table-icon"></i>
|
|
||||||
{{ item.userName }}
|
|
||||||
</td>
|
|
||||||
<td>{{ parseTime(item.loginTime) }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div v-else class="empty-state">
|
|
||||||
<i class="el-icon-folder-opened empty-icon"></i>
|
|
||||||
<p>暂无记录</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<el-pagination
|
|
||||||
@size-change="handleLoginLogSizeChange"
|
|
||||||
@current-change="handleLoginLogCurrentChange"
|
|
||||||
:current-page="loginLogPage.currentPage"
|
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
:page-size="loginLogPage.pageSize"
|
|
||||||
:total="loginLogPage.total"
|
|
||||||
layout="total, prev, pager, next"
|
|
||||||
small
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
|
||||||
<el-card class="module-card notice-card" shadow="hover">
|
<el-card class="module-card notice-card" shadow="hover">
|
||||||
<div slot="header" class="card-header">
|
<div slot="header" class="card-header">
|
||||||
<span><i class="el-icon-bell card-icon"></i> 通知公告</span>
|
<span><i class="el-icon-bell card-icon"></i> 通知公告</span>
|
||||||
@@ -131,7 +50,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listNotice } from "@/api/system/notice"
|
import { listNotice } from "@/api/system/notice"
|
||||||
import { homeList } from "@/api/monitor/logininfor"
|
|
||||||
import NoticeDetailView from "@/layout/components/HeaderNotice/DetailView"
|
import NoticeDetailView from "@/layout/components/HeaderNotice/DetailView"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -142,13 +60,6 @@ export default {
|
|||||||
version: "3.9.2",
|
version: "3.9.2",
|
||||||
noticeList: [],
|
noticeList: [],
|
||||||
noticeLoading: false,
|
noticeLoading: false,
|
||||||
loginLogList: [],
|
|
||||||
loginLogLoading: false,
|
|
||||||
loginLogPage: {
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0
|
|
||||||
},
|
|
||||||
noticePage: {
|
noticePage: {
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -158,7 +69,6 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadNoticeList()
|
this.loadNoticeList()
|
||||||
this.loadLoginLogList()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
goTarget(href) {
|
goTarget(href) {
|
||||||
@@ -208,28 +118,6 @@ export default {
|
|||||||
handleViewNotice(item) {
|
handleViewNotice(item) {
|
||||||
this.$refs.noticeViewRef.open(item)
|
this.$refs.noticeViewRef.open(item)
|
||||||
},
|
},
|
||||||
loadLoginLogList() {
|
|
||||||
this.loginLogLoading = true
|
|
||||||
homeList({
|
|
||||||
pageNum: this.loginLogPage.currentPage,
|
|
||||||
pageSize: this.loginLogPage.pageSize
|
|
||||||
}).then(response => {
|
|
||||||
this.loginLogList = response.rows || []
|
|
||||||
this.loginLogPage.total = response.total || 0
|
|
||||||
this.loginLogLoading = false
|
|
||||||
}).catch(() => {
|
|
||||||
this.loginLogLoading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleLoginLogSizeChange(val) {
|
|
||||||
this.loginLogPage.pageSize = val
|
|
||||||
this.loginLogPage.currentPage = 1
|
|
||||||
this.loadLoginLogList()
|
|
||||||
},
|
|
||||||
handleLoginLogCurrentChange(val) {
|
|
||||||
this.loginLogPage.currentPage = val
|
|
||||||
this.loadLoginLogList()
|
|
||||||
},
|
|
||||||
handleNoticeSizeChange(val) {
|
handleNoticeSizeChange(val) {
|
||||||
this.noticePage.pageSize = val
|
this.noticePage.pageSize = val
|
||||||
this.noticePage.currentPage = 1
|
this.noticePage.currentPage = 1
|
||||||
@@ -371,102 +259,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 14px 0;
|
|
||||||
border-bottom: 1px solid #f5f5f5;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-icon {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: linear-gradient(135deg, var(--edu-green-dark) 0%, var(--edu-green-primary) 100%);
|
|
||||||
color: #ffffff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 12px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
box-shadow: 0 2px 8px rgba(15, 25, 86, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-text {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #909399;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a, .el-link {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--edu-green-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover, .el-link:hover {
|
|
||||||
color: var(--edu-green-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
thead {
|
|
||||||
tr {
|
|
||||||
background: linear-gradient(135deg, rgba(0, 135, 90, 0.06) 0%, rgba(0, 135, 90, 0.04) 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
padding: 10px 20px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--edu-green-dark);
|
|
||||||
border-bottom: 1px solid rgba(0, 135, 90, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody {
|
|
||||||
tr {
|
|
||||||
transition: background 0.2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(0, 135, 90, 0.04);
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 10px 20px;
|
|
||||||
color: #4a4f6b;
|
|
||||||
border-bottom: 1px solid #f0f1f7;
|
|
||||||
|
|
||||||
.table-icon {
|
|
||||||
color: var(--edu-green-light);
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.notice-list {
|
.notice-list {
|
||||||
.notice-item {
|
.notice-item {
|
||||||
padding: 14px 0;
|
padding: 14px 0;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
||||||
<h3 class="title">{{title}}</h3>
|
<h3 class="title">{{title}}</h3>
|
||||||
@@ -50,14 +50,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import Cookies from "js-cookie"
|
import Cookies from "js-cookie"
|
||||||
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
||||||
import defaultSettings from '@/settings'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: "Login",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
title: process.env.VUE_APP_TITLE,
|
||||||
footerContent: defaultSettings.footerContent,
|
footerContent: "Copyright © 2018-2026 roomroot. All Rights Reserved.",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "admin123",
|
password: "admin123",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="register">
|
<div class="register">
|
||||||
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
||||||
<h3 class="title">{{title}}</h3>
|
<h3 class="title">{{title}}</h3>
|
||||||
@@ -55,14 +55,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import { register } from "@/api/login"
|
import { register } from "@/api/login"
|
||||||
import passwordRule from "@/utils/passwordRule"
|
import passwordRule from "@/utils/passwordRule"
|
||||||
import defaultSettings from '@/settings'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [passwordRule],
|
mixins: [passwordRule],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
title: process.env.VUE_APP_TITLE,
|
||||||
footerContent: defaultSettings.footerContent,
|
footerContent: "Copyright © 2018-2026 roomroot. All Rights Reserved.",
|
||||||
registerForm: {
|
registerForm: {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
|
|||||||
@@ -69,12 +69,6 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="24">
|
|
||||||
<div class="form-tip">注意:勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24" class="search-actions">
|
<el-col :span="24" class="search-actions">
|
||||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||||
@@ -101,9 +95,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bar-right">
|
<div class="bar-right">
|
||||||
|
<el-button type="primary" @click="handleImportToSystem" :loading="importing">缓存数据导入到系统</el-button>
|
||||||
<el-button type="primary" @click="handleUploadToCache">上传数据至缓存</el-button>
|
<el-button type="primary" @click="handleUploadToCache">上传数据至缓存</el-button>
|
||||||
<el-button type="primary" @click="handleCheckCache">检查缓存数据</el-button>
|
<el-button type="primary" @click="handleCheckCache">检查缓存数据</el-button>
|
||||||
<el-button type="primary" @click="handleImportToSystem">缓存数据导入到系统</el-button>
|
|
||||||
<el-button type="danger" @click="handleDeleteCache">删除缓存数据</el-button>
|
<el-button type="danger" @click="handleDeleteCache">删除缓存数据</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,10 +106,10 @@
|
|||||||
<!-- ==================== 3. 数据表格 ==================== -->
|
<!-- ==================== 3. 数据表格 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row class="import-table">
|
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row class="import-table">
|
||||||
<el-table-column prop="xq" label="学期" width="53" align="center" />
|
<el-table-column prop="nd" label="年度" width="60" align="center" />
|
||||||
<el-table-column prop="xh" label="序号" width="53" align="center" />
|
<el-table-column prop="xh" label="序号" width="53" align="center" />
|
||||||
<el-table-column prop="yxh" label="原序号" width="67" align="center" />
|
<el-table-column prop="yxh" label="原序号" width="67" align="center" />
|
||||||
<el-table-column prop="rq" label="日期" width="53" align="center" :formatter="formatDate" />
|
<el-table-column prop="rq" label="日期" width="120" align="center" :formatter="formatDate" />
|
||||||
<el-table-column prop="yjc" label="原节次" width="67" align="center" />
|
<el-table-column prop="yjc" label="原节次" width="67" align="center" />
|
||||||
<el-table-column prop="jc" label="节次" width="53" align="center" />
|
<el-table-column prop="jc" label="节次" width="53" align="center" />
|
||||||
<el-table-column prop="kcmc" label="课程名称" width="85" show-overflow-tooltip />
|
<el-table-column prop="kcmc" label="课程名称" width="85" show-overflow-tooltip />
|
||||||
@@ -125,7 +119,6 @@
|
|||||||
<el-table-column prop="jxcd" label="教学场地" width="81" align="center" />
|
<el-table-column prop="jxcd" label="教学场地" width="81" align="center" />
|
||||||
<el-table-column prop="jxnr" label="教学内容" width="81" show-overflow-tooltip />
|
<el-table-column prop="jxnr" label="教学内容" width="81" show-overflow-tooltip />
|
||||||
<el-table-column prop="jxff" label="教学方法" width="81" align="center" />
|
<el-table-column prop="jxff" label="教学方法" width="81" align="center" />
|
||||||
<el-table-column prop="jxyd" label="教学要点" width="81" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="jybz" label="教员备注" width="81" show-overflow-tooltip />
|
<el-table-column prop="jybz" label="教员备注" width="81" show-overflow-tooltip />
|
||||||
<el-table-column prop="jwbz" label="教务备注" width="81" show-overflow-tooltip />
|
<el-table-column prop="jwbz" label="教务备注" width="81" show-overflow-tooltip />
|
||||||
<el-table-column prop="jcjg" label="检查结果" width="81" align="center" />
|
<el-table-column prop="jcjg" label="检查结果" width="81" align="center" />
|
||||||
@@ -134,9 +127,9 @@
|
|||||||
<span>{{ row.ytgjc ? '是' : '否' }}</span>
|
<span>{{ row.ytgjc ? '是' : '否' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="ybhhl" label="已被忽略" width="81" align="center">
|
<el-table-column prop="ybhl" label="已被忽略" width="81" align="center">
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
<span>{{ row.ybhhl ? '是' : '否' }}</span>
|
<span>{{ row.ybhl ? '是' : '否' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="ybcl" label="已被处理" width="81" align="center">
|
<el-table-column prop="ybcl" label="已被处理" width="81" align="center">
|
||||||
@@ -166,12 +159,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟导入记录数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import { listTeachingPlan, importTeachingPlan, downloadTeachingPlanTemplate } from '@/api/schedule/teachingPlan'
|
||||||
const mockTableData = [
|
|
||||||
{ xq: '2026-2027-1', xh: 1, yxh: 1, rq: '2026-09-01 08:00:00', yjc: '1-2', jc: '1', kcmc: '高等数学', bc: '2026级1队', zrdw: '基础部', skjy: '王教员', jxcd: '教学楼101', jxnr: '第一章 函数与极限', jxff: '讲授', jxyd: '理解极限定义', jybz: '', jwbz: '', jcjg: '通过', ytgjc: true, ybhhl: false, ybcl: true, ybdr: false },
|
|
||||||
{ xq: '2026-2027-1', xh: 2, yxh: 2, rq: '2026-09-01 10:00:00', yjc: '3-4', jc: '2', kcmc: '大学英语', bc: '2026级2队', zrdw: '外语系', skjy: '李教员', jxcd: '教学楼102', jxnr: 'Unit 1 课文讲解', jxff: '讲授', jxyd: '掌握重点词汇', jybz: '', jwbz: '', jcjg: '通过', ytgjc: true, ybhhl: false, ybcl: true, ybdr: false },
|
|
||||||
{ xq: '2026-2027-1', xh: 3, yxh: 3, rq: '2026-09-02 08:00:00', yjc: '1-2', jc: '1', kcmc: '军事理论', bc: '2026级1队', zrdw: '军事教研室', skjy: '张教员', jxcd: '学术报告厅', jxnr: '国防概论', jxff: '讲授', jxyd: '了解国防常识', jybz: '', jwbz: '', jcjg: '待检', ytgjc: false, ybhhl: false, ybcl: false, ybdr: false }
|
|
||||||
]
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PlanImportIndex',
|
name: 'PlanImportIndex',
|
||||||
@@ -193,50 +181,68 @@ export default {
|
|||||||
kmmc: ''
|
kmmc: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 文件上传与缓存操作 ====================
|
// ==================== 文件上传与导入 ====================
|
||||||
selectedFileName: '未选择任何文件',
|
selectedFileName: '未选择任何文件',
|
||||||
|
selectedFile: null,
|
||||||
|
importing: false,
|
||||||
|
|
||||||
// ==================== 表格数据 ====================
|
// ==================== 表格数据 ====================
|
||||||
tableData: [],
|
tableData: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
allData: [],
|
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
total: 0
|
total: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.handleSearch()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 查询 ====================
|
// ==================== 查询 ====================
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为接口加载
|
// 仅传后端 Mapper 支持的字段:skjy(授课教员) bc(班次) kcmc(课程名称) ytgjc(已通过检查)
|
||||||
handleSearch() {
|
// 课程时间、忽略状态、教学场地名称后端列表查询不支持,不传
|
||||||
this.loading = true
|
buildSearchParams() {
|
||||||
setTimeout(() => {
|
const f = this.searchForm
|
||||||
this.allData = mockTableData.slice()
|
const params = { pageNum: this.pageNum, pageSize: this.pageSize }
|
||||||
this.total = this.allData.length
|
if (f.jyxm && f.jyxm.trim()) params.skjy = f.jyxm.trim()
|
||||||
this.pageNum = 1
|
if (f.bcmc && f.bcmc.trim()) params.bc = f.bcmc.trim()
|
||||||
this.applyPage()
|
if (f.kmmc && f.kmmc.trim()) params.kcmc = f.kmmc.trim()
|
||||||
this.$message.success(`查询完成,共 ${this.allData.length} 条记录(前端模拟)`)
|
// 检查状态:仅勾选「已通过」或「未通过」其中之一时才按该条件过滤
|
||||||
this.loading = false
|
if (f.jcztEnabled) {
|
||||||
}, 200)
|
if (f.jcztYtg && !f.jcztWtg) params.ytgjc = true
|
||||||
|
else if (!f.jcztYtg && f.jcztWtg) params.ytgjc = false
|
||||||
|
}
|
||||||
|
return params
|
||||||
},
|
},
|
||||||
|
|
||||||
applyPage() {
|
fetchList() {
|
||||||
const start = (this.pageNum - 1) * this.pageSize
|
this.loading = true
|
||||||
this.tableData = this.allData.slice(start, start + this.pageSize)
|
listTeachingPlan(this.buildSearchParams()).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearch() {
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handlePageChange(current) {
|
handlePageChange(current) {
|
||||||
this.pageNum = current
|
this.pageNum = current
|
||||||
this.applyPage()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSizeChange(size) {
|
handleSizeChange(size) {
|
||||||
this.pageSize = size
|
this.pageSize = size
|
||||||
this.pageNum = 1
|
this.pageNum = 1
|
||||||
this.applyPage()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 日期格式化 */
|
/** 日期格式化 */
|
||||||
@@ -244,7 +250,7 @@ export default {
|
|||||||
return cellValue ? String(cellValue).substring(0, 10) : ''
|
return cellValue ? String(cellValue).substring(0, 10) : ''
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 文件上传与缓存操作 ====================
|
// ==================== 文件选择 ====================
|
||||||
handleChooseFile() {
|
handleChooseFile() {
|
||||||
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
||||||
},
|
},
|
||||||
@@ -253,36 +259,68 @@ export default {
|
|||||||
const target = event.target
|
const target = event.target
|
||||||
const file = target.files && target.files[0]
|
const file = target.files && target.files[0]
|
||||||
if (file) {
|
if (file) {
|
||||||
|
this.selectedFile = file
|
||||||
this.selectedFileName = file.name
|
this.selectedFileName = file.name
|
||||||
this.$message.success(`已选择文件:${file.name}`)
|
|
||||||
} else {
|
} else {
|
||||||
|
this.selectedFile = null
|
||||||
this.selectedFileName = '未选择任何文件'
|
this.selectedFileName = '未选择任何文件'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: 后端接口未提供,以下操作均为前端模拟;接口就绪后替换为对应接口
|
// ==================== 下载模板 ====================
|
||||||
handleDownloadTemplate() {
|
handleDownloadTemplate() {
|
||||||
this.$message.success('下载课程表数据文件模板(前端模拟)')
|
downloadTeachingPlanTemplate().then(blob => {
|
||||||
|
this.downloadBlob(blob, '教学实施计划导入模板.xlsx')
|
||||||
|
this.$message.success('模板下载成功')
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleUploadToCache() {
|
downloadBlob(blob, fileName) {
|
||||||
if (this.selectedFileName === '未选择任何文件') {
|
const url = window.URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = fileName
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 导入到系统 ====================
|
||||||
|
handleImportToSystem() {
|
||||||
|
if (!this.selectedFile) {
|
||||||
this.$message.warning('请先选择文件')
|
this.$message.warning('请先选择文件')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$message.success('上传数据至缓存(前端模拟)')
|
this.importing = true
|
||||||
|
importTeachingPlan(this.selectedFile).then(res => {
|
||||||
|
const count = res && res.data
|
||||||
|
if (count !== null && count !== undefined) {
|
||||||
|
this.$message.success(`导入成功,共 ${count} 条记录`)
|
||||||
|
} else {
|
||||||
|
this.$message.success((res && res.msg) || '导入成功')
|
||||||
|
}
|
||||||
|
this.selectedFile = null
|
||||||
|
this.selectedFileName = '未选择任何文件'
|
||||||
|
this.$refs.fileInputRef && (this.$refs.fileInputRef.value = '')
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.importing = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteCache() {
|
// ==================== 缓存操作(后端暂未提供) ====================
|
||||||
this.$message.success('删除缓存数据(前端模拟)')
|
handleUploadToCache() {
|
||||||
|
this.$message.info('后端暂未提供该接口')
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCheckCache() {
|
handleCheckCache() {
|
||||||
this.$message.success('检查缓存数据(前端模拟)')
|
this.$message.info('后端暂未提供该接口')
|
||||||
},
|
},
|
||||||
|
|
||||||
handleImportToSystem() {
|
handleDeleteCache() {
|
||||||
this.$message.success('缓存数据导入到系统(前端模拟)')
|
this.$message.info('后端暂未提供该接口')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,38 +25,38 @@
|
|||||||
<el-tabs v-model="activeTab">
|
<el-tabs v-model="activeTab">
|
||||||
<!-- 课程成绩 -->
|
<!-- 课程成绩 -->
|
||||||
<el-tab-pane label="课程成绩" name="grades">
|
<el-tab-pane label="课程成绩" name="grades">
|
||||||
<el-table v-loading="loading" :data="gradesData" stripe border>
|
<el-table v-loading="loading" :data="gradesData" stripe border style="width: 100%">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="xybh" label="学员编号" width="110" show-overflow-tooltip />
|
<el-table-column prop="xybh" label="学员编号" min-width="110" show-overflow-tooltip />
|
||||||
<el-table-column prop="kmbh" label="科目编号" width="110" show-overflow-tooltip />
|
<el-table-column prop="kmbh" label="科目编号" min-width="110" show-overflow-tooltip />
|
||||||
<el-table-column prop="klx" label="课类型" width="90" align="center" />
|
<el-table-column prop="klx" label="课类型" min-width="90" align="center" />
|
||||||
<el-table-column prop="kscj" label="考试成绩" width="90" align="center" />
|
<el-table-column prop="kscj" label="考试成绩" min-width="90" align="center" />
|
||||||
<el-table-column prop="pscj" label="平时成绩" width="90" align="center" />
|
<el-table-column prop="pscj" label="平时成绩" min-width="90" align="center" />
|
||||||
<el-table-column prop="zzcj" label="最终成绩" width="90" align="center" />
|
<el-table-column prop="zzcj" label="最终成绩" min-width="90" align="center" />
|
||||||
<el-table-column prop="bkcj" label="补考成绩" width="90" align="center" />
|
<el-table-column prop="bkcj" label="补考成绩" min-width="90" align="center" />
|
||||||
<el-table-column prop="bkcs" label="补考次数" width="90" align="center" />
|
<el-table-column prop="bkcs" label="补考次数" min-width="90" align="center" />
|
||||||
<el-table-column prop="ksqk" label="考试情况" width="90" align="center" />
|
<el-table-column prop="ksqk" label="考试情况" min-width="90" align="center" />
|
||||||
<el-table-column prop="qwxf" label="期望学分" width="90" align="center" />
|
<el-table-column prop="qwxf" label="期望学分" min-width="90" align="center" />
|
||||||
<el-table-column prop="ytg" label="已通过" width="80" align="center" />
|
<el-table-column prop="ytg" label="已通过" min-width="80" align="center" />
|
||||||
<el-table-column prop="nd" label="年度" width="80" align="center" />
|
<el-table-column prop="nd" label="年度" min-width="80" align="center" />
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-if="!loading && gradesData.length === 0" description="暂无课程成绩数据" :image-size="60" />
|
<el-empty v-if="!loading && gradesData.length === 0" description="暂无课程成绩数据" :image-size="60" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- 课程过程成绩 -->
|
<!-- 课程过程成绩 -->
|
||||||
<el-tab-pane label="课程过程成绩" name="process">
|
<el-tab-pane label="课程过程成绩" name="process">
|
||||||
<el-table v-loading="loading" :data="processGradesData" stripe border>
|
<el-table v-loading="loading" :data="processGradesData" stripe border style="width: 100%">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="xybh" label="学员编号" width="110" show-overflow-tooltip />
|
<el-table-column prop="xybh" label="学员编号" min-width="110" show-overflow-tooltip />
|
||||||
<el-table-column prop="kmbh" label="科目编号" width="110" show-overflow-tooltip />
|
<el-table-column prop="kmbh" label="科目编号" min-width="110" show-overflow-tooltip />
|
||||||
<el-table-column prop="klx" label="课类型" width="90" align="center" />
|
<el-table-column prop="klx" label="课类型" min-width="90" align="center" />
|
||||||
<el-table-column prop="yscj" label="原始成绩" width="90" align="center" />
|
<el-table-column prop="yscj" label="原始成绩" min-width="90" align="center" />
|
||||||
<el-table-column prop="zzcj" label="最终成绩" width="90" align="center" />
|
<el-table-column prop="zzcj" label="最终成绩" min-width="90" align="center" />
|
||||||
<el-table-column prop="bkcj1" label="补考1" width="80" align="center" />
|
<el-table-column prop="bkcj1" label="补考1" min-width="80" align="center" />
|
||||||
<el-table-column prop="bkcj2" label="补考2" width="80" align="center" />
|
<el-table-column prop="bkcj2" label="补考2" min-width="80" align="center" />
|
||||||
<el-table-column prop="bkcj3" label="补考3" width="80" align="center" />
|
<el-table-column prop="bkcj3" label="补考3" min-width="80" align="center" />
|
||||||
<el-table-column prop="ksqk" label="考试情况" width="90" align="center" />
|
<el-table-column prop="ksqk" label="考试情况" min-width="90" align="center" />
|
||||||
<el-table-column prop="nd" label="年度" width="80" align="center" />
|
<el-table-column prop="nd" label="年度" min-width="80" align="center" />
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-if="!loading && processGradesData.length === 0" description="暂无课程过程成绩数据" :image-size="60" />
|
<el-empty v-if="!loading && processGradesData.length === 0" description="暂无课程过程成绩数据" :image-size="60" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,178 +1,426 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container status-change-page">
|
<div class="app-container status-change-page">
|
||||||
<!-- ==================== 1. 查询条件区域 ==================== -->
|
<!-- ==================== 1. 查询条件 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form :model="searchForm" label-width="140px" class="search-form">
|
<el-form ref="searchFormRef" :model="searchForm" label-width="90px" class="search-form">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<!-- 左栏 -->
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-col :xs="24" :md="12">
|
<el-form-item label="编号">
|
||||||
<el-form-item label="年级">
|
<el-input v-model="searchForm.bh" placeholder="请输入编号" clearable @keyup.enter.native="handleSearch" />
|
||||||
<el-input v-model="searchForm.nj" placeholder="请输入年级" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专业">
|
|
||||||
<el-input v-model="searchForm.zy" placeholder="请输入专业" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxlxChecked">培训类型</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxlx" class="w-full" :disabled="!searchForm.pxlxChecked">
|
|
||||||
<el-option v-for="item in pxlxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxccChecked">培训层次</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxcc" class="w-full" :disabled="!searchForm.pxccChecked">
|
|
||||||
<el-option v-for="item in pxccOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学号">
|
|
||||||
<el-input v-model="searchForm.xh" placeholder="请输入学号" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<!-- 右栏 -->
|
<el-form-item label="学员编号">
|
||||||
<el-col :xs="24" :md="12">
|
<el-input v-model="searchForm.xybh" placeholder="请输入学员编号" clearable @keyup.enter.native="handleSearch" />
|
||||||
<el-form-item label="队别">
|
|
||||||
<el-input v-model="searchForm.db" placeholder="请输入队别" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="班次">
|
</el-col>
|
||||||
<el-input v-model="searchForm.bc" placeholder="请输入班次" clearable />
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
</el-form-item>
|
<el-form-item label="申请类型">
|
||||||
<el-form-item>
|
<el-select v-model="searchForm.sqlx" placeholder="请选择申请类型" clearable class="w-full">
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.sqlbChecked">学籍异动申请类别</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.sqlb" class="w-full" :disabled="!searchForm.sqlbChecked">
|
|
||||||
<el-option v-for="item in applyTypeOptions" :key="item" :label="item" :value="item" />
|
<el-option v-for="item in applyTypeOptions" :key="item" :label="item" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
</el-col>
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.sqztChecked">学籍异动申请状态</el-checkbox></template>
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-select v-model="searchForm.sqzt" class="w-full" :disabled="!searchForm.sqztChecked">
|
<el-form-item label="状态">
|
||||||
<el-option v-for="item in applyStatusOptions" :key="item" :label="item" :value="item" />
|
<el-select v-model="searchForm.zt" placeholder="请选择状态" clearable class="w-full">
|
||||||
|
<el-option v-for="(item, key) in statusMap" :key="key" :label="item.label" :value="Number(key)" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="姓名">
|
|
||||||
<el-input v-model="searchForm.xm" placeholder="请输入姓名" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row>
|
||||||
<div class="search-tip">注意:勾选"选择框"表示启用该项对应的查询条件;文本输入框非空白表示启用对应的查询条件。</div>
|
<el-col :span="24" class="search-actions">
|
||||||
<div class="search-actions">
|
<div class="search-buttons">
|
||||||
<el-button class="gray-btn" @click="handleSearch">查询</el-button>
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||||
</div>
|
<el-button @click="handleReset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 2. 审核意见区域 ==================== -->
|
<!-- ==================== 2. 列表 ==================== -->
|
||||||
<el-card shadow="never" class="opinion-card">
|
|
||||||
<div class="opinion-row">
|
|
||||||
<span class="opinion-label">审核意见:</span>
|
|
||||||
<el-input v-model="auditOpinion" placeholder="请输入审核意见" clearable class="opinion-input" />
|
|
||||||
<el-button type="primary" @click="handleBatchAudit">提交审核意见</el-button>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- ==================== 3. 列表标题 ==================== -->
|
|
||||||
<div class="list-title">学籍异动申请审核列表</div>
|
|
||||||
|
|
||||||
<!-- ==================== 4. 数据表格区域 ==================== -->
|
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table :data="tableData" stripe border @selection-change="handleSelectionChange">
|
<div class="table-header">
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<span class="table-title">学籍异动申请列表:</span>
|
||||||
<el-table-column prop="xhName" label="学号姓名" min-width="150" show-overflow-tooltip />
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增学籍异动申请</el-button>
|
||||||
<el-table-column prop="bcxx" label="班次信息" min-width="160" show-overflow-tooltip />
|
</div>
|
||||||
<el-table-column prop="applyType" label="申请类型" width="90" align="center" />
|
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
|
||||||
<el-table-column prop="reason" label="事由" min-width="120" show-overflow-tooltip />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<el-table-column prop="time" label="时间" width="110" align="center" />
|
<el-table-column prop="bh" label="编号" min-width="140" show-overflow-tooltip />
|
||||||
<el-table-column prop="auditOpinion" label="审核意见" min-width="120" show-overflow-tooltip />
|
<el-table-column prop="xybh" label="学员编号" min-width="120" show-overflow-tooltip />
|
||||||
<el-table-column prop="status" label="状态" width="90" align="center" />
|
<el-table-column prop="sqlx" label="申请类型" width="100" align="center" />
|
||||||
<el-table-column prop="change" label="学籍异动" width="90" align="center" />
|
<el-table-column prop="sy" label="事由" min-width="140" show-overflow-tooltip />
|
||||||
<el-table-column label="操作" width="130" align="center" fixed="right">
|
<el-table-column prop="bz" label="备注" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column label="状态" width="90" align="center">
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
<el-button type="text" size="small" class="text-primary" @click="handleAudit(row)">审核</el-button>
|
<el-tag :type="statusTagType(row.zt)" size="mini" effect="light">{{ statusLabel(row.zt) }}</el-tag>
|
||||||
<el-button type="text" size="small" class="text-primary" @click="handleView(row)">查看</el-button>
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="提交时间" width="160" align="center">
|
||||||
|
<template slot-scope="{ row }">{{ row.tjsj ? fmtDateTime(row.tjsj) : '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" width="160" align="center">
|
||||||
|
<template slot-scope="{ row }">{{ row.cjsj ? fmtDateTime(row.cjsj) : '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="修改时间" width="160" align="center">
|
||||||
|
<template slot-scope="{ row }">{{ row.xgsj ? fmtDateTime(row.xgsj) : '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="230" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button v-if="!row.tjsj" type="text" size="small" icon="el-icon-upload2" @click="handleSubmit(row)">提交</el-button>
|
||||||
|
<el-button v-else type="text" size="small" icon="el-icon-check" disabled>已提交</el-button>
|
||||||
|
<el-button type="text" size="small" icon="el-icon-view" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button type="text" size="small" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button type="text" size="small" class="text-danger" @click="handleDelete(row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<el-empty v-if="!loading && tableData.length === 0" description="暂无学籍异动申请数据" :image-size="60" />
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination-wrapper"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- ==================== 3. 新增/编辑对话框 ==================== -->
|
||||||
|
<el-dialog
|
||||||
|
:visible="formDialogVisible"
|
||||||
|
:title="dialogTitle"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => formDialogVisible = val"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="110px" class="add-form">
|
||||||
|
<el-form-item label="编号" prop="bh">
|
||||||
|
<el-input v-model="form.bh" placeholder="请输入编号" :disabled="!isAdd" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="学员编号" prop="xybh">
|
||||||
|
<el-input v-model="form.xybh" placeholder="请输入学员编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="申请类型" prop="sqlx">
|
||||||
|
<el-select v-model="form.sqlx" placeholder="请选择申请类型" class="w-full">
|
||||||
|
<el-option v-for="item in applyTypeOptions" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="事由" prop="sy">
|
||||||
|
<el-input v-model="form.sy" type="textarea" :rows="3" placeholder="请输入事由" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="zt">
|
||||||
|
<el-select v-model="form.zt" placeholder="请选择状态" class="w-full">
|
||||||
|
<el-option v-for="(item, key) in statusMap" :key="key" :label="item.label" :value="Number(key)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="formDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="formSaving" @click="handleFormSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ==================== 4. 详情对话框 ==================== -->
|
||||||
|
<el-dialog title="学籍异动申请详情" :visible="detailDialogVisible" width="760px" :close-on-click-modal="false"
|
||||||
|
@update:visible="val => detailDialogVisible = val">
|
||||||
|
<div v-loading="detailLoading" class="detail-body">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailForm.bh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员编号">{{ detailForm.xybh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="申请类型">{{ detailForm.sqlx || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">
|
||||||
|
<el-tag :type="statusTagType(detailForm.zt)" size="mini">{{ statusLabel(detailForm.zt) }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="事由" :span="2">{{ detailForm.sy || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ detailForm.bz || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ detailForm.cjsj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="修改时间">{{ detailForm.xgsj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="提交时间">{{ detailForm.tjsj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员队审核意见">{{ detailForm.xydshyj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员队干部编号">{{ detailForm.xydgbbh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员队干部审核时间">{{ detailForm.xydshsj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="管理员账户编号">{{ detailForm.glyzhbh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="管理员审核意见">{{ detailForm.glyshyj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="管理员审核时间">{{ detailForm.glyshsj || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟列表数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import {
|
||||||
const mockTableData = [
|
listApplication,
|
||||||
{ id: 1, xhName: '2025010101 张三', bcxx: '2025级炮兵装备运用54队5区队', applyType: '退学', reason: '身体原因', time: '2026-08-20', auditOpinion: '待审核', status: '拟制', change: '退学' },
|
getApplication,
|
||||||
{ id: 2, xhName: '2025010102 李四', bcxx: '2025级通信工程32队1区队', applyType: '休学', reason: '家庭原因', time: '2026-08-21', auditOpinion: '同意', status: '待审核', change: '休学' },
|
addApplication,
|
||||||
{ id: 3, xhName: '2024010101 王五', bcxx: '2024级军事指挥51队2区队', applyType: '留级', reason: '成绩不达标', time: '2026-08-22', auditOpinion: '', status: '拟制', change: '留级' }
|
updateApplication,
|
||||||
]
|
delApplication
|
||||||
|
} from '@/api/studentRecords/application'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'StatusChangeIndex',
|
name: 'StatusChangeIndex',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 下拉选项(字典数据,接口就绪后可由后端字典加载) ====================
|
// ==================== 申请类型选项(学籍异动) ====================
|
||||||
pxlxOptions: ['军官基础教育', '士兵职业教育', '研究生教育', '其他'],
|
applyTypeOptions: ['休学', '复学', '退学', '转学', '留级', '转专业'],
|
||||||
pxccOptions: ['无', '本科', '硕士', '博士'],
|
|
||||||
applyTypeOptions: ['退学', '休学', '留级', '复学', '转专业'],
|
// ==================== 状态映射:0-待审核 1-已审核 2-驳回等 ====================
|
||||||
applyStatusOptions: ['拟制', '待审核', '已通过', '已驳回'],
|
statusMap: {
|
||||||
|
0: { label: '待审核', type: 'warning' },
|
||||||
|
1: { label: '已审核', type: 'success' },
|
||||||
|
2: { label: '驳回', type: 'danger' }
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 查询条件 ====================
|
// ==================== 查询条件 ====================
|
||||||
searchForm: {
|
searchForm: {
|
||||||
nj: '', zy: '', pxlxChecked: false, pxlx: '军官基础教育', pxccChecked: false, pxcc: '无', xh: '',
|
bh: '',
|
||||||
db: '', bc: '', sqlbChecked: false, sqlb: '退学', sqztChecked: false, sqzt: '拟制', xm: ''
|
xybh: '',
|
||||||
|
sqlx: '',
|
||||||
|
zt: undefined
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 审核意见 ====================
|
// ==================== 列表数据 ====================
|
||||||
auditOpinion: '',
|
loading: false,
|
||||||
|
|
||||||
// ==================== 数据表格 ====================
|
|
||||||
tableData: [],
|
tableData: [],
|
||||||
selectedRows: []
|
total: 0,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
|
||||||
|
// ==================== 新增/编辑 ====================
|
||||||
|
formDialogVisible: false,
|
||||||
|
dialogTitle: '新增学籍异动申请',
|
||||||
|
isAdd: true,
|
||||||
|
formSaving: false,
|
||||||
|
form: this.createEmptyForm(),
|
||||||
|
formRules: {
|
||||||
|
bh: [{ required: true, message: '请输入编号', trigger: 'blur' }],
|
||||||
|
xybh: [{ required: true, message: '请输入学员编号', trigger: 'blur' }],
|
||||||
|
sqlx: [{ required: true, message: '请选择申请类型', trigger: 'change' }],
|
||||||
|
sy: [{ required: true, message: '请输入事由', trigger: 'blur' }],
|
||||||
|
zt: [{ required: true, message: '请选择状态', trigger: 'change' }]
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
detailDialogVisible: false,
|
||||||
|
detailLoading: false,
|
||||||
|
detailForm: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadData()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 列表加载 ====================
|
createEmptyForm() {
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 getStatusChangeList
|
return {
|
||||||
loadData() {
|
bh: '',
|
||||||
this.tableData = mockTableData.slice()
|
xybh: '',
|
||||||
|
sqlx: '',
|
||||||
|
sy: '',
|
||||||
|
bz: '',
|
||||||
|
zt: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 状态展示 ====================
|
||||||
|
// 统一格式化后端 LocalDateTime(去除 T、截断到秒)
|
||||||
|
fmtDateTime(val) {
|
||||||
|
if (val === null || val === undefined || val === '') return ''
|
||||||
|
return String(val).replace('T', ' ').slice(0, 19)
|
||||||
|
},
|
||||||
|
statusLabel(zt) {
|
||||||
|
const item = this.statusMap[zt]
|
||||||
|
return item ? item.label : (zt !== null && zt !== undefined ? String(zt) : '-')
|
||||||
|
},
|
||||||
|
statusTagType(zt) {
|
||||||
|
const item = this.statusMap[zt]
|
||||||
|
return item ? item.type : 'info'
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 查询列表 ====================
|
||||||
|
fetchList() {
|
||||||
|
this.loading = true
|
||||||
|
const params = {
|
||||||
|
pageNum: this.pageNum,
|
||||||
|
pageSize: this.pageSize
|
||||||
|
}
|
||||||
|
// 等值筛选,留空不传
|
||||||
|
;['bh', 'xybh', 'sqlx'].forEach(key => {
|
||||||
|
const value = this.searchForm[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params[key] = String(value).trim()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (this.searchForm.zt !== undefined && this.searchForm.zt !== '' && this.searchForm.zt !== null) {
|
||||||
|
params.zt = this.searchForm.zt
|
||||||
|
}
|
||||||
|
listApplication(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询 ====================
|
|
||||||
// TODO: 后端接口未提供,查询为前端模拟;接口就绪后替换为后端查询
|
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
this.loadData()
|
this.pageNum = 1
|
||||||
this.$message.success('查询完成(前端模拟)')
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSelectionChange(rows) {
|
handleReset() {
|
||||||
this.selectedRows = rows
|
this.$refs.searchFormRef.resetFields()
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: 后端接口未提供,审核为前端模拟;接口就绪后替换为 auditStatusChange
|
handlePageChange(current) {
|
||||||
handleAudit(row) {
|
this.pageNum = current
|
||||||
this.$message.info(`审核「${row.xhName}」的申请(前端模拟)`)
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: 后端接口未提供,查看为前端模拟;接口就绪后替换为 getStatusChangeDetail
|
handleSizeChange(size) {
|
||||||
handleView(row) {
|
this.pageSize = size
|
||||||
this.$message.info(`查看「${row.xhName}」的申请详情(前端模拟)`)
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 批量审核所选 */
|
// ==================== 新增/编辑 ====================
|
||||||
// TODO: 后端接口未提供,批量审核为前端模拟;接口就绪后替换为 batchAuditStatusChange
|
handleAdd() {
|
||||||
handleBatchAudit() {
|
this.isAdd = true
|
||||||
if (this.selectedRows.length === 0) {
|
this.dialogTitle = '新增学籍异动申请'
|
||||||
this.$message.warning('请先选择申请记录')
|
this.form = this.createEmptyForm()
|
||||||
return
|
this.formDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEdit(row) {
|
||||||
|
this.isAdd = false
|
||||||
|
this.dialogTitle = '编辑学籍异动申请'
|
||||||
|
this.form = this.createEmptyForm()
|
||||||
|
this.formDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||||
|
})
|
||||||
|
getApplication(row.bh).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.form = {
|
||||||
|
bh: data.bh || '',
|
||||||
|
xybh: data.xybh || '',
|
||||||
|
sqlx: data.sqlx || '',
|
||||||
|
sy: data.sy || '',
|
||||||
|
bz: data.bz || '',
|
||||||
|
zt: data.zt !== null && data.zt !== undefined ? Number(data.zt) : 0
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
buildPayload() {
|
||||||
|
const f = this.form
|
||||||
|
const payload = {
|
||||||
|
bh: f.bh,
|
||||||
|
xybh: f.xybh,
|
||||||
|
sqlx: f.sqlx,
|
||||||
|
sy: f.sy,
|
||||||
|
zt: Number(f.zt)
|
||||||
}
|
}
|
||||||
if (!this.auditOpinion.trim()) {
|
// 备注留空则移除
|
||||||
this.$message.warning('请输入审核意见')
|
if (f.bz !== '' && f.bz !== null && f.bz !== undefined) {
|
||||||
return
|
payload.bz = f.bz
|
||||||
}
|
}
|
||||||
const names = this.selectedRows.map((r) => r.xhName).join('、')
|
return payload
|
||||||
this.$message.success(`已对「${names}」提交审核意见(前端模拟)`)
|
},
|
||||||
|
|
||||||
|
handleFormSubmit() {
|
||||||
|
this.$refs.formRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
this.formSaving = true
|
||||||
|
const payload = this.buildPayload()
|
||||||
|
const request = this.isAdd ? addApplication(payload) : updateApplication(payload)
|
||||||
|
request.then(() => {
|
||||||
|
this.$message.success(this.isAdd ? '新增成功' : '修改成功')
|
||||||
|
this.formDialogVisible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {
|
||||||
|
}).finally(() => {
|
||||||
|
this.formSaving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 提交 ====================
|
||||||
|
// 无独立提交接口,通过编辑接口写入提交时间 tjsj(zt 保持原值不变)
|
||||||
|
formatNow() {
|
||||||
|
const d = new Date()
|
||||||
|
const pad = n => String(n).padStart(2, '0')
|
||||||
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit(row) {
|
||||||
|
this.$confirm(`确定要提交编号为「${row.bh}」的学籍异动申请吗?`, '系统提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const payload = {
|
||||||
|
bh: row.bh,
|
||||||
|
xybh: row.xybh,
|
||||||
|
sqlx: row.sqlx,
|
||||||
|
sy: row.sy,
|
||||||
|
zt: row.zt !== null && row.zt !== undefined ? Number(row.zt) : 0,
|
||||||
|
tjsj: this.formatNow()
|
||||||
|
}
|
||||||
|
if (row.bz) {
|
||||||
|
payload.bz = row.bz
|
||||||
|
}
|
||||||
|
return updateApplication(payload)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('提交成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 删除 ====================
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm(`确定要删除编号为「${row.bh}」的学籍异动申请吗?`, '系统提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return delApplication(row.bh)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
handleDetail(row) {
|
||||||
|
this.detailDialogVisible = true
|
||||||
|
this.detailLoading = true
|
||||||
|
this.detailForm = {}
|
||||||
|
getApplication(row.bh).then(response => {
|
||||||
|
this.detailForm = response.data || {}
|
||||||
|
this.detailLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.detailLoading = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,87 +434,61 @@ export default {
|
|||||||
.status-change-page {
|
.status-change-page {
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-top: 8px;
|
||||||
|
|
||||||
.search-tip {
|
.search-tip {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-actions {
|
.search-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
gap: 12px;
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.opinion-card {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
.opinion-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
|
|
||||||
.opinion-label {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.opinion-input {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-title {
|
|
||||||
font-size: 17px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #000;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-card {
|
.table-card {
|
||||||
.el-table {
|
.table-header {
|
||||||
width: 100%;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
::v-deep(.cell) {
|
.table-title {
|
||||||
font-size: 12px;
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
.pagination-wrapper {
|
||||||
color: #409eff;
|
display: flex;
|
||||||
padding: 0;
|
justify-content: flex-end;
|
||||||
}
|
margin-top: 16px;
|
||||||
|
|
||||||
.gray-btn {
|
|
||||||
height: 28px;
|
|
||||||
padding: 2px 16px;
|
|
||||||
font-size: 12px;
|
|
||||||
background: #f5f5f5;
|
|
||||||
border: 1px solid #c0c4cc;
|
|
||||||
color: #333;
|
|
||||||
border-radius: 2px;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
background: #ebebeb;
|
|
||||||
border-color: #c0c4cc;
|
|
||||||
color: #333;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-form {
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: #f56c6c;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,67 +6,11 @@
|
|||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<!-- 左栏 -->
|
<!-- 左栏 -->
|
||||||
<el-col :xs="24" :md="12">
|
<el-col :xs="24" :md="12">
|
||||||
<el-form-item label="年级">
|
|
||||||
<el-input v-model="searchForm.nj" placeholder="请输入年级" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专业">
|
|
||||||
<el-input v-model="searchForm.zy" placeholder="请输入专业" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxlxChecked">培训类型</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxlx" class="w-full" :disabled="!searchForm.pxlxChecked">
|
|
||||||
<el-option v-for="item in pxlxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxccChecked">培训层次</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxcc" class="w-full" :disabled="!searchForm.pxccChecked">
|
|
||||||
<el-option v-for="item in pxccOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学号">
|
<el-form-item label="学号">
|
||||||
<el-input v-model="searchForm.xh" placeholder="请输入学号" clearable />
|
<el-input v-model="searchForm.xh" placeholder="请输入学号" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="证件号码">
|
<el-form-item label="姓名">
|
||||||
<el-input v-model="searchForm.zjhm" placeholder="请输入证件号码" clearable />
|
<el-input v-model="searchForm.xm" placeholder="请输入姓名" clearable />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="政治面貌">
|
|
||||||
<el-input v-model="searchForm.zzmm" placeholder="请输入政治面貌" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="籍贯">
|
|
||||||
<el-input v-model="searchForm.jg" placeholder="请输入籍贯" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学位">
|
|
||||||
<el-input v-model="searchForm.xw" placeholder="请输入学位" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="原部职别">
|
|
||||||
<el-input v-model="searchForm.ybzb" placeholder="请输入原部职别" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="标签">
|
|
||||||
<el-input v-model="searchForm.bq" placeholder="请输入标签" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.xjydEnabled">学籍异动状态</el-checkbox></template>
|
|
||||||
<el-radio-group v-model="searchForm.xjyd" :disabled="!searchForm.xjydEnabled">
|
|
||||||
<el-radio :label="'无异动'">无异动</el-radio>
|
|
||||||
<el-radio :label="'异动'">异动</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.ksqkEnabled">考试情况</el-checkbox></template>
|
|
||||||
<el-radio-group v-model="searchForm.ksqk" :disabled="!searchForm.ksqkEnabled">
|
|
||||||
<el-radio :label="'正常'">正常</el-radio>
|
|
||||||
<el-radio :label="'异动'">异动</el-radio>
|
|
||||||
<el-radio :label="'旷考'">旷考</el-radio>
|
|
||||||
<el-radio :label="'作弊'">作弊</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="不及格门数">
|
|
||||||
<div class="range-control">
|
|
||||||
<el-input v-model="searchForm.bjgmMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="searchForm.bjgmMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.xbEnabled">性别</el-checkbox></template>
|
<template slot="label"><el-checkbox v-model="searchForm.xbEnabled">性别</el-checkbox></template>
|
||||||
@@ -75,84 +19,49 @@
|
|||||||
<el-radio :label="'女'">女</el-radio>
|
<el-radio :label="'女'">女</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item label="证件号码">
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.zcztEnabled">注册状态</el-checkbox></template>
|
<el-input v-model="searchForm.zjhm" placeholder="请输入证件号码" clearable />
|
||||||
<el-radio-group v-model="searchForm.zczt" :disabled="!searchForm.zcztEnabled">
|
</el-form-item>
|
||||||
<el-radio :label="'已注册'">已注册</el-radio>
|
<el-form-item label="政治面貌">
|
||||||
<el-radio :label="'未注册'">未注册</el-radio>
|
<el-input v-model="searchForm.zzmm" placeholder="请输入政治面貌" clearable />
|
||||||
</el-radio-group>
|
</el-form-item>
|
||||||
|
<el-form-item label="民族">
|
||||||
|
<el-input v-model="searchForm.mz" placeholder="请输入民族" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="籍贯">
|
||||||
|
<el-input v-model="searchForm.jg" placeholder="请输入籍贯" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="学位">
|
||||||
|
<el-input v-model="searchForm.xw" placeholder="请输入学位" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 右栏 -->
|
<!-- 右栏 -->
|
||||||
<el-col :xs="24" :md="12">
|
<el-col :xs="24" :md="12">
|
||||||
<el-form-item label="队别">
|
<el-form-item label="原部职别">
|
||||||
<el-input v-model="searchForm.db" placeholder="请输入队别" clearable />
|
<el-input v-model="searchForm.ybzb" placeholder="请输入原部职别" clearable />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="班次">
|
|
||||||
<el-input v-model="searchForm.bc" placeholder="请输入班次" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxlx2Checked">培训类型2</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxlx2" class="w-full" :disabled="!searchForm.pxlx2Checked">
|
|
||||||
<el-option v-for="item in pxlx2Options" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="自定义分类">
|
|
||||||
<el-input v-model="searchForm.zdyfl" placeholder="请输入自定义分类" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="姓名">
|
|
||||||
<el-input v-model="searchForm.xm" placeholder="请输入姓名" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份证号">
|
<el-form-item label="身份证号">
|
||||||
<el-input v-model="searchForm.sfzh" placeholder="请输入身份证号" clearable />
|
<el-input v-model="searchForm.sfzh" placeholder="请输入身份证号" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="民族">
|
|
||||||
<el-input v-model="searchForm.mz" placeholder="请输入民族" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="文化程度">
|
<el-form-item label="文化程度">
|
||||||
<el-input v-model="searchForm.whcd" placeholder="请输入文化程度" clearable />
|
<el-input v-model="searchForm.whcd" placeholder="请输入文化程度" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="本科毕业院校">
|
<el-form-item label="本科毕业院校">
|
||||||
<el-input v-model="searchForm.bkbyyx" placeholder="请输入本科毕业院校" clearable />
|
<el-input v-model="searchForm.bkbyyx" placeholder="请输入本科毕业院校" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属战区">
|
<el-form-item label="标签">
|
||||||
<el-input v-model="searchForm.sszq" placeholder="请输入所属战区" clearable />
|
<el-input v-model="searchForm.bq" placeholder="请输入标签" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="奖惩情况">
|
<el-form-item label="联系电话">
|
||||||
<el-input v-model="searchForm.jcqk" placeholder="请输入奖惩情况" clearable />
|
<el-input v-model="searchForm.lxdh" placeholder="请输入联系电话" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item label="通信地址">
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.txEnabled">退学状态</el-checkbox></template>
|
<el-input v-model="searchForm.txdz" placeholder="请输入通信地址" clearable />
|
||||||
<el-radio-group v-model="searchForm.tx" :disabled="!searchForm.txEnabled">
|
|
||||||
<el-radio :label="'未退学'">未退学</el-radio>
|
|
||||||
<el-radio :label="'退学'">退学</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="曾不及格门数">
|
|
||||||
<div class="range-control">
|
|
||||||
<el-input v-model="searchForm.lbjgmMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="searchForm.lbjgmMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="补考不及格门数">
|
|
||||||
<div class="range-control">
|
|
||||||
<el-input v-model="searchForm.bkcljgmMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="searchForm.bkcljgmMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.gljgChecked">管理机构</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.gljg" class="w-full" :disabled="!searchForm.gljgChecked">
|
|
||||||
<el-option v-for="item in gljgOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<div class="search-tip">注意:勾选"选择框"表示启用该项对应的查询条件;文本输入框非空白表示启用对应的查询条件。</div>
|
|
||||||
<div class="search-actions">
|
<div class="search-actions">
|
||||||
<el-button class="gray-btn" @click="handleSearch">查询</el-button>
|
<el-button class="gray-btn" @click="handleSearch">查询</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -312,21 +221,11 @@ export default {
|
|||||||
name: 'StudentInfoIndex',
|
name: 'StudentInfoIndex',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 下拉选项(字典数据,接口就绪后可由后端字典加载) ====================
|
|
||||||
pxlxOptions: ['军官基础教育', '士兵职业教育', '研究生教育', '其他'],
|
|
||||||
pxccOptions: ['无', '本科', '硕士', '博士'],
|
|
||||||
pxlx2Options: ['其他', '军官基础教育', '任职培训', '研究生教育'],
|
|
||||||
gljgOptions: ['教务处', '教研室1', '教研室2'],
|
|
||||||
|
|
||||||
// ==================== 查询条件 ====================
|
// ==================== 查询条件 ====================
|
||||||
|
// 仅保留后端 XYXX 实体支持的字段:/student-records/list 会按实体字段动态构建查询条件
|
||||||
searchForm: {
|
searchForm: {
|
||||||
nj: '', zy: '', pxlxChecked: false, pxlx: '军官基础教育', pxccChecked: false, pxcc: '无', xh: '', zjhm: '', zzmm: '',
|
xh: '', xm: '', xbEnabled: false, xb: '男', zjhm: '', zzmm: '', mz: '', jg: '', xw: '',
|
||||||
jg: '', xw: '', ybzb: '', bq: '', xjydEnabled: false, xjyd: '无异动', ksqkEnabled: false, ksqk: '正常',
|
ybzb: '', sfzh: '', whcd: '', bkbyyx: '', bq: '', lxdh: '', txdz: ''
|
||||||
bjgmMin: '', bjgmMax: '', xbEnabled: false, xb: '男', zcztEnabled: false, zczt: '已注册',
|
|
||||||
db: '', bc: '', pxlx2Checked: false, pxlx2: '其他', zdyfl: '', xm: '', sfzh: '', mz: '', whcd: '',
|
|
||||||
bkbyyx: '', sszq: '', jcqk: '', txEnabled: false, tx: '未退学', lbjgmMin: '', lbjgmMax: '',
|
|
||||||
bkcljgmMin: '', bkcljgmMax: '', gljgChecked: false, gljg: '教务处',
|
|
||||||
xylb: ''
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 数据表格 ====================
|
// ==================== 数据表格 ====================
|
||||||
@@ -406,33 +305,14 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 组装查询参数:文本非空才传,勾选启用的字段才传,门数范围二者其一非空才传 */
|
/** 组装查询参数:仅传后端 XYXX 实体支持的字符串字段,空值忽略 */
|
||||||
buildQueryParams(params) {
|
buildQueryParams(params) {
|
||||||
const textFields = ['xh', 'xm', 'sfzh', 'zjhm', 'zzmm', 'mz', 'jg', 'xw', 'ybzb', 'bq', 'whcd', 'bkbyyx', 'xylb', 'zdyfl', 'nj', 'zy', 'db', 'bc', 'sszq', 'jcqk']
|
const textFields = ['xh', 'xm', 'zjhm', 'zzmm', 'mz', 'jg', 'xw', 'ybzb', 'sfzh', 'whcd', 'bkbyyx', 'bq', 'lxdh', 'txdz']
|
||||||
textFields.forEach(key => {
|
textFields.forEach(key => {
|
||||||
const v = this.searchForm[key]
|
const v = this.searchForm[key]
|
||||||
if (v !== '' && v !== null && v !== undefined) params[key] = v.trim()
|
if (v !== '' && v !== null && v !== undefined) params[key] = v.trim()
|
||||||
})
|
})
|
||||||
if (this.searchForm.pxlxChecked) params.pxlx = this.searchForm.pxlx
|
|
||||||
if (this.searchForm.pxccChecked) params.pxcc = this.searchForm.pxcc
|
|
||||||
if (this.searchForm.pxlx2Checked) params.pxlx2 = this.searchForm.pxlx2
|
|
||||||
if (this.searchForm.xjydEnabled) params.xjyd = this.searchForm.xjyd
|
|
||||||
if (this.searchForm.ksqkEnabled) params.ksqk = this.searchForm.ksqk
|
|
||||||
if (this.searchForm.xbEnabled) params.xb = this.searchForm.xb
|
if (this.searchForm.xbEnabled) params.xb = this.searchForm.xb
|
||||||
if (this.searchForm.zcztEnabled) params.zczt = this.searchForm.zczt
|
|
||||||
if (this.searchForm.txEnabled) params.txzt = this.searchForm.tx
|
|
||||||
if (this.searchForm.gljgChecked) params.gljg = this.searchForm.gljg
|
|
||||||
const ranges = [
|
|
||||||
['bjgmMin', 'bjgmMax'],
|
|
||||||
['lbjgmMin', 'lbjgmMax'],
|
|
||||||
['bkcljgmMin', 'bkcljgmMax']
|
|
||||||
]
|
|
||||||
ranges.forEach(([minKey, maxKey]) => {
|
|
||||||
if (this.searchForm[minKey] !== '' || this.searchForm[maxKey] !== '') {
|
|
||||||
params[minKey] = this.searchForm[minKey]
|
|
||||||
params[maxKey] = this.searchForm[maxKey]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询/分页 ====================
|
// ==================== 查询/分页 ====================
|
||||||
|
|||||||
@@ -1,15 +1,256 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container warning-result-page">
|
||||||
<placeholder-page title="学员学籍预警结果" icon="checkbox"
|
<!-- ==================== 1. 查询条件 ==================== -->
|
||||||
description="用于查看学员学籍预警的触发结果列表,支持按条件筛选、导出与处理。" />
|
<el-card shadow="never" class="search-card">
|
||||||
|
<el-form ref="searchFormRef" :model="searchForm" label-width="110px" class="search-form">
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||||
|
<el-form-item label="年度">
|
||||||
|
<el-input v-model="searchForm.nd" placeholder="请输入年度" clearable @keyup.enter.native="handleSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||||
|
<el-form-item label="预警条件编号">
|
||||||
|
<el-input v-model="searchForm.yjtjbh" placeholder="请输入预警条件编号" clearable @keyup.enter.native="handleSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||||
|
<el-form-item label="学员编号">
|
||||||
|
<el-input v-model="searchForm.xybh" placeholder="请输入学员编号" clearable @keyup.enter.native="handleSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||||
|
<el-form-item label="发布">
|
||||||
|
<el-select v-model="searchForm.fb" placeholder="请选择发布状态" clearable class="w-full">
|
||||||
|
<el-option label="未发布" :value="0" />
|
||||||
|
<el-option label="已发布" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row class="search-actions-row">
|
||||||
|
<el-col :span="24" class="search-actions">
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- ==================== 2. 列表 ==================== -->
|
||||||
|
<el-card shadow="never" class="table-card">
|
||||||
|
<div class="table-header">
|
||||||
|
<span class="table-title">预警结果列表:</span>
|
||||||
|
</div>
|
||||||
|
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
|
||||||
|
<el-table-column prop="bh" label="编号" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="nd" label="年度" width="90" align="center" />
|
||||||
|
<el-table-column prop="yjtjbh" label="预警条件编号" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="xybh" label="学员编号" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="cjsj" label="创建时间" width="160" show-overflow-tooltip />
|
||||||
|
<el-table-column label="发布" width="90" align="center">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-tag :type="Number(row.fb) === 1 ? 'success' : 'info'" size="mini">
|
||||||
|
{{ Number(row.fb) === 1 ? '是' : '否' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="fbsj" label="发布时间" width="160" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" icon="el-icon-view" @click="handleDetail(row)">详情</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination-wrapper"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- ==================== 3. 详情对话框 ==================== -->
|
||||||
|
<el-dialog title="预警结果详情" :visible="detailDialogVisible" width="560px" :close-on-click-modal="false"
|
||||||
|
@update:visible="val => detailDialogVisible = val">
|
||||||
|
<div v-loading="detailLoading" class="detail-body">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailForm.bh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="年度">{{ detailForm.nd || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预警条件编号">{{ detailForm.yjtjbh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员编号">{{ detailForm.xybh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ detailForm.cjsj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发布时间">{{ detailForm.fbsj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发布">
|
||||||
|
<el-tag :type="Number(detailForm.fb) === 1 ? 'success' : 'info'" size="mini">
|
||||||
|
{{ Number(detailForm.fb) === 1 ? '是' : '否' }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PlaceholderPage from "@/components/PlaceholderPage"
|
import {
|
||||||
|
listWarningResult,
|
||||||
|
getWarningResult
|
||||||
|
} from '@/api/studentRecords/warningResult'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "WarningResult",
|
name: 'WarningResult',
|
||||||
components: { PlaceholderPage }
|
data() {
|
||||||
|
return {
|
||||||
|
// ==================== 查询条件 ====================
|
||||||
|
searchForm: {
|
||||||
|
nd: '',
|
||||||
|
yjtjbh: '',
|
||||||
|
xybh: '',
|
||||||
|
fb: undefined
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 列表数据 ====================
|
||||||
|
loading: false,
|
||||||
|
tableData: [],
|
||||||
|
total: 0,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
detailDialogVisible: false,
|
||||||
|
detailLoading: false,
|
||||||
|
detailForm: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// ==================== 查询列表 ====================
|
||||||
|
fetchList() {
|
||||||
|
this.loading = true
|
||||||
|
const params = {
|
||||||
|
pageNum: this.pageNum,
|
||||||
|
pageSize: this.pageSize
|
||||||
|
}
|
||||||
|
// 文本条件非空时才传
|
||||||
|
;['nd', 'yjtjbh', 'xybh'].forEach(key => {
|
||||||
|
const value = this.searchForm[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params[key] = String(value).trim()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 发布:等值筛选(选中时才传)
|
||||||
|
if (this.searchForm.fb !== undefined && this.searchForm.fb !== '' && this.searchForm.fb !== null) {
|
||||||
|
params.fb = this.searchForm.fb
|
||||||
|
}
|
||||||
|
listWarningResult(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearch() {
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleReset() {
|
||||||
|
this.$refs.searchFormRef.resetFields()
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePageChange(current) {
|
||||||
|
this.pageNum = current
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.pageSize = size
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
handleDetail(row) {
|
||||||
|
this.detailDialogVisible = true
|
||||||
|
this.detailLoading = true
|
||||||
|
this.detailForm = {}
|
||||||
|
getWarningResult(row.bh).then(response => {
|
||||||
|
this.detailForm = response.data || {}
|
||||||
|
this.detailLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.detailLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.app-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-result-page {
|
||||||
|
.search-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-actions-row {
|
||||||
|
margin-top: 2px;
|
||||||
|
border-top: 1px dashed #ebeef5;
|
||||||
|
padding-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-card {
|
||||||
|
.table-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.table-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -6,22 +6,22 @@
|
|||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-form-item label="专业名称">
|
<el-form-item label="专业名称">
|
||||||
<el-input v-model="searchForm.zymc" placeholder="请输入专业名称" clearable />
|
<el-input v-model="searchForm.zymc" placeholder="请输入专业名称" clearable @keyup.enter.native="handleSearch" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-form-item label="专业代码">
|
<el-form-item label="专业代码">
|
||||||
<el-input v-model="searchForm.zydm" placeholder="请输入专业代码" clearable />
|
<el-input v-model="searchForm.zydm" placeholder="请输入专业代码" clearable @keyup.enter.native="handleSearch" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-form-item label="专业方向">
|
<el-form-item label="专业方向">
|
||||||
<el-input v-model="searchForm.zyfx" placeholder="请输入专业方向" clearable />
|
<el-input v-model="searchForm.zyfx" placeholder="请输入专业方向" clearable @keyup.enter.native="handleSearch" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-form-item label="学年制">
|
<el-form-item label="学年制">
|
||||||
<el-input v-model="searchForm.xnz" placeholder="请输入学年制" clearable />
|
<el-input v-model="searchForm.xnz" placeholder="请输入学年制" clearable @keyup.enter.native="handleSearch" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
@@ -41,7 +41,6 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24" class="search-actions">
|
<el-col :span="24" class="search-actions">
|
||||||
<div class="search-tip">注意:"勾选框" 表示启用该项对应的查询条件。</div>
|
|
||||||
<div class="search-buttons">
|
<div class="search-buttons">
|
||||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||||
<el-button @click="handleReset">重置</el-button>
|
<el-button @click="handleReset">重置</el-button>
|
||||||
@@ -55,23 +54,25 @@
|
|||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<div class="table-header">
|
<div class="table-header">
|
||||||
<span class="table-title">学科专业列表:</span>
|
<span class="table-title">学科专业列表:</span>
|
||||||
<el-button type="primary" @click="handleAdd">新建学科专业</el-button>
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新建学科专业</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
|
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column prop="jxgljgbh" label="教学管理机构" width="120" show-overflow-tooltip />
|
<el-table-column label="序号" width="60" align="center">
|
||||||
<el-table-column prop="xh" label="序号" width="60" align="center" />
|
<template slot-scope="scope">{{ fmtXh(scope.$index) }}</template>
|
||||||
<el-table-column prop="zydm" label="专业代码" width="85" />
|
</el-table-column>
|
||||||
<el-table-column prop="zymc" label="专业名称" show-overflow-tooltip />
|
<el-table-column prop="jxgljgbh" label="教学管理机构" width="200" show-overflow-tooltip />
|
||||||
<el-table-column prop="rcpyfaCount" label="在用人才培养方案数" width="180" align="center" />
|
<el-table-column prop="zydm" label="专业代码" width="200" />
|
||||||
<el-table-column prop="zypyfa" label="在用人才培养方案" width="160" show-overflow-tooltip />
|
<el-table-column prop="zymc" label="专业名称" width="200" show-overflow-tooltip />
|
||||||
<el-table-column prop="zdyfl" label="分类" width="100" align="center" />
|
<el-table-column prop="zdyfl" label="分类" width="150" align="center" />
|
||||||
<el-table-column prop="xylb" label="学员类别" width="100" align="center" />
|
<el-table-column prop="xylb" label="学员类别" width="150" align="center" />
|
||||||
<el-table-column prop="xnz" label="学年制" width="90" align="center" />
|
<el-table-column prop="xnz" label="学年制" width="120" align="center" />
|
||||||
<el-table-column prop="xqs" label="学期数" width="90" align="center" />
|
<el-table-column prop="xqs" label="学期数" width="120" align="center" />
|
||||||
<el-table-column prop="zgzy" label="主干专业" width="100" align="center" />
|
<el-table-column prop="zgzy" label="主干专业" align="center" />
|
||||||
<el-table-column label="操作" width="160" align="center" fixed="right">
|
<el-table-column label="操作" width="230" align="center" fixed="right">
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" icon="el-icon-view" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button type="text" size="small" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
|
||||||
<el-button v-if="row.ty === 1" type="text" size="small" class="text-success" @click="handleEnable(row)">
|
<el-button v-if="row.ty === 1" type="text" size="small" class="text-success" @click="handleEnable(row)">
|
||||||
启用
|
启用
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -94,125 +95,160 @@
|
|||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 3. 新增学科专业对话框 ==================== -->
|
<!-- ==================== 3. 新增/编辑学科专业对话框 ==================== -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible="addDialogVisible"
|
:visible="formDialogVisible"
|
||||||
title="新增学科专业"
|
:title="dialogTitle"
|
||||||
width="750px"
|
width="750px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@update:visible="val => addDialogVisible = val"
|
@update:visible="val => formDialogVisible = val"
|
||||||
>
|
>
|
||||||
<el-form :model="addForm" label-width="130px" class="add-form">
|
<el-form ref="formRef" :model="form" label-width="130px" class="add-form">
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="规范名称">
|
<el-form-item label="规范名称">
|
||||||
<el-input v-model="addForm.gfmc" placeholder="请输入规范名称" />
|
<el-input v-model="form.gfmc" placeholder="请输入规范名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="序号">
|
<el-form-item label="序号">
|
||||||
<el-input v-model="addForm.xh" placeholder="请输入序号" />
|
<el-input-number v-model="form.xh" :min="0" controls-position="right" style="width: 100%" placeholder="请输入序号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="专业代码">
|
<el-form-item label="专业代码">
|
||||||
<el-input v-model="addForm.zydm" placeholder="请输入专业代码" />
|
<el-input v-model="form.zydm" placeholder="请输入专业代码" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="专业名称">
|
<el-form-item label="专业名称">
|
||||||
<el-input v-model="addForm.zymc" placeholder="请输入专业名称" />
|
<el-input v-model="form.zymc" placeholder="请输入专业名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="专业方向">
|
<el-form-item label="专业方向">
|
||||||
<el-input v-model="addForm.zyfx" placeholder="请输入专业方向" />
|
<el-input v-model="form.zyfx" placeholder="请输入专业方向" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="学年制">
|
<el-form-item label="学年制">
|
||||||
<el-input v-model="addForm.xnz" placeholder="请输入学年制" />
|
<el-input v-model="form.xnz" placeholder="请输入学年制" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="学期数">
|
<el-form-item label="学期数">
|
||||||
<el-input v-model="addForm.xqs" placeholder="请输入学期数" />
|
<el-input-number v-model="form.xqs" :min="0" controls-position="right" style="width: 100%" placeholder="请输入学期数" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="培训层次">
|
<el-form-item label="培训层次">
|
||||||
<el-input v-model="addForm.pxcc" placeholder="请输入培训层次" />
|
<el-input v-model="form.pxcc" placeholder="请输入培训层次" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="培训类型">
|
<el-form-item label="培训类型">
|
||||||
<el-input v-model="addForm.pxlx" placeholder="请输入培训类型" />
|
<el-input v-model="form.pxlx" placeholder="请输入培训类型" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="培训类型2">
|
<el-form-item label="培训类型2">
|
||||||
<el-input v-model="addForm.pxlx2" placeholder="请输入培训类型2" />
|
<el-input v-model="form.pxlx2" placeholder="请输入培训类型2" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="教学管理机构编号">
|
<el-form-item label="教学管理机构编号">
|
||||||
<el-input v-model="addForm.jxgljgbh" placeholder="请输入教学管理机构编号" />
|
<el-input v-model="form.jxgljgbh" placeholder="请输入教学管理机构编号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="学员类别">
|
<el-form-item label="学员类别">
|
||||||
<el-input v-model="addForm.xylb" placeholder="请输入学员类别" />
|
<el-input v-model="form.xylb" placeholder="请输入学员类别" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="指导分类">
|
<el-form-item label="自定义分类">
|
||||||
<el-input v-model="addForm.zdyfl" placeholder="请输入指导分类" />
|
<el-input v-model="form.zdyfl" placeholder="请输入自定义分类" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="主干专业">
|
<el-form-item label="主干专业">
|
||||||
<el-input v-model="addForm.zgzy" placeholder="请输入主干专业" />
|
<el-input v-model="form.zgzy" placeholder="请输入主干专业" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="JSON字段">
|
<el-form-item label="JSON字段">
|
||||||
<el-input v-model="addForm.jsonzd" placeholder="请输入JSON字段" />
|
<el-input v-model="form.jsonzd" placeholder="请输入JSON字段" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input v-model="addForm.bz" type="textarea" :rows="3" placeholder="请输入备注" />
|
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
<el-button @click="addDialogVisible = false">取消</el-button>
|
<el-button @click="formDialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" :loading="addSaving" @click="handleAddConfirm">确定</el-button>
|
<el-button type="primary" :loading="formSaving" @click="handleFormSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ==================== 4. 详情对话框 ==================== -->
|
||||||
|
<el-dialog title="学科专业详情" :visible="detailDialogVisible" width="700px" :close-on-click-modal="false"
|
||||||
|
@update:visible="val => detailDialogVisible = val">
|
||||||
|
<div v-loading="detailLoading" class="detail-body">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="规范名称">{{ detailForm.gfmc || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="序号">{{ fmtValue(detailForm.xh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业代码">{{ detailForm.zydm || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业名称">{{ detailForm.zymc || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业方向">{{ detailForm.zyfx || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学年制">{{ detailForm.xnz || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学期数">{{ fmtValue(detailForm.xqs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培训层次">{{ detailForm.pxcc || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培训类型">{{ detailForm.pxlx || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培训类型2">{{ detailForm.pxlx2 || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学管理机构编号">{{ detailForm.jxgljgbh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员类别">{{ detailForm.xylb || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="自定义分类">{{ detailForm.zdyfl || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="主干专业">{{ detailForm.zgzy || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="停用">
|
||||||
|
<el-tag :type="detailForm.ty === 1 ? 'danger' : 'success'" size="mini">
|
||||||
|
{{ detailForm.ty === 1 ? '是' : '否' }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="停用时间">{{ detailForm.tysj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="JSON字段" :span="2">{{ detailForm.jsonzd || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ detailForm.bz || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟学科专业列表数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import {
|
||||||
const mockTableData = [
|
listDiscipline,
|
||||||
{ bsh: 'Z001', jxgljgbh: 'JG001', xh: 1, zydm: '110101', zymc: '军事指挥', rcpyfaCount: 2, zypyfa: '2026版军事指挥人才培养方案', zdyfl: '指挥类', xylb: '生长干部', xnz: '4', xqs: '8', zgzy: '是', ty: 0 },
|
getDiscipline,
|
||||||
{ bsh: 'Z002', jxgljgbh: 'JG002', xh: 2, zydm: '110102', zymc: '通信工程', rcpyfaCount: 1, zypyfa: '2025版通信工程人才培养方案', zdyfl: '技术类', xylb: '现职干部', xnz: '3', xqs: '6', zgzy: '是', ty: 1 },
|
addDiscipline,
|
||||||
{ bsh: 'Z003', jxgljgbh: 'JG003', xh: 3, zydm: '110103', zymc: '装备维修', rcpyfaCount: 0, zypyfa: '-', zdyfl: '勤务类', xylb: '士官', xnz: '2', xqs: '4', zgzy: '否', ty: 0 }
|
updateDiscipline,
|
||||||
]
|
disableDiscipline
|
||||||
|
} from '@/api/subjectMajor/discipline'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DisciplineIndex',
|
name: 'DisciplineIndex',
|
||||||
@@ -231,79 +267,87 @@ export default {
|
|||||||
// ==================== 列表数据 ====================
|
// ==================== 列表数据 ====================
|
||||||
loading: false,
|
loading: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
allData: [],
|
|
||||||
total: 0,
|
total: 0,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
|
|
||||||
// ==================== 新增学科专业 ====================
|
// ==================== 新增/编辑 ====================
|
||||||
addDialogVisible: false,
|
formDialogVisible: false,
|
||||||
addSaving: false,
|
dialogTitle: '新增学科专业',
|
||||||
addForm: this.createEmptyAddForm()
|
isAdd: true,
|
||||||
|
formSaving: false,
|
||||||
|
form: this.createEmptyForm(),
|
||||||
|
|
||||||
|
// ==================== 详情 ====================
|
||||||
|
detailDialogVisible: false,
|
||||||
|
detailLoading: false,
|
||||||
|
detailForm: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
createEmptyAddForm() {
|
/** 序号:按当前页数据索引生成跨页连续的序号 */
|
||||||
|
fmtXh(index) {
|
||||||
|
return (this.pageNum - 1) * this.pageSize + index + 1
|
||||||
|
},
|
||||||
|
|
||||||
|
createEmptyForm() {
|
||||||
return {
|
return {
|
||||||
|
bsh: '',
|
||||||
gfmc: '',
|
gfmc: '',
|
||||||
xh: '',
|
xh: undefined,
|
||||||
zydm: '',
|
zydm: '',
|
||||||
zymc: '',
|
zymc: '',
|
||||||
zyfx: '',
|
zyfx: '',
|
||||||
xnz: '',
|
xnz: '',
|
||||||
xqs: '',
|
xqs: undefined,
|
||||||
pxcc: '',
|
pxcc: '',
|
||||||
pxlx: '',
|
pxlx: '',
|
||||||
jxgljgbh: '',
|
|
||||||
bz: '',
|
|
||||||
pxlx2: '',
|
pxlx2: '',
|
||||||
|
jxgljgbh: '',
|
||||||
xylb: '',
|
xylb: '',
|
||||||
zdyfl: '',
|
zdyfl: '',
|
||||||
jsonzd: '',
|
jsonzd: '',
|
||||||
zgzy: ''
|
zgzy: '',
|
||||||
|
bz: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询列表 ====================
|
// ==================== 查询列表 ====================
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 getDisciplineList
|
|
||||||
fetchList() {
|
fetchList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
setTimeout(() => {
|
const params = {
|
||||||
let records = mockTableData.slice()
|
pageNum: this.pageNum,
|
||||||
if (this.searchForm.zymc.trim()) {
|
pageSize: this.pageSize
|
||||||
records = records.filter((item) => (item.zymc || '').includes(this.searchForm.zymc.trim()))
|
}
|
||||||
|
// 状态:勾选「停用」时仅查已停用(ty=1),未勾选则查询全部
|
||||||
|
if (this.searchForm.ty) {
|
||||||
|
params.ty = 1
|
||||||
|
}
|
||||||
|
// 其余文本条件非空时才传
|
||||||
|
;['zymc', 'zydm', 'zyfx', 'xnz', 'pxlx2'].forEach(key => {
|
||||||
|
const value = this.searchForm[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params[key] = String(value).trim()
|
||||||
}
|
}
|
||||||
if (this.searchForm.zydm.trim()) {
|
})
|
||||||
records = records.filter((item) => (item.zydm || '').includes(this.searchForm.zydm.trim()))
|
listDiscipline(params).then(response => {
|
||||||
}
|
const data = response.data || {}
|
||||||
if (this.searchForm.zyfx.trim()) {
|
this.tableData = data.records || []
|
||||||
records = records.filter((item) => (item.zyfx || '').includes(this.searchForm.zyfx.trim()))
|
this.total = data.total || 0
|
||||||
}
|
|
||||||
if (this.searchForm.xnz.trim()) {
|
|
||||||
records = records.filter((item) => String(item.xnz || '').includes(this.searchForm.xnz.trim()))
|
|
||||||
}
|
|
||||||
if (this.searchForm.ty) {
|
|
||||||
records = records.filter((item) => item.ty === 1)
|
|
||||||
}
|
|
||||||
this.allData = records
|
|
||||||
this.total = records.length
|
|
||||||
this.applyPage()
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}, 200)
|
}).catch(() => {
|
||||||
},
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
applyPage() {
|
this.loading = false
|
||||||
const start = (this.pageNum - 1) * this.pageSize
|
})
|
||||||
this.tableData = this.allData.slice(start, start + this.pageSize)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
this.pageNum = 1
|
this.pageNum = 1
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
this.$message.success('查询完成(前端模拟)')
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleReset() {
|
handleReset() {
|
||||||
@@ -323,47 +367,127 @@ export default {
|
|||||||
this.fetchList()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ==================== 新增/编辑 ====================
|
||||||
|
handleAdd() {
|
||||||
|
this.isAdd = true
|
||||||
|
this.dialogTitle = '新增学科专业'
|
||||||
|
this.form = this.createEmptyForm()
|
||||||
|
this.formDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEdit(row) {
|
||||||
|
this.isAdd = false
|
||||||
|
this.dialogTitle = '编辑学科专业'
|
||||||
|
this.form = this.createEmptyForm()
|
||||||
|
this.formDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||||
|
})
|
||||||
|
getDiscipline(row.bsh).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.form = {
|
||||||
|
bsh: data.bsh || '',
|
||||||
|
gfmc: data.gfmc || '',
|
||||||
|
xh: data.xh !== null && data.xh !== undefined ? data.xh : undefined,
|
||||||
|
zydm: data.zydm || '',
|
||||||
|
zymc: data.zymc || '',
|
||||||
|
zyfx: data.zyfx || '',
|
||||||
|
xnz: data.xnz || '',
|
||||||
|
xqs: data.xqs !== null && data.xqs !== undefined ? data.xqs : undefined,
|
||||||
|
pxcc: data.pxcc || '',
|
||||||
|
pxlx: data.pxlx || '',
|
||||||
|
pxlx2: data.pxlx2 || '',
|
||||||
|
jxgljgbh: data.jxgljgbh || '',
|
||||||
|
xylb: data.xylb || '',
|
||||||
|
zdyfl: data.zdyfl || '',
|
||||||
|
jsonzd: data.jsonzd || '',
|
||||||
|
zgzy: data.zgzy || '',
|
||||||
|
bz: data.bz || ''
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
buildPayload() {
|
||||||
|
const f = this.form
|
||||||
|
const payload = {
|
||||||
|
bsh: f.bsh || undefined,
|
||||||
|
gfmc: f.gfmc,
|
||||||
|
zydm: f.zydm,
|
||||||
|
zymc: f.zymc,
|
||||||
|
zyfx: f.zyfx,
|
||||||
|
xnz: f.xnz,
|
||||||
|
pxcc: f.pxcc,
|
||||||
|
pxlx: f.pxlx,
|
||||||
|
pxlx2: f.pxlx2,
|
||||||
|
jxgljgbh: f.jxgljgbh,
|
||||||
|
xylb: f.xylb,
|
||||||
|
zdyfl: f.zdyfl,
|
||||||
|
zgzy: f.zgzy,
|
||||||
|
jsonzd: f.jsonzd,
|
||||||
|
bz: f.bz
|
||||||
|
}
|
||||||
|
// 序号、学期数为数值字段,转为数字后再提交
|
||||||
|
if (f.xh !== '' && f.xh !== null && f.xh !== undefined) {
|
||||||
|
payload.xh = Number(f.xh)
|
||||||
|
}
|
||||||
|
if (f.xqs !== '' && f.xqs !== null && f.xqs !== undefined) {
|
||||||
|
payload.xqs = Number(f.xqs)
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
|
||||||
|
handleFormSubmit() {
|
||||||
|
this.formSaving = true
|
||||||
|
const payload = this.buildPayload()
|
||||||
|
const request = this.isAdd ? addDiscipline(payload) : updateDiscipline(payload)
|
||||||
|
request.then(() => {
|
||||||
|
this.$message.success(this.isAdd ? '新增成功' : '修改成功')
|
||||||
|
this.formDialogVisible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {
|
||||||
|
}).finally(() => {
|
||||||
|
this.formSaving = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 停用/启用 ====================
|
// ==================== 停用/启用 ====================
|
||||||
// TODO: 后端接口未提供,停用/启用为前端模拟;接口就绪后替换为 toggleDiscipline
|
|
||||||
handleDisable(row) {
|
handleDisable(row) {
|
||||||
this.$confirm(`确定要停用「${row.zymc || row.zydm || '该专业'}」吗?`, '系统提示', {
|
this.$confirm(`确定要停用「${row.zymc || row.zydm || '该专业'}」吗?`, '系统提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
row.ty = 1
|
return disableDiscipline(row.bsh)
|
||||||
this.$message.success('停用成功(前端模拟)')
|
|
||||||
this.fetchList()
|
|
||||||
}).catch(() => {})
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEnable(row) {
|
|
||||||
this.$confirm(`确定要启用「${row.zymc || row.zydm || '该专业'}」吗?`, '系统提示', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning'
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
row.ty = 0
|
this.$message.success('停用成功')
|
||||||
this.$message.success('启用成功(前端模拟)')
|
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 新增学科专业 ====================
|
// 后端暂未提供启用接口,仅作提示
|
||||||
handleAdd() {
|
handleEnable(row) {
|
||||||
this.addForm = this.createEmptyAddForm()
|
this.$message.info('后端暂未提供该接口')
|
||||||
this.addDialogVisible = true
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: 后端接口未提供,新增为前端模拟;接口就绪后替换为 addDiscipline
|
// ==================== 详情 ====================
|
||||||
handleAddConfirm() {
|
// 数值字段空值显示为 '-'(保留 0)
|
||||||
this.addSaving = true
|
fmtValue(val) {
|
||||||
setTimeout(() => {
|
return val === null || val === undefined || val === '' ? '-' : val
|
||||||
this.$message.success('新增学科专业成功(前端模拟)')
|
},
|
||||||
this.addDialogVisible = false
|
|
||||||
this.fetchList()
|
handleDetail(row) {
|
||||||
this.addSaving = false
|
this.detailDialogVisible = true
|
||||||
}, 300)
|
this.detailLoading = true
|
||||||
|
this.detailForm = {}
|
||||||
|
getDiscipline(row.bsh).then(response => {
|
||||||
|
this.detailForm = response.data || {}
|
||||||
|
this.detailLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.detailLoading = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="app-container major-page">
|
<div class="app-container major-page">
|
||||||
<!-- ==================== 1. 查询条件 ==================== -->
|
<!-- ==================== 1. 查询条件 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form ref="searchFormRef" :model="searchForm" label-width="90px" class="search-form">
|
<el-form ref="searchFormRef" :model="searchForm" label-width="140px" class="search-form">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||||
<el-form-item label="专业名称">
|
<el-form-item label="专业名称">
|
||||||
@@ -72,7 +72,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
|
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column label="序号" width="60" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtXh(scope.$index) }}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="zydh" label="专业代号" width="120" show-overflow-tooltip />
|
<el-table-column prop="zydh" label="专业代号" width="120" show-overflow-tooltip />
|
||||||
<el-table-column prop="zymc" label="专业名称" min-width="140" show-overflow-tooltip />
|
<el-table-column prop="zymc" label="专业名称" min-width="140" show-overflow-tooltip />
|
||||||
<el-table-column prop="zyfx" label="专业方向" min-width="120" show-overflow-tooltip />
|
<el-table-column prop="zyfx" label="专业方向" min-width="120" show-overflow-tooltip />
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ export default {
|
|||||||
totalWeeks: 0,
|
totalWeeks: 0,
|
||||||
dateRangeText: '',
|
dateRangeText: '',
|
||||||
weeks: [],
|
weeks: [],
|
||||||
// 显示控制:默认勾选显示日期;节次全部展示
|
// 显示控制:默认不勾选显示日期;节次全部展示
|
||||||
showDate: true,
|
showDate: false,
|
||||||
// 事件存储:key = cellKey -> event
|
// 事件存储:key = cellKey -> event
|
||||||
events: {},
|
events: {},
|
||||||
loading: false
|
loading: false
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container teach-semester">
|
<div class="app-container teach-semester">
|
||||||
<!-- 工具栏 -->
|
<!-- 工具栏 -->
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="semester-toolbar">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新添</el-button>
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新添</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -17,62 +17,75 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<div class="semester-table-wrap">
|
||||||
v-loading="loading"
|
<el-table
|
||||||
:data="semesterList"
|
v-loading="loading"
|
||||||
border
|
:data="semesterList"
|
||||||
:height="tableHeight"
|
border
|
||||||
@selection-change="handleSelectionChange"
|
stripe
|
||||||
>
|
:height="tableHeight"
|
||||||
<el-table-column type="selection" align="center" width="50" />
|
:row-class-name="tableRowClassName"
|
||||||
<el-table-column label="学期名称" align="center" min-width="190">
|
:header-cell-style="{ background: '#F4F8F5', color: '#303133', fontWeight: 600 }"
|
||||||
<template slot-scope="scope">
|
@selection-change="handleSelectionChange"
|
||||||
<span>{{ getSemesterName(scope.row.nd) }}</span>
|
>
|
||||||
</template>
|
<el-table-column type="selection" align="center" width="50" />
|
||||||
</el-table-column>
|
<el-table-column label="学期名称" align="center" min-width="190">
|
||||||
<el-table-column label="当前" align="center" width="70">
|
<template slot-scope="scope">
|
||||||
<template slot-scope="scope">
|
<span class="semester-name">
|
||||||
<el-tag v-if="scope.row.dqxq" type="success" size="mini">当前</el-tag>
|
<i v-if="scope.row.dqxq" class="semester-name-icon el-icon-star-on"></i>
|
||||||
<span v-else>-</span>
|
<span>{{ getSemesterName(scope.row.nd) }}</span>
|
||||||
</template>
|
</span>
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column label="开学日期" align="center" prop="kxrq" min-width="130">
|
</el-table-column>
|
||||||
<template slot-scope="scope">
|
<el-table-column label="当前" align="center" width="80">
|
||||||
<span>{{ formatDate(scope.row.kxrq) }}</span>
|
<template slot-scope="scope">
|
||||||
</template>
|
<el-tag v-if="scope.row.dqxq" type="success" effect="dark" size="mini">当前学期</el-tag>
|
||||||
</el-table-column>
|
<span v-else class="text-muted">—</span>
|
||||||
<el-table-column label="结束日期" align="center" prop="jsrq" min-width="130">
|
</template>
|
||||||
<template slot-scope="scope">
|
</el-table-column>
|
||||||
<span>{{ formatDate(scope.row.jsrq) }}</span>
|
<el-table-column label="开学日期" align="center" min-width="120">
|
||||||
</template>
|
<template slot-scope="scope">
|
||||||
</el-table-column>
|
<span class="date-cell"><i class="el-icon-date"></i>{{ formatDate(scope.row.kxrq) || '—' }}</span>
|
||||||
<el-table-column label="周数" align="center" prop="sdzs" width="70" />
|
</template>
|
||||||
<el-table-column label="调课不审批" align="center" width="100">
|
</el-table-column>
|
||||||
<template slot-scope="scope">
|
<el-table-column label="结束日期" align="center" min-width="120">
|
||||||
<el-tag :type="scope.row.tkbsp ? 'primary' : 'info'" size="mini">{{ scope.row.tkbsp ? '是' : '否' }}</el-tag>
|
<template slot-scope="scope">
|
||||||
</template>
|
<span class="date-cell"><i class="el-icon-date"></i>{{ formatDate(scope.row.jsrq) || '—' }}</span>
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column label="禁止调课" align="center" width="90">
|
</el-table-column>
|
||||||
<template slot-scope="scope">
|
<el-table-column label="周数" align="center" prop="sdzs" width="80">
|
||||||
<el-tag :type="scope.row.jztk ? 'danger' : 'info'" size="mini">{{ scope.row.jztk ? '是' : '否' }}</el-tag>
|
<template slot-scope="scope">
|
||||||
</template>
|
<el-tag v-if="scope.row.sdzs !== undefined && scope.row.sdzs !== null" type="info" effect="plain" size="mini">{{ scope.row.sdzs }} 周</el-tag>
|
||||||
</el-table-column>
|
<span v-else class="text-muted">—</span>
|
||||||
<el-table-column label="终结成绩定及格" align="center" width="120">
|
</template>
|
||||||
<template slot-scope="scope">
|
</el-table-column>
|
||||||
<el-tag :type="scope.row.zjcjdjg ? 'primary' : 'info'" size="mini">{{ scope.row.zjcjdjg ? '是' : '否' }}</el-tag>
|
<el-table-column label="调课不审批" align="center" width="116">
|
||||||
</template>
|
<template slot-scope="scope">
|
||||||
</el-table-column>
|
<span :class="boolCellClass(scope.row.tkbsp)">{{ scope.row.tkbsp ? '是' : '否' }}</span>
|
||||||
<el-table-column label="课时系数方案" align="center" min-width="120">
|
</template>
|
||||||
<template slot-scope="scope">
|
</el-table-column>
|
||||||
<span>{{ getCoefficientLabel(scope.row.ksxsfabh) }}</span>
|
<el-table-column label="禁止调课" align="center" width="100">
|
||||||
</template>
|
<template slot-scope="scope">
|
||||||
</el-table-column>
|
<span :class="boolCellClass(scope.row.jztk)">{{ scope.row.jztk ? '是' : '否' }}</span>
|
||||||
<el-table-column label="锁定时长" align="center" min-width="100">
|
</template>
|
||||||
<template slot-scope="scope">
|
</el-table-column>
|
||||||
<span>{{ scope.row.sdjldw || '-' }}</span>
|
<el-table-column label="终结成绩定及格" align="center" width="132">
|
||||||
</template>
|
<template slot-scope="scope">
|
||||||
</el-table-column>
|
<span :class="boolCellClass(scope.row.zjcjdjg)">{{ scope.row.zjcjdjg ? '是' : '否' }}</span>
|
||||||
</el-table>
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="课时系数方案" align="center" min-width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ getCoefficientLabel(scope.row.ksxsfabh) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="锁定时长" align="center" min-width="96">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span class="lock-cell">{{ scope.row.sdjldw || '—' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<pagination
|
<pagination
|
||||||
v-show="total > 0"
|
v-show="total > 0"
|
||||||
@@ -335,6 +348,14 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
/** 当前学期行高亮类名 */
|
||||||
|
tableRowClassName({ row }) {
|
||||||
|
return row.dqxq ? 'current-semester-row' : ''
|
||||||
|
},
|
||||||
|
/** 布尔开关单元格样式:是=实心绿点,否=灰色横线标记 */
|
||||||
|
boolCellClass(val) {
|
||||||
|
return val ? 'bool-cell is-true' : 'bool-cell is-false'
|
||||||
|
},
|
||||||
/** 多选变化 */
|
/** 多选变化 */
|
||||||
handleSelectionChange(selection) {
|
handleSelectionChange(selection) {
|
||||||
this.ids = selection.map(item => item.nd)
|
this.ids = selection.map(item => item.nd)
|
||||||
@@ -491,8 +512,146 @@ export default {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.teach-semester {
|
.teach-semester {
|
||||||
.mb8 {
|
/* 页面标题区 */
|
||||||
margin-bottom: 8px;
|
.semester-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding-bottom: 14px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.semester-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-dot {
|
||||||
|
width: 5px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: var(--color, #00875A);
|
||||||
|
}
|
||||||
|
|
||||||
|
.semester-subtitle {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #909399;
|
||||||
|
line-height: 1.5;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 工具栏 */
|
||||||
|
.semester-toolbar {
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格卡片容器 */
|
||||||
|
.semester-table-wrap {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表头由 header-cell-style 设置底色,这里兜底 */
|
||||||
|
::v-deep .el-table__header th {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当前学期行高亮:浅绿底 + 左侧加深强调 */
|
||||||
|
::v-deep .el-table .current-semester-row td {
|
||||||
|
background: #F2FAF5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-table .current-semester-row:hover > td {
|
||||||
|
background: #EAF6EF;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-table .current-semester-row td:first-child {
|
||||||
|
box-shadow: inset 3px 0 0 #00875A;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 学期名称 + 当前星标 */
|
||||||
|
.semester-name {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.semester-name-icon {
|
||||||
|
color: #00875A;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 日期单元格 */
|
||||||
|
.date-cell {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
color: #606266;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: #a0a6ad;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 锁定时长 */
|
||||||
|
.lock-cell {
|
||||||
|
background: #F4F6F8;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 1px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 布尔开关:实心圆点 + 是/否 */
|
||||||
|
.bool-cell {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-true {
|
||||||
|
color: #00875A;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background: #00875A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-false {
|
||||||
|
color: #C0C4CC;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border: 1px solid #CDD1D6;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: #C0C4CC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 弹窗内表单:防止 label 文字换行、字段拥挤换行 */
|
/* 弹窗内表单:防止 label 文字换行、字段拥挤换行 */
|
||||||
|
|||||||
@@ -2,64 +2,28 @@
|
|||||||
<div class="app-container syllabus-page">
|
<div class="app-container syllabus-page">
|
||||||
<!-- 查询条件 -->
|
<!-- 查询条件 -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form :model="searchForm" label-width="120px" class="search-form">
|
<el-form :model="searchForm" label-width="100px" class="search-form" @submit.native.prevent>
|
||||||
<el-row :gutter="32">
|
<el-row :gutter="32">
|
||||||
<!-- 左栏 -->
|
<el-col :xs="24" :md="8">
|
||||||
<el-col :xs="24" :md="12">
|
<el-form-item label="专业代号">
|
||||||
<el-form-item label="专业名称">
|
<el-input v-model="searchForm.zydh" placeholder="请输入专业代号" clearable />
|
||||||
<el-input v-model="searchForm.zymc" placeholder="请输入专业名称" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专业方向">
|
|
||||||
<el-input v-model="searchForm.zyfx" placeholder="请输入专业方向" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxlxEnabled">培训类型</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxlx" placeholder="请选择培训类型" clearable class="w-full" :disabled="!searchForm.pxlxEnabled">
|
|
||||||
<el-option v-for="item in pxlxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.pxccEnabled">培训层次</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.pxcc" placeholder="请选择培训层次" clearable class="w-full" :disabled="!searchForm.pxccEnabled">
|
|
||||||
<el-option v-for="item in pxccOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="自定义分类">
|
|
||||||
<el-input v-model="searchForm.zdyfl" placeholder="请输入自定义分类" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
<!-- 右栏 -->
|
<el-form-item label="停用标识">
|
||||||
<el-col :xs="24" :md="12">
|
<el-select v-model="searchForm.ty" placeholder="全部" clearable class="w-full">
|
||||||
<el-form-item label="专业代码">
|
<el-option :value="0" label="正常" />
|
||||||
<el-input v-model="searchForm.zydm" placeholder="请输入专业代码" clearable />
|
<el-option :value="1" label="停用" />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学年制">
|
|
||||||
<el-input v-model="searchForm.xnz" placeholder="请输入学年制" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="培训类型2">
|
|
||||||
<el-select v-model="searchForm.pxlx2" placeholder="请选择培训类型2" clearable class="w-full">
|
|
||||||
<el-option v-for="item in pxlx2Options" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="启用状态">
|
|
||||||
<el-checkbox v-model="searchForm.ty">停用</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="大纲版本">
|
|
||||||
<el-input v-model="searchForm.dgbb" placeholder="请输入大纲版本" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label"><el-checkbox v-model="searchForm.gljgEnabled">管理机构</el-checkbox></template>
|
|
||||||
<el-select v-model="searchForm.gljg" placeholder="请选择管理机构" clearable class="w-full" :disabled="!searchForm.gljgEnabled">
|
|
||||||
<el-option v-for="item in gljgOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<div class="search-actions">
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="search-footer">
|
|
||||||
<div class="notice">注意:勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
<el-button type="primary" @click="handleQuery">查询</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@@ -67,79 +31,393 @@
|
|||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<div class="list-title">教学大纲列表</div>
|
<div class="list-title">教学大纲列表</div>
|
||||||
<el-button type="primary" @click="handleDownload">下载</el-button>
|
<div class="list-actions">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
|
||||||
|
<el-button type="danger" icon="el-icon-delete" :disabled="!selection.length" @click="handleBatchDelete">删除所选</el-button>
|
||||||
|
<el-button icon="el-icon-download" @click="handleDownload">下载</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="tableData" border stripe style="width: 100%">
|
<el-table v-loading="loading" :data="pagedData" border stripe highlight-current-row
|
||||||
<el-table-column prop="jxgljg" label="教学管理机构" min-width="140" />
|
@selection-change="handleSelectionChange">
|
||||||
<el-table-column prop="xkzyxx" label="学科专业信息" min-width="140" />
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
<el-table-column prop="jxdgxx" label="教学大纲信息" min-width="200" />
|
<el-table-column prop="bh" label="编号" width="170" show-overflow-tooltip align="center" />
|
||||||
<el-table-column prop="fl" label="分类" width="100" align="center" />
|
<el-table-column prop="zydh" label="专业代号" width="150" align="center" />
|
||||||
<el-table-column prop="xylb" label="学员类别" width="100" align="center" />
|
<el-table-column prop="kbh" label="课编号" width="110" show-overflow-tooltip align="center" />
|
||||||
<el-table-column prop="xnz" label="学年制" width="80" align="center" />
|
<el-table-column prop="jc" label="简称" width="100" show-overflow-tooltip align="center" />
|
||||||
<el-table-column prop="xsfb" label="学时分布" min-width="140" align="center" />
|
<el-table-column prop="klx" label="课类型" width="80" align="center" />
|
||||||
<el-table-column prop="zy" label="停用" width="80" align="center" />
|
<el-table-column prop="xqdc" label="学期第次" width="80" align="center" />
|
||||||
|
<el-table-column prop="xs" label="学时" width="70" align="center" />
|
||||||
|
<el-table-column prop="xf" label="学分" width="70" align="center" />
|
||||||
|
<el-table-column prop="llxs" label="理论学时" width="80" align="center" />
|
||||||
|
<el-table-column prop="sjxs" label="实践学时" width="80" align="center" />
|
||||||
|
<el-table-column prop="zks" label="周课时" width="70" align="center" />
|
||||||
|
<el-table-column prop="ksks" label="考试课时" width="80" align="center" />
|
||||||
|
<el-table-column label="大纲课程" width="90" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtYesNo(scope.row.dgkc) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="停用" width="80" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="Number(scope.row.ty) === 1 ? 'danger' : 'success'" size="mini">
|
||||||
|
{{ Number(scope.row.ty) === 1 ? '停用' : '正常' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="启用时间" width="150" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtDateTime(scope.row.qysj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="停用时间" width="150" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtDateTime(scope.row.tysj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="140" align="center" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-delete" class="danger-text-btn" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
class="pagination"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next"
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 新增/编辑弹窗 -->
|
||||||
|
<el-dialog :title="dialog.title" :visible.sync="dialog.visible" width="720px" append-to-body
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<el-form ref="syllabusForm" :model="dialog.form" :rules="rules" label-width="130px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="专业代号" prop="zydh">
|
||||||
|
<el-input v-model="dialog.form.zydh" placeholder="请输入专业代号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="课编号" prop="kbh">
|
||||||
|
<el-input v-model="dialog.form.kbh" placeholder="请输入课编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="学期第次" prop="xqdc">
|
||||||
|
<el-input-number v-model="dialog.form.xqdc" :min="1" :max="20" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="课类型" prop="klx">
|
||||||
|
<el-input v-model="dialog.form.klx" placeholder="请输入课类型" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="学时" prop="xs">
|
||||||
|
<el-input-number v-model="dialog.form.xs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="停用" prop="ty">
|
||||||
|
<el-select v-model="dialog.form.ty" class="w-full">
|
||||||
|
<el-option :value="0" label="正常" />
|
||||||
|
<el-option :value="1" label="停用" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="简称">
|
||||||
|
<el-input v-model="dialog.form.jc" placeholder="请输入课程简称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="学分">
|
||||||
|
<el-input-number v-model="dialog.form.xf" :min="0" :step="0.5" :precision="1" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="课程定位">
|
||||||
|
<el-input v-model="dialog.form.kcdw" placeholder="请输入课程定位" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="模块">
|
||||||
|
<el-input v-model="dialog.form.mk" placeholder="请输入模块" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="成绩分制">
|
||||||
|
<el-input v-model="dialog.form.cjfz" placeholder="请输入成绩分制" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="教研室代号">
|
||||||
|
<el-input v-model="dialog.form.jysdh" placeholder="请输入教研室代号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="考试课时">
|
||||||
|
<el-input-number v-model="dialog.form.ksks" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="理论学时">
|
||||||
|
<el-input-number v-model="dialog.form.llxs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="实践学时">
|
||||||
|
<el-input-number v-model="dialog.form.sjxs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="周课时">
|
||||||
|
<el-input-number v-model="dialog.form.zks" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="不计入平均分">
|
||||||
|
<el-radio-group v-model="dialog.form.bjrxypjf">
|
||||||
|
<el-radio :label="0">否</el-radio>
|
||||||
|
<el-radio :label="1">是</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="考试课时不显示">
|
||||||
|
<el-radio-group v-model="dialog.form.ksksbxs">
|
||||||
|
<el-radio :label="0">否</el-radio>
|
||||||
|
<el-radio :label="1">是</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="大纲课程">
|
||||||
|
<el-radio-group v-model="dialog.form.dgkc">
|
||||||
|
<el-radio :label="0">否</el-radio>
|
||||||
|
<el-radio :label="1">是</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialog.visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="dialog.submitting" @click="submitDialog">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟列表数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import {
|
||||||
const mockTableData = [
|
addSyllabus,
|
||||||
{ jxgljg: '教务处', xkzyxx: '通信工程', jxdgxx: '通信工程导论教学大纲', fl: '专业基础', xylb: '军官', xnz: '4', xsfb: '理论48/实践16', zy: '教学' },
|
deleteSyllabus,
|
||||||
{ jxgljg: '教务处', xkzyxx: '信息工程', jxdgxx: '信息工程基础教学大纲', fl: '专业基础', xylb: '军官', xnz: '4', xsfb: '理论64/实践32', zy: '教学' }
|
batchDeleteSyllabus,
|
||||||
]
|
updateSyllabus,
|
||||||
|
listSyllabus,
|
||||||
|
listSyllabusByZydhAndTy
|
||||||
|
} from '@/api/teachBusiness/syllabus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SyllabusIndex',
|
name: 'SyllabusIndex',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 查询表单 ====================
|
loading: false,
|
||||||
searchForm: {
|
searchForm: {
|
||||||
zymc: '',
|
zydh: '',
|
||||||
zydm: '',
|
ty: ''
|
||||||
zyfx: '',
|
|
||||||
xnz: '',
|
|
||||||
pxlx: '军官基础教育', pxlxEnabled: false,
|
|
||||||
pxlx2: '其他',
|
|
||||||
pxcc: '无', pxccEnabled: false,
|
|
||||||
ty: false,
|
|
||||||
zdyfl: '',
|
|
||||||
dgbb: '',
|
|
||||||
gljg: '教务处', gljgEnabled: false
|
|
||||||
},
|
},
|
||||||
|
tableData: [],
|
||||||
// ==================== 下拉选项(字典数据,接口就绪后可由后端字典加载) ====================
|
total: 0,
|
||||||
pxlxOptions: ['军官基础教育', '士兵职业教育', '研究生教育', '其他'],
|
pageNum: 1,
|
||||||
pxlx2Options: ['军官基础教育', '其他', '任职培训', '研究生教育'],
|
pageSize: 20,
|
||||||
pxccOptions: ['无', '本科', '硕士', '博士'],
|
selection: [],
|
||||||
gljgOptions: ['教务处', '教研室1', '教研室2', '学员队'],
|
dialog: {
|
||||||
|
visible: false,
|
||||||
// ==================== 表格数据 ====================
|
title: '',
|
||||||
tableData: []
|
submitting: false,
|
||||||
|
form: this.createEmptyForm()
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
zydh: [{ required: true, message: '请输入专业代号', trigger: 'blur' }],
|
||||||
|
kbh: [{ required: true, message: '请输入课编号', trigger: 'blur' }],
|
||||||
|
xqdc: [{ required: true, message: '请输入学期第次', trigger: 'blur' }],
|
||||||
|
klx: [{ required: true, message: '请输入课类型', trigger: 'blur' }],
|
||||||
|
xs: [{ required: true, message: '请输入学时', trigger: 'blur' }],
|
||||||
|
ty: [{ required: true, message: '请选择停用标识', trigger: 'change' }]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
computed: {
|
||||||
|
pagedData() {
|
||||||
|
const start = (this.pageNum - 1) * this.pageSize
|
||||||
|
return this.tableData.slice(start, start + this.pageSize)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 列表加载 ====================
|
/* ---------- 列表加载 ---------- */
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 getSyllabusList
|
|
||||||
fetchList() {
|
fetchList() {
|
||||||
this.tableData = mockTableData.slice()
|
this.loading = true
|
||||||
|
const { zydh, ty } = this.searchForm
|
||||||
|
// 专业代号与停用标识同时给出时走后端 /listByZydhAndTy;否则查全部后本地过滤
|
||||||
|
const useApiQuery = zydh && ty !== '' && ty !== null && ty !== undefined
|
||||||
|
const req = useApiQuery
|
||||||
|
? listSyllabusByZydhAndTy(zydh, ty)
|
||||||
|
: listSyllabus()
|
||||||
|
req.then(response => {
|
||||||
|
let list = response.data || []
|
||||||
|
if (!useApiQuery) {
|
||||||
|
if (zydh) list = list.filter(i => i.zydh && i.zydh.indexOf(zydh) !== -1)
|
||||||
|
if (ty !== '' && ty !== null && ty !== undefined) {
|
||||||
|
list = list.filter(i => Number(i.ty) === Number(ty))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tableData = list
|
||||||
|
this.total = list.length
|
||||||
|
this.pageNum = 1
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询 ====================
|
|
||||||
// TODO: 后端接口未提供,查询为前端模拟;接口就绪后替换为后端查询
|
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
this.$message.success('查询教学大纲(前端模拟)')
|
},
|
||||||
|
handleReset() {
|
||||||
|
this.searchForm = { zydh: '', ty: '' }
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
handleSelectionChange(val) {
|
||||||
|
this.selection = val
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 下载 ====================
|
/* ---------- 新增 / 编辑 ---------- */
|
||||||
// TODO: 后端接口未提供,下载为前端模拟;接口就绪后替换为 downloadSyllabusList
|
handleAdd() {
|
||||||
|
this.dialog.title = '新增教学大纲'
|
||||||
|
this.dialog.form = this.createEmptyForm()
|
||||||
|
this.dialog.visible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.syllabusForm) this.$refs.syllabusForm.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
this.dialog.title = '编辑教学大纲'
|
||||||
|
this.dialog.form = Object.assign({}, this.createEmptyForm(), row)
|
||||||
|
this.dialog.visible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.syllabusForm) this.$refs.syllabusForm.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
submitDialog() {
|
||||||
|
this.$refs.syllabusForm.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
this.dialog.submitting = true
|
||||||
|
const payload = this.cleanPayload(this.dialog.form)
|
||||||
|
const isEdit = !!payload.bh
|
||||||
|
const req = isEdit ? updateSyllabus(payload) : addSyllabus(payload)
|
||||||
|
req.then(() => {
|
||||||
|
this.$message.success(isEdit ? '修改成功' : '新增成功')
|
||||||
|
this.dialog.visible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).finally(() => {
|
||||||
|
this.dialog.submitting = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 删除 / 批量删除 ---------- */
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm('删除后该条记录将置为「停用」,是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return deleteSyllabus(row.bh)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
handleBatchDelete() {
|
||||||
|
if (!this.selection.length) {
|
||||||
|
this.$message.warning('请先勾选要删除的记录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const bhList = this.selection.map(row => row.bh)
|
||||||
|
this.$confirm('确定删除所选 ' + bhList.length + ' 条记录吗?(将置为「停用」)', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return batchDeleteSyllabus(bhList)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('批量删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 下载(无后端接口) ---------- */
|
||||||
handleDownload() {
|
handleDownload() {
|
||||||
this.$message.success('下载教学大纲列表(前端模拟)')
|
this.$message.warning('后端暂未提供该接口')
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 分页 ---------- */
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.pageSize = size
|
||||||
|
this.pageNum = 1
|
||||||
|
},
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.pageNum = page
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 工具 ---------- */
|
||||||
|
createEmptyForm() {
|
||||||
|
return {
|
||||||
|
bh: '',
|
||||||
|
zydh: '',
|
||||||
|
kbh: '',
|
||||||
|
xqdc: 1,
|
||||||
|
klx: '',
|
||||||
|
xs: 0,
|
||||||
|
ty: 0,
|
||||||
|
jc: '',
|
||||||
|
xf: null,
|
||||||
|
kcdw: '',
|
||||||
|
ksks: 0,
|
||||||
|
mk: '',
|
||||||
|
cjfz: '',
|
||||||
|
bjrxypjf: 0,
|
||||||
|
llxs: 0,
|
||||||
|
sjxs: 0,
|
||||||
|
zks: 0,
|
||||||
|
ksksbxs: 0,
|
||||||
|
dgkc: 0,
|
||||||
|
jysdh: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 移除空值(''/null/undefined),保留 0 等有效值 */
|
||||||
|
cleanPayload(obj) {
|
||||||
|
const payload = {}
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
payload[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
fmtYesNo(val) {
|
||||||
|
return Number(val) === 1 ? '是' : '否'
|
||||||
|
},
|
||||||
|
fmtDateTime(val) {
|
||||||
|
return (val || '').substring(0, 16) || '-'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,23 +437,8 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item__label {
|
.search-actions {
|
||||||
text-align: left;
|
padding-top: 4px;
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-footer {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-top: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 12px;
|
|
||||||
|
|
||||||
.notice {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #f56c6c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,6 +456,19 @@ export default {
|
|||||||
color: #303133;
|
color: #303133;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 16px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-text-btn {
|
||||||
|
color: #f56c6c;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #f78989;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,282 +1,246 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container teaching-task-page">
|
<div class="app-container teaching-task-page">
|
||||||
<!-- 页面标题 -->
|
<!-- ==================== 页面标题 ==================== -->
|
||||||
<div class="page-title">{{ pageTitle }}</div>
|
<div class="page-title">教学任务列表</div>
|
||||||
|
|
||||||
<!-- 查询条件 -->
|
<!-- ==================== 1. 查询条件区域 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form :model="searchForm" label-width="110px" class="search-form">
|
<el-form :model="searchForm" label-width="80px" class="search-form">
|
||||||
<el-row :gutter="32">
|
<el-row :gutter="24">
|
||||||
<!-- 左栏 -->
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-col :xs="24" :md="12">
|
<el-form-item label="任务名称">
|
||||||
<el-form-item label="授课教员">
|
<el-input
|
||||||
<el-input v-model="searchForm.skjy" placeholder="请输入授课教员" clearable />
|
v-model="searchForm.rwmc"
|
||||||
|
placeholder="请输入任务名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="可选班次年级">
|
</el-col>
|
||||||
<el-input v-model="searchForm.kxbcnj" placeholder="请输入可选班次年级" clearable />
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
</el-form-item>
|
<el-form-item label="年度">
|
||||||
<el-form-item>
|
<el-select
|
||||||
<template slot="label">
|
v-model="searchForm.nd"
|
||||||
<el-checkbox v-model="searchForm.fzkztEnabled">分组课状态</el-checkbox>
|
placeholder="请选择年度"
|
||||||
</template>
|
clearable
|
||||||
<el-select v-model="searchForm.fzkzt" placeholder="请选择分组课状态" class="w-full"
|
style="width: 100%"
|
||||||
:disabled="!searchForm.fzkztEnabled">
|
>
|
||||||
<el-option v-for="item in groupStatusOptions" :key="item" :label="item" :value="item" />
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<!-- 右栏 -->
|
<el-form-item label="状态">
|
||||||
<el-col :xs="24" :md="12">
|
<el-select
|
||||||
<el-form-item label="课程科目名称">
|
v-model="searchForm.zt"
|
||||||
<el-input v-model="searchForm.kckmmc" placeholder="请输入课程科目名称" clearable />
|
placeholder="请选择状态"
|
||||||
</el-form-item>
|
clearable
|
||||||
<el-form-item label="分组班名称">
|
style="width: 100%"
|
||||||
<el-input v-model="searchForm.fzbmc" placeholder="请输入分组班名称" clearable />
|
>
|
||||||
</el-form-item>
|
<el-option
|
||||||
<el-form-item>
|
v-for="opt in statusOptions"
|
||||||
<template slot="label">
|
:key="opt.value"
|
||||||
<el-checkbox v-model="searchForm.pxccEnabled">培训层次</el-checkbox>
|
:label="opt.label"
|
||||||
</template>
|
:value="opt.value"
|
||||||
<el-select v-model="searchForm.pxcc" placeholder="请选择培训层次" class="w-full"
|
/>
|
||||||
:disabled="!searchForm.pxccEnabled">
|
|
||||||
<el-option v-for="item in trainLevelOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<div class="search-tip">
|
|
||||||
注意:勾选"选择框"表示启用该项对应的查询条件;文本输入框非空白表示启用对应的查询条件。
|
|
||||||
</div>
|
|
||||||
<div class="search-actions">
|
<div class="search-actions">
|
||||||
<el-button class="gray-btn" @click="handleSearch">查询</el-button>
|
<el-button class="gray-btn" @click="handleQuery">查询</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 下载按钮 -->
|
<!-- ==================== 2. 数据表格 ==================== -->
|
||||||
<div class="toolbar-right">
|
|
||||||
<el-button type="primary" @click="handleDownloadGroupCourseList">下载分组班列表</el-button>
|
|
||||||
<el-button type="primary" @click="handleDownloadWord">下载分组班学员名单Word</el-button>
|
|
||||||
<el-button type="primary" @click="handleDownloadExcel">下载分组班学员名单Excel</el-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 批量操作 -->
|
|
||||||
<el-card shadow="never" class="action-card">
|
|
||||||
<div class="action-groups">
|
|
||||||
<div class="action-group">
|
|
||||||
<el-button type="primary" plain @click="handleNewGroupCourse">新建分组课</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleBatchOpen">所选班早开放报名</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleBatchCancelOpen">所选班早取消开放报名</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="action-group">
|
|
||||||
<el-button type="primary" plain @click="handleBatchStop">批量停止报名</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleBatchReverseRange">所选班早根据学员反向确定班次范围</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 导入数据 -->
|
|
||||||
<el-card shadow="never" class="import-card">
|
|
||||||
<div class="import-toolbar">
|
|
||||||
<el-button type="primary" @click="handleDownloadTemplate">【分组课数据文件模板】下载</el-button>
|
|
||||||
<div class="file-input">
|
|
||||||
<input ref="fileInput" type="file" accept=".xls,.xlsx" style="display: none" @change="handleFileChange" />
|
|
||||||
<el-button type="primary" plain @click="handleChooseFile">选择文件</el-button>
|
|
||||||
<span class="file-name">{{ fileName }}</span>
|
|
||||||
</div>
|
|
||||||
<el-button type="primary" plain @click="handleUploadData">上传数据</el-button>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row
|
<el-table v-loading="loading" :data="tableData" border stripe>
|
||||||
@selection-change="handleSelectionChange">
|
|
||||||
<template slot="empty">
|
<template slot="empty">
|
||||||
<span>无数据!</span>
|
<span>无数据!</span>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
<el-table-column type="index" label="序号" width="100" align="center" />
|
<el-table-column prop="bh" label="编号" width="200" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="kc" label="课程" width="100" show-overflow-tooltip />
|
<el-table-column prop="rwmc" label="任务名称" min-width="160" align="left" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="jc" label="教材" width="100" show-overflow-tooltip />
|
<el-table-column prop="nd" label="年度" width="90" align="center" />
|
||||||
<el-table-column prop="ssjy" label="实施教员" width="150" align="center" />
|
<el-table-column label="状态" width="100" align="center">
|
||||||
<el-table-column prop="jxcd" label="教学场地" width="150" align="center" />
|
|
||||||
<el-table-column align="center">
|
|
||||||
<template slot="header">
|
|
||||||
<el-checkbox v-model="showOptionalClasses">显示可选队别班次</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="计划学时/运行学时/学分" width="130" align="center">
|
|
||||||
<template slot="header">
|
|
||||||
<div class="triple-header">
|
|
||||||
<span>计划学时</span>
|
|
||||||
<span>运行学时</span>
|
|
||||||
<span>学分</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
<div class="triple-cell">
|
<el-tag :type="row.zt === '发布' ? 'success' : 'info'" size="small">
|
||||||
<span>{{ row.jhxs }}</span>
|
{{ row.zt || '-' }}
|
||||||
<span>{{ row.zxs }}</span>
|
</el-tag>
|
||||||
<span>{{ row.xf }}</span>
|
</template>
|
||||||
</div>
|
</el-table-column>
|
||||||
|
<el-table-column prop="fbsj" label="发布时间" width="150" align="center" :formatter="fmtDateTime" />
|
||||||
|
<el-table-column prop="jssj" label="结束时间" width="150" align="center" :formatter="fmtDateTime" />
|
||||||
|
<el-table-column prop="cjsj" label="创建时间" width="150" align="center" :formatter="fmtDateTime" />
|
||||||
|
<el-table-column prop="jcxqscsj" label="教材需求生成时间" width="170" align="center" :formatter="fmtDateTime" />
|
||||||
|
<el-table-column label="操作" width="80" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" @click="handleDetail(row)">详情</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="kkjkrq" label="开课结课日期" width="110" align="center" :formatter="formatDate" />
|
|
||||||
<el-table-column prop="bmrq" label="报名日期" width="120" align="center" :formatter="formatDate" />
|
|
||||||
<el-table-column prop="jhrs" label="计划人数" width="90" align="center" />
|
|
||||||
<el-table-column prop="yqsm" label="要求说明" width="150" show-overflow-tooltip />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- ==================== 3. 详情对话框 ==================== -->
|
||||||
|
<el-dialog
|
||||||
|
:visible="detailVisible"
|
||||||
|
title="教学任务详情"
|
||||||
|
width="620px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => detailVisible = val"
|
||||||
|
>
|
||||||
|
<el-descriptions v-if="detailData.bh" :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailData.bh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="任务名称">{{ detailData.rwmc || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="年度">{{ fmtVal(detailData.nd) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">{{ detailData.zt || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发布时间">{{ fmtVal(detailData.fbsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="结束时间">{{ fmtVal(detailData.jssj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ fmtVal(detailData.cjsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教材需求生成时间">{{ fmtVal(detailData.jcxqscsj) }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div v-else v-loading="detailLoading" class="detail-empty">加载中...</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button type="primary" @click="detailVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 教学任务列表(只读查询页)
|
||||||
|
* 对应菜单:teachBusiness/teachingTask(原「分组课列表」页,下载类功能后端无接口已移除)
|
||||||
|
* 仅提供 分页查询 list + 详情 get?bh=,不做增删改发(避免与教学任务计划管理页重复操作同一实体)
|
||||||
|
* 增删改发统一在 src/views/teachOffice/taskPlan/index.vue(教学任务计划管理)完成
|
||||||
|
*/
|
||||||
|
import { listTeachingTask, getTeachingTask } from '@/api/teachBusiness/teachingTask'
|
||||||
|
import { listAllSemester } from '@/api/teachBusiness/semester'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TeachingTask',
|
name: 'TeachingTask',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pageTitle: '分组课列表',
|
// ==================== 1. 查询条件 ====================
|
||||||
|
|
||||||
// ==================== 查询表单 ====================
|
|
||||||
searchForm: {
|
searchForm: {
|
||||||
skjy: '',
|
rwmc: '',
|
||||||
kckmmc: '',
|
nd: undefined,
|
||||||
kxbcnj: '',
|
zt: ''
|
||||||
fzbmc: '',
|
|
||||||
fzkzt: '拟制',
|
|
||||||
fzkztEnabled: false,
|
|
||||||
pxcc: '无',
|
|
||||||
pxccEnabled: false
|
|
||||||
},
|
},
|
||||||
groupStatusOptions: ['拟制', '已发布', '已结课'],
|
yearOptions: [],
|
||||||
trainLevelOptions: ['无', '初级', '中级', '高级'],
|
statusOptions: [
|
||||||
|
{ label: '未发布', value: '未发布' },
|
||||||
// ==================== 批量操作 ====================
|
{ label: '发布', value: '发布' }
|
||||||
selectedRows: [],
|
|
||||||
|
|
||||||
// ==================== 表格数据 ====================
|
|
||||||
loading: false,
|
|
||||||
showOptionalClasses: false,
|
|
||||||
/** 模拟列表数据(后端接口未提供) */
|
|
||||||
tableData: [
|
|
||||||
{ xh: 1, kc: '高等数学', jc: '高等数学(上册)', ssjy: '张三', jxcd: '1-301', jhxs: 48, zxs: 46, xf: 3, kkjkrq: '2017-09-03', bmrq: '2017-08-20', jhrs: 40, yqsm: '按教学计划执行' },
|
|
||||||
{ xh: 2, kc: '军事英语', jc: '军事英语教程', ssjy: '李四', jxcd: '2-101', jhxs: 32, zxs: 30, xf: 2, kkjkrq: '2017-09-03', bmrq: '2017-08-22', jhrs: 36, yqsm: '含听力训练' },
|
|
||||||
{ xh: 3, kc: '导弹发射原理', jc: '导弹发射原理', ssjy: '王五', jxcd: '3-205', jhxs: 40, zxs: 40, xf: 2.5, kkjkrq: '2017-09-10', bmrq: '2017-08-25', jhrs: 42, yqsm: '实验课随堂进行' },
|
|
||||||
{ xh: 4, kc: '通信原理', jc: '通信原理', ssjy: '赵六', jxcd: '5-102', jhxs: 48, zxs: 44, xf: 3, kkjkrq: '2017-09-03', bmrq: '2017-08-28', jhrs: 38, yqsm: '' },
|
|
||||||
{ xh: 5, kc: '联合作战指挥', jc: '联合作战指挥', ssjy: '孙七', jxcd: '学术报告厅', jhxs: 40, zxs: 40, xf: 2.5, kkjkrq: '2017-09-17', bmrq: '2017-09-01', jhrs: 45, yqsm: '理论授课+想定作业' }
|
|
||||||
],
|
],
|
||||||
|
|
||||||
// ==================== 导入 ====================
|
// ==================== 2. 表格数据 ====================
|
||||||
selectedFile: null
|
loading: false,
|
||||||
|
tableData: [],
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
|
||||||
|
// ==================== 3. 详情 ====================
|
||||||
|
detailVisible: false,
|
||||||
|
detailLoading: false,
|
||||||
|
detailData: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
created() {
|
||||||
fileName() {
|
this.loadYearOptions().then(() => this.fetchList())
|
||||||
return (this.selectedFile && this.selectedFile.name) || '未选择任何文件'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.fetchList()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 表格日期格式化 */
|
/* ---------- 年度下拉(数据来自 /semester/all,禁止硬编码) ---------- */
|
||||||
formatDate(row, column, cellValue) {
|
loadYearOptions() {
|
||||||
return cellValue ? String(cellValue).substring(0, 10) : ''
|
return listAllSemester().then(response => {
|
||||||
|
const list = response.data || []
|
||||||
|
const map = {}
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.nd !== null && item.nd !== undefined && item.nd !== '') map[item.nd] = item
|
||||||
|
})
|
||||||
|
const arr = Object.keys(map).sort((a, b) => String(b).localeCompare(String(a)))
|
||||||
|
this.yearOptions = arr
|
||||||
|
// 默认年度:优先当前学期(dqxq=true),否则取最新年度
|
||||||
|
const current = list.find(item => item.dqxq === true)
|
||||||
|
const defaultNd = (current && current.nd) || arr[0]
|
||||||
|
if (!this.searchForm.nd) this.searchForm.nd = defaultNd
|
||||||
|
return arr
|
||||||
|
}).catch(() => {
|
||||||
|
this.yearOptions = []
|
||||||
|
return []
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 列表加载 ====================
|
/* ---------- 通用格式化 ---------- */
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为真实查询接口
|
fmtDateTime(row, column, cellValue) {
|
||||||
|
if (cellValue === null || cellValue === undefined || cellValue === '') return '-'
|
||||||
|
return String(cellValue).replace('T', ' ').slice(0, 16)
|
||||||
|
},
|
||||||
|
fmtVal(val) {
|
||||||
|
if (val === null || val === undefined || val === '') return '-'
|
||||||
|
return String(val).replace('T', ' ').slice(0, 16)
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 列表加载 ---------- */
|
||||||
fetchList() {
|
fetchList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
setTimeout(() => {
|
const params = { pageNum: this.pageNum, pageSize: this.pageSize }
|
||||||
|
if (this.searchForm.rwmc && this.searchForm.rwmc.trim()) params.rwmc = this.searchForm.rwmc.trim()
|
||||||
|
if (this.searchForm.nd !== undefined && this.searchForm.nd !== null && this.searchForm.nd !== '') {
|
||||||
|
params.nd = this.searchForm.nd
|
||||||
|
}
|
||||||
|
if (this.searchForm.zt && this.searchForm.zt.trim()) params.zt = this.searchForm.zt.trim()
|
||||||
|
listTeachingTask(params).then(res => {
|
||||||
|
const data = (res && res.data) || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}, 200)
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询 ====================
|
handleQuery() {
|
||||||
handleSearch() {
|
this.pageNum = 1
|
||||||
this.$message.success('查询分组课列表(前端模拟)')
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 批量操作 ====================
|
handlePageChange(page) {
|
||||||
handleSelectionChange(rows) {
|
this.pageNum = page
|
||||||
this.selectedRows = rows
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handleNewGroupCourse() {
|
handleSizeChange(size) {
|
||||||
this.$message.success('新建分组课(前端模拟)')
|
this.pageSize = size
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
},
|
},
|
||||||
|
|
||||||
handleBatchOpen() {
|
/* ---------- 详情(只读,走真实 get?bh= 接口) ---------- */
|
||||||
if (this.selectedRows.length === 0) {
|
handleDetail(row) {
|
||||||
this.$message.warning('请先选择数据')
|
this.detailVisible = true
|
||||||
return
|
this.detailLoading = true
|
||||||
}
|
this.detailData = {}
|
||||||
this.$message.success('所选批量开放报名(前端模拟)')
|
getTeachingTask(row.bh).then(res => {
|
||||||
},
|
this.detailData = (res && res.data) || {}
|
||||||
|
this.detailLoading = false
|
||||||
handleBatchCancelOpen() {
|
}).catch(() => {
|
||||||
if (this.selectedRows.length === 0) {
|
this.detailLoading = false
|
||||||
this.$message.warning('请先选择数据')
|
})
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$message.success('所选批量取消开放报名(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
handleBatchStop() {
|
|
||||||
if (this.selectedRows.length === 0) {
|
|
||||||
this.$message.warning('请先选择数据')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$message.success('批量停止报名(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
handleBatchReverseRange() {
|
|
||||||
if (this.selectedRows.length === 0) {
|
|
||||||
this.$message.warning('请先选择数据')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$message.success('所选批量根据学员反向确定班次范围(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 下载按钮 ====================
|
|
||||||
handleDownloadGroupCourseList() {
|
|
||||||
this.$message.success('下载分组课列表(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
handleDownloadWord() {
|
|
||||||
this.$message.success('下载分组学员名单Word(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
handleDownloadExcel() {
|
|
||||||
this.$message.success('下载分组学员名单Excel(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 导入 ====================
|
|
||||||
handleChooseFile() {
|
|
||||||
this.$refs.fileInput && this.$refs.fileInput.click()
|
|
||||||
},
|
|
||||||
|
|
||||||
handleFileChange(e) {
|
|
||||||
const input = e.target
|
|
||||||
if (input.files && input.files.length > 0) {
|
|
||||||
this.selectedFile = input.files[0]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleDownloadTemplate() {
|
|
||||||
this.$message.success('下载分组课数据文件模板(前端模拟)')
|
|
||||||
},
|
|
||||||
|
|
||||||
handleUploadData() {
|
|
||||||
if (!this.selectedFile) {
|
|
||||||
this.$message.warning('请先选择文件')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$message.success('上传数据(前端模拟)')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,99 +251,45 @@ export default {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-title {
|
.teaching-task-page {
|
||||||
text-align: center;
|
.page-title {
|
||||||
font-size: 20px;
|
text-align: center;
|
||||||
font-weight: 600;
|
font-size: 20px;
|
||||||
color: #303133;
|
font-weight: 600;
|
||||||
margin-bottom: 20px;
|
color: #303133;
|
||||||
}
|
margin-bottom: 20px;
|
||||||
|
|
||||||
.search-card {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
.search-form {
|
|
||||||
.w-full {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-tip {
|
// ==================== 1. 查询条件区域 ====================
|
||||||
font-size: 12px;
|
.search-card {
|
||||||
color: #f56c6c;
|
margin-bottom: 16px;
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-actions {
|
.search-form {
|
||||||
display: flex;
|
.search-actions {
|
||||||
justify-content: flex-end;
|
display: flex;
|
||||||
padding-top: 12px;
|
justify-content: flex-end;
|
||||||
border-top: 1px solid #ebeef5;
|
padding-top: 12px;
|
||||||
}
|
border-top: 1px solid #ebeef5;
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-right {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-card {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
.action-groups {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
gap: 12px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.action-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 12px;
|
|
||||||
|
|
||||||
.el-button {
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.import-card {
|
// ==================== 2. 数据表格 ====================
|
||||||
margin-bottom: 16px;
|
.table-card {
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.import-toolbar {
|
// ==================== 3. 详情 ====================
|
||||||
|
.detail-empty {
|
||||||
|
min-height: 120px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
justify-content: center;
|
||||||
flex-wrap: wrap;
|
color: #909399;
|
||||||
|
|
||||||
.file-input {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
.file-name {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #606266;
|
|
||||||
min-width: 120px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-card {
|
|
||||||
::v-deep(.el-table) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.triple-header,
|
|
||||||
.triple-cell {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,58 +11,28 @@
|
|||||||
<el-link type="primary" :underline="false" class="nav-link" @click="handleNextDay">后一天</el-link>
|
<el-link type="primary" :underline="false" class="nav-link" @click="handleNextDay">后一天</el-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 批量操作栏 -->
|
|
||||||
<div class="toolbar-card">
|
|
||||||
<div class="toolbar">
|
|
||||||
<div class="toolbar-left">
|
|
||||||
<el-button type="primary" size="mini" :disabled="!todaySelected.length" @click="handleComing">批量设置备注信息</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!todaySelected.length" @click="handleComing">批量变更时间</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!todaySelected.length" @click="handleComing">批量平移时间</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!todaySelected.length" @click="handleComing">批量变更授课教员</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!todaySelected.length" @click="handleComing">批量变更授课场地</el-button>
|
|
||||||
<el-button type="danger" size="mini" :disabled="!todaySelected.length" @click="handleComing">批量删除</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="toolbar-right">
|
|
||||||
<el-button type="primary" size="mini" @click="handleComing">自定义格式下载</el-button>
|
|
||||||
<el-button type="primary" size="mini" @click="handleComing">下载</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 今日表格 -->
|
<!-- 今日表格 -->
|
||||||
<div class="table-card">
|
<div class="table-card">
|
||||||
<el-table :data="todayList" v-loading="loading" stripe border @selection-change="todaySelected = $event">
|
<el-table :data="todayList" v-loading="todayLoading" stripe border>
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column label="上课时间" width="130" align="center">
|
<el-table-column label="上课时间" width="200" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">{{ formatTime(scope.row.jc) }}</template>
|
<template slot-scope="scope">{{ fmtLessonTime(scope.row) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="kcmc" label="课程" min-width="140" show-overflow-tooltip />
|
<el-table-column prop="kcmc" label="课程" min-width="150" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="zrdw" label="责任单位" width="110" align="center" />
|
<el-table-column prop="kcxh" label="课次序号" width="90" align="center" />
|
||||||
<el-table-column prop="bc" label="班次" width="120" show-overflow-tooltip />
|
<el-table-column label="教学内容" min-width="180" show-overflow-tooltip header-align="center">
|
||||||
<el-table-column prop="skjy" label="教员" width="90" align="center" />
|
<template slot-scope="scope">{{ scope.row.jxnr || '-' }}</template>
|
||||||
<el-table-column label="场地" width="140" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">{{ scope.row.jxcd || '-' }}</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="教学内容方法" min-width="160" show-overflow-tooltip>
|
<el-table-column label="教学方法" width="130" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">{{ scope.row._jxnrff || '-' }}</template>
|
<template slot-scope="scope">{{ scope.row.jxff || '-' }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="jybz" label="备注" width="100" show-overflow-tooltip>
|
<el-table-column label="填写状态" width="100" align="center">
|
||||||
<template slot-scope="scope">{{ scope.row.jybz || '-' }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="计划变更明细" width="120" align="center">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="mini" @click="openDetail(scope.row)">变更明细</el-button>
|
<el-tag :type="txztType(scope.row.txzt)" size="mini">{{ txztText(scope.row.txzt) }}</el-tag>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="180" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button type="text" size="mini" @click="openRemark(scope.row)">编辑备注</el-button>
|
|
||||||
<el-button type="text" size="mini" class="danger-text" @click="handleComing">删除</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-show="!loading && !todayList.length" description="当日暂无教学计划数据" />
|
<el-empty v-show="!todayLoading && !todayList.length" description="当日暂无教学计划数据" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -77,58 +47,28 @@
|
|||||||
<el-link type="primary" :underline="false" class="nav-link" @click="handleNextWeek">下一周</el-link>
|
<el-link type="primary" :underline="false" class="nav-link" @click="handleNextWeek">下一周</el-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 批量操作栏 -->
|
|
||||||
<div class="toolbar-card">
|
|
||||||
<div class="toolbar">
|
|
||||||
<div class="toolbar-left">
|
|
||||||
<el-button type="primary" size="mini" :disabled="!weekSelected.length" @click="handleComing">批量设置备注信息</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!weekSelected.length" @click="handleComing">批量变更时间</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!weekSelected.length" @click="handleComing">批量平移时间</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!weekSelected.length" @click="handleComing">批量变更授课教员</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!weekSelected.length" @click="handleComing">批量变更授课场地</el-button>
|
|
||||||
<el-button type="danger" size="mini" :disabled="!weekSelected.length" @click="handleComing">批量删除</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="toolbar-right">
|
|
||||||
<el-button type="primary" size="mini" @click="handleComing">报批下载</el-button>
|
|
||||||
<el-button type="primary" size="mini" @click="handleComing">下载</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 本周表格 -->
|
<!-- 本周表格 -->
|
||||||
<div class="table-card">
|
<div class="table-card">
|
||||||
<el-table :data="weekList" v-loading="loading" stripe border @selection-change="weekSelected = $event">
|
<el-table :data="weekList" v-loading="weekLoading" stripe border>
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column label="上课时间" width="170" align="center" show-overflow-tooltip>
|
<el-table-column label="上课时间" width="200" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">{{ scope.row._sjsj || '-' }}</template>
|
<template slot-scope="scope">{{ fmtLessonTime(scope.row) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="kcmc" label="课程" min-width="130" show-overflow-tooltip />
|
<el-table-column prop="kcmc" label="课程" min-width="150" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="zrdw" label="责任单位" width="100" align="center" />
|
<el-table-column prop="kcxh" label="课次序号" width="90" align="center" />
|
||||||
<el-table-column prop="bc" label="班次" width="130" show-overflow-tooltip />
|
<el-table-column label="教学内容" min-width="180" show-overflow-tooltip header-align="center">
|
||||||
<el-table-column prop="skjy" label="教员" width="90" align="center" />
|
<template slot-scope="scope">{{ scope.row.jxnr || '-' }}</template>
|
||||||
<el-table-column label="场地" width="140" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">{{ scope.row.jxcd || '-' }}</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="教学内容方法" min-width="150" show-overflow-tooltip>
|
<el-table-column label="教学方法" width="130" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">{{ scope.row._jxnrff || '-' }}</template>
|
<template slot-scope="scope">{{ scope.row.jxff || '-' }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="jybz" label="备注" width="100" show-overflow-tooltip>
|
<el-table-column label="填写状态" width="100" align="center">
|
||||||
<template slot-scope="scope">{{ scope.row.jybz || '-' }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="计划变更明细" width="120" align="center">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="mini" @click="openDetail(scope.row)">计划变更明细</el-button>
|
<el-tag :type="txztType(scope.row.txzt)" size="mini">{{ txztText(scope.row.txzt) }}</el-tag>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="180" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button type="text" size="mini" @click="openRemark(scope.row)">编辑备注</el-button>
|
|
||||||
<el-button type="text" size="mini" class="danger-text" @click="handleComing">删除</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-show="!loading && !weekList.length" description="本周暂无教学计划数据" />
|
<el-empty v-show="!weekLoading && !weekList.length" description="本周暂无教学计划数据" />
|
||||||
<pagination
|
<pagination
|
||||||
v-show="weekTotal > 0"
|
v-show="weekTotal > 0"
|
||||||
:total="weekTotal"
|
:total="weekTotal"
|
||||||
@@ -150,58 +90,36 @@
|
|||||||
<el-link type="primary" :underline="false" class="nav-link" @click="handleNextWeek3">下一周</el-link>
|
<el-link type="primary" :underline="false" class="nav-link" @click="handleNextWeek3">下一周</el-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 批量操作栏 -->
|
<el-alert
|
||||||
<div class="toolbar-card">
|
class="mb8"
|
||||||
<div class="toolbar">
|
type="info"
|
||||||
<div class="toolbar-left">
|
:closable="false"
|
||||||
<el-button type="primary" size="mini" :disabled="!practiceSelected.length" @click="handleComing">批量设置备注信息</el-button>
|
show-icon
|
||||||
<el-button type="primary" size="mini" :disabled="!practiceSelected.length" @click="handleComing">批量变更时间</el-button>
|
title="说明:后端教学实施计划课次接口未返回课程类型字段,无法按三实课类型筛选,当前展示本周全部教学实施计划课次。"
|
||||||
<el-button type="primary" size="mini" :disabled="!practiceSelected.length" @click="handleComing">批量平移时间</el-button>
|
/>
|
||||||
<el-button type="primary" size="mini" :disabled="!practiceSelected.length" @click="handleComing">批量变更授课教员</el-button>
|
|
||||||
<el-button type="primary" size="mini" :disabled="!practiceSelected.length" @click="handleComing">批量变更授课场地</el-button>
|
|
||||||
<el-button type="danger" size="mini" :disabled="!practiceSelected.length" @click="handleComing">批量删除</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="toolbar-right">
|
|
||||||
<el-button type="primary" size="mini" @click="handleComing">报批下载</el-button>
|
|
||||||
<el-button type="primary" size="mini" @click="handleComing">下载</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 三实表格 -->
|
<!-- 三实表格 -->
|
||||||
<div class="table-card">
|
<div class="table-card">
|
||||||
<el-table :data="practiceList" v-loading="loading" stripe border @selection-change="practiceSelected = $event">
|
<el-table :data="practiceList" v-loading="practiceLoading" stripe border>
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column label="上课时间" width="170" align="center" show-overflow-tooltip>
|
<el-table-column label="上课时间" width="200" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">{{ scope.row._sjsj || '-' }}</template>
|
<template slot-scope="scope">{{ fmtLessonTime(scope.row) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="kcmc" label="课程" min-width="130" show-overflow-tooltip />
|
<el-table-column prop="kcmc" label="课程" min-width="150" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="zrdw" label="责任单位" width="100" align="center" />
|
<el-table-column prop="kcxh" label="课次序号" width="90" align="center" />
|
||||||
<el-table-column prop="bc" label="班次" width="130" show-overflow-tooltip />
|
<el-table-column label="教学内容" min-width="180" show-overflow-tooltip header-align="center">
|
||||||
<el-table-column prop="skjy" label="教员" width="90" align="center" />
|
<template slot-scope="scope">{{ scope.row.jxnr || '-' }}</template>
|
||||||
<el-table-column label="场地" width="140" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">{{ scope.row.jxcd || '-' }}</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="教学内容方法" min-width="150" show-overflow-tooltip>
|
<el-table-column label="教学方法" width="130" align="center" show-overflow-tooltip>
|
||||||
<template slot-scope="scope">{{ scope.row._jxnrff || '-' }}</template>
|
<template slot-scope="scope">{{ scope.row.jxff || '-' }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="jybz" label="备注" width="100" show-overflow-tooltip>
|
<el-table-column label="填写状态" width="100" align="center">
|
||||||
<template slot-scope="scope">{{ scope.row.jybz || '-' }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="计划变更明细" width="120" align="center">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="mini" @click="openDetail(scope.row)">计划变更明细</el-button>
|
<el-tag :type="txztType(scope.row.txzt)" size="mini">{{ txztText(scope.row.txzt) }}</el-tag>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="180" align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button type="text" size="mini" @click="openRemark(scope.row)">编辑备注</el-button>
|
|
||||||
<el-button type="text" size="mini" class="danger-text" @click="handleComing">删除</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-show="!loading && !practiceList.length" description="本周暂无三实教学计划数据" />
|
<el-empty v-show="!practiceLoading && !practiceList.length" description="本周暂无三实教学计划数据" />
|
||||||
<pagination
|
<pagination
|
||||||
v-show="practiceTotal > 0"
|
v-show="practiceTotal > 0"
|
||||||
:total="practiceTotal"
|
:total="practiceTotal"
|
||||||
@@ -219,122 +137,115 @@
|
|||||||
<!-- 查询条件 -->
|
<!-- 查询条件 -->
|
||||||
<el-form :inline="true" class="shift-search">
|
<el-form :inline="true" class="shift-search">
|
||||||
<el-form-item label="队别班次">
|
<el-form-item label="队别班次">
|
||||||
<el-select v-model="shiftTeamClass" placeholder="请选择队别班次" clearable class="shift-select">
|
<el-select
|
||||||
<el-option label="一班" value="一班" />
|
v-model="shiftXydbh"
|
||||||
<el-option label="二班" value="二班" />
|
placeholder="请选择队别班次"
|
||||||
<el-option label="三班" value="三班" />
|
clearable
|
||||||
<el-option label="四班" value="四班" />
|
filterable
|
||||||
|
class="shift-select"
|
||||||
|
>
|
||||||
|
<el-option v-for="t in teamOptions" :key="t.xydbh" :label="t.xydmc" :value="t.xydbh" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="年度">
|
||||||
|
<el-select v-model="shiftNd" placeholder="请选择年度" class="shift-select">
|
||||||
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleComing">查询</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleShiftSearch">查询</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<div class="shift-title">2026年秋季学期{{ shiftTeamClass || '' }}课程表</div>
|
<div class="shift-title">{{ shiftTitle }}</div>
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期教学实施计划</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期教学实施计划</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期课程表(周次星期)</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期课程表(周次星期)</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期课程表(班次视图)</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期课程表(班次视图)</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期课程表(排课周)含选修</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期课程表(排课周)含选修</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期教学实施计划(含选修)</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期教学实施计划(含选修)</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期课程表(周次星期)详细</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期课程表(周次星期)详细</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleComing">学期成绩表</el-button>
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleNotProvided">学期成绩表</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="success" plain icon="el-icon-download" size="mini" @click="handleComing">课程列表另存Excel</el-button>
|
<el-button type="success" plain icon="el-icon-download" size="mini" @click="handleNotProvided">课程列表另存Excel</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 班次课程表 -->
|
<!-- 班次课程表 -->
|
||||||
<el-table v-loading="loading" :data="shiftList" border stripe>
|
<div class="table-card">
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table v-loading="shiftLoading" :data="shiftList" border stripe>
|
||||||
<el-table-column label="课程名称/课时系数" min-width="220">
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<template slot-scope="scope">
|
<el-table-column label="课程名称/简称" min-width="200" header-align="center">
|
||||||
<div>{{ scope.row.kcmc }}</div>
|
<template slot-scope="scope">
|
||||||
<div class="sub-text">{{ scope.row.kssk }}</div>
|
<div>{{ scope.row._kcmc || '-' }}</div>
|
||||||
</template>
|
<div class="sub-text">{{ scope.row.jc || '-' }}</div>
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column prop="zrjs" label="责任教员/课次" min-width="150" />
|
</el-table-column>
|
||||||
<el-table-column prop="bc" label="班次" min-width="120" />
|
<el-table-column label="责任教员/课次" width="160" header-align="center">
|
||||||
<el-table-column prop="nj" label="年级" width="80" align="center" />
|
<template slot-scope="scope">
|
||||||
<el-table-column prop="zy" label="专业" min-width="120" />
|
<div>{{ scope.row._zrjy || '-' }}</div>
|
||||||
<el-table-column prop="jhxs" label="计划学时" width="90" align="center" />
|
<div class="sub-text">第{{ scope.row.kcxh || '-' }}次课</div>
|
||||||
<el-table-column prop="yxxs" label="运行学时" width="90" align="center" />
|
</template>
|
||||||
<el-table-column prop="khlxfs" label="考核类型方式" min-width="140" />
|
</el-table-column>
|
||||||
<el-table-column prop="ssjs" label="实施教员" min-width="120" />
|
<el-table-column prop="xydmc" label="班次" width="130" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="rscd" label="人数/场地" min-width="140" />
|
<el-table-column prop="xs" label="计划学时" width="90" align="center" />
|
||||||
<el-table-column prop="kcjd" label="课程进度" width="120" align="center" />
|
<el-table-column prop="llxs" label="理论学时" width="90" align="center" />
|
||||||
<el-table-column prop="ssjhbg" label="实施计划变更" min-width="120" align="center" />
|
<el-table-column prop="sjxs" label="实践学时" width="90" align="center" />
|
||||||
</el-table>
|
<el-table-column prop="cjfz" label="考核类型方式" min-width="110" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column label="实施教员" width="110" align="center" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">{{ scope.row._ssjy || '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="人数/场地" width="130" header-align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.rs || '-' }} 人</div>
|
||||||
|
<div class="sub-text">{{ scope.row.jsbh || '-' }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="xf" label="学分" width="80" align="center" />
|
||||||
|
<el-table-column label="实施计划变更" width="150" header-align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtKbbdsj(scope.row.kbbdsj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-empty v-show="!shiftLoading && !shiftList.length" description="该班次暂无课程数据" />
|
||||||
|
<pagination
|
||||||
|
v-show="shiftTotal > 0"
|
||||||
|
:total="shiftTotal"
|
||||||
|
:page.sync="shiftQuery.pageNum"
|
||||||
|
:limit.sync="shiftQuery.pageSize"
|
||||||
|
@pagination="getShiftList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
<!-- 编辑备注弹窗 -->
|
|
||||||
<el-dialog title="编辑备注" :visible.sync="remarkVisible" width="500px" append-to-body>
|
|
||||||
<el-form label-width="80px">
|
|
||||||
<el-form-item label="课程">
|
|
||||||
<span>{{ remarkTarget.kcmc || '-' }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="备注内容">
|
|
||||||
<el-input v-model="remarkText" type="textarea" :rows="4" placeholder="请输入备注内容" maxlength="500" show-word-limit />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="confirmRemark">确定</el-button>
|
|
||||||
<el-button @click="remarkVisible = false">取消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 计划变更明细弹窗 -->
|
|
||||||
<el-dialog title="计划变更明细" :visible.sync="detailVisible" width="560px" append-to-body>
|
|
||||||
<el-descriptions :column="2" border size="small" v-if="detailTarget">
|
|
||||||
<el-descriptions-item label="课程">{{ detailTarget.kcmc }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="班次">{{ detailTarget.bc }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="责任单位">{{ detailTarget.zrdw }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="上课时间">{{ detailTarget._sjsj || formatTime(detailTarget.jc) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="原节次">{{ detailTarget.yjc || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="授课教员">{{ detailTarget.skjy }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="教学场地">{{ detailTarget.jxcd || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="检查结果">{{ detailTarget.jcjg || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="已通过检查" :span="2">
|
|
||||||
<el-tag :type="detailTarget.ytgjc ? 'success' : 'info'" size="mini">{{ detailTarget.ytgjc ? '是' : '否' }}</el-tag>
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 节次 -> 时间映射
|
import { listTeachingPlan } from '@/api/teachBusiness/courseRunning'
|
||||||
const JC_TIME = {
|
import { listStudentTeamTask } from '@/api/teachBusiness/studentTeamTask'
|
||||||
1: '08:00-08:45',
|
import { listTeam } from '@/api/studentRecords/team'
|
||||||
2: '08:55-09:40',
|
import { listSubject } from '@/api/teachOffice/subject'
|
||||||
3: '10:00-10:45',
|
import { listTeacher } from '@/api/teachOffice/teacher'
|
||||||
4: '10:55-11:40',
|
import { listAllSemester } from '@/api/teachBusiness/semester'
|
||||||
5: '14:30-15:15',
|
|
||||||
6: '15:25-16:10',
|
|
||||||
7: '16:20-17:05',
|
|
||||||
8: '19:00-19:45',
|
|
||||||
9: '19:55-20:40'
|
|
||||||
}
|
|
||||||
// 节次 -> 节次区间映射
|
// 节次 -> 节次区间映射
|
||||||
const JC_SECTION = {
|
const JC_SECTION = {
|
||||||
1: '1-2节', 2: '3-4节', 3: '5-6节', 4: '7-8节', 5: '9-10节', 6: '11-12节'
|
1: '1-2节', 2: '3-4节', 3: '5-6节', 4: '7-8节', 5: '9-10节', 6: '11-12节'
|
||||||
@@ -362,32 +273,36 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeTab: 'today',
|
activeTab: 'today',
|
||||||
loading: false,
|
|
||||||
// 今日
|
// 今日
|
||||||
todayDate: new Date(),
|
todayDate: new Date(),
|
||||||
todayList: [],
|
todayList: [],
|
||||||
todaySelected: [],
|
todayLoading: false,
|
||||||
// 本周
|
// 本周
|
||||||
weekStart: getMonday(new Date()),
|
weekStart: getMonday(new Date()),
|
||||||
weekList: [],
|
weekList: [],
|
||||||
weekSelected: [],
|
weekLoading: false,
|
||||||
weekTotal: 0,
|
weekTotal: 0,
|
||||||
weekQuery: { pageNum: 1, pageSize: 20 },
|
weekQuery: { pageNum: 1, pageSize: 20 },
|
||||||
// 三实
|
// 三实
|
||||||
practiceStart: getMonday(new Date()),
|
practiceStart: getMonday(new Date()),
|
||||||
practiceList: [],
|
practiceList: [],
|
||||||
practiceSelected: [],
|
practiceLoading: false,
|
||||||
practiceTotal: 0,
|
practiceTotal: 0,
|
||||||
practiceQuery: { pageNum: 1, pageSize: 20 },
|
practiceQuery: { pageNum: 1, pageSize: 20 },
|
||||||
// 班次(仅占位数据,待对接接口)
|
// 班次
|
||||||
shiftTeamClass: '',
|
teamOptions: [],
|
||||||
|
shiftXydbh: '',
|
||||||
|
shiftNd: undefined,
|
||||||
shiftList: [],
|
shiftList: [],
|
||||||
// 弹窗
|
shiftLoading: false,
|
||||||
remarkVisible: false,
|
shiftTotal: 0,
|
||||||
remarkTarget: {},
|
shiftQuery: { pageNum: 1, pageSize: 20 },
|
||||||
remarkText: '',
|
// 年度下拉数据来自 /semester/all(真实后端数据)
|
||||||
detailVisible: false,
|
yearOptions: [],
|
||||||
detailTarget: null
|
defaultNd: undefined,
|
||||||
|
// 名称映射(真实接口数据,用于班次 tab 课程/教员编号转名称)
|
||||||
|
kbMap: {},
|
||||||
|
teacherMap: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -405,32 +320,75 @@ export default {
|
|||||||
end.setDate(end.getDate() + 6)
|
end.setDate(end.getDate() + 6)
|
||||||
return formatDate(this.practiceStart) + '(' + this.weekDayName(this.practiceStart) + ') 至 ' +
|
return formatDate(this.practiceStart) + '(' + this.weekDayName(this.practiceStart) + ') 至 ' +
|
||||||
formatDate(end) + '(' + this.weekDayName(end) + ') 三实教学实施计划'
|
formatDate(end) + '(' + this.weekDayName(end) + ') 三实教学实施计划'
|
||||||
|
},
|
||||||
|
shiftTitle() {
|
||||||
|
const team = this.teamOptions.find(t => t.xydbh === this.shiftXydbh)
|
||||||
|
const name = (team && team.xydmc) || ''
|
||||||
|
return (this.shiftNd ? this.shiftNd + '年' : '') + name + '课程表'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.loadYearOptions()
|
||||||
this.getTodayList()
|
this.getTodayList()
|
||||||
this.getWeekList()
|
this.getWeekList()
|
||||||
this.getPracticeList()
|
this.getPracticeList()
|
||||||
|
this.loadTeamOptions()
|
||||||
|
this.loadKbMap()
|
||||||
|
this.loadTeacherMap()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/* ---------- 年度下拉(数据来自 /semester/all) ---------- */
|
||||||
|
loadYearOptions() {
|
||||||
|
return listAllSemester().then(response => {
|
||||||
|
const list = response.data || []
|
||||||
|
// 去重并按年度倒序
|
||||||
|
const map = {}
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.nd !== null && item.nd !== undefined && item.nd !== '') map[item.nd] = item
|
||||||
|
})
|
||||||
|
const arr = Object.keys(map).sort((a, b) => String(b).localeCompare(String(a)))
|
||||||
|
this.yearOptions = arr
|
||||||
|
// 默认年度:优先当前学期(dqxq=true),否则取最新年度
|
||||||
|
const current = list.find(item => item.dqxq === true)
|
||||||
|
this.defaultNd = (current && current.nd) || arr[0]
|
||||||
|
if (!this.shiftNd) this.shiftNd = this.defaultNd
|
||||||
|
return arr
|
||||||
|
}).catch(() => {
|
||||||
|
this.yearOptions = []
|
||||||
|
this.defaultNd = undefined
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
},
|
||||||
weekDayName(d) {
|
weekDayName(d) {
|
||||||
return WEEK_DAY_NAMES[d.getDay()]
|
return WEEK_DAY_NAMES[d.getDay()]
|
||||||
},
|
},
|
||||||
formatTime(jc) {
|
|
||||||
if (!jc) return '-'
|
|
||||||
return JC_TIME[jc] || ('第' + jc + '节')
|
|
||||||
},
|
|
||||||
formatSection(jc) {
|
formatSection(jc) {
|
||||||
if (!jc) return ''
|
if (jc === null || jc === undefined || jc === '') return '第?节'
|
||||||
return JC_SECTION[jc] || ('第' + jc + '节')
|
return JC_SECTION[jc] || ('第' + jc + '节')
|
||||||
},
|
},
|
||||||
buildSjsj(rq, jc) {
|
/** 后端 LocalDateTime -> 日期+周X+节次区间 */
|
||||||
const date = (rq || '').substring(0, 10)
|
fmtLessonTime(row) {
|
||||||
|
const rq = row.rq || ''
|
||||||
|
const date = String(rq).substring(0, 10)
|
||||||
if (!date) return '-'
|
if (!date) return '-'
|
||||||
const d = new Date(date.replace(/-/g, '/'))
|
const d = new Date(date.replace(/-/g, '/'))
|
||||||
const wn = WEEK_DAY_NAMES[d.getDay()]
|
const wn = WEEK_DAY_NAMES[d.getDay()]
|
||||||
const section = this.formatSection(jc)
|
return (date + ' 周' + wn + ' ' + this.formatSection(row.jc)).trim()
|
||||||
return (date + ' 周' + wn + ' ' + section).trim()
|
},
|
||||||
|
/** 后端 LocalDateTime -> yyyy-MM-dd HH:mm */
|
||||||
|
fmtKbbdsj(v) {
|
||||||
|
if (!v) return '-'
|
||||||
|
return String(v).replace('T', ' ').substring(0, 16)
|
||||||
|
},
|
||||||
|
txztText(txzt) {
|
||||||
|
if (txzt === 1) return '已填写'
|
||||||
|
if (txzt === 2) return '已提交'
|
||||||
|
return '未填写'
|
||||||
|
},
|
||||||
|
txztType(txzt) {
|
||||||
|
if (txzt === 1) return 'success'
|
||||||
|
if (txzt === 2) return 'primary'
|
||||||
|
return 'info'
|
||||||
},
|
},
|
||||||
/* ---------- 今日 ---------- */
|
/* ---------- 今日 ---------- */
|
||||||
handlePrevDay() {
|
handlePrevDay() {
|
||||||
@@ -446,115 +404,178 @@ export default {
|
|||||||
this.getTodayList()
|
this.getTodayList()
|
||||||
},
|
},
|
||||||
getTodayList() {
|
getTodayList() {
|
||||||
this.loading = true
|
const day = formatDate(this.todayDate)
|
||||||
setTimeout(() => {
|
const params = {
|
||||||
this.todayList = this.buildMockList(this.todayDate)
|
rqStart: day + 'T00:00:00',
|
||||||
this.loading = false
|
rqEnd: day + 'T23:59:59',
|
||||||
}, 200)
|
pageNum: 1,
|
||||||
|
pageSize: 200
|
||||||
|
}
|
||||||
|
this.todayLoading = true
|
||||||
|
listTeachingPlan(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.todayList = data.records || []
|
||||||
|
this.todayLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.todayList = []
|
||||||
|
this.todayLoading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/* ---------- 本周 ---------- */
|
/* ---------- 本周 ---------- */
|
||||||
handlePrevWeek() {
|
handlePrevWeek() {
|
||||||
const d = new Date(this.weekStart)
|
const d = new Date(this.weekStart)
|
||||||
d.setDate(d.getDate() - 7)
|
d.setDate(d.getDate() - 7)
|
||||||
this.weekStart = d
|
this.weekStart = d
|
||||||
|
this.weekQuery.pageNum = 1
|
||||||
this.getWeekList()
|
this.getWeekList()
|
||||||
},
|
},
|
||||||
handleNextWeek() {
|
handleNextWeek() {
|
||||||
const d = new Date(this.weekStart)
|
const d = new Date(this.weekStart)
|
||||||
d.setDate(d.getDate() + 7)
|
d.setDate(d.getDate() + 7)
|
||||||
this.weekStart = d
|
this.weekStart = d
|
||||||
|
this.weekQuery.pageNum = 1
|
||||||
this.getWeekList()
|
this.getWeekList()
|
||||||
},
|
},
|
||||||
|
weekRange() {
|
||||||
|
const start = formatDate(this.weekStart) + 'T00:00:00'
|
||||||
|
const endDate = new Date(this.weekStart)
|
||||||
|
endDate.setDate(endDate.getDate() + 6)
|
||||||
|
const end = formatDate(endDate) + 'T23:59:59'
|
||||||
|
return { start: start, end: end }
|
||||||
|
},
|
||||||
getWeekList() {
|
getWeekList() {
|
||||||
this.loading = true
|
const range = this.weekRange()
|
||||||
setTimeout(() => {
|
const params = {
|
||||||
this.weekList = this.buildMockWeekList(this.weekStart)
|
rqStart: range.start,
|
||||||
this.weekTotal = this.weekList.length
|
rqEnd: range.end,
|
||||||
this.loading = false
|
pageNum: this.weekQuery.pageNum,
|
||||||
}, 200)
|
pageSize: this.weekQuery.pageSize
|
||||||
|
}
|
||||||
|
this.weekLoading = true
|
||||||
|
listTeachingPlan(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.weekList = data.records || []
|
||||||
|
this.weekTotal = data.total || 0
|
||||||
|
this.weekLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.weekList = []
|
||||||
|
this.weekTotal = 0
|
||||||
|
this.weekLoading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/* ---------- 三实 ---------- */
|
/* ---------- 三实 ---------- */
|
||||||
handlePrevWeek3() {
|
handlePrevWeek3() {
|
||||||
const d = new Date(this.practiceStart)
|
const d = new Date(this.practiceStart)
|
||||||
d.setDate(d.getDate() - 7)
|
d.setDate(d.getDate() - 7)
|
||||||
this.practiceStart = d
|
this.practiceStart = d
|
||||||
|
this.practiceQuery.pageNum = 1
|
||||||
this.getPracticeList()
|
this.getPracticeList()
|
||||||
},
|
},
|
||||||
handleNextWeek3() {
|
handleNextWeek3() {
|
||||||
const d = new Date(this.practiceStart)
|
const d = new Date(this.practiceStart)
|
||||||
d.setDate(d.getDate() + 7)
|
d.setDate(d.getDate() + 7)
|
||||||
this.practiceStart = d
|
this.practiceStart = d
|
||||||
|
this.practiceQuery.pageNum = 1
|
||||||
this.getPracticeList()
|
this.getPracticeList()
|
||||||
},
|
},
|
||||||
|
practiceRange() {
|
||||||
|
const start = formatDate(this.practiceStart) + 'T00:00:00'
|
||||||
|
const endDate = new Date(this.practiceStart)
|
||||||
|
endDate.setDate(endDate.getDate() + 6)
|
||||||
|
const end = formatDate(endDate) + 'T23:59:59'
|
||||||
|
return { start: start, end: end }
|
||||||
|
},
|
||||||
getPracticeList() {
|
getPracticeList() {
|
||||||
this.loading = true
|
// 后端 plan/list 接口未返回课程类型字段,无法按三实课筛选,与本周共用同一数据源
|
||||||
setTimeout(() => {
|
const range = this.practiceRange()
|
||||||
this.practiceList = this.buildMockWeekList(this.practiceStart)
|
const params = {
|
||||||
this.practiceTotal = this.practiceList.length
|
rqStart: range.start,
|
||||||
this.loading = false
|
rqEnd: range.end,
|
||||||
}, 200)
|
pageNum: this.practiceQuery.pageNum,
|
||||||
},
|
pageSize: this.practiceQuery.pageSize
|
||||||
/* ---------- 静态示例数据(待对接接口) ---------- */
|
|
||||||
buildMockList(date) {
|
|
||||||
const dateStr = formatDate(date)
|
|
||||||
const samples = [
|
|
||||||
{ jc: 1, kcmc: '高等数学', zrdw: '基础部', bc: '一班', skjy: '张教员', jxcd: '1号教学楼-101', jxnr: '函数与极限', jxff: '讲授', jybz: '携带教材' },
|
|
||||||
{ jc: 3, kcmc: '大学英语', zrdw: '基础部', bc: '二班', skjy: '李教员', jxcd: '2号教学楼-205', jxnr: 'Unit 3 课文精读', jxff: '讲授/讨论', jybz: '' },
|
|
||||||
{ jc: 5, kcmc: '计算机基础', zrdw: '信息工程系', bc: '三班', skjy: '王教员', jxcd: '实验楼-303', jxnr: 'Word 文档排版', jxff: '实操', jybz: '机房上课' }
|
|
||||||
]
|
|
||||||
return samples.map((item, index) => ({
|
|
||||||
...item,
|
|
||||||
xh: index + 1,
|
|
||||||
rq: dateStr,
|
|
||||||
_jxnrff: [item.jxnr, item.jxff].filter(Boolean).join(' / ')
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
buildMockWeekList(weekStart) {
|
|
||||||
const list = []
|
|
||||||
const dates = []
|
|
||||||
for (let i = 0; i < 7; i++) {
|
|
||||||
const d = new Date(weekStart)
|
|
||||||
d.setDate(d.getDate() + i)
|
|
||||||
dates.push(formatDate(d))
|
|
||||||
}
|
}
|
||||||
const courses = [
|
this.practiceLoading = true
|
||||||
{ jc: 1, kcmc: '高等数学', zrdw: '基础部', bc: '一班', skjy: '张教员', jxcd: '1号教学楼-101', jxnr: '函数与极限', jxff: '讲授', jybz: '携带教材' },
|
listTeachingPlan(params).then(response => {
|
||||||
{ jc: 2, kcmc: '大学英语', zrdw: '基础部', bc: '二班', skjy: '李教员', jxcd: '2号教学楼-205', jxnr: 'Unit 3 课文精读', jxff: '讲授/讨论', jybz: '' },
|
const data = response.data || {}
|
||||||
{ jc: 3, kcmc: '计算机基础', zrdw: '信息工程系', bc: '三班', skjy: '王教员', jxcd: '实验楼-303', jxnr: 'Word 文档排版', jxff: '实操', jybz: '机房上课' },
|
this.practiceList = data.records || []
|
||||||
{ jc: 4, kcmc: '军事理论', zrdw: '政工系', bc: '一班', skjy: '赵教员', jxcd: '3号教学楼-110', jxnr: '国防动员概述', jxff: '讲授', jybz: '' }
|
this.practiceTotal = data.total || 0
|
||||||
]
|
this.practiceLoading = false
|
||||||
dates.forEach((dateStr, i) => {
|
}).catch(() => {
|
||||||
courses.forEach((item, idx) => {
|
this.practiceList = []
|
||||||
// 隔天轮换部分课程,保证每周有内容且不重复
|
this.practiceTotal = 0
|
||||||
if ((i + idx) % 2 === 0) {
|
this.practiceLoading = false
|
||||||
list.push({
|
|
||||||
...item,
|
|
||||||
xh: list.length + 1,
|
|
||||||
rq: dateStr,
|
|
||||||
_sjsj: this.buildSjsj(dateStr, item.jc),
|
|
||||||
_jxnrff: [item.jxnr, item.jxff].filter(Boolean).join(' / ')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
return list
|
|
||||||
},
|
},
|
||||||
/* ---------- 弹窗 ---------- */
|
/* ---------- 班次 ---------- */
|
||||||
openRemark(row) {
|
loadTeamOptions() {
|
||||||
this.remarkTarget = row
|
listTeam({ pageNum: 1, pageSize: 1000 }).then(response => {
|
||||||
this.remarkText = row.jybz || ''
|
const data = response.data || {}
|
||||||
this.remarkVisible = true
|
this.teamOptions = data.records || []
|
||||||
|
}).catch(() => {
|
||||||
|
this.teamOptions = []
|
||||||
|
})
|
||||||
},
|
},
|
||||||
confirmRemark() {
|
loadKbMap() {
|
||||||
this.$message.success('备注已更新')
|
listSubject({ pageNum: 1, pageSize: 1000 }).then(response => {
|
||||||
this.remarkVisible = false
|
const data = response.data || {}
|
||||||
|
const map = {}
|
||||||
|
;(data.records || []).forEach(item => {
|
||||||
|
if (item.kbh) map[item.kbh] = item.kmc
|
||||||
|
})
|
||||||
|
this.kbMap = map
|
||||||
|
}).catch(() => {
|
||||||
|
this.kbMap = {}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
openDetail(row) {
|
loadTeacherMap() {
|
||||||
this.detailTarget = row
|
listTeacher({ pageNum: 1, pageSize: 1000 }).then(response => {
|
||||||
this.detailVisible = true
|
const data = response.data || {}
|
||||||
|
const map = {}
|
||||||
|
;(data.records || []).forEach(item => {
|
||||||
|
if (item.jybh) map[item.jybh] = item.jyxm
|
||||||
|
})
|
||||||
|
this.teacherMap = map
|
||||||
|
}).catch(() => {
|
||||||
|
this.teacherMap = {}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleComing() {
|
handleShiftSearch() {
|
||||||
this.$message.info('功能建设中,敬请期待')
|
if (!this.shiftXydbh) {
|
||||||
|
this.$message.warning('请先选择队别班次')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.shiftQuery.pageNum = 1
|
||||||
|
this.getShiftList()
|
||||||
|
},
|
||||||
|
getShiftList() {
|
||||||
|
const params = {
|
||||||
|
xydbh: this.shiftXydbh,
|
||||||
|
nd: this.shiftNd,
|
||||||
|
pageNum: this.shiftQuery.pageNum,
|
||||||
|
pageSize: this.shiftQuery.pageSize
|
||||||
|
}
|
||||||
|
this.shiftLoading = true
|
||||||
|
listStudentTeamTask(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
const team = this.teamOptions.find(t => t.xydbh === this.shiftXydbh)
|
||||||
|
this.shiftList = (data.records || []).map(item => ({
|
||||||
|
...item,
|
||||||
|
xydmc: (team && team.xydmc) || item.xydbh,
|
||||||
|
_kcmc: this.kbMap[item.kbh] || item.kbh,
|
||||||
|
_zrjy: this.teacherMap[item.jysjhjybh] || item.jysjhjybh || '-',
|
||||||
|
_ssjy: this.teacherMap[item.jybh] || item.jybh || '-'
|
||||||
|
}))
|
||||||
|
this.shiftTotal = data.total || 0
|
||||||
|
this.shiftLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.shiftList = []
|
||||||
|
this.shiftTotal = 0
|
||||||
|
this.shiftLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/* ---------- 无后端接口的操作 ---------- */
|
||||||
|
handleNotProvided() {
|
||||||
|
this.$message.info('后端暂未提供该接口')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,6 +594,10 @@ export default {
|
|||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mb8 {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 日期/周次导航 */
|
/* 日期/周次导航 */
|
||||||
.nav-header {
|
.nav-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -596,31 +621,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 批量操作栏 */
|
|
||||||
.toolbar-card {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding: 10px 14px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
.toolbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.toolbar-left,
|
|
||||||
.toolbar-right {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 表格区 */
|
/* 表格区 */
|
||||||
.table-card {
|
.table-card {
|
||||||
.danger-text {
|
.danger-text {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<!-- 近期申请统计卡片 -->
|
<!-- 统计卡片 -->
|
||||||
<div class="section-card">
|
<div class="section-card">
|
||||||
<div class="section-title">近期课表调整申请</div>
|
<div class="section-title">调课申请统计(当前页)</div>
|
||||||
<div class="stat-grid">
|
<div class="stat-grid">
|
||||||
<div
|
<div
|
||||||
v-for="card in statCards"
|
v-for="card in statCards"
|
||||||
@@ -22,19 +22,18 @@
|
|||||||
|
|
||||||
<!-- 查询条件 -->
|
<!-- 查询条件 -->
|
||||||
<div class="section-card">
|
<div class="section-card">
|
||||||
<el-form :model="queryParams" :inline="true" size="small" class="search-form">
|
<el-form :model="queryParams" :inline="true" size="small" class="search-form" @submit.native.prevent>
|
||||||
<el-form-item label="课程名称">
|
<el-form-item label="年度">
|
||||||
<el-input v-model="queryParams.kcmc" placeholder="请输入课程名称" clearable style="width: 180px" @keyup.enter.native="handleQuery" />
|
<el-select v-model="queryParams.nd" placeholder="请选择年度" clearable style="width: 140px">
|
||||||
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="队别(班次)">
|
<el-form-item label="申请教员编号">
|
||||||
<el-input v-model="queryParams.dbbc" placeholder="请输入队别班次" clearable style="width: 160px" @keyup.enter.native="handleQuery" />
|
<el-input v-model="queryParams.sqjybh" placeholder="请输入申请教员编号" clearable style="width: 180px" @keyup.enter.native="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="申请教员">
|
<el-form-item label="教研室审批状态">
|
||||||
<el-input v-model="queryParams.sqjy" placeholder="请输入申请教员" clearable style="width: 160px" @keyup.enter.native="handleQuery" />
|
<el-select v-model="queryParams.jyspzzt" placeholder="请选择" clearable style="width: 150px">
|
||||||
</el-form-item>
|
<el-option v-for="item in auditStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
<el-form-item label="状态">
|
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 140px">
|
|
||||||
<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -53,87 +52,270 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="filteredData" v-loading="loading" size="small" border stripe class="compact-table" max-height="520">
|
<el-table :data="tableData" v-loading="loading" size="small" border stripe class="compact-table" max-height="520">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="kcmc" label="课程名称" min-width="140" show-overflow-tooltip />
|
<el-table-column prop="kcmc" label="课程名称" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="jxsj" label="教学时间" width="110" align="center" />
|
<el-table-column label="申请教员" min-width="110" align="center" show-overflow-tooltip>
|
||||||
<el-table-column prop="sksj" label="上课时间" width="180" />
|
<template slot-scope="scope">{{ scope.row.sqjyxm || scope.row.sqjybh || '-' }}</template>
|
||||||
<el-table-column prop="jy" label="教员" width="90" align="center" />
|
</el-table-column>
|
||||||
<el-table-column prop="jxcd" label="教学场地" width="120" show-overflow-tooltip />
|
<el-table-column prop="sy" label="调课事由" min-width="180" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="dbbc" label="队别(班次)" min-width="140" show-overflow-tooltip />
|
<el-table-column label="拟调整时间" width="170" align="center" show-overflow-tooltip>
|
||||||
<el-table-column prop="sqjy" label="申请教员" width="90" align="center" />
|
<template slot-scope="scope">{{ fmtRqJc(scope.row.rq, scope.row.jc) }}</template>
|
||||||
<el-table-column prop="zxkb" label="拟调整时间" width="180" />
|
</el-table-column>
|
||||||
<el-table-column label="申请类型" width="90" align="center">
|
<el-table-column prop="nd" label="年度" width="80" align="center" />
|
||||||
|
<el-table-column label="教研室审批状态" width="110" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag :type="typeTag(scope.row.lx)" size="mini">{{ scope.row.lx }}</el-tag>
|
<el-tag :type="auditStatusTag(scope.row.jyspzzt).type" size="mini">{{ auditStatusTag(scope.row.jyspzzt).label }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="状态" width="90" align="center">
|
<el-table-column label="教研室查收状态" width="100" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag :type="statusTag(scope.row.status).type" size="mini">{{ statusTag(scope.row.status).label }}</el-tag>
|
<el-tag :type="receiveStatusTag(scope.row.jyscszt).type" size="mini">{{ receiveStatusTag(scope.row.jyscszt).label }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
<el-table-column label="创建时间" width="150" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtDateTime(scope.row.cjsj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="210" align="center" fixed="right">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="mini" icon="el-icon-view" @click="openDetail(scope.row)">查看</el-button>
|
<div class="ops-cell">
|
||||||
<template v-if="scope.row.status === '0'">
|
<el-button type="text" size="mini" icon="el-icon-view" @click="openDetail(scope.row)">详情</el-button>
|
||||||
<el-button type="text" size="mini" icon="el-icon-check" @click="approve(scope.row)">批准</el-button>
|
<el-dropdown v-if="showAuditMenu(scope.row)" trigger="click" @command="cmd => openAudit(scope.row, cmd)">
|
||||||
<el-button type="text" size="mini" icon="el-icon-close" class="danger-btn" @click="reject(scope.row)">驳回</el-button>
|
<el-button type="text" size="mini" @click.stop>审批<i class="el-icon-arrow-down el-icon--right" /></el-button>
|
||||||
</template>
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-button v-else type="text" size="mini" class="danger-btn" @click="removeRow(scope.row)">删除</el-button>
|
<el-dropdown-item v-if="scope.row.jyspzzt === 0" command="jys">教研室审批</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-if="scope.row.jyspzzt === 1" command="jxx">教学系审批</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-if="scope.row.jyspzzt === 1" command="jg">机关审批</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-dropdown v-if="showReceiveMenu(scope.row)" trigger="click" @command="cmd => openReceive(scope.row, cmd)">
|
||||||
|
<el-button type="text" size="mini" @click.stop>查收<i class="el-icon-arrow-down el-icon--right" /></el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item v-if="scope.row.jyscszt === 0" command="jys">教研室查收</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="jg">机关查收</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-button v-if="scope.row.sczt === 0 && scope.row.jyspzzt !== 1" type="text" size="mini" class="danger-btn" @click="handleCancel(scope.row)">撤销</el-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-show="!loading && filteredData.length === 0" description="暂无调整申请" />
|
<el-empty v-show="!loading && tableData.length === 0" description="暂无调整申请" />
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="loadList"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 新增申请弹窗 -->
|
<!-- 新增申请弹窗 -->
|
||||||
<el-dialog title="新增课表调整申请" :visible.sync="dialogVisible" width="640px" append-to-body>
|
<el-dialog title="新增课表调整申请" :visible.sync="addVisible" width="640px" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
<el-form ref="addForm" :model="addForm" :rules="addRules" label-width="110px">
|
||||||
<el-form-item label="课程名称" prop="kcmc">
|
<el-form-item label="年度" prop="nd">
|
||||||
<el-input v-model="form.kcmc" placeholder="请输入课程名称" />
|
<el-select v-model="addForm.nd" placeholder="请选择年度" style="width: 100%">
|
||||||
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="申请类型" prop="lx">
|
<el-form-item label="课次编号" prop="sskcbbh">
|
||||||
<el-radio-group v-model="form.lx">
|
<el-input v-model="addForm.sskcbbh" placeholder="请输入课次编号" />
|
||||||
<el-radio label="调课" />
|
<el-button type="primary" plain size="mini" class="pick-lesson-btn" :loading="lessonLoading" @click="loadAdjustableLessons">选择可供调课课次</el-button>
|
||||||
<el-radio label="停课" />
|
|
||||||
<el-radio label="补课" />
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="队别(班次)" prop="dbbc">
|
<el-form-item label="调课事由" prop="sy">
|
||||||
<el-input v-model="form.dbbc" placeholder="请输入队别班次" />
|
<el-input v-model="addForm.sy" type="textarea" :rows="2" placeholder="请输入调课事由" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="原上课时间" prop="sksj">
|
<el-form-item label="拟调整日期" prop="rq">
|
||||||
<el-input v-model="form.sksj" placeholder="如:周一 第3-4节" />
|
<el-date-picker v-model="addForm.rq" type="date" value-format="yyyy-MM-dd" placeholder="请选择日期" style="width: 100%" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="拟调整时间" prop="zxkb">
|
<el-form-item label="拟调整节次" prop="jc">
|
||||||
<el-input v-model="form.zxkb" placeholder="请输入拟调整后的上课时间" />
|
<el-select v-model="addForm.jc" placeholder="请选择节次" style="width: 100%">
|
||||||
|
<el-option v-for="n in jcOptions" :key="n" :label="jcLabel(n)" :value="n" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="申请理由" prop="bz">
|
<el-form-item label="申请教员编号" prop="sqjybh">
|
||||||
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="请输入申请理由" />
|
<el-input v-model="addForm.sqjybh" placeholder="请输入申请教员编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教学内容">
|
||||||
|
<el-input v-model="addForm.jxnr" placeholder="选填" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教学要点">
|
||||||
|
<el-input v-model="addForm.jxyd" placeholder="选填" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教学方法">
|
||||||
|
<el-input v-model="addForm.jxff" placeholder="选填" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教学保障备注">
|
||||||
|
<el-input v-model="addForm.jxbzbz" placeholder="选填" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用车信息">
|
||||||
|
<el-input v-model="addForm.ycxx" placeholder="选填" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="addForm.bz" type="textarea" :rows="2" placeholder="选填" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" :loading="submitLoading" @click="submitForm">提交申请</el-button>
|
<el-button type="primary" :loading="addLoading" @click="submitAdd">提交申请</el-button>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="addVisible = false">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 可供调课课次选择弹窗 -->
|
||||||
|
<el-dialog title="选择可供调课课次" :visible.sync="lessonDialogVisible" width="760px" append-to-body>
|
||||||
|
<el-table :data="lessonOptions" v-loading="lessonLoading" size="small" border stripe max-height="420">
|
||||||
|
<el-table-column prop="kcmc" label="课程名称" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column label="原上课时间" width="160" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtRqJc(scope.row.rq, scope.row.jc) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="xydmc" label="学员队" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="kcxh" label="课次序号" width="90" align="center" />
|
||||||
|
<el-table-column prop="jsbh" label="教室编号" width="110" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column label="操作" width="90" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="text" size="mini" @click="pickLesson(scope.row)">选择</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-empty v-show="!lessonLoading && lessonOptions.length === 0" description="暂无可供调课课次" />
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 审批弹窗 -->
|
||||||
|
<el-dialog :title="auditTitle" :visible.sync="auditVisible" width="520px" append-to-body>
|
||||||
|
<el-form ref="auditForm" :model="auditForm" label-width="100px">
|
||||||
|
<el-form-item label="审批结果" required>
|
||||||
|
<el-radio-group v-model="auditForm.spzt">
|
||||||
|
<el-radio :label="1">同意</el-radio>
|
||||||
|
<el-radio :label="2">发回</el-radio>
|
||||||
|
<el-radio :label="3">拒绝</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审批意见">
|
||||||
|
<el-input v-model="auditForm.fhyj" type="textarea" :rows="3" placeholder="请输入审批意见(发回/拒绝时必填)" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审批人编号" required>
|
||||||
|
<el-input v-model="auditForm.sprbh" placeholder="请输入审批人编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="auditForm.auditRole === 'jg'" label="机关编号" required>
|
||||||
|
<el-input v-model="auditForm.jgbh" placeholder="请输入机关编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" :loading="auditLoading" @click="submitAudit">确定</el-button>
|
||||||
|
<el-button @click="auditVisible = false">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 查收弹窗 -->
|
||||||
|
<el-dialog :title="receiveTitle" :visible.sync="receiveVisible" width="460px" append-to-body>
|
||||||
|
<el-form ref="receiveForm" :model="receiveForm" label-width="100px">
|
||||||
|
<el-form-item v-if="receiveForm.type === 'jg'" label="机关编号" required>
|
||||||
|
<el-input v-model="receiveForm.jgbh" placeholder="请输入机关编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="查收人编号" required>
|
||||||
|
<el-input v-model="receiveForm.csrbh" placeholder="请输入查收人编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" :loading="receiveLoading" @click="submitReceive">确定</el-button>
|
||||||
|
<el-button @click="receiveVisible = false">取消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 查看详情弹窗 -->
|
<!-- 查看详情弹窗 -->
|
||||||
<el-dialog title="申请详情" :visible.sync="detailVisible" width="580px" append-to-body>
|
<el-dialog title="申请详情" :visible.sync="detailVisible" width="760px" append-to-body>
|
||||||
<el-descriptions v-if="detailTarget" :column="2" border size="small">
|
<div v-loading="detailLoading">
|
||||||
<el-descriptions-item label="课程名称">{{ detailTarget.kcmc }}</el-descriptions-item>
|
<el-descriptions v-if="detailData" :column="2" border size="small">
|
||||||
<el-descriptions-item label="申请类型">
|
<el-descriptions-item label="课程名称">{{ detailData.kcmc || '-' }}</el-descriptions-item>
|
||||||
<el-tag :type="typeTag(detailTarget.lx)" size="mini">{{ detailTarget.lx }}</el-tag>
|
<el-descriptions-item label="申请教员">{{ detailData.sqjyxm || detailData.sqjybh || '-' }}</el-descriptions-item>
|
||||||
</el-descriptions-item>
|
<el-descriptions-item label="调课事由" :span="2">{{ detailData.sy || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="队别(班次)">{{ detailTarget.dbbc }}</el-descriptions-item>
|
<el-descriptions-item label="拟调整时间">{{ fmtRqJc(detailData.rq, detailData.jc) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="教员">{{ detailTarget.jy }} / {{ detailTarget.sqjy }}</el-descriptions-item>
|
<el-descriptions-item label="年度">{{ detailData.nd || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="教学场地">{{ detailTarget.jxcd }}</el-descriptions-item>
|
<el-descriptions-item label="创建时间">{{ fmtDateTime(detailData.cjsj) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="执行时间">{{ detailTarget.zxsj }}</el-descriptions-item>
|
<el-descriptions-item label="教研室审批状态">
|
||||||
<el-descriptions-item label="原上课时间" :span="2">{{ detailTarget.sksj }}</el-descriptions-item>
|
<el-tag :type="auditStatusTag(detailData.jyspzzt).type" size="mini">{{ auditStatusTag(detailData.jyspzzt).label }}</el-tag>
|
||||||
<el-descriptions-item label="拟调整时间" :span="2">{{ detailTarget.zxkb }}</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请理由" :span="2">{{ detailTarget.bz }}</el-descriptions-item>
|
<el-descriptions-item label="教研室查收状态">
|
||||||
</el-descriptions>
|
<el-tag :type="receiveStatusTag(detailData.jyscszt).type" size="mini">{{ receiveStatusTag(detailData.jyscszt).label }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教研室审批人">{{ detailData.jyspzrbh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教研室审批时间">{{ fmtDateTime(detailData.jyspzsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教研室查收人">{{ detailData.jyscsrbh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教研室查收时间">{{ fmtDateTime(detailData.jyscssj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发回意见" :span="2">{{ detailData.fhyj || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学内容" :span="2">{{ detailData.jxnr || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学要点" :span="2">{{ detailData.jxyd || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学方法" :span="2">{{ detailData.jxff || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学保障备注" :span="2">{{ detailData.jxbzbz || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="用车信息" :span="2">{{ detailData.ycxx || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ detailData.bz || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<!-- 新教室 -->
|
||||||
|
<div v-if="detailData && detailData.roomList && detailData.roomList.length" class="sub-section">
|
||||||
|
<div class="sub-title">新教室</div>
|
||||||
|
<el-table :data="detailData.roomList" size="small" border stripe>
|
||||||
|
<el-table-column prop="jsbh" label="教室编号" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="jsmc" label="教室名称" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="bz" label="备注" min-width="160" show-overflow-tooltip header-align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新辅助教员 -->
|
||||||
|
<div v-if="detailData && detailData.teacherList && detailData.teacherList.length" class="sub-section">
|
||||||
|
<div class="sub-title">新辅助教员</div>
|
||||||
|
<el-table :data="detailData.teacherList" size="small" border stripe>
|
||||||
|
<el-table-column prop="fzjybh" label="教员编号" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="fzjyxm" label="教员姓名" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column label="是否主教员" width="100" align="center">
|
||||||
|
<template slot-scope="scope">{{ scope.row.zjy === 1 ? '是' : '否' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="bz" label="备注" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新学员队 -->
|
||||||
|
<div v-if="detailData && detailData.teamList && detailData.teamList.length" class="sub-section">
|
||||||
|
<div class="sub-title">新学员队</div>
|
||||||
|
<el-table :data="detailData.teamList" size="small" border stripe>
|
||||||
|
<el-table-column prop="xydbh" label="学员队编号" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="xydmc" label="学员队名称" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新保障明细 -->
|
||||||
|
<div v-if="detailData && detailData.supportList && detailData.supportList.length" class="sub-section">
|
||||||
|
<div class="sub-title">新保障明细</div>
|
||||||
|
<el-table :data="detailData.supportList" size="small" border stripe>
|
||||||
|
<el-table-column prop="bztgmxbh" label="保障编号" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="bztgmxmc" label="保障名称" min-width="160" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="sl" label="数量" width="80" align="center" />
|
||||||
|
<el-table-column prop="bz" label="备注" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 机关审批记录 -->
|
||||||
|
<div v-if="detailData && detailData.auditList && detailData.auditList.length" class="sub-section">
|
||||||
|
<div class="sub-title">机关审批记录</div>
|
||||||
|
<el-table :data="detailData.auditList" size="small" border stripe>
|
||||||
|
<el-table-column prop="jgmc" label="机关" min-width="140" show-overflow-tooltip header-align="center">
|
||||||
|
<template slot-scope="scope">{{ scope.row.jgmc || scope.row.jgbh || '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="审批状态" width="100" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="auditStatusTag(scope.row.spzt).type" size="mini">{{ auditStatusTag(scope.row.spzt).label }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="sprxm" label="审批人" min-width="110" show-overflow-tooltip header-align="center">
|
||||||
|
<template slot-scope="scope">{{ scope.row.sprxm || scope.row.sprbh || '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="审批时间" width="150" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtDateTime(scope.row.spsj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="fhyj" label="发回意见" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="detailVisible = false">关闭</el-button>
|
<el-button @click="detailVisible = false">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -142,175 +324,371 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 课表调整申请静态示例数据(待对接 getTimetableAdjustList 接口)
|
import {
|
||||||
const MOCK_LIST = [
|
listScheduleAdjust,
|
||||||
{ id: 1, kcmc: '高等数学', lx: '调课', jxsj: '2026-2027-1', sksj: '周一 第1-2节', zxkb: '周二 第3-4节', jy: '张教员', sqjy: '张教员', jxcd: '1号教学楼-101', dbbc: '一班', zxsj: '2026-09-01', bz: '因学院集中活动调整上课时间', status: '0' },
|
listAdjustableLessons,
|
||||||
{ id: 2, kcmc: '大学英语', lx: '停课', jxsj: '2026-2027-1', sksj: '周三 第5-6节', zxkb: '—', jy: '李教员', sqjy: '王教员', jxcd: '1号教学楼-205', dbbc: '二班', zxsj: '2026-09-03', bz: '教员参加教研会议,申请停课顺延', status: '1' },
|
getScheduleAdjustDetail,
|
||||||
{ id: 3, kcmc: '计算机基础', lx: '补课', jxsj: '2026-2027-1', sksj: '周五 第7-8节', zxkb: '周六 第1-2节', jy: '王教员', sqjy: '王教员', jxcd: '实验楼-303', dbbc: '三班', zxsj: '2026-09-04', bz: '补上周五因停课落下的课程', status: '1' },
|
submitScheduleAdjust,
|
||||||
{ id: 4, kcmc: '军事理论', lx: '调课', jxsj: '2026-2027-1', sksj: '周四 第3-4节', zxkb: '周五 第3-4节', jy: '赵教员', sqjy: '赵教员', jxcd: '3号教学楼-110', dbbc: '一班', zxsj: '2026-09-05', bz: '场地临时被占用,调换上课时间', status: '2' },
|
auditByTeachingOffice,
|
||||||
{ id: 5, kcmc: '高等数学', lx: '补课', jxsj: '2026-2027-1', sksj: '周二 第1-2节', zxkb: '周四 第7-8节', jy: '张教员', sqjy: '张教员', jxcd: '1号教学楼-101', dbbc: '二班', zxsj: '2026-09-06', bz: '补国庆假期调休停上的课程', status: '0' }
|
auditByTeachingDepartment,
|
||||||
]
|
auditByAuthority,
|
||||||
|
receiveByTeachingOffice,
|
||||||
|
receiveByAuthority,
|
||||||
|
cancelScheduleAdjust
|
||||||
|
} from '@/api/teachBusiness/courseRunning'
|
||||||
|
import { listAllSemester } from '@/api/teachBusiness/semester'
|
||||||
|
|
||||||
// 状态描述
|
// 节次 -> 节次区间映射
|
||||||
const STATUS_MAP = {
|
const JC_SECTION = {
|
||||||
'0': { label: '待审批', type: 'warning' },
|
1: '1-2节', 2: '3-4节', 3: '5-6节', 4: '7-8节', 5: '9-10节', 6: '11-12节'
|
||||||
'1': { label: '已批准', type: 'success' },
|
}
|
||||||
'2': { label: '已驳回', type: 'danger' }
|
|
||||||
|
// 审批状态:0-未审批,1-已同意,2-已发回,3-已拒绝
|
||||||
|
const AUDIT_STATUS = {
|
||||||
|
0: { label: '未审批', type: 'info' },
|
||||||
|
1: { label: '已同意', type: 'success' },
|
||||||
|
2: { label: '已发回', type: 'warning' },
|
||||||
|
3: { label: '已拒绝', type: 'danger' }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查收状态:0-未查收,1-已查收
|
||||||
|
const RECEIVE_STATUS = {
|
||||||
|
0: { label: '未查收', type: 'info' },
|
||||||
|
1: { label: '已查收', type: 'success' }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TimetableAdjust',
|
name: 'TimetableAdjust',
|
||||||
data() {
|
data() {
|
||||||
|
const curUserName = (this.$store.state.user && this.$store.state.user.name) || ''
|
||||||
return {
|
return {
|
||||||
|
curUserName: curUserName,
|
||||||
loading: false,
|
loading: false,
|
||||||
submitLoading: false,
|
tableData: [],
|
||||||
allData: [],
|
total: 0,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
kcmc: undefined,
|
nd: undefined,
|
||||||
dbbc: undefined,
|
sqjybh: undefined,
|
||||||
sqjy: undefined,
|
jyspzzt: undefined,
|
||||||
status: undefined
|
pageNum: 1,
|
||||||
|
pageSize: 20
|
||||||
},
|
},
|
||||||
statusOptions: [
|
// 年度下拉数据来自 /semester/all(真实后端数据)
|
||||||
{ label: '待审批', value: '0' },
|
yearOptions: [],
|
||||||
{ label: '已批准', value: '1' },
|
defaultNd: undefined,
|
||||||
{ label: '已驳回', value: '2' }
|
jcOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||||
|
auditStatusOptions: [
|
||||||
|
{ label: '未审批', value: 0 },
|
||||||
|
{ label: '已同意', value: 1 },
|
||||||
|
{ label: '已发回', value: 2 },
|
||||||
|
{ label: '已拒绝', value: 3 }
|
||||||
],
|
],
|
||||||
statCards: [],
|
statCards: [],
|
||||||
dialogVisible: false,
|
// 新增申请
|
||||||
|
addVisible: false,
|
||||||
|
addLoading: false,
|
||||||
|
addForm: {},
|
||||||
|
addRules: {
|
||||||
|
nd: [{ required: true, message: '请选择年度', trigger: 'change' }],
|
||||||
|
sskcbbh: [{ required: true, message: '请输入课次编号', trigger: 'blur' }],
|
||||||
|
sy: [{ required: true, message: '请输入调课事由', trigger: 'blur' }],
|
||||||
|
rq: [{ required: true, message: '请选择拟调整日期', trigger: 'change' }],
|
||||||
|
jc: [{ required: true, message: '请选择拟调整节次', trigger: 'change' }],
|
||||||
|
sqjybh: [{ required: true, message: '请输入申请教员编号', trigger: 'blur' }]
|
||||||
|
},
|
||||||
|
// 可供调课课次
|
||||||
|
lessonDialogVisible: false,
|
||||||
|
lessonLoading: false,
|
||||||
|
lessonOptions: [],
|
||||||
|
// 审批
|
||||||
|
auditVisible: false,
|
||||||
|
auditLoading: false,
|
||||||
|
auditTitle: '审批',
|
||||||
|
auditForm: { ssdksqbh: '', auditRole: 'jys', spzt: 1, fhyj: '', sprbh: '', jgbh: '' },
|
||||||
|
// 查收
|
||||||
|
receiveVisible: false,
|
||||||
|
receiveLoading: false,
|
||||||
|
receiveTitle: '查收',
|
||||||
|
receiveForm: { ssdksqbh: '', type: 'jys', csrbh: '', jgbh: '' },
|
||||||
|
// 详情
|
||||||
detailVisible: false,
|
detailVisible: false,
|
||||||
detailTarget: null,
|
detailLoading: false,
|
||||||
form: {},
|
detailData: null
|
||||||
rules: {
|
|
||||||
kcmc: [{ required: true, message: '请输入课程名称', trigger: 'blur' }],
|
|
||||||
lx: [{ required: true, message: '请选择申请类型', trigger: 'change' }],
|
|
||||||
dbbc: [{ required: true, message: '请输入队别班次', trigger: 'blur' }],
|
|
||||||
bz: [{ required: true, message: '请输入申请理由', trigger: 'blur' }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
filteredData() {
|
|
||||||
const q = this.queryParams
|
|
||||||
return this.allData.filter(item => {
|
|
||||||
if (q.kcmc && !(item.kcmc || '').includes(q.kcmc)) return false
|
|
||||||
if (q.dbbc && !(item.dbbc || '').includes(q.dbbc)) return false
|
|
||||||
if (q.sqjy && !(item.sqjy || '').includes(q.sqjy)) return false
|
|
||||||
if (q.status !== undefined && q.status !== '' && item.status !== q.status) return false
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadData()
|
this.loadYearOptions().then(() => this.loadList())
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
typeTag(lx) {
|
/* ---------- 年度下拉(数据来自 /semester/all) ---------- */
|
||||||
const map = { '调课': 'warning', '停课': 'danger', '补课': 'success' }
|
loadYearOptions() {
|
||||||
return map[lx] || 'info'
|
return listAllSemester().then(response => {
|
||||||
|
const list = response.data || []
|
||||||
|
// 去重并按年度倒序
|
||||||
|
const map = {}
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.nd !== null && item.nd !== undefined && item.nd !== '') map[item.nd] = item
|
||||||
|
})
|
||||||
|
const arr = Object.keys(map).sort((a, b) => String(b).localeCompare(String(a)))
|
||||||
|
this.yearOptions = arr
|
||||||
|
// 默认年度:优先当前学期(dqxq=true),否则取最新年度
|
||||||
|
const current = list.find(item => item.dqxq === true)
|
||||||
|
this.defaultNd = (current && current.nd) || arr[0]
|
||||||
|
if (!this.queryParams.nd) this.queryParams.nd = this.defaultNd
|
||||||
|
return arr
|
||||||
|
}).catch(() => {
|
||||||
|
this.yearOptions = []
|
||||||
|
this.defaultNd = undefined
|
||||||
|
return []
|
||||||
|
})
|
||||||
},
|
},
|
||||||
statusTag(status) {
|
/* ---------- 通用格式化 ---------- */
|
||||||
return STATUS_MAP[status] || { label: status, type: 'info' }
|
fmtDateTime(v) {
|
||||||
|
if (!v) return '-'
|
||||||
|
return String(v).replace('T', ' ').substring(0, 16)
|
||||||
},
|
},
|
||||||
loadData() {
|
fmtRqJc(rq, jc) {
|
||||||
|
if (!rq) return '-'
|
||||||
|
const date = String(rq).substring(0, 10)
|
||||||
|
const sec = jc === null || jc === undefined || jc === '' ? '第?节' : (JC_SECTION[jc] || '第' + jc + '节')
|
||||||
|
return date + ' ' + sec
|
||||||
|
},
|
||||||
|
jcLabel(n) {
|
||||||
|
return JC_SECTION[n] || ('第' + n + '节')
|
||||||
|
},
|
||||||
|
auditStatusTag(v) {
|
||||||
|
return AUDIT_STATUS[v] || { label: '-', type: 'info' }
|
||||||
|
},
|
||||||
|
receiveStatusTag(v) {
|
||||||
|
return RECEIVE_STATUS[v] || { label: '-', type: 'info' }
|
||||||
|
},
|
||||||
|
/* ---------- 列表查询 ---------- */
|
||||||
|
loadList() {
|
||||||
|
const params = {
|
||||||
|
pageNum: this.queryParams.pageNum,
|
||||||
|
pageSize: this.queryParams.pageSize
|
||||||
|
}
|
||||||
|
if (this.queryParams.nd) params.nd = this.queryParams.nd
|
||||||
|
if (this.queryParams.sqjybh) params.sqjybh = this.queryParams.sqjybh
|
||||||
|
if (this.queryParams.jyspzzt !== undefined && this.queryParams.jyspzzt !== '') {
|
||||||
|
params.jyspzzt = this.queryParams.jyspzzt
|
||||||
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
// 模拟接口延迟,后续替换为真实接口
|
listScheduleAdjust(params).then(response => {
|
||||||
setTimeout(() => {
|
const data = response.data || {}
|
||||||
this.allData = MOCK_LIST.map((item, index) => ({ ...item, xh: index + 1 }))
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
this.refreshStatCards()
|
this.refreshStatCards()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}, 200)
|
}).catch(() => {
|
||||||
},
|
this.tableData = []
|
||||||
refreshStatCards() {
|
this.total = 0
|
||||||
const total = this.allData.length
|
this.refreshStatCards()
|
||||||
const pending = this.allData.filter(i => i.status === '0').length
|
this.loading = false
|
||||||
const approved = this.allData.filter(i => i.status === '1').length
|
})
|
||||||
const rejected = this.allData.filter(i => i.status === '2').length
|
|
||||||
this.statCards = [
|
|
||||||
{ title: '申请总数', value: total, gradient: 'linear-gradient(135deg, #00875a 0%, #00b877 100%)' },
|
|
||||||
{ title: '待审批', value: pending, gradient: 'linear-gradient(135deg, #e6a23c 0%, #f8b04c 100%)' },
|
|
||||||
{ title: '已批准', value: approved, gradient: 'linear-gradient(135deg, #409eff 0%, #66b1ff 100%)' },
|
|
||||||
{ title: '已驳回', value: rejected, gradient: 'linear-gradient(135deg, #f56c6c 0%, #f78989 100%)' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
handleStatClick(card) {
|
|
||||||
const statusMap = { '待审批': '0', '已批准': '1', '已驳回': '2' }
|
|
||||||
if (statusMap[card.title]) {
|
|
||||||
this.queryParams.status = this.queryParams.status === statusMap[card.title] ? undefined : statusMap[card.title]
|
|
||||||
this.$message.info(`已按「${card.title}」筛选`)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.$message.success('查询完成')
|
this.queryParams.pageNum = 1
|
||||||
|
this.loadList()
|
||||||
},
|
},
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
this.queryParams = {
|
this.queryParams = {
|
||||||
kcmc: undefined,
|
nd: this.defaultNd,
|
||||||
dbbc: undefined,
|
sqjybh: undefined,
|
||||||
sqjy: undefined,
|
jyspzzt: undefined,
|
||||||
status: undefined
|
pageNum: 1,
|
||||||
|
pageSize: 20
|
||||||
}
|
}
|
||||||
|
this.loadList()
|
||||||
},
|
},
|
||||||
|
refreshStatCards() {
|
||||||
|
const list = this.tableData
|
||||||
|
this.statCards = [
|
||||||
|
{ title: '本页申请', value: list.length, gradient: 'linear-gradient(135deg, #00875a 0%, #00b877 100%)', filter: undefined },
|
||||||
|
{ title: '教研室待审批', value: list.filter(i => i.jyspzzt === 0).length, gradient: 'linear-gradient(135deg, #e6a23c 0%, #f8b04c 100%)', filter: 0 },
|
||||||
|
{ title: '教研室已同意', value: list.filter(i => i.jyspzzt === 1).length, gradient: 'linear-gradient(135deg, #409eff 0%, #66b1ff 100%)', filter: 1 },
|
||||||
|
{ title: '教研室已拒绝', value: list.filter(i => i.jyspzzt === 3).length, gradient: 'linear-gradient(135deg, #f56c6c 0%, #f78989 100%)', filter: 3 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
handleStatClick(card) {
|
||||||
|
if (card.filter === undefined) return
|
||||||
|
this.queryParams.jyspzzt = this.queryParams.jyspzzt === card.filter ? undefined : card.filter
|
||||||
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
/* ---------- 新增申请 ---------- */
|
||||||
openAdd() {
|
openAdd() {
|
||||||
this.form = { kcmc: '', lx: '调课', dbbc: '', sksj: '', zxkb: '', bz: '' }
|
this.addForm = {
|
||||||
this.$nextTick(() => this.$refs.form && this.$refs.form.clearValidate())
|
nd: this.defaultNd || this.yearOptions[0],
|
||||||
this.dialogVisible = true
|
sskcbbh: '',
|
||||||
|
sy: '',
|
||||||
|
rq: '',
|
||||||
|
jc: 1,
|
||||||
|
sqjybh: this.curUserName,
|
||||||
|
jxnr: '',
|
||||||
|
jxyd: '',
|
||||||
|
jxff: '',
|
||||||
|
jxbzbz: '',
|
||||||
|
ycxx: '',
|
||||||
|
bz: ''
|
||||||
|
}
|
||||||
|
this.$nextTick(() => this.$refs.addForm && this.$refs.addForm.clearValidate())
|
||||||
|
this.addVisible = true
|
||||||
},
|
},
|
||||||
submitForm() {
|
loadAdjustableLessons() {
|
||||||
this.$refs.form.validate(valid => {
|
if (!this.addForm.nd) {
|
||||||
if (!valid) return
|
this.$message.warning('请先选择年度')
|
||||||
this.submitLoading = true
|
return
|
||||||
setTimeout(() => {
|
}
|
||||||
const nextId = this.allData.length ? Math.max(...this.allData.map(i => i.id)) + 1 : 1
|
this.lessonLoading = true
|
||||||
this.allData.unshift({
|
listAdjustableLessons({ nd: this.addForm.nd }).then(response => {
|
||||||
id: nextId,
|
this.lessonOptions = response.data || []
|
||||||
kcmc: this.form.kcmc,
|
this.lessonLoading = false
|
||||||
lx: this.form.lx,
|
this.lessonDialogVisible = true
|
||||||
jxsj: '2026-2027-1',
|
}).catch(() => {
|
||||||
sksj: this.form.sksj || '待定',
|
this.lessonLoading = false
|
||||||
zxkb: this.form.lx === '停课' ? '—' : (this.form.zxkb || '待定'),
|
this.$message.info('后端暂未提供可供调课课次接口,请手动填写课次编号')
|
||||||
jy: '-',
|
|
||||||
sqjy: this.form.sqjy || '-',
|
|
||||||
jxcd: '-',
|
|
||||||
dbbc: this.form.dbbc,
|
|
||||||
zxsj: this.getNow(),
|
|
||||||
bz: this.form.bz,
|
|
||||||
status: '0'
|
|
||||||
})
|
|
||||||
this.refreshStatCards()
|
|
||||||
this.submitLoading = false
|
|
||||||
this.dialogVisible = false
|
|
||||||
this.$message.success('申请已提交')
|
|
||||||
}, 300)
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getNow() {
|
pickLesson(row) {
|
||||||
const d = new Date()
|
this.addForm.sskcbbh = row.sskcbbh
|
||||||
const p = n => (n < 10 ? '0' + n : '' + n)
|
this.lessonDialogVisible = false
|
||||||
return d.getFullYear() + '-' + p(d.getMonth() + 1) + '-' + p(d.getDate())
|
this.$message.success('已选择课次:' + (row.kcmc || row.sskcbbh))
|
||||||
},
|
},
|
||||||
approve(row) {
|
submitAdd() {
|
||||||
row.status = '1'
|
this.$refs.addForm.validate(valid => {
|
||||||
this.refreshStatCards()
|
if (!valid) return
|
||||||
this.$message.success('已批准该申请')
|
const payload = {
|
||||||
|
sskcbbh: this.addForm.sskcbbh,
|
||||||
|
sy: this.addForm.sy,
|
||||||
|
rq: this.addForm.rq + 'T00:00:00',
|
||||||
|
jc: this.addForm.jc,
|
||||||
|
nd: this.addForm.nd,
|
||||||
|
sqjybh: this.addForm.sqjybh
|
||||||
|
}
|
||||||
|
;['jxnr', 'jxyd', 'jxff', 'jxbzbz', 'ycxx', 'bz'].forEach(key => {
|
||||||
|
if (this.addForm[key]) payload[key] = this.addForm[key]
|
||||||
|
})
|
||||||
|
this.addLoading = true
|
||||||
|
submitScheduleAdjust(payload).then(() => {
|
||||||
|
this.addLoading = false
|
||||||
|
this.addVisible = false
|
||||||
|
this.$message.success('申请提交成功')
|
||||||
|
this.loadList()
|
||||||
|
}).catch(() => {
|
||||||
|
this.addLoading = false
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
reject(row) {
|
/* ---------- 审批 ---------- */
|
||||||
row.status = '2'
|
showAuditMenu(row) {
|
||||||
this.refreshStatCards()
|
return row.sczt === 0 && (row.jyspzzt === 0 || row.jyspzzt === 1)
|
||||||
this.$message.warning('已驳回该申请')
|
|
||||||
},
|
},
|
||||||
removeRow(row) {
|
openAudit(row, role) {
|
||||||
this.$confirm('确认删除该申请?', '提示', { type: 'warning' })
|
const titleMap = { jys: '教研室审批', jxx: '教学系审批', jg: '机关审批' }
|
||||||
|
this.auditTitle = titleMap[role] || '审批'
|
||||||
|
this.auditForm = {
|
||||||
|
ssdksqbh: row.ssdksqbh,
|
||||||
|
auditRole: role,
|
||||||
|
spzt: 1,
|
||||||
|
fhyj: '',
|
||||||
|
sprbh: this.curUserName,
|
||||||
|
jgbh: ''
|
||||||
|
}
|
||||||
|
this.auditVisible = true
|
||||||
|
},
|
||||||
|
submitAudit() {
|
||||||
|
const f = this.auditForm
|
||||||
|
if (!f.sprbh) {
|
||||||
|
this.$message.warning('请填写审批人编号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (f.auditRole === 'jg' && !f.jgbh) {
|
||||||
|
this.$message.warning('请填写机关编号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const payload = {
|
||||||
|
ssdksqbh: f.ssdksqbh,
|
||||||
|
auditRole: f.auditRole,
|
||||||
|
spzt: f.spzt,
|
||||||
|
fhyj: f.fhyj,
|
||||||
|
sprbh: f.sprbh
|
||||||
|
}
|
||||||
|
if (f.jgbh) payload.jgbh = f.jgbh
|
||||||
|
const apiMap = {
|
||||||
|
jys: auditByTeachingOffice,
|
||||||
|
jxx: auditByTeachingDepartment,
|
||||||
|
jg: auditByAuthority
|
||||||
|
}
|
||||||
|
this.auditLoading = true
|
||||||
|
apiMap[f.auditRole](payload).then(() => {
|
||||||
|
this.auditLoading = false
|
||||||
|
this.auditVisible = false
|
||||||
|
this.$message.success('审批成功')
|
||||||
|
this.loadList()
|
||||||
|
}).catch(() => {
|
||||||
|
this.auditLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/* ---------- 查收 ---------- */
|
||||||
|
showReceiveMenu(row) {
|
||||||
|
return row.sczt === 0 && row.jyspzzt === 1
|
||||||
|
},
|
||||||
|
openReceive(row, type) {
|
||||||
|
this.receiveTitle = type === 'jys' ? '教研室查收' : '机关查收'
|
||||||
|
this.receiveForm = {
|
||||||
|
ssdksqbh: row.ssdksqbh,
|
||||||
|
type: type,
|
||||||
|
csrbh: this.curUserName,
|
||||||
|
jgbh: ''
|
||||||
|
}
|
||||||
|
this.receiveVisible = true
|
||||||
|
},
|
||||||
|
submitReceive() {
|
||||||
|
const f = this.receiveForm
|
||||||
|
if (!f.csrbh) {
|
||||||
|
this.$message.warning('请填写查收人编号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (f.type === 'jg' && !f.jgbh) {
|
||||||
|
this.$message.warning('请填写机关编号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const params = { ssdksqbh: f.ssdksqbh, csrbh: f.csrbh }
|
||||||
|
if (f.jgbh) params.jgbh = f.jgbh
|
||||||
|
const api = f.type === 'jys' ? receiveByTeachingOffice : receiveByAuthority
|
||||||
|
this.receiveLoading = true
|
||||||
|
api(params).then(() => {
|
||||||
|
this.receiveLoading = false
|
||||||
|
this.receiveVisible = false
|
||||||
|
this.$message.success('查收成功')
|
||||||
|
this.loadList()
|
||||||
|
}).catch(() => {
|
||||||
|
this.receiveLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/* ---------- 撤销 ---------- */
|
||||||
|
handleCancel(row) {
|
||||||
|
this.$confirm('确认撤销该调课申请?撤销后课次将恢复原时间。', '提示', { type: 'warning' })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.allData = this.allData.filter(i => i.id !== row.id)
|
cancelScheduleAdjust({ ssdksqbh: row.ssdksqbh, sqjybh: row.sqjybh }).then(() => {
|
||||||
this.refreshStatCards()
|
this.$message.success('撤销成功')
|
||||||
this.$message.success('删除成功')
|
this.loadList()
|
||||||
|
}).catch(() => {})
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
},
|
},
|
||||||
|
/* ---------- 详情 ---------- */
|
||||||
openDetail(row) {
|
openDetail(row) {
|
||||||
this.detailTarget = row
|
|
||||||
this.detailVisible = true
|
this.detailVisible = true
|
||||||
|
this.detailLoading = true
|
||||||
|
this.detailData = null
|
||||||
|
getScheduleAdjustDetail(row.ssdksqbh).then(response => {
|
||||||
|
this.detailData = response.data || {}
|
||||||
|
this.detailLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.detailData = null
|
||||||
|
this.detailLoading = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,6 +783,30 @@ export default {
|
|||||||
color: #f78989;
|
color: #f78989;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ops-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pick-lesson-btn {
|
||||||
|
margin-top: 6px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-section {
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
.sub-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 992px) {
|
@media (max-width: 992px) {
|
||||||
|
|||||||
@@ -5,9 +5,16 @@
|
|||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<div>
|
<div>
|
||||||
<div class="section-title">教学资源冲突检查</div>
|
<div class="section-title">教学资源冲突检查</div>
|
||||||
<div class="section-desc">2026年秋季学期教学资源冲突检查,可单独检查或执行全部检查</div>
|
<div class="section-desc">当前检查年度:{{ nd ? nd + ' 年' : '未选择' }},可单独检查或执行全部检查</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
|
<el-form inline class="toolbar-form" @submit.native.prevent>
|
||||||
|
<el-form-item label="年度" class="year-item">
|
||||||
|
<el-select v-model="nd" placeholder="请选择年度" style="width: 130px" @change="handleNdChange">
|
||||||
|
<el-option v-for="y in yearOptions" :key="y" :label="y + ' 年'" :value="y" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
<el-button size="mini" :disabled="loading" @click="handleReset">重置</el-button>
|
<el-button size="mini" :disabled="loading" @click="handleReset">重置</el-button>
|
||||||
<el-button type="primary" size="mini" :loading="loading" @click="handleCheckAll">执行全部检查</el-button>
|
<el-button type="primary" size="mini" :loading="loading" @click="handleCheckAll">执行全部检查</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,7 +27,7 @@
|
|||||||
:key="item.key"
|
:key="item.key"
|
||||||
class="check-item-card"
|
class="check-item-card"
|
||||||
:class="{ active: activeKey === item.key }"
|
:class="{ active: activeKey === item.key }"
|
||||||
@click="activeKey = item.checked ? item.key : activeKey"
|
@click="selectCard(item)"
|
||||||
>
|
>
|
||||||
<div class="check-item-header">
|
<div class="check-item-header">
|
||||||
<span class="check-item-name">{{ item.label }}</span>
|
<span class="check-item-name">{{ item.label }}</span>
|
||||||
@@ -45,145 +52,228 @@
|
|||||||
冲突明细
|
冲突明细
|
||||||
<span v-if="activeKey" class="active-label">— {{ activeLabel }}</span>
|
<span v-if="activeKey" class="active-label">— {{ activeLabel }}</span>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="activeKey" class="detail-count">共 {{ activeDetails.length }} 条记录</span>
|
<span v-if="activeKey" class="detail-count">共 {{ detailTotal }} 条记录</span>
|
||||||
</div>
|
</div>
|
||||||
<el-table v-if="activeKey" :data="activeDetails" border stripe size="mini" max-height="500">
|
<template v-if="activeKey">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table v-loading="detailLoading" :data="activeDetails" border stripe size="mini" max-height="500">
|
||||||
<el-table-column label="冲突号" width="80" align="center">
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<template slot-scope="scope">
|
<el-table-column label="冲突号" width="90" align="center" show-overflow-tooltip>
|
||||||
<el-tag type="danger" size="mini">#{{ Math.floor(scope.$index / 2) + 1 }}</el-tag>
|
<template slot-scope="scope">{{ scope.row.conflictNo || '-' }}</template>
|
||||||
</template>
|
</el-table-column>
|
||||||
</el-table-column>
|
<el-table-column prop="courseNames" label="课程" min-width="150" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="kcmc" label="课程" min-width="130" show-overflow-tooltip />
|
<el-table-column label="日期" width="100" align="center">
|
||||||
<el-table-column label="日期" width="100">
|
<template slot-scope="scope">{{ fmtDate(scope.row.rq) }}</template>
|
||||||
<template slot-scope="scope">{{ formatDateStr(scope.row.rq) }}</template>
|
</el-table-column>
|
||||||
</el-table-column>
|
<el-table-column prop="jc" label="节次" width="70" align="center" />
|
||||||
<el-table-column prop="jc" label="节次" width="70" align="center" />
|
<el-table-column prop="xydNames" label="班次" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="bc" label="班次" width="130" show-overflow-tooltip />
|
<el-table-column prop="teacherNames" label="教员" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="skjy" label="教员" width="90" />
|
<el-table-column prop="classroomNames" label="场地" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="jxcd" label="场地" width="130" show-overflow-tooltip />
|
<el-table-column prop="responsibleDept" label="责任单位" min-width="110" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="zrdw" label="责任单位" width="100" />
|
</el-table>
|
||||||
</el-table>
|
<el-pagination
|
||||||
|
v-if="detailTotal > 0"
|
||||||
|
class="detail-pagination"
|
||||||
|
background
|
||||||
|
layout="total, prev, pager, next"
|
||||||
|
:current-page="detailQuery.pageNum"
|
||||||
|
:page-size="detailQuery.pageSize"
|
||||||
|
:total="detailTotal"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
<el-empty v-if="detailTotal === 0 && !detailLoading" description="暂无冲突明细" />
|
||||||
|
</template>
|
||||||
<el-empty v-else v-show="!loading" description="点击上方卡片「检查」按钮,在此查看冲突明细" />
|
<el-empty v-else v-show="!loading" description="点击上方卡片「检查」按钮,在此查看冲突明细" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 教学计划静态示例数据(待对接 getTeachingPlanList 接口)
|
import { checkConflict, checkAllConflict, resetConflict, getConflictDetails } from '@/api/teachBusiness/timetableConflict'
|
||||||
const MOCK_PLANS = [
|
import { listAllSemester } from '@/api/teachBusiness/semester'
|
||||||
{ kcmc: '高等数学', rq: '2026-09-01', jc: 1, bc: '一班', skjy: '张教员', jxcd: '1号教学楼-101', zrdw: '基础部' },
|
|
||||||
{ kcmc: '高等数学', rq: '2026-09-01', jc: 1, bc: '一班', skjy: '张教员', jxcd: '1号教学楼-101', zrdw: '基础部' },
|
|
||||||
{ kcmc: '大学英语', rq: '2026-09-01', jc: 1, bc: '二班', skjy: '李教员', jxcd: '1号教学楼-101', zrdw: '基础部' },
|
|
||||||
{ kcmc: '大学英语', rq: '2026-09-02', jc: 3, bc: '二班', skjy: '李教员', jxcd: '2号教学楼-205', zrdw: '基础部' },
|
|
||||||
{ kcmc: '计算机基础', rq: '2026-09-01', jc: 1, bc: '三班', skjy: '王教员', jxcd: '实验楼-303', zrdw: '信息工程系' },
|
|
||||||
{ kcmc: '军事理论', rq: '2026-09-02', jc: 3, bc: '一班', skjy: '赵教员', jxcd: '3号教学楼-110', zrdw: '政工系' }
|
|
||||||
]
|
|
||||||
|
|
||||||
function formatDateStr(rq) {
|
// 四类检查卡片定义(标题/描述与后端 TimetableConflictDimension 枚举一致,作为页面布局常量;
|
||||||
return (rq || '').substring(0, 10)
|
// 检查状态与冲突数完全来自后端接口)
|
||||||
}
|
const CARD_DEFS = [
|
||||||
|
{ key: 'TEAM_CONFLICT', label: '教学班时间冲突检查', desc: '同一教学班次在同一时间段被安排多门课程' },
|
||||||
|
{ key: 'ELECTIVE_REQUIRED_CONFLICT', label: '教学班必修与选修时间冲突检查', desc: '教学班次必修课与选修课时间重叠' },
|
||||||
|
{ key: 'TEACHER_CONFLICT', label: '教员时间冲突检查', desc: '同一教员在同一时间段被安排多门课程' },
|
||||||
|
{ key: 'CLASSROOM_CONFLICT', label: '教室时间冲突检查', desc: '同一教室在同一时间段被多门课程占用' }
|
||||||
|
]
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TimetableConflict',
|
name: 'TimetableConflict',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
allRecords: [],
|
detailLoading: false,
|
||||||
|
// 年度(数据来自 /semester/all,真实后端数据)
|
||||||
|
nd: undefined,
|
||||||
|
yearOptions: [],
|
||||||
|
conflictItems: CARD_DEFS.map(c => ({ ...c, count: 0, checked: false })),
|
||||||
activeKey: '',
|
activeKey: '',
|
||||||
conflictItems: [
|
activeDetails: [],
|
||||||
{ key: 'jxbssj', label: '教学班次时间冲突检查', desc: '同一教学班次在同一时间段被安排多门课程', count: 0, checked: false, details: [] },
|
detailTotal: 0,
|
||||||
{ key: 'jxbskcsj', label: '教学班次必修与选修时间冲突检查', desc: '教学班次必修课与选修课时间重叠', count: 0, checked: false, details: [] },
|
detailQuery: { pageNum: 1, pageSize: 20 }
|
||||||
{ key: 'jysj', label: '教员时间冲突检查', desc: '同一教员在同一时间段被安排多门课程', count: 0, checked: false, details: [] },
|
|
||||||
{ key: 'jssj', label: '教室时间冲突检查', desc: '同一教室在同一时间段被多门课程占用', count: 0, checked: false, details: [] }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
activeLabel() {
|
activeLabel() {
|
||||||
const item = this.conflictItems.find(i => i.key === this.activeKey)
|
const item = this.conflictItems.find(i => i.key === this.activeKey)
|
||||||
return item ? item.label : ''
|
return item ? item.label : ''
|
||||||
},
|
|
||||||
// 当前选中检查项的展开明细(打平所有冲突记录)
|
|
||||||
activeDetails() {
|
|
||||||
const item = this.conflictItems.find(i => i.key === this.activeKey)
|
|
||||||
if (!item) return []
|
|
||||||
const flat = []
|
|
||||||
item.details.forEach(d => {
|
|
||||||
d.items.forEach(it => flat.push(it))
|
|
||||||
})
|
|
||||||
return flat
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 初始化演示数据(模拟接口返回)
|
this.loadYearOptions()
|
||||||
this.allRecords = MOCK_PLANS.map((item, index) => ({ ...item, xh: index + 1 }))
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/* ---------- 年度下拉(数据来自 /semester/all) ---------- */
|
||||||
|
loadYearOptions() {
|
||||||
|
return listAllSemester().then(response => {
|
||||||
|
const list = response.data || []
|
||||||
|
// 去重并按年度倒序
|
||||||
|
const map = {}
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.nd !== null && item.nd !== undefined && item.nd !== '') map[item.nd] = item
|
||||||
|
})
|
||||||
|
const arr = Object.keys(map).sort((a, b) => String(b).localeCompare(String(a)))
|
||||||
|
this.yearOptions = arr
|
||||||
|
// 默认年度:优先当前学期(dqxq=true),否则取最新年度
|
||||||
|
const current = list.find(item => item.dqxq === true)
|
||||||
|
this.nd = (current && current.nd) || arr[0]
|
||||||
|
return arr
|
||||||
|
}).catch(() => {
|
||||||
|
this.yearOptions = []
|
||||||
|
this.nd = undefined
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fmtDate(rq) {
|
||||||
|
return (rq || '').substring(0, 10)
|
||||||
|
},
|
||||||
getStatus(item) {
|
getStatus(item) {
|
||||||
if (!item.checked) return { type: 'info', text: '未检查' }
|
if (!item.checked) return { type: 'info', text: '未检查' }
|
||||||
return item.count > 0
|
return item.count > 0
|
||||||
? { type: 'danger', text: '存在 ' + item.count + ' 处冲突' }
|
? { type: 'danger', text: '存在 ' + item.count + ' 处冲突' }
|
||||||
: { type: 'success', text: '无冲突' }
|
: { type: 'success', text: '无冲突' }
|
||||||
},
|
},
|
||||||
/** 通用冲突检测:按分组字段找 > 1 的记录 */
|
/* 用后端返回的单卡片结果同步对应卡片状态 */
|
||||||
detectConflicts(records, groupFields) {
|
applyCard(card) {
|
||||||
const map = {}
|
if (!card) return
|
||||||
records.forEach(item => {
|
const item = this.conflictItems.find(i => i.key === card.dimensionCode)
|
||||||
const key = groupFields.map(f => f + '=' + (item[f] !== undefined && item[f] !== null ? item[f] : '')).join('|') +
|
if (!item) return
|
||||||
'|rq=' + formatDateStr(item.rq) + '|jc=' + (item.jc !== undefined && item.jc !== null ? item.jc : '')
|
item.checked = card.checked
|
||||||
if (!map[key]) map[key] = []
|
item.count = card.conflictCount
|
||||||
map[key].push(item)
|
|
||||||
})
|
|
||||||
return Object.keys(map)
|
|
||||||
.filter(k => map[k].length > 1)
|
|
||||||
.map(k => ({ key: k, items: map[k] }))
|
|
||||||
.sort((a, b) => a.key.localeCompare(b.key))
|
|
||||||
},
|
},
|
||||||
|
applySummary(summary) {
|
||||||
|
if (!summary || !summary.cards) return
|
||||||
|
summary.cards.forEach(card => this.applyCard(card))
|
||||||
|
},
|
||||||
|
/* ---------- 单个检查 ---------- */
|
||||||
handleCheck(item) {
|
handleCheck(item) {
|
||||||
if (this.allRecords.length === 0) return
|
if (!this.nd) {
|
||||||
let details = []
|
this.$message.warning('请先选择年度')
|
||||||
switch (item.key) {
|
return
|
||||||
case 'jxbssj':
|
|
||||||
details = this.detectConflicts(this.allRecords, ['bc'])
|
|
||||||
break
|
|
||||||
case 'jxbskcsj':
|
|
||||||
details = this.detectConflicts(this.allRecords, ['bc'])
|
|
||||||
break
|
|
||||||
case 'jysj':
|
|
||||||
details = this.detectConflicts(this.allRecords, ['skjy'])
|
|
||||||
break
|
|
||||||
case 'jssj':
|
|
||||||
details = this.detectConflicts(this.allRecords, ['jxcd'])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
item.details = details
|
|
||||||
item.count = details.length
|
|
||||||
item.checked = true
|
|
||||||
this.activeKey = item.key
|
|
||||||
if (item.count > 0) {
|
|
||||||
this.$message.warning('「' + item.label + '」发现 ' + item.count + ' 处冲突')
|
|
||||||
} else {
|
|
||||||
this.$message.success('「' + item.label + '」未发现冲突')
|
|
||||||
}
|
}
|
||||||
|
this.loading = true
|
||||||
|
checkConflict({ nd: this.nd, dimensionCode: item.key }).then(response => {
|
||||||
|
this.applyCard(response.data)
|
||||||
|
this.activeKey = item.key
|
||||||
|
this.detailQuery.pageNum = 1
|
||||||
|
this.loadDetails()
|
||||||
|
if (item.count > 0) {
|
||||||
|
this.$message.warning('「' + item.label + '」检查完成,发现 ' + item.count + ' 处冲突')
|
||||||
|
} else {
|
||||||
|
this.$message.success('「' + item.label + '」检查完成,未发现冲突')
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
/* ---------- 全部检查 ---------- */
|
||||||
handleCheckAll() {
|
handleCheckAll() {
|
||||||
this.conflictItems.forEach(item => this.handleCheck(item))
|
if (!this.nd) {
|
||||||
const firstConflict = this.conflictItems.find(i => i.count > 0)
|
this.$message.warning('请先选择年度')
|
||||||
if (firstConflict) {
|
return
|
||||||
this.activeKey = firstConflict.key
|
|
||||||
}
|
}
|
||||||
const total = this.conflictItems.reduce((sum, item) => sum + item.count, 0)
|
this.loading = true
|
||||||
this.$message.success('全部检查完成,共发现 ' + total + ' 处冲突')
|
checkAllConflict({ nd: this.nd }).then(response => {
|
||||||
|
const summary = response.data
|
||||||
|
this.applySummary(summary)
|
||||||
|
const total = summary ? summary.totalConflictCount : 0
|
||||||
|
this.$message.success('全部检查完成,共发现 ' + total + ' 处冲突')
|
||||||
|
const firstConflict = this.conflictItems.find(i => i.checked && i.count > 0)
|
||||||
|
const firstChecked = this.conflictItems.find(i => i.checked)
|
||||||
|
this.activeKey = firstConflict ? firstConflict.key : (firstChecked ? firstChecked.key : '')
|
||||||
|
this.detailQuery.pageNum = 1
|
||||||
|
if (this.activeKey) {
|
||||||
|
this.loadDetails()
|
||||||
|
} else {
|
||||||
|
this.activeDetails = []
|
||||||
|
this.detailTotal = 0
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
/* ---------- 重置 ---------- */
|
||||||
handleReset() {
|
handleReset() {
|
||||||
this.conflictItems.forEach(item => {
|
if (!this.nd) {
|
||||||
item.count = 0
|
this.$message.warning('请先选择年度')
|
||||||
item.checked = false
|
return
|
||||||
item.details = []
|
}
|
||||||
|
resetConflict({ nd: this.nd }).then(response => {
|
||||||
|
this.applySummary(response.data)
|
||||||
|
this.activeKey = ''
|
||||||
|
this.activeDetails = []
|
||||||
|
this.detailTotal = 0
|
||||||
|
this.$message.success('检查结果已重置')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/* 点击卡片:仅已检查的卡片可查看其明细 */
|
||||||
|
selectCard(item) {
|
||||||
|
if (!item.checked) return
|
||||||
|
this.activeKey = item.key
|
||||||
|
this.detailQuery.pageNum = 1
|
||||||
|
this.loadDetails()
|
||||||
|
},
|
||||||
|
/* ---------- 冲突明细 ---------- */
|
||||||
|
loadDetails() {
|
||||||
|
if (!this.activeKey) {
|
||||||
|
this.activeDetails = []
|
||||||
|
this.detailTotal = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.detailLoading = true
|
||||||
|
getConflictDetails({
|
||||||
|
nd: this.nd,
|
||||||
|
dimensionCode: this.activeKey,
|
||||||
|
pageNum: this.detailQuery.pageNum,
|
||||||
|
pageSize: this.detailQuery.pageSize
|
||||||
|
}).then(response => {
|
||||||
|
const page = response.data || {}
|
||||||
|
this.activeDetails = page.records || []
|
||||||
|
this.detailTotal = page.total || 0
|
||||||
|
}).catch(() => {
|
||||||
|
this.activeDetails = []
|
||||||
|
this.detailTotal = 0
|
||||||
|
}).finally(() => {
|
||||||
|
this.detailLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.detailQuery.pageNum = page
|
||||||
|
this.loadDetails()
|
||||||
|
},
|
||||||
|
/* 切换年度:该年度检查状态未知,重置为未检查 */
|
||||||
|
handleNdChange() {
|
||||||
|
this.conflictItems.forEach(i => {
|
||||||
|
i.checked = false
|
||||||
|
i.count = 0
|
||||||
})
|
})
|
||||||
this.activeKey = ''
|
this.activeKey = ''
|
||||||
this.$message.info('已重置检查结果')
|
this.activeDetails = []
|
||||||
|
this.detailTotal = 0
|
||||||
|
this.detailQuery.pageNum = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,6 +306,14 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
|
||||||
|
.toolbar-form {
|
||||||
|
margin-right: 4px;
|
||||||
|
|
||||||
|
.year-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,5 +408,10 @@ export default {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,100 +2,46 @@
|
|||||||
<div class="app-container training-plan-page">
|
<div class="app-container training-plan-page">
|
||||||
<!-- ==================== 1. 查询条件区域 ==================== -->
|
<!-- ==================== 1. 查询条件区域 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form :model="searchForm" label-width="120px" class="search-form">
|
<el-form :model="searchForm" label-width="100px" class="search-form" @submit.native.prevent>
|
||||||
<el-row :gutter="32">
|
<el-row :gutter="24">
|
||||||
<!-- 左栏 -->
|
<el-col :xs="24" :md="8">
|
||||||
<el-col :xs="24" :md="12">
|
|
||||||
<el-form-item label="专业名称">
|
<el-form-item label="专业名称">
|
||||||
<el-input v-model="searchForm.zymc" placeholder="请输入专业名称" clearable />
|
<el-input v-model="searchForm.zymc" placeholder="请输入专业名称(模糊)" clearable />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专业方向">
|
|
||||||
<el-input v-model="searchForm.zyfx" placeholder="请输入专业方向" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="searchForm.pxlxEnabled">培训类型</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="searchForm.pxlx" placeholder="请选择培训类型" clearable class="w-full"
|
|
||||||
:disabled="!searchForm.pxlxEnabled">
|
|
||||||
<el-option v-for="item in pxlxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="searchForm.pxccEnabled">培训层次</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="searchForm.pxcc" placeholder="请选择培训层次" clearable class="w-full"
|
|
||||||
:disabled="!searchForm.pxccEnabled">
|
|
||||||
<el-option v-for="item in pxccOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="自定义分类">
|
|
||||||
<el-input v-model="searchForm.zdyfl" placeholder="请输入自定义分类" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="searchForm.zgzyEnabled">主干专业</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="searchForm.zgzy" placeholder="请选择" clearable class="w-full"
|
|
||||||
:disabled="!searchForm.zgzyEnabled">
|
|
||||||
<el-option v-for="item in zgzyOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
<!-- 右栏 -->
|
|
||||||
<el-col :xs="24" :md="12">
|
|
||||||
<el-form-item label="专业代码">
|
<el-form-item label="专业代码">
|
||||||
<el-input v-model="searchForm.zydm" placeholder="请输入专业代码" clearable />
|
<el-input v-model="searchForm.zydm" placeholder="请输入专业代码(模糊)" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="学年制">
|
</el-col>
|
||||||
<el-input v-model="searchForm.xnz" placeholder="请输入学年制" clearable />
|
<el-col :xs="24" :md="8">
|
||||||
|
<el-form-item label="培训类型">
|
||||||
|
<el-input v-model="searchForm.pxlx" placeholder="请输入培训类型(精确)" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
</el-col>
|
||||||
<template slot="label">
|
<el-col :xs="24" :md="8">
|
||||||
<el-checkbox v-model="searchForm.pxlx2Enabled">培训类型2</el-checkbox>
|
<el-form-item label="培训层次">
|
||||||
</template>
|
<el-input v-model="searchForm.pxcc" placeholder="请输入培训层次(精确)" clearable />
|
||||||
<el-select v-model="searchForm.pxlx2" placeholder="请选择培训类型2" clearable class="w-full"
|
|
||||||
:disabled="!searchForm.pxlx2Enabled">
|
|
||||||
<el-option v-for="item in pxlx2Options" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template slot="label">
|
|
||||||
<el-checkbox v-model="searchForm.qyztEnabled">启用状态</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<el-radio-group v-model="searchForm.qyzt" :disabled="!searchForm.qyztEnabled">
|
|
||||||
<el-radio :label="'启用'">启用</el-radio>
|
|
||||||
<el-radio :label="'停用'">停用</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="大纲版本">
|
|
||||||
<el-input v-model="searchForm.zybb" placeholder="请输入大纲版本" clearable />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="培养目标">
|
|
||||||
<el-input v-model="searchForm.pymb" placeholder="请输入培养目标" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<div class="search-actions">
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="search-footer">
|
|
||||||
<div class="notice">注意:勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
<div class="search-actions">
|
|
||||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
|
||||||
<el-button @click="handleReset">重置</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 2. 操作与上传区域 ==================== -->
|
<!-- ==================== 2. 操作与上传区域 ==================== -->
|
||||||
<el-card shadow="never" class="action-card">
|
<el-card shadow="never" class="action-card">
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleOpenAdd">新建</el-button>
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新建</el-button>
|
||||||
<el-button icon="el-icon-download" @click="handleDownload">下载</el-button>
|
<el-button icon="el-icon-download" @click="handleDownload">下载</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<el-button type="primary" @click="handleTemplateDownload">【人才培养方案目录模板】下载</el-button>
|
<el-button icon="el-icon-download" @click="handleTemplateDownload">【人才培养方案目录模板】下载</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="upload-row">
|
<div class="upload-row">
|
||||||
<div class="upload-left">
|
<div class="upload-left">
|
||||||
@@ -114,237 +60,387 @@
|
|||||||
|
|
||||||
<!-- ==================== 3. 数据表格区域 ==================== -->
|
<!-- ==================== 3. 数据表格区域 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row
|
<div class="list-header">
|
||||||
@selection-change="handleSelectionChange">
|
<div class="list-title">人才培养方案列表</div>
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
</div>
|
||||||
<el-table-column prop="jxgljg" label="教学管理机构" show-overflow-tooltip />
|
<el-table v-loading="loading" :data="tableData" border stripe highlight-current-row>
|
||||||
<el-table-column prop="xkzyxx" label="学科专业信息" show-overflow-tooltip />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<el-table-column prop="rpyx" label="人培信息" width="180" show-overflow-tooltip />
|
<el-table-column prop="zydh" label="专业代号" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="fl" label="分类" align="center" />
|
<el-table-column prop="zymc" label="专业名称" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="xylb" label="学员类别" align="center" />
|
<el-table-column prop="zyfx" label="专业方向" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="xnz" label="学年制" align="center" />
|
<el-table-column prop="zydm" label="专业代码" min-width="110" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="xsfb" label="学时分布" align="center" />
|
<el-table-column prop="pxlx" label="培训类型" min-width="110" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="zt" label="状态" align="center" />
|
<el-table-column prop="pxcc" label="培训层次" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column prop="wjzl" label="文件资料" align="center" />
|
<el-table-column prop="pxlx2" label="培训类型2" min-width="110" show-overflow-tooltip header-align="center" />
|
||||||
<el-table-column label="操作" align="center" fixed="right" width="140">
|
<el-table-column prop="xylb" label="学员类别" min-width="100" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="xnz" label="学年制" min-width="80" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="xqs" label="学期数" width="80" align="center" />
|
||||||
|
<el-table-column prop="zybb" label="专业版本" min-width="100" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column label="主干专业" width="90" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtYesNo(scope.row.zgzy) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" width="80" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
|
<el-tag :type="isTrue(scope.row.ty) ? 'danger' : 'success'" size="mini">
|
||||||
<el-button type="text" style="color: #f56c6c" :disabled="scope.row.ty === 1 || scope.row.zt === '停用'"
|
{{ isTrue(scope.row.ty) ? '停用' : '启用' }}
|
||||||
@click="handleDisable(scope.row)">
|
</el-tag>
|
||||||
停用
|
</template>
|
||||||
</el-button>
|
</el-table-column>
|
||||||
|
<el-table-column label="启用时间" width="150" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtDateTime(scope.row.qysj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="停用时间" width="150" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtDateTime(scope.row.tysj) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="180" align="center" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-view" @click="handleDetail(scope.row)">详情</el-button>
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-circle-close" class="danger-text-btn"
|
||||||
|
:disabled="isTrue(scope.row.ty)" @click="handleDisable(scope.row)">停用</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-pagination
|
<el-pagination
|
||||||
|
class="pagination"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
:current-page="pageNum"
|
:current-page="pageNum"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
class="pagination-wrapper"
|
|
||||||
@current-change="handlePageChange"
|
|
||||||
@size-change="handleSizeChange"
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<el-dialog :visible.sync="dialogVisible" :title="dialogTitle" width="1000px" :align-center="true"
|
<el-dialog :title="dialog.title" :visible.sync="dialog.visible" width="860px" append-to-body
|
||||||
:destroy-on-close="true">
|
:close-on-click-modal="false">
|
||||||
<div v-loading="editLoading">
|
<el-form ref="trainingForm" :model="dialog.form" :rules="rules" label-width="130px">
|
||||||
<el-form ref="addFormRef" :model="addForm" :rules="rules" label-width="140px" class="add-form">
|
<el-row :gutter="20">
|
||||||
<el-row :gutter="20">
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="专业代号" prop="zydh">
|
||||||
<el-form-item label="专业代号" prop="zydh">
|
<el-input v-model="dialog.form.zydh" placeholder="请输入专业代号(主键)" :disabled="dialog.isEdit" />
|
||||||
<el-input v-model="addForm.zydh" placeholder="请输入专业代号" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="专业名称" prop="zymc">
|
||||||
<el-form-item label="专业名称" prop="zymc">
|
<el-input v-model="dialog.form.zymc" placeholder="请输入专业名称" />
|
||||||
<el-input v-model="addForm.zymc" placeholder="请输入专业名称" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="专业代码" prop="zydm">
|
||||||
<el-form-item label="专业方向">
|
<el-input v-model="dialog.form.zydm" placeholder="请输入专业代码" />
|
||||||
<el-input v-model="addForm.zyfx" placeholder="请输入专业方向" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="专业方向">
|
||||||
<el-form-item label="专业代码" prop="zydm">
|
<el-input v-model="dialog.form.zyfx" placeholder="请输入专业方向" />
|
||||||
<el-input v-model="addForm.zydm" placeholder="请输入专业代码" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="培训层次" prop="pxcc">
|
||||||
<el-form-item label="专业版本">
|
<el-input v-model="dialog.form.pxcc" placeholder="请输入培训层次" />
|
||||||
<el-input v-model="addForm.zybb" placeholder="请输入专业版本" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="培训类型" prop="pxlx">
|
||||||
<el-form-item label="培训层次" prop="pxcc">
|
<el-input v-model="dialog.form.pxlx" placeholder="请输入培训类型" />
|
||||||
<el-input v-model="addForm.pxcc" placeholder="硕士研究生/博士研究生/本科" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="培训类型2">
|
||||||
<el-form-item label="培训类型" prop="pxlx">
|
<el-input v-model="dialog.form.pxlx2" placeholder="请输入培训类型2" />
|
||||||
<el-input v-model="addForm.pxlx" placeholder="学历教育/非学历教育" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="学员类别">
|
||||||
<el-form-item label="培训类型2">
|
<el-input v-model="dialog.form.xylb" placeholder="请输入学员类别" />
|
||||||
<el-input v-model="addForm.pxlx2" placeholder="全日制/非全日制" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="学年制">
|
||||||
<el-form-item label="学员类别">
|
<el-input v-model="dialog.form.xnz" placeholder="请输入学年制" />
|
||||||
<el-input v-model="addForm.xylb" placeholder="请输入学员类别" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="学期数">
|
||||||
<el-form-item label="学年制">
|
<el-input-number v-model="dialog.form.xqs" :min="1" :max="20" controls-position="right" class="w-full" />
|
||||||
<el-input v-model="addForm.xnz" placeholder="两年半/三年/四年" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="专业版本">
|
||||||
<el-form-item label="学期数">
|
<el-input v-model="dialog.form.zybb" placeholder="请输入专业版本" />
|
||||||
<el-input-number v-model="addForm.xqs" :min="1" :max="12" class="w-full" />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="自定义分类">
|
||||||
<el-form-item label="自定义分类">
|
<el-input v-model="dialog.form.zdyfl" placeholder="请输入自定义分类" />
|
||||||
<el-input v-model="addForm.zdyfl" placeholder="兵器类/电子信息类" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="教学管理机构编号">
|
||||||
<el-form-item label="教学管理机构编号">
|
<el-input v-model="dialog.form.jxgljgbh" placeholder="请输入教学管理机构编号" />
|
||||||
<el-input v-model="addForm.jxgljgbh" placeholder="请输入" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="规范名称">
|
||||||
<el-form-item label="规范名称">
|
<el-input v-model="dialog.form.gfmc" placeholder="请输入规范名称" />
|
||||||
<el-input v-model="addForm.gfmc" placeholder="请输入规范名称" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="专业规范">
|
||||||
<el-form-item label="专业备注">
|
<el-input v-model="dialog.form.zygf" placeholder="请输入专业规范" />
|
||||||
<el-input v-model="addForm.zybz" placeholder="请输入备注" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
<el-col :span="24">
|
<el-form-item label="简称">
|
||||||
<el-form-item label="培养目标" prop="pymb">
|
<el-input v-model="dialog.form.jc" placeholder="请输入简称" />
|
||||||
<el-input v-model="addForm.pymb" type="textarea" :rows="3" placeholder="请输入培养目标" />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="12">
|
||||||
</el-row>
|
<el-form-item label="主干专业">
|
||||||
</el-form>
|
<el-radio-group v-model="dialog.form.zgzy">
|
||||||
|
<el-radio :label="true">是</el-radio>
|
||||||
|
<el-radio :label="false">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="专业备注">
|
||||||
|
<el-input v-model="dialog.form.zybz" placeholder="请输入专业备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="培养目标">
|
||||||
|
<el-input v-model="dialog.form.pymb" type="textarea" :rows="3" placeholder="请输入培养目标" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialog.visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="dialog.submitting" @click="submitDialog">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 详情弹窗 -->
|
||||||
|
<el-dialog title="人才培养方案详情" :visible.sync="detail.visible" width="760px" append-to-body
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<div v-loading="detail.loading" class="detail-body">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="专业代号">{{ fmtVal(detail.data.zydh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业名称">{{ fmtVal(detail.data.zymc) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业代码">{{ fmtVal(detail.data.zydm) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业方向">{{ fmtVal(detail.data.zyfx) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培训类型">{{ fmtVal(detail.data.pxlx) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培训层次">{{ fmtVal(detail.data.pxcc) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培训类型2">{{ fmtVal(detail.data.pxlx2) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学员类别">{{ fmtVal(detail.data.xylb) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学年制">{{ fmtVal(detail.data.xnz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学期数">{{ fmtVal(detail.data.xqs) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业版本">{{ fmtVal(detail.data.zybb) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="主干专业">{{ fmtYesNo(detail.data.zgzy) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="自定义分类">{{ fmtVal(detail.data.zdyfl) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学管理机构编号">{{ fmtVal(detail.data.jxgljgbh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="规范名称">{{ fmtVal(detail.data.gfmc) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业规范">{{ fmtVal(detail.data.zygf) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="简称">{{ fmtVal(detail.data.jc) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业标识号">{{ fmtVal(detail.data.zybsh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="学科专业信息标识号">{{ fmtVal(detail.data.xkzyxxbsh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教学大纲编号">{{ fmtVal(detail.data.jxdgbh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="人培编号">{{ fmtVal(detail.data.rpbh) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="节次类别">{{ fmtVal(detail.data.jclb) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="系统模式">{{ fmtVal(detail.data.xtms) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="启用时间">{{ fmtDateTime(detail.data.qysj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="停用时间">{{ fmtDateTime(detail.data.tysj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="专业备注" :span="2">{{ fmtVal(detail.data.zybz) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="培养目标" :span="2">{{ fmtVal(detail.data.pymb) }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="handleCancel">取消</el-button>
|
<el-button @click="detail.visible = false">关 闭</el-button>
|
||||||
<el-button type="primary" :loading="addLoading" @click="handleSubmit">保存</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 各下拉框选项:数据待后端接口返回后替换
|
import {
|
||||||
const PXLX_OPTIONS = [] // 培训类型
|
addTraining,
|
||||||
const PXCC_OPTIONS = [] // 培训层次
|
disableTraining,
|
||||||
const ZGZY_OPTIONS = [] // 主干专业
|
updateTraining,
|
||||||
const PXLX2_OPTIONS = [] // 培训类型2
|
getTraining,
|
||||||
|
listTraining
|
||||||
|
} from '@/api/teachBusiness/training'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TrainingPlan',
|
name: 'TrainingPlan',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
options: {
|
loading: false,
|
||||||
pxlx: PXLX_OPTIONS,
|
// 查询条件(仅传后端 ZYBMapper 支持的字段)
|
||||||
pxcc: PXCC_OPTIONS,
|
|
||||||
zgzy: ZGZY_OPTIONS,
|
|
||||||
pxlx2: PXLX2_OPTIONS
|
|
||||||
},
|
|
||||||
// 查询条件
|
|
||||||
searchForm: {
|
searchForm: {
|
||||||
zymc: '', zyfx: '',
|
zymc: '',
|
||||||
pxlxEnabled: false, pxlx: '',
|
zydm: '',
|
||||||
pxccEnabled: false, pxcc: '',
|
pxlx: '',
|
||||||
zdyfl: '',
|
pxcc: ''
|
||||||
zgzyEnabled: false, zgzy: '',
|
|
||||||
zydm: '', xnz: '',
|
|
||||||
pxlx2Enabled: false, pxlx2: '',
|
|
||||||
qyztEnabled: false, qyzt: '启用',
|
|
||||||
zybb: '', pymb: ''
|
|
||||||
},
|
},
|
||||||
// 列表
|
// 列表
|
||||||
loading: false,
|
|
||||||
tableData: [],
|
tableData: [],
|
||||||
selectedRows: [],
|
|
||||||
total: 0,
|
total: 0,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 20,
|
||||||
// 上传
|
// 上传
|
||||||
selectedFile: null,
|
selectedFile: null,
|
||||||
fileName: '',
|
fileName: '',
|
||||||
// 新增/编辑弹窗
|
// 新增/编辑弹窗
|
||||||
dialogVisible: false,
|
dialog: {
|
||||||
dialogTitle: '新建',
|
visible: false,
|
||||||
editLoading: false,
|
title: '',
|
||||||
addLoading: false,
|
isEdit: false,
|
||||||
addForm: {
|
submitting: false,
|
||||||
zydh: '', zymc: '', zyfx: '', zydm: '', zybb: '', pxcc: '', pxlx: '',
|
form: this.createEmptyForm()
|
||||||
pxlx2: '', xylb: '', xnz: '', xqs: 1, zdyfl: '', jxgljgbh: '',
|
},
|
||||||
gfmc: '', zybz: '', pymb: ''
|
// 详情弹窗
|
||||||
|
detail: {
|
||||||
|
visible: false,
|
||||||
|
loading: false,
|
||||||
|
data: {}
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
zydh: [{ required: true, message: '请输入专业代号', trigger: 'blur' }],
|
zydh: [{ required: true, message: '请输入专业代号', trigger: 'blur' }],
|
||||||
zymc: [{ required: true, message: '请输入专业名称', trigger: 'blur' }],
|
zymc: [{ required: true, message: '请输入专业名称', trigger: 'blur' }],
|
||||||
zydm: [{ required: true, message: '请输入专业代码', trigger: 'blur' }],
|
zydm: [{ required: true, message: '请输入专业代码', trigger: 'blur' }],
|
||||||
pxcc: [{ required: true, message: '请输入培训层次', trigger: 'blur' }],
|
pxcc: [{ required: true, message: '请输入培训层次', trigger: 'blur' }],
|
||||||
pxlx: [{ required: true, message: '请输入培训类型', trigger: 'blur' }],
|
pxlx: [{ required: true, message: '请输入培训类型', trigger: 'blur' }]
|
||||||
pymb: [{ required: true, message: '请输入培养目标', trigger: 'blur' }]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
pxlxOptions() { return this.options.pxlx },
|
|
||||||
pxccOptions() { return this.options.pxcc },
|
|
||||||
zgzyOptions() { return this.options.zgzy },
|
|
||||||
pxlx2Options() { return this.options.pxlx2 }
|
|
||||||
},
|
|
||||||
created() {
|
created() {
|
||||||
// TODO: 待后端接口,拉取下拉选项与列表
|
this.fetchList()
|
||||||
// this.loadOptions()
|
|
||||||
// this.getList()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询 */
|
/* ---------- 列表加载 ---------- */
|
||||||
handleSearch() {
|
fetchList() {
|
||||||
// TODO: 调用查询接口
|
this.loading = true
|
||||||
},
|
const params = {
|
||||||
/** 重置 */
|
pageNum: this.pageNum,
|
||||||
handleReset() {
|
pageSize: this.pageSize
|
||||||
this.searchForm = {
|
|
||||||
zymc: '', zyfx: '', pxlxEnabled: false, pxlx: '',
|
|
||||||
pxccEnabled: false, pxcc: '', zdyfl: '', zgzyEnabled: false, zgzy: '',
|
|
||||||
zydm: '', xnz: '', pxlx2Enabled: false, pxlx2: '',
|
|
||||||
qyztEnabled: false, qyzt: '启用', zybb: '', pymb: ''
|
|
||||||
}
|
}
|
||||||
|
Object.keys(this.searchForm).forEach(key => {
|
||||||
|
const value = this.searchForm[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
listTraining(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/** 新建 */
|
|
||||||
handleOpenAdd() {
|
/* ---------- 查询 / 重置 ---------- */
|
||||||
// TODO: 打开新建对话框
|
handleQuery() {
|
||||||
this.dialogVisible = true
|
this.pageNum = 1
|
||||||
this.dialogTitle = '新建人才培养方案'
|
this.fetchList()
|
||||||
},
|
},
|
||||||
/** 下载 */
|
handleReset() {
|
||||||
|
this.searchForm = { zymc: '', zydm: '', pxlx: '', pxcc: '' }
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 分页 ---------- */
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.pageSize = size
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.pageNum = page
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 新增 / 编辑 ---------- */
|
||||||
|
handleAdd() {
|
||||||
|
this.dialog.title = '新建人才培养方案'
|
||||||
|
this.dialog.isEdit = false
|
||||||
|
this.dialog.form = this.createEmptyForm()
|
||||||
|
this.dialog.visible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.trainingForm) this.$refs.trainingForm.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
this.dialog.title = '编辑人才培养方案'
|
||||||
|
this.dialog.isEdit = true
|
||||||
|
this.dialog.form = Object.assign({}, this.createEmptyForm(), row)
|
||||||
|
this.dialog.visible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.trainingForm) this.$refs.trainingForm.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
submitDialog() {
|
||||||
|
this.$refs.trainingForm.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
this.dialog.submitting = true
|
||||||
|
const payload = this.cleanPayload(this.dialog.form)
|
||||||
|
const isEdit = this.dialog.isEdit
|
||||||
|
const req = isEdit ? updateTraining(payload) : addTraining(payload)
|
||||||
|
req.then(() => {
|
||||||
|
this.$message.success(isEdit ? '修改成功' : '新增成功')
|
||||||
|
this.dialog.visible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.dialog.submitting = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 详情 ---------- */
|
||||||
|
handleDetail(row) {
|
||||||
|
this.detail.visible = true
|
||||||
|
this.detail.loading = true
|
||||||
|
this.detail.data = {}
|
||||||
|
getTraining(row.zydh).then(response => {
|
||||||
|
this.detail.data = response.data || {}
|
||||||
|
}).catch(() => {
|
||||||
|
this.detail.data = {}
|
||||||
|
}).finally(() => {
|
||||||
|
this.detail.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 停用(逻辑删除) ---------- */
|
||||||
|
handleDisable(row) {
|
||||||
|
this.$confirm('确定停用人才培养方案「' + (row.zymc || row.zydh) + '」吗?停用后列表不再展示。', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return disableTraining(row.zydh)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('停用成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 下载 / 模板下载 / 上传(后端未提供接口) ---------- */
|
||||||
handleDownload() {
|
handleDownload() {
|
||||||
// TODO: 列表数据下载
|
this.$message.warning('后端暂未提供该接口')
|
||||||
},
|
},
|
||||||
/** 模板下载 */
|
|
||||||
handleTemplateDownload() {
|
handleTemplateDownload() {
|
||||||
// TODO: 模板下载
|
this.$message.warning('后端暂未提供该接口')
|
||||||
},
|
},
|
||||||
/** 选择文件 */
|
|
||||||
handleChooseFile() {
|
handleChooseFile() {
|
||||||
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
||||||
},
|
},
|
||||||
@@ -352,76 +448,78 @@ export default {
|
|||||||
const file = e.target.files && e.target.files[0]
|
const file = e.target.files && e.target.files[0]
|
||||||
this.selectedFile = file || null
|
this.selectedFile = file || null
|
||||||
this.fileName = file ? file.name : ''
|
this.fileName = file ? file.name : ''
|
||||||
// TODO: 校验文件类型后保留
|
|
||||||
},
|
},
|
||||||
/** 上传数据 */
|
|
||||||
handleUpload() {
|
handleUpload() {
|
||||||
// TODO: 上传接口(上传 selectedFile)
|
this.$message.warning('后端暂未提供该接口')
|
||||||
},
|
},
|
||||||
/** 表格多选 */
|
|
||||||
handleSelectionChange(rows) {
|
/* ---------- 工具 ---------- */
|
||||||
this.selectedRows = rows
|
createEmptyForm() {
|
||||||
|
return {
|
||||||
|
zydh: '',
|
||||||
|
zymc: '',
|
||||||
|
zyfx: '',
|
||||||
|
zydm: '',
|
||||||
|
pxcc: '',
|
||||||
|
pxlx: '',
|
||||||
|
pxlx2: '',
|
||||||
|
xylb: '',
|
||||||
|
xnz: '',
|
||||||
|
xqs: null,
|
||||||
|
zybb: '',
|
||||||
|
zdyfl: '',
|
||||||
|
jxgljgbh: '',
|
||||||
|
gfmc: '',
|
||||||
|
zygf: '',
|
||||||
|
jc: '',
|
||||||
|
zgzy: false,
|
||||||
|
zybz: '',
|
||||||
|
pymb: ''
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/** 编辑 */
|
/** 移除空值(''/null/undefined),保留 0/false 等有效值 */
|
||||||
handleEdit(row) {
|
cleanPayload(obj) {
|
||||||
// TODO: 回填并打开编辑对话框
|
const payload = {}
|
||||||
this.dialogVisible = true
|
Object.keys(obj).forEach(key => {
|
||||||
this.dialogTitle = '编辑人才培养方案'
|
const value = obj[key]
|
||||||
},
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
/** 停用 */
|
payload[key] = value
|
||||||
handleDisable(row) {
|
}
|
||||||
// TODO: 停用接口
|
|
||||||
},
|
|
||||||
/** 分页 */
|
|
||||||
handlePageChange(val) {
|
|
||||||
this.pageNum = val
|
|
||||||
// TODO: 重新查询
|
|
||||||
},
|
|
||||||
handleSizeChange(val) {
|
|
||||||
this.pageSize = val
|
|
||||||
// TODO: 重新查询
|
|
||||||
},
|
|
||||||
/** 取消 */
|
|
||||||
handleCancel() {
|
|
||||||
this.dialogVisible = false
|
|
||||||
this.$refs.addFormRef && this.$refs.addFormRef.clearValidate()
|
|
||||||
},
|
|
||||||
/** 保存 */
|
|
||||||
handleSubmit() {
|
|
||||||
this.$refs.addFormRef.validate(valid => {
|
|
||||||
if (!valid) return
|
|
||||||
// TODO: 新增/编辑接口
|
|
||||||
this.dialogVisible = false
|
|
||||||
})
|
})
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
isTrue(val) {
|
||||||
|
return val === true || val === 1 || val === '1' || val === 'true'
|
||||||
|
},
|
||||||
|
fmtYesNo(val) {
|
||||||
|
return this.isTrue(val) ? '是' : '否'
|
||||||
|
},
|
||||||
|
fmtDateTime(val) {
|
||||||
|
return (val || '').substring(0, 19) || '-'
|
||||||
|
},
|
||||||
|
fmtVal(val) {
|
||||||
|
return val === '' || val === null || val === undefined ? '-' : val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.app-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.training-plan-page {
|
.training-plan-page {
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
|
||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-footer {
|
.search-actions {
|
||||||
display: flex;
|
padding-top: 4px;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 12px;
|
|
||||||
margin-top: 8px;
|
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
|
|
||||||
.notice {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #909399;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,10 +564,35 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.table-card {
|
.table-card {
|
||||||
.pagination-wrapper {
|
.list-header {
|
||||||
margin-top: 14px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.list-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 16px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-body {
|
||||||
|
min-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-text-btn {
|
||||||
|
color: #f56c6c;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #f78989;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,13 +1,444 @@
|
|||||||
<template>
|
<template>
|
||||||
<placeholder-page title="教学场地" icon="build" description="维护教学楼、教室、实验室等教学场地资源,支持场地类型、容量与使用状态管理。" />
|
<div class="app-container venue-page">
|
||||||
|
<!-- 查询条件 -->
|
||||||
|
<el-card shadow="never" class="search-card">
|
||||||
|
<el-form :model="searchForm" label-width="100px" class="search-form" @submit.native.prevent>
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<el-form-item label="教室编号">
|
||||||
|
<el-input v-model="searchForm.jsbh" placeholder="请输入教室编号" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<el-form-item label="教室名称">
|
||||||
|
<el-input v-model="searchForm.jsmc" placeholder="请输入教室名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<el-form-item label="教学楼代号">
|
||||||
|
<el-input v-model="searchForm.jxldh" placeholder="请输入教学楼代号" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<el-form-item label="教学场地类型">
|
||||||
|
<el-select v-model="searchForm.jxcdlx" placeholder="请选择场地类型" clearable filterable allow-create
|
||||||
|
default-first-option class="w-full">
|
||||||
|
<el-option v-for="item in jxcdlxOptions" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<el-form-item label="停用">
|
||||||
|
<el-select v-model="searchForm.ty" placeholder="全部" clearable class="w-full">
|
||||||
|
<el-option :value="true" label="停用" />
|
||||||
|
<el-option :value="false" label="正常" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :md="8">
|
||||||
|
<div class="search-actions">
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 数据列表 -->
|
||||||
|
<el-card shadow="never" class="table-card">
|
||||||
|
<div class="list-header">
|
||||||
|
<div class="list-title">教室列表</div>
|
||||||
|
<div class="list-actions">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-table v-loading="loading" :data="tableData" border stripe highlight-current-row>
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
|
<el-table-column prop="jsbh" label="教室编号" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="jsmc" label="教室名称" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="jxldh" label="教学楼代号" min-width="110" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="jxcdlx" label="教学场地类型" min-width="120" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="jc" label="简称" min-width="90" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column prop="rnrs" label="容纳人数" width="90" align="center" />
|
||||||
|
<el-table-column prop="mj" label="面积" width="90" align="center" />
|
||||||
|
<el-table-column prop="ksrnrs" label="考试容纳人数" width="110" align="center" />
|
||||||
|
<el-table-column prop="ewyxkbs" label="额外可开班数" width="100" align="center" />
|
||||||
|
<el-table-column label="虚实类型" width="90" align="center">
|
||||||
|
<template slot-scope="scope">{{ fmtXslx(scope.row.xslx) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="停用" width="80" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="isTrue(scope.row.ty) ? 'danger' : 'success'" size="mini">
|
||||||
|
{{ isTrue(scope.row.ty) ? '停用' : '正常' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="sssb" label="设施设备" min-width="140" show-overflow-tooltip header-align="center" />
|
||||||
|
<el-table-column label="操作" width="140" align="center" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||||
|
<el-button type="text" size="mini" icon="el-icon-delete" class="danger-text-btn" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
class="pagination"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next"
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 新增/编辑弹窗 -->
|
||||||
|
<el-dialog :title="dialog.title" :visible.sync="dialog.visible" width="780px" append-to-body
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<el-form ref="classroomForm" :model="dialog.form" :rules="rules" label-width="110px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="主键编号" prop="id">
|
||||||
|
<el-input v-model="dialog.form.id" placeholder="请输入主键编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="教室编号" prop="jsbh">
|
||||||
|
<el-input v-model="dialog.form.jsbh" placeholder="请输入教室编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="教室名称" prop="jsmc">
|
||||||
|
<el-input v-model="dialog.form.jsmc" placeholder="请输入教室名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="教学楼代号">
|
||||||
|
<el-input v-model="dialog.form.jxldh" placeholder="请输入教学楼代号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="教学场地类型">
|
||||||
|
<el-select v-model="dialog.form.jxcdlx" placeholder="请选择场地类型" clearable filterable allow-create
|
||||||
|
default-first-option class="w-full">
|
||||||
|
<el-option v-for="item in jxcdlxOptions" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="简称">
|
||||||
|
<el-input v-model="dialog.form.jc" placeholder="请输入简称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="容纳人数">
|
||||||
|
<el-input-number v-model="dialog.form.rnrs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="面积">
|
||||||
|
<el-input-number v-model="dialog.form.mj" :min="0" :precision="1" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="考试容纳人数">
|
||||||
|
<el-input-number v-model="dialog.form.ksrnrs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="额外可开班数">
|
||||||
|
<el-input-number v-model="dialog.form.ewyxkbs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="序号">
|
||||||
|
<el-input v-model="dialog.form.xh" placeholder="请输入序号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="拼音">
|
||||||
|
<el-input v-model="dialog.form.py" placeholder="请输入拼音" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="虚实类型">
|
||||||
|
<el-radio-group v-model="dialog.form.xslx">
|
||||||
|
<el-radio :label="true">实教</el-radio>
|
||||||
|
<el-radio :label="false">非实教</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="停用">
|
||||||
|
<el-radio-group v-model="dialog.form.ty">
|
||||||
|
<el-radio :label="false">正常</el-radio>
|
||||||
|
<el-radio :label="true">停用</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="设施设备">
|
||||||
|
<el-input v-model="dialog.form.sssb" placeholder="请输入设施设备" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="dialog.form.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialog.visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="dialog.submitting" @click="submitDialog">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PlaceholderPage from '@/components/PlaceholderPage'
|
import {
|
||||||
|
addClassroom,
|
||||||
|
deleteClassroom,
|
||||||
|
updateClassroom,
|
||||||
|
listClassroom
|
||||||
|
} from '@/api/teachBusiness/classroom'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Venue',
|
name: 'Venue',
|
||||||
components: { PlaceholderPage }
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
searchForm: {
|
||||||
|
jsbh: '',
|
||||||
|
jsmc: '',
|
||||||
|
jxldh: '',
|
||||||
|
jxcdlx: '',
|
||||||
|
ty: ''
|
||||||
|
},
|
||||||
|
tableData: [],
|
||||||
|
total: 0,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
dialog: {
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
|
submitting: false,
|
||||||
|
form: this.createEmptyForm()
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
id: [{ required: true, message: '请输入主键编号', trigger: 'blur' }],
|
||||||
|
jsbh: [{ required: true, message: '请输入教室编号', trigger: 'blur' }],
|
||||||
|
jsmc: [{ required: true, message: '请输入教室名称', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
/** 教学场地类型下拉:由已加载数据中的去重值动态生成,避免硬编码 */
|
||||||
|
jxcdlxOptions() {
|
||||||
|
const set = new Set()
|
||||||
|
this.tableData.forEach(row => {
|
||||||
|
if (row.jxcdlx) set.add(row.jxcdlx)
|
||||||
|
})
|
||||||
|
return Array.from(set)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/* ---------- 列表加载 ---------- */
|
||||||
|
fetchList() {
|
||||||
|
this.loading = true
|
||||||
|
const params = {
|
||||||
|
pageNum: this.pageNum,
|
||||||
|
pageSize: this.pageSize
|
||||||
|
}
|
||||||
|
Object.keys(this.searchForm).forEach(key => {
|
||||||
|
const value = this.searchForm[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
listClassroom(params).then(response => {
|
||||||
|
const data = response.data || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 查询 / 重置 ---------- */
|
||||||
|
handleQuery() {
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
handleReset() {
|
||||||
|
this.searchForm = {
|
||||||
|
jsbh: '',
|
||||||
|
jsmc: '',
|
||||||
|
jxldh: '',
|
||||||
|
jxcdlx: '',
|
||||||
|
ty: ''
|
||||||
|
}
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 分页 ---------- */
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.pageSize = size
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.pageNum = page
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 新增 / 编辑 ---------- */
|
||||||
|
handleAdd() {
|
||||||
|
this.dialog.title = '新增教室'
|
||||||
|
this.dialog.form = this.createEmptyForm()
|
||||||
|
this.dialog.visible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.classroomForm) this.$refs.classroomForm.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
this.dialog.title = '编辑教室'
|
||||||
|
this.dialog.form = Object.assign({}, this.createEmptyForm(), row)
|
||||||
|
this.dialog.visible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.classroomForm) this.$refs.classroomForm.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
submitDialog() {
|
||||||
|
this.$refs.classroomForm.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
this.dialog.submitting = true
|
||||||
|
const payload = this.cleanPayload(this.dialog.form)
|
||||||
|
const isEdit = !!payload.id
|
||||||
|
const req = isEdit ? updateClassroom(payload) : addClassroom(payload)
|
||||||
|
req.then(() => {
|
||||||
|
this.$message.success(isEdit ? '修改成功' : '新增成功')
|
||||||
|
this.dialog.visible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.dialog.submitting = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 删除(后端仅提供单条删除,参数为 id) ---------- */
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm('确定删除教室「' + (row.jsmc || row.jsbh) + '」吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
return deleteClassroom(row.id)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 工具 ---------- */
|
||||||
|
createEmptyForm() {
|
||||||
|
return {
|
||||||
|
id: '',
|
||||||
|
jsbh: '',
|
||||||
|
jsmc: '',
|
||||||
|
jxldh: '',
|
||||||
|
jxcdlx: '',
|
||||||
|
jc: '',
|
||||||
|
rnrs: null,
|
||||||
|
mj: null,
|
||||||
|
ksrnrs: null,
|
||||||
|
ewyxkbs: null,
|
||||||
|
xh: '',
|
||||||
|
py: '',
|
||||||
|
xslx: false,
|
||||||
|
ty: false,
|
||||||
|
sssb: '',
|
||||||
|
bz: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 移除空值(''/null/undefined),保留 0/false 等有效值 */
|
||||||
|
cleanPayload(obj) {
|
||||||
|
const payload = {}
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
payload[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
isTrue(val) {
|
||||||
|
return val === true || val === 1 || val === '1' || val === 'true'
|
||||||
|
},
|
||||||
|
fmtXslx(val) {
|
||||||
|
return this.isTrue(val) ? '实教' : '非实教'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.app-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.venue-page {
|
||||||
|
.search-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-actions {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-card {
|
||||||
|
.list-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.list-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 16px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-text-btn {
|
||||||
|
color: #f56c6c;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #f78989;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="notice">注意:勾选"选择框"表示启用该项对应的查询条件;文本输入框非空白表示启用对应的查询条件。</div>
|
|
||||||
<div class="query-footer">
|
<div class="query-footer">
|
||||||
<el-button class="gray-btn" @click="handleQuery">查询</el-button>
|
<el-button class="gray-btn" @click="handleQuery">查询</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,15 +98,7 @@
|
|||||||
<el-table-column prop="textbook" label="教材" min-width="120" show-overflow-tooltip />
|
<el-table-column prop="textbook" label="教材" min-width="120" show-overflow-tooltip />
|
||||||
<el-table-column prop="teacher" label="实施教员" width="90" align="center" />
|
<el-table-column prop="teacher" label="实施教员" width="90" align="center" />
|
||||||
<el-table-column prop="place" label="教学场地" width="100" show-overflow-tooltip />
|
<el-table-column prop="place" label="教学场地" width="100" show-overflow-tooltip />
|
||||||
<el-table-column label="显示可选队别班次" min-width="150" show-overflow-tooltip>
|
<el-table-column prop="teamClass" label="显示可选队别班次" min-width="150" align="center" show-overflow-tooltip />
|
||||||
<template slot="header">
|
|
||||||
<div class="checkable-header">
|
|
||||||
<el-checkbox />
|
|
||||||
<span>显示可选队别班次</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template slot-scope="{ row }">{{ row.teamClass }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="计划学时/运行学时/学分" width="130" align="center">
|
<el-table-column label="计划学时/运行学时/学分" width="130" align="center">
|
||||||
<template slot="header">
|
<template slot="header">
|
||||||
<div class="triple-header">
|
<div class="triple-header">
|
||||||
@@ -488,13 +479,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkable-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.triple-header,
|
.triple-header,
|
||||||
.triple-cell {
|
.triple-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible="dialogVisible"
|
:visible="dialogVisible"
|
||||||
title="教学班次学期信息明细"
|
:title="isEdit ? '编辑班次学期信息' : '教学班次学期信息明细'"
|
||||||
width="720px"
|
width="620px"
|
||||||
class="class-detail-dialog"
|
class="class-detail-dialog"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@update:visible="val => dialogVisible = val"
|
@update:visible="val => dialogVisible = val"
|
||||||
>
|
>
|
||||||
<el-form label-width="100px" class="detail-form">
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px" class="detail-form">
|
||||||
<el-row :gutter="24">
|
<!-- 班次信息(只读展示) -->
|
||||||
<!-- 左列 -->
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="班次">
|
<el-form-item label="班次">
|
||||||
<el-input v-model="form.bc" readonly />
|
<el-input :value="form.xydmc || form.xydbh" readonly />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专业">
|
|
||||||
<el-input v-model="form.xkzy" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="年级">
|
|
||||||
<el-input v-model="form.nj" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学期">
|
|
||||||
<div class="semester-field">
|
|
||||||
<el-input v-model="form.xq" readonly />
|
|
||||||
<el-input v-model="form.ghn" class="plan-input" placeholder="" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="开学日期">
|
|
||||||
<el-date-picker v-model="form.kxrq" type="date" format="yyyy年M月d日" value-format="yyyy-MM-dd" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="结束日期">
|
|
||||||
<el-date-picker v-model="form.jsrq" type="date" format="yyyy年M月d日" value-format="yyyy-MM-dd" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学期周数">
|
|
||||||
<el-input v-model="form.zs" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- 右列 -->
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="教学任务">
|
<el-form-item label="班次编号">
|
||||||
<el-select v-model="form.jxrw" clearable placeholder="请选择" style="width: 100%">
|
<el-input v-model="form.xydbh" :readonly="isEdit" :disabled="isEdit" placeholder="编辑模式不可修改" />
|
||||||
<el-option v-for="opt in taskOptions" :key="opt" :label="opt" :value="opt" />
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="年度" prop="nd">
|
||||||
|
<el-select v-model="form.nd" placeholder="请选择年度" style="width: 100%">
|
||||||
|
<el-option v-for="y in yearOptions" :key="y" :label="`${y}年`" :value="y" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="学期层次">
|
</el-col>
|
||||||
<el-select v-model="form.xqcc" style="width: 100%">
|
<el-col :span="12">
|
||||||
<el-option v-for="opt in levelOptions" :key="opt" :label="opt" :value="opt" />
|
<el-form-item label="学期第次" prop="xqdc">
|
||||||
</el-select>
|
<el-select v-model="form.xqdc" placeholder="请选择学期" style="width: 100%">
|
||||||
</el-form-item>
|
<el-option v-for="opt in levelOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||||
<el-form-item label="开放教员排课">
|
|
||||||
<el-checkbox v-model="form.kfpy" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="查找教室">
|
|
||||||
<el-select v-model="form.zxjs" style="width: 100%">
|
|
||||||
<el-option v-for="opt in roomOptions" :key="opt" :label="opt" :value="opt" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="教学楼">
|
|
||||||
<el-select v-model="form.jxl" style="width: 100%">
|
|
||||||
<el-option v-for="opt in buildingOptions" :key="opt" :label="opt" :value="opt" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="专用教室">
|
|
||||||
<el-select v-model="form.zyjs" style="width: 100%">
|
|
||||||
<el-option v-for="opt in zyjsOptions" :key="opt" :label="opt" :value="opt" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- 备注 -->
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="开学日期" prop="kxrq">
|
||||||
|
<el-date-picker v-model="form.kxrq" type="date" value-format="yyyy-MM-dd" placeholder="请选择" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="结束日期" prop="jsrq">
|
||||||
|
<el-date-picker v-model="form.jsrq" type="date" value-format="yyyy-MM-dd" placeholder="请选择" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="专用教室">
|
||||||
|
<el-input v-model="form.zyjsbh" placeholder="请输入专用教室编号" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="教学任务">
|
||||||
|
<el-select v-model="form.jxrwbh" clearable filterable placeholder="请选择教学任务" style="width: 100%">
|
||||||
|
<el-option v-for="opt in taskOptions" :key="opt.bh" :label="opt.rwmc" :value="opt.bh" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="开放教员排课">
|
||||||
|
<el-checkbox v-model="form.kfjypk">开放教员排课</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="" style="width: 100%" />
|
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
<el-button type="primary" :loading="saving" @click="handleSubmit">确定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
@@ -86,35 +83,32 @@ export default {
|
|||||||
name: 'ClassSemesterDetailDialog',
|
name: 'ClassSemesterDetailDialog',
|
||||||
props: {
|
props: {
|
||||||
visible: { type: Boolean, default: false },
|
visible: { type: Boolean, default: false },
|
||||||
/** 选中的班次信息 */
|
/** 编辑模式:edit / add */
|
||||||
classInfo: { type: Object, default: null },
|
mode: { type: String, default: 'add' },
|
||||||
/** 学期名称 */
|
/** 编辑时的班次学期记录 */
|
||||||
semesterName: { type: String, default: '2017年秋季学期' }
|
semester: { type: Object, default: null },
|
||||||
|
/** 新增时选中的班次(学员队)信息 */
|
||||||
|
teamInfo: { type: Object, default: null },
|
||||||
|
/** 年度下拉 */
|
||||||
|
yearOptions: { type: Array, default: () => [] },
|
||||||
|
/** 教学任务下拉({ bh, rwmc }) */
|
||||||
|
taskOptions: { type: Array, default: () => [] }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {
|
form: this.createEmptyForm(),
|
||||||
bc: '班次0633', // 班次
|
levelOptions: [
|
||||||
xkzy: '专业209', // 专业
|
{ label: '第1学期', value: 1 },
|
||||||
nj: '2017级', // 年级
|
{ label: '第2学期', value: 2 },
|
||||||
xq: this.semesterName, // 学期
|
{ label: '第3学期', value: 3 }
|
||||||
ghn: '规划内', // 规划内
|
],
|
||||||
kxrq: '2017-09-03', // 开学日期
|
saving: false,
|
||||||
jsrq: '2018-02-11', // 结束日期
|
rules: {
|
||||||
zs: 24, // 学期周数
|
nd: [{ required: true, message: '请选择年度', trigger: 'change' }],
|
||||||
jxrw: '', // 教学任务
|
xqdc: [{ required: true, message: '请选择学期第次', trigger: 'change' }],
|
||||||
xqcc: '第1学期', // 学期层次
|
kxrq: [{ required: true, message: '请选择开学日期', trigger: 'change' }],
|
||||||
kfpy: true, // 开放教员排课
|
jsrq: [{ required: true, message: '请选择结束日期', trigger: 'change' }]
|
||||||
zxjs: '10-03&10-03(50)', // 查找教室
|
}
|
||||||
jxl: '5号楼', // 教学楼
|
|
||||||
zyjs: '作战实验中心学术报告厅', // 专用教室
|
|
||||||
bz: '' // 备注
|
|
||||||
},
|
|
||||||
taskOptions: ['2017年下半年教学任务', '研究生2017下半年教学任务'],
|
|
||||||
levelOptions: ['第1学期', '第2学期', '第3学期'],
|
|
||||||
roomOptions: ['10-03&10-03(50)', '10-04&10-04(40)', '9-01'],
|
|
||||||
buildingOptions: ['5号楼', '6号楼', '综合楼'],
|
|
||||||
zyjsOptions: ['作战实验中心学术报告厅', '综合教学楼101', '学术报告厅']
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -125,22 +119,93 @@ export default {
|
|||||||
set(val) {
|
set(val) {
|
||||||
this.$emit('update:visible', val)
|
this.$emit('update:visible', val)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
isEdit() {
|
||||||
|
return this.mode === 'edit'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// 每次打开时按传入的班次信息初始化表单
|
|
||||||
visible(val) {
|
visible(val) {
|
||||||
if (!val) return
|
if (!val) return
|
||||||
this.form.bc = (this.classInfo && this.classInfo.bc) || '班次0633'
|
this.initForm()
|
||||||
this.form.xkzy = (this.classInfo && this.classInfo.xkzy) || '专业209'
|
this.$nextTick(() => {
|
||||||
this.form.nj = (this.classInfo && this.classInfo.nj) || '2017级'
|
if (this.$refs.formRef) this.$refs.formRef.clearValidate()
|
||||||
this.form.xq = this.semesterName
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleConfirm() {
|
createEmptyForm() {
|
||||||
this.$emit('confirm')
|
return {
|
||||||
this.dialogVisible = false
|
bh: '',
|
||||||
|
xydbh: '',
|
||||||
|
xydmc: '',
|
||||||
|
nd: undefined,
|
||||||
|
xqdc: undefined,
|
||||||
|
kxrq: '',
|
||||||
|
jsrq: '',
|
||||||
|
zyjsbh: '',
|
||||||
|
jxrwbh: undefined,
|
||||||
|
kfjypk: false,
|
||||||
|
bz: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 打开时按编辑/新增模式初始化表单 */
|
||||||
|
initForm() {
|
||||||
|
const form = this.createEmptyForm()
|
||||||
|
if (this.isEdit && this.semester) {
|
||||||
|
const row = this.semester
|
||||||
|
form.bh = row.bh || ''
|
||||||
|
form.xydbh = row.xydbh || ''
|
||||||
|
form.xydmc = row.xydmc || ''
|
||||||
|
form.nd = row.nd
|
||||||
|
form.xqdc = row.xqdc
|
||||||
|
form.kxrq = row.kxrq ? String(row.kxrq).slice(0, 10) : ''
|
||||||
|
form.jsrq = row.jsrq ? String(row.jsrq).slice(0, 10) : ''
|
||||||
|
form.zyjsbh = row.zyjsbh || ''
|
||||||
|
form.jxrwbh = row.jxrwbh || undefined
|
||||||
|
form.kfjypk = Number(row.kfjypk) === 1
|
||||||
|
form.bz = row.bz || ''
|
||||||
|
} else if (this.teamInfo) {
|
||||||
|
form.xydbh = this.teamInfo.xydbh || ''
|
||||||
|
form.xydmc = this.teamInfo.xydmc || ''
|
||||||
|
// 默认取当前选中年度的第一学期,日期可后续修改
|
||||||
|
form.nd = this.yearOptions[0]
|
||||||
|
form.xqdc = 1
|
||||||
|
}
|
||||||
|
this.form = form
|
||||||
|
},
|
||||||
|
/** 移除空值(保留 0 等有效值) */
|
||||||
|
cleanPayload(obj) {
|
||||||
|
const payload = {}
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
payload[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.formRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
if (!this.form.xydbh) {
|
||||||
|
this.$message.warning('缺少班次编号,无法保存')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const payload = this.cleanPayload({
|
||||||
|
bh: this.form.bh,
|
||||||
|
xydbh: this.form.xydbh,
|
||||||
|
nd: this.form.nd,
|
||||||
|
xqdc: this.form.xqdc,
|
||||||
|
kxrq: this.form.kxrq,
|
||||||
|
jsrq: this.form.jsrq,
|
||||||
|
zyjsbh: this.form.zyjsbh,
|
||||||
|
jxrwbh: this.form.jxrwbh,
|
||||||
|
kfjypk: this.form.kfjypk ? 1 : 0,
|
||||||
|
bz: this.form.bz
|
||||||
|
})
|
||||||
|
this.$emit('submit', payload)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,22 +218,6 @@ export default {
|
|||||||
::v-deep .el-input__inner[readonly] {
|
::v-deep .el-input__inner[readonly] {
|
||||||
background-color: #f5f7fa;
|
background-color: #f5f7fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.semester-field {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.el-input:first-child {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plan-input {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,148 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible="dialogVisible"
|
:visible="dialogVisible"
|
||||||
title="学员队选取"
|
:title="title"
|
||||||
width="90%"
|
width="900px"
|
||||||
top="5vh"
|
top="8vh"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
class="team-select-dialog"
|
class="team-select-dialog"
|
||||||
@update:visible="val => dialogVisible = val"
|
@update:visible="val => dialogVisible = val"
|
||||||
>
|
>
|
||||||
<div class="team-select">
|
<div class="team-select">
|
||||||
<!-- ==================== 1. 查询条件区域 ==================== -->
|
<!-- ==================== 操作说明 ==================== -->
|
||||||
|
<div v-if="excludeNote" class="note-bar">
|
||||||
|
<i class="el-icon-info"></i>
|
||||||
|
<span>{{ excludeNote }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ==================== 查询条件区域 ==================== -->
|
||||||
<div class="query-panel">
|
<div class="query-panel">
|
||||||
<el-form label-width="88px" class="query-form">
|
<el-form :inline="true" class="query-form" @submit.native.prevent>
|
||||||
<el-row :gutter="20">
|
<el-form-item label="班次编号">
|
||||||
<el-col :span="12">
|
<el-input
|
||||||
<el-form-item label="专业">
|
v-model="queryForm.xydbh"
|
||||||
<div class="check-field">
|
placeholder="请输入班次编号(模糊)"
|
||||||
<el-checkbox v-model="queryForm.zyEnabled" />
|
clearable
|
||||||
<el-select v-model="queryForm.zy" :disabled="!queryForm.zyEnabled" style="flex: 1">
|
style="width: 220px"
|
||||||
<el-option v-for="opt in zyOptions" :key="opt" :label="opt" :value="opt" />
|
@keyup.enter.native="handleQuery"
|
||||||
</el-select>
|
/>
|
||||||
</div>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item>
|
||||||
<el-form-item label="年级">
|
<el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||||
<div class="check-field">
|
<el-button size="small" @click="handleResetQuery">重置</el-button>
|
||||||
<el-checkbox v-model="queryForm.njEnabled" />
|
</el-form-item>
|
||||||
<el-input v-model="queryForm.nj" :disabled="!queryForm.njEnabled" placeholder="" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="在校状态">
|
|
||||||
<div class="check-field">
|
|
||||||
<el-checkbox v-model="queryForm.zxztEnabled" />
|
|
||||||
<el-select v-model="queryForm.zxzt" :disabled="!queryForm.zxztEnabled" style="flex: 1">
|
|
||||||
<el-option v-for="opt in zxztOptions" :key="opt" :label="opt" :value="opt" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="学员队名称">
|
|
||||||
<div class="check-field">
|
|
||||||
<el-checkbox v-model="queryForm.xydmcEnabled" />
|
|
||||||
<el-input v-model="queryForm.xydmc" :disabled="!queryForm.xydmcEnabled" placeholder="" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="任务类别">
|
|
||||||
<div class="check-field">
|
|
||||||
<el-checkbox v-model="queryForm.rwlbEnabled" />
|
|
||||||
<el-select v-model="queryForm.rwlb" :disabled="!queryForm.rwlbEnabled" style="flex: 1">
|
|
||||||
<el-option v-for="opt in rwlbOptions" :key="opt" :label="opt" :value="opt" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 分页控制区域 -->
|
|
||||||
<div class="pager-row">
|
|
||||||
<button type="button" class="gray-btn" @click="handleQuery">查询</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handleFirst">首页</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handlePrev">上页</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handleNext">下页</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handleLast">末页</button>
|
|
||||||
<el-input-number v-model="currentPage" :min="1" size="small" controls-position="right" style="width: 90px" />
|
|
||||||
<span class="pager-label">每页条数</span>
|
|
||||||
<el-select v-model="pageSize" size="small" style="width: 70px">
|
|
||||||
<el-option v-for="n in pageSizeOptions" :key="n" :label="String(n)" :value="n" />
|
|
||||||
</el-select>
|
|
||||||
<button type="button" class="gray-btn" @click="handleLocate">定位</button>
|
|
||||||
<el-select v-model="displaySize" size="small" style="width: 80px">
|
|
||||||
<el-option v-for="n in displaySizeOptions" :key="n" :label="String(n)" :value="n" />
|
|
||||||
</el-select>
|
|
||||||
<button type="button" class="blue-btn" @click="handleSetPageSize">设置页项数</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ==================== 2. 上方数据表格 ==================== -->
|
<!-- ==================== 目标班次学期表格 ==================== -->
|
||||||
<div class="table-panel">
|
<div class="table-panel">
|
||||||
<el-table
|
<el-table
|
||||||
:data="teamList"
|
ref="tableRef"
|
||||||
border
|
v-loading="loading"
|
||||||
stripe
|
:data="filteredList"
|
||||||
highlight-current-row
|
|
||||||
size="small"
|
|
||||||
class="team-table"
|
|
||||||
@selection-change="handleTopSelectionChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
|
||||||
<el-table-column prop="xzdbm" label="行政队别名称" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="xydmc" label="学员队名称" width="90" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="nj" label="年级" width="70" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="zy" label="专业" width="80" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column label="人数" width="60" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ row.rs }}人</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="zxzt" label="在校状态" width="80" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="rwlb" label="任务类别" width="80" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="zyjs" label="专用教室" width="120" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="rxrq" label="入学日期" width="120" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="byrq" label="毕业日期" width="120" align="center" show-overflow-tooltip />
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 3. 中间操作按钮区域 ==================== -->
|
|
||||||
<div class="mid-actions">
|
|
||||||
<span class="mid-label">已选择列表项</span>
|
|
||||||
<button type="button" class="gray-btn" @click="handleAdd">加入</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handleRemove">移除</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handleClear">清除</button>
|
|
||||||
<button type="button" class="gray-btn" @click="handleReset">重置</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 4. 下方数据表格(已选学员队列表) ==================== -->
|
|
||||||
<div class="table-panel">
|
|
||||||
<el-table
|
|
||||||
:data="selectedList"
|
|
||||||
border
|
border
|
||||||
stripe
|
stripe
|
||||||
size="small"
|
size="small"
|
||||||
|
max-height="360"
|
||||||
class="team-table"
|
class="team-table"
|
||||||
@selection-change="handleBottomSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="44" align="center" reserve-selection />
|
||||||
<el-table-column prop="zy" label="专业" width="80" align="center" show-overflow-tooltip />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="xydmc" label="学员队名称" width="90" align="center" show-overflow-tooltip />
|
<el-table-column prop="nd" label="年度" width="80" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="nj" label="年级" width="70" align="center" show-overflow-tooltip />
|
<el-table-column label="学期第次" width="90" align="center">
|
||||||
<el-table-column label="人数" width="60" align="center">
|
<template slot-scope="{ row }">{{ xqdcLabel(row.xqdc) }}</template>
|
||||||
<template slot-scope="{ row }">{{ row.rs }}人</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="rwlb" label="任务类别" width="80" align="center" show-overflow-tooltip />
|
<el-table-column prop="xydbh" label="班次编号" min-width="150" align="left" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="zxzt" label="在校状态" width="80" align="center" show-overflow-tooltip />
|
<el-table-column prop="kxrq" label="开学日期" width="110" align="center" :formatter="fmtDate" />
|
||||||
<el-table-column prop="zyjs" label="专用教室" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="jsrq" label="结束日期" width="110" align="center" :formatter="fmtDate" />
|
||||||
<el-table-column prop="rxrq" label="入学日期" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="bz" label="备注" min-width="120" align="left" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="byrq" label="毕业日期" width="120" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="bz" label="备注" width="80" align="center" show-overflow-tooltip />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-if="!selectedList.length" description="暂无已选学员队,请从上方表格加入" :image-size="60" />
|
<el-empty v-if="!filteredList.length" description="暂无可选的目标班次学期" :image-size="60" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ==================== 5. 底部按钮区域 ==================== -->
|
<!-- ==================== 底部按钮区域 ==================== -->
|
||||||
<div class="footer-actions">
|
<div class="footer-actions">
|
||||||
<button type="button" class="gray-btn" @click="handleConfirm">确定</button>
|
<span class="selected-count">已选择 {{ selection.length }} 个班次学期</span>
|
||||||
<button type="button" class="gray-btn" @click="handleCancel">取消</button>
|
<el-button size="small" @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button size="small" type="primary" :disabled="!selection.length" @click="handleConfirm">确定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -152,52 +75,21 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'ClassTeamSelectDialog',
|
name: 'ClassTeamSelectDialog',
|
||||||
props: {
|
props: {
|
||||||
visible: { type: Boolean, default: false }
|
visible: { type: Boolean, default: false },
|
||||||
|
/** 标题(可选) */
|
||||||
|
title: { type: String, default: '目标班次学期选取' },
|
||||||
|
/** 可选的目标班次学期列表(含 bh/nd/xqdc/xydbh/kxrq/jsrq 等) */
|
||||||
|
semesterList: { type: Array, default: () => [] },
|
||||||
|
/** 需要排除的班次学期编号(当前班次学期,不可复制给自己) */
|
||||||
|
excludeBh: { type: String, default: '' },
|
||||||
|
/** 顶部操作说明 */
|
||||||
|
excludeNote: { type: String, default: '' }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 查询条件区域 ====================
|
loading: false,
|
||||||
queryForm: {
|
queryForm: { xydbh: '' },
|
||||||
zyEnabled: false, // 专业启用复选框(未勾选)
|
selection: []
|
||||||
zy: '专业219', // 专业(默认值)
|
|
||||||
njEnabled: true, // 年级启用复选框(已勾选)
|
|
||||||
nj: '', // 年级(空值)
|
|
||||||
zxztEnabled: false, // 在校状态启用复选框(未勾选)
|
|
||||||
zxzt: '毕业', // 在校状态(默认值)
|
|
||||||
xydmcEnabled: true, // 学员队名称启用复选框(已勾选)
|
|
||||||
xydmc: '', // 学员队名称(空值)
|
|
||||||
rwlbEnabled: false, // 任务类别启用复选框(未勾选)
|
|
||||||
rwlb: '规划内' // 任务类别(默认值)
|
|
||||||
},
|
|
||||||
zyOptions: ['专业219', '专业220', '专业221'],
|
|
||||||
zxztOptions: ['毕业', '在校'],
|
|
||||||
rwlbOptions: ['规划内', '规划外'],
|
|
||||||
|
|
||||||
// ==================== 分页控制区域 ====================
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 1,
|
|
||||||
displaySize: 100,
|
|
||||||
pageSizeOptions: [1, 5, 10, 20],
|
|
||||||
displaySizeOptions: [50, 100, 200],
|
|
||||||
|
|
||||||
// ==================== 上方数据表格(可选学员队列表) ====================
|
|
||||||
teamList: [
|
|
||||||
{ xzdbm: '教学五系', xydmc: '班次0417', nj: '2016级', zy: '专业113', rs: 36, zxzt: '毕业', rwlb: '规划内', zyjs: '8-011', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
|
|
||||||
{ xzdbm: '教学七系', xydmc: '班次0423', nj: '2016级', zy: '专业114', rs: 9, zxzt: '毕业', rwlb: '规划内', zyjs: '8-212(南楼)', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
|
|
||||||
{ xzdbm: '教学七系', xydmc: '班次0411', nj: '2016级', zy: '专业112', rs: 38, zxzt: '毕业', rwlb: '规划内', zyjs: '6-203', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
|
|
||||||
{ xzdbm: '教学七系', xydmc: '班次0405', nj: '2016级', zy: '专业111', rs: 34, zxzt: '毕业', rwlb: '规划内', zyjs: '8-007', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
|
|
||||||
{ xzdbm: '教学五系', xydmc: '班次0429', nj: '2017级', zy: '专业117', rs: 43, zxzt: '毕业', rwlb: '规划内', zyjs: '6-202', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
|
|
||||||
{ xzdbm: '教学五系', xydmc: '班次0431', nj: '2017级', zy: '专业118', rs: 22, zxzt: '毕业', rwlb: '规划内', zyjs: '2-403', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
|
|
||||||
{ xzdbm: '教学七系', xydmc: '班次0425', nj: '2017级', zy: '专业115', rs: 19, zxzt: '毕业', rwlb: '规划内', zyjs: '2-406', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
|
|
||||||
{ xzdbm: '教学七系', xydmc: '班次0432', nj: '2017级', zy: '专业119', rs: 15, zxzt: '毕业', rwlb: '规划内', zyjs: '8-009(南楼)', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
|
|
||||||
{ xzdbm: '教学七系', xydmc: '班次0434', nj: '2017级', zy: '专业120', rs: 45, zxzt: '毕业', rwlb: '规划内', zyjs: '6-303', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
|
|
||||||
{ xzdbm: '教学六系', xydmc: '班次0427', nj: '2017级', zy: '专业116', rs: 64, zxzt: '毕业', rwlb: '规划内', zyjs: '2-501', rxrq: '2017年8月24日', byrq: '2019年1月21日' }
|
|
||||||
],
|
|
||||||
/** 上方表格多选 */
|
|
||||||
topSelection: [],
|
|
||||||
/** 下方数据表格(已选学员队列表) */
|
|
||||||
selectedList: [],
|
|
||||||
bottomSelection: []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -208,105 +100,54 @@ export default {
|
|||||||
set(val) {
|
set(val) {
|
||||||
this.$emit('update:visible', val)
|
this.$emit('update:visible', val)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/** 排除当前班次学期后的可选列表 */
|
||||||
|
availableList() {
|
||||||
|
const excludeBh = this.excludeBh || ''
|
||||||
|
return (this.semesterList || []).filter(item => item.bh && String(item.bh) !== String(excludeBh))
|
||||||
|
},
|
||||||
|
/** 本地过滤后的列表 */
|
||||||
|
filteredList() {
|
||||||
|
const kw = (this.queryForm.xydbh || '').trim()
|
||||||
|
if (!kw) return this.availableList
|
||||||
|
return this.availableList.filter(item => item.xydbh && String(item.xydbh).includes(kw))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(val) {
|
||||||
|
if (val) {
|
||||||
|
this.selection = []
|
||||||
|
this.queryForm.xydbh = ''
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.tableRef) this.$refs.tableRef.clearSelection()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleTopSelectionChange(rows) {
|
fmtDate(val) {
|
||||||
this.topSelection = rows
|
if (!val) return '-'
|
||||||
|
return String(val).slice(0, 10)
|
||||||
},
|
},
|
||||||
handleBottomSelectionChange(rows) {
|
xqdcLabel(val) {
|
||||||
this.bottomSelection = rows
|
if (val === 1 || val === '1') return '第1学期'
|
||||||
|
if (val === 2 || val === '2') return '第2学期'
|
||||||
|
if (val === 3 || val === '3') return '第3学期'
|
||||||
|
return val !== undefined && val !== null && val !== '' ? `第${val}学期` : '-'
|
||||||
},
|
},
|
||||||
|
handleSelectionChange(rows) {
|
||||||
// ==================== 分页控制 ====================
|
this.selection = rows
|
||||||
handleQuery() {
|
|
||||||
this.$message.success('查询(前端演示)')
|
|
||||||
},
|
},
|
||||||
handleFirst() {
|
handleQuery() {},
|
||||||
this.currentPage = 1
|
handleResetQuery() {
|
||||||
this.$message.success('已跳转首页')
|
this.queryForm.xydbh = ''
|
||||||
},
|
},
|
||||||
handlePrev() {
|
|
||||||
if (this.currentPage > 1) this.currentPage--
|
|
||||||
},
|
|
||||||
handleNext() {
|
|
||||||
this.currentPage++
|
|
||||||
},
|
|
||||||
handleLast() {
|
|
||||||
this.currentPage = this.teamList.length || 1
|
|
||||||
},
|
|
||||||
handleLocate() {
|
|
||||||
this.$message.success(`已定位到第 ${this.currentPage} 页`)
|
|
||||||
},
|
|
||||||
handleSetPageSize() {
|
|
||||||
this.$message.success(`每页显示条数已设置为 ${this.displaySize}`)
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 中间操作按钮 ====================
|
|
||||||
/** 加入:将上方表格选中行加入已选列表(去重) */
|
|
||||||
handleAdd() {
|
|
||||||
if (!this.topSelection.length) {
|
|
||||||
this.$message.warning('请先在上方表格选择学员队')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const existing = new Set(this.selectedList.map((r) => r.xydmc))
|
|
||||||
let added = 0
|
|
||||||
this.topSelection.forEach((r) => {
|
|
||||||
if (!existing.has(r.xydmc)) {
|
|
||||||
this.selectedList.push({ ...r, bz: '' })
|
|
||||||
added++
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (added) this.$message.success(`已加入 ${added} 个学员队`)
|
|
||||||
else this.$message.info('所选学员队已在列表中')
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 移除:将下方表格选中行移除 */
|
|
||||||
handleRemove() {
|
|
||||||
if (!this.bottomSelection.length) {
|
|
||||||
this.$message.warning('请先在下方表格选择要移除的学员队')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const removeKeys = new Set(this.bottomSelection.map((r) => r.xydmc))
|
|
||||||
this.selectedList = this.selectedList.filter((r) => !removeKeys.has(r.xydmc))
|
|
||||||
this.$message.success(`已移除 ${this.bottomSelection.length} 个学员队`)
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 清除:清空已选列表 */
|
|
||||||
handleClear() {
|
|
||||||
if (!this.selectedList.length) {
|
|
||||||
this.$message.info('已选列表为空')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.selectedList = []
|
|
||||||
this.$message.success('已清空已选列表')
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 重置:清空已选列表并重置查询条件 */
|
|
||||||
handleReset() {
|
|
||||||
this.selectedList = []
|
|
||||||
Object.assign(this.queryForm, {
|
|
||||||
zyEnabled: false, zy: '专业219',
|
|
||||||
njEnabled: true, nj: '',
|
|
||||||
zxztEnabled: false, zxzt: '毕业',
|
|
||||||
xydmcEnabled: true, xydmc: '',
|
|
||||||
rwlbEnabled: false, rwlb: '规划内'
|
|
||||||
})
|
|
||||||
this.currentPage = 1
|
|
||||||
this.$message.success('已重置')
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 底部按钮 ====================
|
|
||||||
handleConfirm() {
|
handleConfirm() {
|
||||||
if (!this.selectedList.length) {
|
if (!this.selection.length) {
|
||||||
this.$message.warning('请先选择要应用的学员队')
|
this.$message.warning('请先勾选目标班次学期')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$emit('confirm', this.selectedList.slice())
|
this.$emit('confirm', this.selection.slice())
|
||||||
this.dialogVisible = false
|
|
||||||
this.$message.success(`选定区域设置已应用于 ${this.selectedList.length} 个班次`)
|
|
||||||
},
|
|
||||||
handleCancel() {
|
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,40 +160,34 @@ export default {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
|
||||||
// ========== 1. 查询条件区域 ==========
|
// ========== 操作说明 ==========
|
||||||
|
.note-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #1e6fff;
|
||||||
|
background: #ecf5ff;
|
||||||
|
border: 1px solid #d9ecff;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 查询条件区域 ==========
|
||||||
.query-panel {
|
.query-panel {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #ebeef5;
|
border: 1px solid #ebeef5;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 12px 16px 8px;
|
padding: 10px 12px 2px;
|
||||||
|
|
||||||
.query-form {
|
.query-form {
|
||||||
.check-field {
|
::v-deep .el-form-item {
|
||||||
display: flex;
|
margin-bottom: 8px;
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pager-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
padding-top: 10px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
margin-top: 4px;
|
|
||||||
|
|
||||||
.pager-label {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #606266;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 2/4. 表格区域 ==========
|
// ========== 表格区域 ==========
|
||||||
.table-panel {
|
.table-panel {
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -370,69 +205,19 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 3. 中间操作按钮区域 ==========
|
// ========== 底部按钮区域 ==========
|
||||||
.mid-actions {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
.mid-label {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 5. 底部按钮区域 ==========
|
|
||||||
.footer-actions {
|
.footer-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
border-top: 1px solid #ebeef5;
|
border-top: 1px solid #ebeef5;
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 银灰色 / 蓝色边框按钮 ==========
|
.selected-count {
|
||||||
.gray-btn {
|
flex: 1;
|
||||||
min-width: 70px;
|
font-size: 13px;
|
||||||
height: 28px;
|
color: #606266;
|
||||||
padding: 0 14px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #000;
|
|
||||||
background: linear-gradient(180deg, #fdfdfd 0%, #ececec 50%, #dcdcdc 100%);
|
|
||||||
border: 1px solid #7a7a7a;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: linear-gradient(180deg, #ffffff 0%, #f4f4f4 50%, #e6e6e6 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background: #c8c8c8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue-btn {
|
|
||||||
min-width: 110px;
|
|
||||||
height: 28px;
|
|
||||||
padding: 0 14px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #1e6fff;
|
|
||||||
background: #ecf5ff;
|
|
||||||
border: 1px solid #1e6fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #d9ecff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background: #c6e2ff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,706 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
:visible="dialogVisible"
|
|
||||||
:show-close="false"
|
|
||||||
width="96%"
|
|
||||||
top="3vh"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:close-on-press-escape="false"
|
|
||||||
class="peidang-dialog"
|
|
||||||
@update:visible="val => dialogVisible = val"
|
|
||||||
>
|
|
||||||
<!-- ==================== 自定义标题栏 ==================== -->
|
|
||||||
<div slot="header">
|
|
||||||
<div class="peidang-titlebar">
|
|
||||||
<i class="el-icon-reading title-icon"></i>
|
|
||||||
<span class="title-text">
|
|
||||||
班次学期配档——{{ semesterName }}——{{ classLabel }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="peidang-body">
|
|
||||||
<!-- ==================== 上半部分:左右分栏 ==================== -->
|
|
||||||
<div class="upper">
|
|
||||||
<!-- 左侧 75%:配档课程编组管理表格 -->
|
|
||||||
<div class="table-area">
|
|
||||||
<el-table
|
|
||||||
ref="tableRef"
|
|
||||||
:data="displayCourses"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
highlight-current-row
|
|
||||||
size="small"
|
|
||||||
max-height="240"
|
|
||||||
class="peidang-table"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
>
|
|
||||||
<el-table-column prop="name" label="科目名称" width="100" align="left" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="short" label="简称" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="planStart" label="计划起始周" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="actualStart" label="实际起始周" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="endWeek" label="结束周" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column label="连排课" width="50" align="center">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-checkbox :value="row.continuous" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="priority" label="优先序数" width="50" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="weeklyHours" label="周学时" width="50" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="hours" label="学时" width="50" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column label="正课时间" width="60" align="center">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-checkbox :value="row.scheduleTime" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="已排学时" width="50" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ courseStats(row).scheduled }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="未排学时" width="50" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ courseStats(row).remaining }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="总班次任务数" width="70" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ row.continuous ? 1 : 1 }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="配档编组任务数" width="80" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ row.continuous ? 2 : 1 }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧 25%:配档课程属性设置区 + 优先序数上下移动 -->
|
|
||||||
<div class="prop-area">
|
|
||||||
<div class="prop-title">配档课程属性</div>
|
|
||||||
<el-form label-width="72px" size="small" class="prop-form">
|
|
||||||
<el-form-item label="周学时">
|
|
||||||
<el-input-number v-model="propForm.weeklyHours" :min="1" :max="40" controls-position="right" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="起始周次">
|
|
||||||
<el-input-number v-model="propForm.startWeek" :min="startWeek" :max="endWeek" controls-position="right" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="结束周次">
|
|
||||||
<el-input-number v-model="propForm.endWeek" :min="startWeek" :max="endWeek" controls-position="right" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="连排课">
|
|
||||||
<el-checkbox v-model="propForm.continuous">单科独进</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="优先序数">
|
|
||||||
<div class="priority-field">
|
|
||||||
<el-input-number v-model="propForm.priority" :min="1" controls-position="right" style="width: 100%" />
|
|
||||||
<el-button type="primary" plain icon="el-icon-arrow-up" @click="handlePriorityUp" />
|
|
||||||
<el-button type="primary" plain icon="el-icon-arrow-down" @click="handlePriorityDown" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="配档编组">
|
|
||||||
<el-input v-model="propForm.group" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-button type="primary" class="apply-btn" @click="handleApplyProp">应用属性</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 下半部分:配档显示区域(甘特图) ==================== -->
|
|
||||||
<div class="gantt-area">
|
|
||||||
<div class="gantt-head">
|
|
||||||
<div class="gantt-label-col">
|
|
||||||
<div class="gantt-label">课程 / 周次</div>
|
|
||||||
</div>
|
|
||||||
<div class="gantt-body">
|
|
||||||
<!-- 行1:周次刻度(红色竖线为周刻度) -->
|
|
||||||
<div class="gantt-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell week-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>{{ w }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- 行2:本周可安排正课学时 -->
|
|
||||||
<div class="gantt-row info-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>可排{{ weeklyCapacity }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- 行3:已安排学时 / 剩余学时 -->
|
|
||||||
<div class="gantt-row info-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>
|
|
||||||
<span class="sch">已{{ monthlyScheduled(w) }}</span>
|
|
||||||
<span class="rem">余{{ Math.max(0, weeklyCapacity - monthlyScheduled(w)) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 课程甘特条 -->
|
|
||||||
<div class="gantt-courses">
|
|
||||||
<div v-for="course in displayCourses" :key="course.id" class="gantt-course">
|
|
||||||
<div class="gantt-label-col">
|
|
||||||
<div class="course-tag" :class="course.continuous ? 'tag-continuous' : 'tag-normal'">
|
|
||||||
<span class="course-name">{{ course.name }}({{ course.short }})</span>
|
|
||||||
<span class="course-hours">
|
|
||||||
已排{{ courseStats(course).scheduled }}
|
|
||||||
<template v-if="courseStats(course).remaining > 0">+{{ courseStats(course).remaining }}</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gantt-body">
|
|
||||||
<div class="gantt-row bar-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell bar-cell"
|
|
||||||
:class="{
|
|
||||||
'month-boundary': isMonthBoundary(w),
|
|
||||||
'bar-active': w >= course.actualStart && w <= course.endWeek,
|
|
||||||
'bar-continuous': course.continuous,
|
|
||||||
'bar-normal': !course.continuous
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<span v-if="w >= course.actualStart && w <= course.endWeek" class="bar-hours">
|
|
||||||
{{ courseWeekHours(course)[w] || '' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 底部:本月可安排正课总学时(月刻度) -->
|
|
||||||
<div class="gantt-foot">
|
|
||||||
<div class="gantt-label-col">
|
|
||||||
<div class="gantt-label">本月正课总学时</div>
|
|
||||||
</div>
|
|
||||||
<div class="gantt-body">
|
|
||||||
<div class="gantt-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell month-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>
|
|
||||||
<span v-if="bottomCells[w] && isMonthEndWeek(w)" class="month-total">
|
|
||||||
第{{ bottomCells[w].no }}月:可排{{ bottomCells[w].total }}(已排{{ bottomCells[w].scheduled }} + 余{{ bottomCells[w].remaining }})
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 底部操作 ==================== -->
|
|
||||||
<div slot="footer">
|
|
||||||
<div class="peidang-footer">
|
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'PeidangEditDialog',
|
|
||||||
props: {
|
|
||||||
visible: { type: Boolean, default: false },
|
|
||||||
/** 学年学期名称 */
|
|
||||||
semesterName: { type: String, default: '2017-2018学年第一学期' },
|
|
||||||
/** 班次标签(如 教学五系2016级专业0113班次0417) */
|
|
||||||
classLabel: { type: String, default: '教学五系2016级专业0113班次0417' }
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// ==================== 时间轴参数 ====================
|
|
||||||
/** 该班次开学起始周次 */
|
|
||||||
startWeek: 8,
|
|
||||||
/** 该班次学期结束周次 */
|
|
||||||
endWeek: 32,
|
|
||||||
/** 该班次每周可安排的正课学时时数(去除不能排课学时) */
|
|
||||||
weeklyCapacity: 40,
|
|
||||||
/** 月刻度:每 4 周为一月(8-11 第1月,12-15 第2月...),虚线分隔 */
|
|
||||||
monthBreaks: [12, 16, 20, 24, 28, 32],
|
|
||||||
|
|
||||||
// ==================== 配档课程数据 ====================
|
|
||||||
courses: [
|
|
||||||
// ---- 非连排课(按周学时安排,蓝色,每门独立一组) ----
|
|
||||||
{ id: 'p1', name: '课程科目001', short: '政治', planStart: 8, actualStart: 8, endWeek: 23, continuous: false, priority: 1, weeklyHours: 4, hours: 60, scheduleTime: true, group: '组1' },
|
|
||||||
{ id: 'p2', name: '课程科目002', short: '军事', planStart: 8, actualStart: 8, endWeek: 20, continuous: false, priority: 2, weeklyHours: 4, hours: 48, scheduleTime: true, group: '组2' },
|
|
||||||
{ id: 'p3', name: '课程科目003', short: '战术', planStart: 8, actualStart: 10, endWeek: 21, continuous: false, priority: 3, weeklyHours: 4, hours: 44, scheduleTime: true, group: '组3' },
|
|
||||||
{ id: 'p4', name: '课程科目004', short: '指挥', planStart: 8, actualStart: 12, endWeek: 22, continuous: false, priority: 4, weeklyHours: 4, hours: 40, scheduleTime: true, group: '组4' },
|
|
||||||
// ---- 连排课(单科独进,红色,共为一组) ----
|
|
||||||
{ id: 'p5', name: '课程科目005', short: '综合演练', planStart: 8, actualStart: 8, endWeek: 13, continuous: true, priority: 5, weeklyHours: 20, hours: 100, scheduleTime: true, group: '连排组' },
|
|
||||||
{ id: 'p6', name: '课程科目006', short: '野营拉练', planStart: 14, actualStart: 14, endWeek: 16, continuous: true, priority: 6, weeklyHours: 24, hours: 48, scheduleTime: true, group: '连排组' }
|
|
||||||
],
|
|
||||||
|
|
||||||
// ==================== 表格选中与属性设置 ====================
|
|
||||||
currentCourse: null,
|
|
||||||
propForm: {
|
|
||||||
weeklyHours: 4,
|
|
||||||
startWeek: 8,
|
|
||||||
endWeek: 16,
|
|
||||||
continuous: false,
|
|
||||||
priority: 1,
|
|
||||||
group: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
dialogVisible: {
|
|
||||||
get() {
|
|
||||||
return this.visible
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$emit('update:visible', val)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/** 周序列:8 ~ 32 */
|
|
||||||
weeks() {
|
|
||||||
const arr = []
|
|
||||||
for (let w = this.startWeek; w <= this.endWeek; w++) arr.push(w)
|
|
||||||
return arr
|
|
||||||
},
|
|
||||||
/** 月份信息:每月包含的周次与可安排正课学时 */
|
|
||||||
months() {
|
|
||||||
const list = []
|
|
||||||
let mNo = 1
|
|
||||||
let cur = this.startWeek
|
|
||||||
while (cur <= this.endWeek) {
|
|
||||||
const next = this.monthBreaks.find((b) => b > cur)
|
|
||||||
const mEnd = Math.min((next === undefined ? this.endWeek + 1 : next) - 1, this.endWeek)
|
|
||||||
list.push({ no: mNo, start: cur, end: mEnd, total: (mEnd - cur + 1) * this.weeklyCapacity })
|
|
||||||
cur = mEnd + 1
|
|
||||||
mNo++
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
},
|
|
||||||
/** 底部每月汇总行数据:week -> 该月信息(仅月首格展示文字) */
|
|
||||||
bottomCells() {
|
|
||||||
const map = {}
|
|
||||||
this.weeks.forEach((w) => {
|
|
||||||
const m = this.months.find((item) => w >= item.start && w <= item.end)
|
|
||||||
if (!m) return
|
|
||||||
map[w] = {
|
|
||||||
no: m.no,
|
|
||||||
total: m.total,
|
|
||||||
scheduled: this.monthlyScheduled(w),
|
|
||||||
remaining: m.total - this.monthlyScheduled(w)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return map
|
|
||||||
},
|
|
||||||
/** 表格展示顺序:非连排课在前,连排课在后;组内按实际起始周、优先序数排序 */
|
|
||||||
displayCourses() {
|
|
||||||
return [...this.courses].sort((a, b) => {
|
|
||||||
if (a.continuous !== b.continuous) return a.continuous ? 1 : -1
|
|
||||||
if (a.actualStart !== b.actualStart) return a.actualStart - b.actualStart
|
|
||||||
return a.priority - b.priority
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
if (!val) return
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.$refs.tableRef) {
|
|
||||||
this.$refs.tableRef.setCurrentRow(this.displayCourses[0])
|
|
||||||
}
|
|
||||||
this.currentCourse = this.displayCourses[0] || null
|
|
||||||
this.syncPropForm()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 是否为月边界列(左侧画虚线) */
|
|
||||||
isMonthBoundary(week) {
|
|
||||||
return this.monthBreaks.includes(week)
|
|
||||||
},
|
|
||||||
/** 是否为某月的结束周(仅月结束列展示文字) */
|
|
||||||
isMonthEndWeek(week) {
|
|
||||||
return this.months.some((m) => m.end === week)
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 某周所有课程已安排学时之和 */
|
|
||||||
monthlyScheduled(week) {
|
|
||||||
return this.courses.reduce((sum, c) => {
|
|
||||||
const map = this.courseWeekHours(c)
|
|
||||||
return sum + (map[week] !== undefined ? map[week] : 0)
|
|
||||||
}, 0)
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 每门课程按周分布的安排学时 */
|
|
||||||
courseWeekHours(course) {
|
|
||||||
const map = {}
|
|
||||||
let remaining = course.hours
|
|
||||||
let w = course.actualStart
|
|
||||||
while (remaining > 0 && w <= course.endWeek) {
|
|
||||||
const h = Math.min(course.weeklyHours, remaining)
|
|
||||||
map[w] = h
|
|
||||||
remaining -= h
|
|
||||||
w++
|
|
||||||
}
|
|
||||||
return map
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 课程计算属性:已排学时 / 未排学时 */
|
|
||||||
courseStats(course) {
|
|
||||||
const map = this.courseWeekHours(course)
|
|
||||||
const scheduled = Object.keys(map).reduce((sum, k) => sum + map[k], 0)
|
|
||||||
return { scheduled, remaining: Math.max(0, course.hours - scheduled) }
|
|
||||||
},
|
|
||||||
|
|
||||||
handleCurrentChange(row) {
|
|
||||||
this.currentCourse = row
|
|
||||||
this.syncPropForm()
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 属性设置表单同步(右侧) */
|
|
||||||
syncPropForm() {
|
|
||||||
if (!this.currentCourse) return
|
|
||||||
this.propForm.weeklyHours = this.currentCourse.weeklyHours
|
|
||||||
this.propForm.startWeek = this.currentCourse.actualStart
|
|
||||||
this.propForm.endWeek = this.currentCourse.endWeek
|
|
||||||
this.propForm.continuous = this.currentCourse.continuous
|
|
||||||
this.propForm.priority = this.currentCourse.priority
|
|
||||||
this.propForm.group = this.currentCourse.group
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 属性设置保存:应用所选课程的配档属性 */
|
|
||||||
handleApplyProp() {
|
|
||||||
if (!this.currentCourse) {
|
|
||||||
this.$message.warning('请先在表格中选择一门课程')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const row = this.currentCourse
|
|
||||||
row.weeklyHours = this.propForm.weeklyHours
|
|
||||||
row.actualStart = this.propForm.startWeek
|
|
||||||
row.endWeek = this.propForm.endWeek
|
|
||||||
row.continuous = this.propForm.continuous
|
|
||||||
row.priority = this.propForm.priority
|
|
||||||
row.group = this.propForm.group
|
|
||||||
this.$message.success('配档属性已应用(前端演示)')
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 优先序数上移:优先序数减 1 */
|
|
||||||
handlePriorityUp() {
|
|
||||||
if (!this.currentCourse) {
|
|
||||||
this.$message.warning('请先在表格中选择一门课程')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.currentCourse.priority <= 1) {
|
|
||||||
this.$message.info('已是最高优先序数')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.currentCourse.priority -= 1
|
|
||||||
this.syncPropForm()
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 优先序数下移:优先序数加 1 */
|
|
||||||
handlePriorityDown() {
|
|
||||||
if (!this.currentCourse) {
|
|
||||||
this.$message.warning('请先在表格中选择一门课程')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.currentCourse.priority += 1
|
|
||||||
this.syncPropForm()
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 底部操作 ====================
|
|
||||||
handleConfirm() {
|
|
||||||
this.$emit('confirm')
|
|
||||||
this.dialogVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.peidang-dialog {
|
|
||||||
// ========== 自定义标题栏 ==========
|
|
||||||
::v-deep .el-dialog__header {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.peidang-titlebar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
height: 40px;
|
|
||||||
padding: 0 14px;
|
|
||||||
background: linear-gradient(90deg, #0a246a 0%, #a6caf0 100%);
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.title-icon {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-text {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #fff;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-dialog__body {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-dialog__footer {
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.peidang-footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.peidang-body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
// ========== 上半部分:左右分栏 ==========
|
|
||||||
.upper {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
// 左侧 75%:表格
|
|
||||||
.table-area {
|
|
||||||
flex: 3;
|
|
||||||
min-width: 0;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.peidang-table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 右侧 25%:属性设置
|
|
||||||
.prop-area {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 240px;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
|
|
||||||
.prop-title {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prop-form {
|
|
||||||
.priority-field {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.el-button {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.apply-btn {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 下半部分:配档显示区域 ==========
|
|
||||||
.gantt-area {
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 8px;
|
|
||||||
overflow: auto;
|
|
||||||
max-height: 320px;
|
|
||||||
|
|
||||||
.gantt-head,
|
|
||||||
.gantt-course,
|
|
||||||
.gantt-foot {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
min-width: 860px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-label-col {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 210px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.gantt-label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
font-weight: 600;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-body {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-row {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.gantt-cell {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 34px;
|
|
||||||
height: 24px;
|
|
||||||
line-height: 24px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 11px;
|
|
||||||
color: #303133;
|
|
||||||
border-right: 1px solid #ebeef5;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 周刻度:顶部红色竖线
|
|
||||||
.week-cell {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #f56c6c;
|
|
||||||
border-top: 2px solid #f56c6c;
|
|
||||||
background: #fff5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-row .gantt-cell {
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
|
|
||||||
.sch {
|
|
||||||
color: #1e6fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rem {
|
|
||||||
color: #e6a23c;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 月刻度虚线
|
|
||||||
.month-boundary {
|
|
||||||
border-left: 1px dashed #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 课程条
|
|
||||||
.bar-cell {
|
|
||||||
height: 26px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.bar-hours {
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bar-active {
|
|
||||||
&.bar-normal {
|
|
||||||
background: #409eff;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.bar-hours {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bar-continuous {
|
|
||||||
background: #f56c6c;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.bar-hours {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.month-cell {
|
|
||||||
height: 22px;
|
|
||||||
line-height: 22px;
|
|
||||||
|
|
||||||
.month-total {
|
|
||||||
font-size: 11px;
|
|
||||||
color: #606266;
|
|
||||||
font-weight: 600;
|
|
||||||
background: #f4f4f5;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0 4px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-course {
|
|
||||||
.gantt-label-col {
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.course-tag {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 1px;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 11px;
|
|
||||||
|
|
||||||
&.tag-normal {
|
|
||||||
background: #ecf5ff;
|
|
||||||
border: 1px solid #a0cfff;
|
|
||||||
color: #337ecc;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.tag-continuous {
|
|
||||||
background: #fef0f0;
|
|
||||||
border: 1px solid #fbc4c4;
|
|
||||||
color: #d63031;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-name {
|
|
||||||
font-weight: 600;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-hours {
|
|
||||||
font-size: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-foot {
|
|
||||||
.gantt-label-col {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,369 +1,591 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container shift-semester-page">
|
<div class="app-container shift-semester-page">
|
||||||
<!-- ==================== 1. 学年学期标题 ==================== -->
|
<!-- ==================== 页面标题 ==================== -->
|
||||||
<div class="list-title">{{ semesterName }}</div>
|
<div class="page-title">班次学期信息管理</div>
|
||||||
|
|
||||||
<!-- ==================== 2. 校历 / 预设日期信息区 ==================== -->
|
<!-- ==================== 1. 查询条件区域 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form class="search-form">
|
<el-form :inline="true" :model="searchForm" class="search-form">
|
||||||
<div class="date-group">
|
<el-form-item label="班次编号">
|
||||||
<span class="date-group-label">校历</span>
|
<el-input
|
||||||
<el-form-item label="开学日期">
|
v-model="searchForm.xydbh"
|
||||||
<el-date-picker v-model="semester.kxrq" type="date" format="yyyy年M月d日" value-format="yyyy-MM-dd" style="width: 160px" />
|
placeholder="请输入班次编号(模糊)"
|
||||||
</el-form-item>
|
clearable
|
||||||
<el-form-item label="结束日期">
|
style="width: 220px"
|
||||||
<el-date-picker v-model="semester.jsrq" type="date" format="yyyy年M月d日" value-format="yyyy-MM-dd" style="width: 160px" />
|
@keyup.enter.native="handleQuery"
|
||||||
</el-form-item>
|
/>
|
||||||
<el-form-item label="学期周数">
|
</el-form-item>
|
||||||
<el-input-number v-model="semester.weeks" :min="1" controls-position="right" style="width: 90px" />
|
<el-form-item label="年度">
|
||||||
</el-form-item>
|
<el-select v-model="filterYear" placeholder="全部年度" clearable style="width: 140px" @change="handleYearChange">
|
||||||
</div>
|
<el-option v-for="y in yearFilterOptions" :key="y" :label="`${y}年`" :value="y" />
|
||||||
<div class="date-group">
|
</el-select>
|
||||||
<span class="date-group-label">预设</span>
|
</el-form-item>
|
||||||
<el-form-item label="开学日期">
|
<el-form-item>
|
||||||
<el-date-picker v-model="preset.kxrq" type="date" format="yyyy年M月d日" value-format="yyyy-MM-dd" style="width: 160px" />
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||||
</el-form-item>
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||||
<el-form-item label="结束日期">
|
</el-form-item>
|
||||||
<el-date-picker v-model="preset.jsrq" type="date" format="yyyy年M月d日" value-format="yyyy-MM-dd" style="width: 160px" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学期周数">
|
|
||||||
<el-input-number v-model="preset.weeks" :min="1" controls-position="right" style="width: 90px" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-button class="absorb-btn" type="primary" plain @click="handleAbsorbDate">吸取日期</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 3. 工具栏按钮区 ==================== -->
|
<!-- ==================== 2. 工具栏按钮区 ==================== -->
|
||||||
<div class="list-toolbar">
|
<div class="list-toolbar">
|
||||||
<div class="left-group">
|
<div class="left-group">
|
||||||
<!-- 新添:下拉列出可新建学期信息的班次 -->
|
<el-button type="primary" icon="el-icon-plus" @click="handleBatchAdd">批量创建班次学期</el-button>
|
||||||
<el-dropdown trigger="click" @command="handleNewCommand">
|
<el-button type="primary" plain icon="el-icon-document-add" @click="handleAdd">新增</el-button>
|
||||||
<el-button type="primary">
|
<el-button type="primary" plain icon="el-icon-edit" :disabled="!currentRow" @click="handleEdit">编辑</el-button>
|
||||||
<i class="el-icon-plus"></i>
|
<el-button type="danger" plain icon="el-icon-delete" :disabled="!selection.length" @click="handleDelete">删除所选</el-button>
|
||||||
<span>新添</span>
|
<el-button type="primary" plain icon="el-icon-date" :disabled="!selection.length" @click="handleQuickSetDates">快速设定学期日期</el-button>
|
||||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
<el-button type="primary" plain icon="el-icon-notebook-2" :disabled="!selection.length" @click="handleSetJxrw">批量设置教学任务</el-button>
|
||||||
</el-button>
|
</div>
|
||||||
<el-dropdown-menu slot="dropdown" class="new-class-menu">
|
<div class="right-group">
|
||||||
<el-dropdown-item v-for="item in newableClasses" :key="item.bc" :command="item">
|
<el-button type="success" plain icon="el-icon-calendar" :disabled="!currentRow" @click="handleEditCalendar">编辑班历</el-button>
|
||||||
{{ item.bc }}({{ item.xkzy }}、{{ item.nj }})
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
|
|
||||||
<el-button type="primary" plain @click="handleAction('编辑')">编辑</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleQuickSetDates">快速设定学期日期</el-button>
|
|
||||||
<el-button type="danger" @click="handleAction('删除')">删除</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleEditCalendar">编辑班历</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleAction('自动生成教学计划')">自动生成教学计划</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleAction('教学计划管理')">教学计划管理</el-button>
|
|
||||||
|
|
||||||
<!-- 序号排序:带下拉箭头,点击弹出排序方式 -->
|
|
||||||
<el-dropdown trigger="click" @command="handleSortCommand">
|
|
||||||
<el-button type="primary" plain>
|
|
||||||
<span>{{ sortLabel }}</span>
|
|
||||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
|
||||||
</el-button>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="xh">序号排序</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="bw">波次排序</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
|
|
||||||
<el-button type="primary" plain @click="handleMerge">预设合班</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleAction('预设拆班')">预设拆班</el-button>
|
|
||||||
<el-button type="primary" plain @click="handlePeidangEdit">配档编辑</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ==================== 4. 班次学期信息列表 ==================== -->
|
<!-- ==================== 3. 班次学期信息列表 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table
|
<el-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
v-loading="loading"
|
||||||
:data="displayData"
|
:data="displayData"
|
||||||
border
|
border
|
||||||
stripe
|
stripe
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
:span-method="spanMethod"
|
size="small"
|
||||||
:row-class-name="rowClassName"
|
|
||||||
:header-cell-class-name="headerCellClassName"
|
|
||||||
max-height="480"
|
max-height="480"
|
||||||
class="class-table"
|
class="class-table"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
>
|
>
|
||||||
<el-table-column prop="xzdw" label="行政队别" width="90" align="center" show-overflow-tooltip />
|
<template slot="empty">
|
||||||
<el-table-column prop="xh" label="班次序号" width="70" align="center" />
|
<span>无数据!</span>
|
||||||
<el-table-column prop="bc" label="班级" width="70" align="center" show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column prop="rs" label="人数" width="55" align="center" show-overflow-tooltip />
|
<el-table-column type="selection" width="44" align="center" />
|
||||||
<el-table-column prop="nj" label="年级" width="85" align="center" show-overflow-tooltip />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="xkzy" label="学科专业" width="85" align="center" show-overflow-tooltip />
|
<el-table-column prop="xydbh" label="班次编号" min-width="150" align="left" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="kxrq" label="开学日期" width="90" align="center" show-overflow-tooltip />
|
<el-table-column prop="nd" label="年度" width="80" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="jsrq" label="结束日期" width="90" align="center" show-overflow-tooltip />
|
<el-table-column label="学期第次" width="90" align="center">
|
||||||
<el-table-column prop="xqcc" label="学期第次" width="80" align="center" show-overflow-tooltip />
|
<template slot-scope="{ row }">{{ xqdcLabel(row.xqdc) }}</template>
|
||||||
<el-table-column prop="zyjs" label="专用教室" width="80" align="center" show-overflow-tooltip />
|
</el-table-column>
|
||||||
<el-table-column prop="jxrw" label="教学任务" min-width="160" align="left" show-overflow-tooltip />
|
<el-table-column prop="kxrq" label="开学日期" width="110" align="center" :formatter="fmtDate" />
|
||||||
<el-table-column prop="zs" label="周数" width="55" align="center" show-overflow-tooltip />
|
<el-table-column prop="jsrq" label="结束日期" width="110" align="center" :formatter="fmtDate" />
|
||||||
<el-table-column prop="kcrws" label="总课程数" width="80" align="center" show-overflow-tooltip />
|
<el-table-column prop="zyjsbh" label="专用教室" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="kczs" label="总课时数" width="80" align="center" show-overflow-tooltip />
|
<el-table-column label="教学任务" min-width="160" align="left" header-align="center" show-overflow-tooltip>
|
||||||
<el-table-column label="周学时" width="80" align="center">
|
<template slot-scope="{ row }">{{ taskName(row.jxrwbh) }}</template>
|
||||||
<template slot-scope="{ row }">{{ row.zxs.toFixed(2) }}</template>
|
</el-table-column>
|
||||||
|
<el-table-column label="开放教员排课" width="110" align="center">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-tag v-if="Number(row.kfjypk) === 1" type="success" size="small">开放</el-tag>
|
||||||
|
<el-tag v-else type="info" size="small">关闭</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="bz" label="备注" min-width="120" align="left" header-align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button type="text" size="small" @click="handleEditCalendar(row)">班历</el-button>
|
||||||
|
<el-button type="text" size="small" class="text-danger" @click="handleDeleteRow(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="zxf" label="总学分" width="70" align="center" show-overflow-tooltip />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
class="list-pagination"
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:total="total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 教学班次学期信息明细弹窗(新添) ==================== -->
|
<!-- ==================== 班次学期新增/编辑弹窗 ==================== -->
|
||||||
<ClassSemesterDetailDialog
|
<ClassSemesterDetailDialog
|
||||||
:visible="detailVisible"
|
:visible="detailVisible"
|
||||||
:class-info="selectedNewClass"
|
:mode="detailMode"
|
||||||
:semester-name="semesterName"
|
:semester="detailSemester"
|
||||||
|
:team-info="detailTeamInfo"
|
||||||
|
:year-options="yearOptions"
|
||||||
|
:task-options="taskOptions"
|
||||||
@update:visible="val => detailVisible = val"
|
@update:visible="val => detailVisible = val"
|
||||||
@confirm="handleDetailConfirm"
|
@submit="handleDetailSubmit"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- ==================== 班历设置弹窗(编辑班历) ==================== -->
|
<!-- ==================== 班历管理弹窗 ==================== -->
|
||||||
<ClassCalendarDialog
|
<ClassCalendarDialog
|
||||||
:visible="calendarVisible"
|
:visible="calendarVisible"
|
||||||
:bc="currentRow ? currentRow.bc : ''"
|
:semester="calendarSemester"
|
||||||
:semester-name="semesterName"
|
:semester-options="semesterOptions"
|
||||||
@update:visible="val => calendarVisible = val"
|
@update:visible="val => calendarVisible = val"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- ==================== 预设合班弹窗 ==================== -->
|
<!-- ==================== 批量创建班次学期弹窗 ==================== -->
|
||||||
<ClassTeamSelectDialog
|
<el-dialog
|
||||||
:visible="teamVisible"
|
:visible="batchAddVisible"
|
||||||
@update:visible="val => teamVisible = val"
|
title="批量创建班次学期"
|
||||||
@confirm="handleTeamConfirm"
|
width="520px"
|
||||||
/>
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => batchAddVisible = val"
|
||||||
|
>
|
||||||
|
<el-form ref="batchAddFormRef" :model="batchAddForm" :rules="batchAddRules" label-width="100px">
|
||||||
|
<el-form-item label="年度" prop="nd">
|
||||||
|
<el-select v-model="batchAddForm.nd" placeholder="请选择年度" style="width: 100%">
|
||||||
|
<el-option v-for="y in yearOptions" :key="y" :label="`${y}年`" :value="y" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="学期" prop="xqdc">
|
||||||
|
<el-select v-model="batchAddForm.xqdc" placeholder="请选择学期" style="width: 100%">
|
||||||
|
<el-option label="春季学期" value="春季学期" />
|
||||||
|
<el-option label="夏季学期" value="夏季学期" />
|
||||||
|
<el-option label="秋季学期" value="秋季学期" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开始日期" prop="startTime">
|
||||||
|
<el-date-picker v-model="batchAddForm.startTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择开始日期" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束日期" prop="endTime">
|
||||||
|
<el-date-picker v-model="batchAddForm.endTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择结束日期" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="batchAddVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="saving" @click="handleBatchAddSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- ==================== 班次学期配档编辑弹窗 ==================== -->
|
<!-- ==================== 快速设定学期日期弹窗 ==================== -->
|
||||||
<PeidangEditDialog
|
<el-dialog
|
||||||
:visible="peidangVisible"
|
:visible="dateRangeVisible"
|
||||||
:semester-name="semesterName"
|
title="快速设定学期日期"
|
||||||
:class-label="peidangClassLabel"
|
width="480px"
|
||||||
@update:visible="val => peidangVisible = val"
|
:close-on-click-modal="false"
|
||||||
@confirm="handleAction('配档编辑')"
|
@update:visible="val => dateRangeVisible = val"
|
||||||
/>
|
>
|
||||||
|
<el-alert
|
||||||
|
type="info"
|
||||||
|
:closable="false"
|
||||||
|
show-icon
|
||||||
|
:title="`将对选中的 ${selection.length} 条班次学期统一设定开学/结束日期`"
|
||||||
|
style="margin-bottom: 16px"
|
||||||
|
/>
|
||||||
|
<el-form ref="dateRangeFormRef" :model="dateRangeForm" :rules="dateRangeRules" label-width="100px">
|
||||||
|
<el-form-item label="开学日期" prop="kxrq">
|
||||||
|
<el-date-picker v-model="dateRangeForm.kxrq" type="date" value-format="yyyy-MM-dd" placeholder="请选择开学日期" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束日期" prop="jsrq">
|
||||||
|
<el-date-picker v-model="dateRangeForm.jsrq" type="date" value-format="yyyy-MM-dd" placeholder="请选择结束日期" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="dateRangeVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="saving" @click="handleDateRangeSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ==================== 批量设置教学任务弹窗 ==================== -->
|
||||||
|
<el-dialog
|
||||||
|
:visible="jxrwVisible"
|
||||||
|
title="批量设置教学任务"
|
||||||
|
width="480px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => jxrwVisible = val"
|
||||||
|
>
|
||||||
|
<el-alert
|
||||||
|
type="info"
|
||||||
|
:closable="false"
|
||||||
|
show-icon
|
||||||
|
:title="`将对选中的 ${selection.length} 条班次学期统一设置教学任务`"
|
||||||
|
style="margin-bottom: 16px"
|
||||||
|
/>
|
||||||
|
<el-form ref="jxrwFormRef" :model="jxrwForm" :rules="jxrwRules" label-width="100px">
|
||||||
|
<el-form-item label="教学任务" prop="jxrwbh">
|
||||||
|
<el-select v-model="jxrwForm.jxrwbh" placeholder="请选择教学任务" filterable style="width: 100%">
|
||||||
|
<el-option v-for="opt in taskOptions" :key="opt.bh" :label="opt.rwmc" :value="opt.bh" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="jxrwVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="saving" @click="handleJxrwSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ClassSemesterDetailDialog from './ClassSemesterDetailDialog.vue'
|
import ClassSemesterDetailDialog from './ClassSemesterDetailDialog.vue'
|
||||||
import ClassCalendarDialog from './ClassCalendarDialog.vue'
|
import ClassCalendarDialog from './ClassCalendarDialog.vue'
|
||||||
import ClassTeamSelectDialog from './ClassTeamSelectDialog.vue'
|
import { listSemester, allSemester, addSemester, updateSemester, delSemester, batchDeleteSemester, batchUpdateDateRange, batchUpdateJxrwbh, batchAddFromElective } from '@/api/studentRecords/semester'
|
||||||
import PeidangEditDialog from './PeidangEditDialog.vue'
|
import { listAllSemester } from '@/api/teachBusiness/semester'
|
||||||
|
import { listTeachingTask } from '@/api/teachBusiness/teachingTask'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ShiftSemester',
|
name: 'ShiftSemester',
|
||||||
components: {
|
components: {
|
||||||
ClassSemesterDetailDialog,
|
ClassSemesterDetailDialog,
|
||||||
ClassCalendarDialog,
|
ClassCalendarDialog
|
||||||
ClassTeamSelectDialog,
|
|
||||||
PeidangEditDialog
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 1. 学年学期标题区 ====================
|
loading: false,
|
||||||
semesterName: '2017-2018学年第一学期',
|
saving: false,
|
||||||
|
|
||||||
// ==================== 2. 校历 / 预设日期信息区 ====================
|
// ==================== 查询条件 ====================
|
||||||
/** 校历日期 */
|
searchForm: { xydbh: '' },
|
||||||
semester: {
|
filterYear: undefined,
|
||||||
kxrq: '2017-07-08', // 校历开学日期
|
yearFilterOptions: [],
|
||||||
jsrq: '2018-02-11', // 校历结束日期
|
|
||||||
weeks: 32 // 学期周数
|
|
||||||
},
|
|
||||||
/** 预设(班次)日期 */
|
|
||||||
preset: {
|
|
||||||
kxrq: '2017-07-08', // 预设开学日期
|
|
||||||
jsrq: '2018-02-11', // 预设结束日期
|
|
||||||
weeks: 32 // 预设学期周数
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 3. 工具栏按钮区 ====================
|
// ==================== 列表与分页 ====================
|
||||||
/** 可新建学期信息的班次 */
|
tableData: [],
|
||||||
newableClasses: [
|
selection: [],
|
||||||
{ bc: '班次0633', xkzy: '专业209', nj: '2017级' },
|
|
||||||
{ bc: '班次0634', xkzy: '专业209', nj: '2017级' },
|
|
||||||
{ bc: '班次0709', xkzy: '专业205', nj: '2017级' },
|
|
||||||
{ bc: '班次0710', xkzy: '专业205', nj: '2017级' },
|
|
||||||
{ bc: '班次0901', xkzy: '专业301', nj: '2017级' }
|
|
||||||
],
|
|
||||||
|
|
||||||
/** 教学班次学期信息明细弹窗(新添) */
|
|
||||||
detailVisible: false,
|
|
||||||
selectedNewClass: null,
|
|
||||||
|
|
||||||
/** 班历设置弹窗(编辑班历) */
|
|
||||||
calendarVisible: false,
|
|
||||||
currentRow: null,
|
currentRow: null,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
|
||||||
/** 预设合班弹窗 */
|
// ==================== 下拉数据 ====================
|
||||||
teamVisible: false,
|
/** 年度下拉(来自 /semester/all) */
|
||||||
|
yearOptions: [],
|
||||||
|
/** 教学任务下拉({ bh, rwmc }) */
|
||||||
|
taskOptions: [],
|
||||||
|
/** 全部班次学期(用于班历复制目标选择) */
|
||||||
|
semesterOptions: [],
|
||||||
|
|
||||||
/** 配档编辑弹窗(班次学期配档)显示状态 */
|
// ==================== 班次学期新增/编辑 ====================
|
||||||
peidangVisible: false,
|
detailVisible: false,
|
||||||
/** 配档编辑弹窗标题(班次学期配档——...——班次) */
|
detailMode: 'add',
|
||||||
peidangClassLabel: '',
|
detailSemester: null,
|
||||||
|
detailTeamInfo: null,
|
||||||
|
|
||||||
/** 排序方式:xh=序号排序 / bw=波次排序 */
|
// ==================== 班历管理 ====================
|
||||||
sortType: 'xh',
|
calendarVisible: false,
|
||||||
|
calendarSemester: null,
|
||||||
|
|
||||||
/** 波次背景色(同一波次使用同一颜色连在一起显示) */
|
// ==================== 批量创建班次学期 ====================
|
||||||
bwColors: [
|
batchAddVisible: false,
|
||||||
'#e3f2fd', // 浅蓝
|
batchAddForm: { nd: undefined, xqdc: '', startTime: '', endTime: '' },
|
||||||
'#e8f5e9', // 浅绿
|
batchAddRules: {
|
||||||
'#fff8e1', // 浅黄
|
nd: [{ required: true, message: '请选择年度', trigger: 'change' }],
|
||||||
'#f3e5f5', // 浅紫
|
xqdc: [{ required: true, message: '请选择学期', trigger: 'change' }],
|
||||||
'#e0f2f1' // 浅青
|
startTime: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
|
||||||
],
|
endTime: [{ required: true, message: '请选择结束日期', trigger: 'change' }]
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 4. 班次学期信息列表 ====================
|
// ==================== 快速设定学期日期 ====================
|
||||||
tableData: [
|
dateRangeVisible: false,
|
||||||
// ---- 学员1队(跨 10 行) ----
|
dateRangeForm: { kxrq: '', jsrq: '' },
|
||||||
{ xzdw: '学员1队', xh: 1, bw: 1, bc: '0150', rs: 40, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-307', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 512, zxs: 21.33, zxf: 40 },
|
dateRangeRules: {
|
||||||
{ xzdw: '学员1队', xh: 2, bw: 1, bc: '0151', rs: 40, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-307', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 512, zxs: 21.33, zxf: 40 },
|
kxrq: [{ required: true, message: '请选择开学日期', trigger: 'change' }],
|
||||||
{ xzdw: '学员1队', xh: 3, bw: 1, bc: '0152', rs: 40, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-308', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 512, zxs: 21.33, zxf: 40 },
|
jsrq: [{ required: true, message: '请选择结束日期', trigger: 'change' }]
|
||||||
{ xzdw: '学员1队', xh: 4, bw: 1, bc: '0153', rs: 40, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-308', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 512, zxs: 21.33, zxf: 40 },
|
},
|
||||||
{ xzdw: '学员1队', xh: 5, bw: 1, bc: '0154', rs: 42, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-309', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 528, zxs: 22.0, zxf: 42 },
|
|
||||||
{ xzdw: '学员1队', xh: 6, bw: 1, bc: '0155', rs: 42, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-309', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 528, zxs: 22.0, zxf: 42 },
|
// ==================== 批量设置教学任务 ====================
|
||||||
{ xzdw: '学员1队', xh: 7, bw: 1, bc: '0156', rs: 42, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-310', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 15, kczs: 540, zxs: 22.5, zxf: 43 },
|
jxrwVisible: false,
|
||||||
{ xzdw: '学员1队', xh: 8, bw: 1, bc: '0157', rs: 38, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-310', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 15, kczs: 540, zxs: 22.5, zxf: 43 },
|
jxrwForm: { jxrwbh: undefined },
|
||||||
{ xzdw: '学员1队', xh: 9, bw: 1, bc: '0158', rs: 38, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-311', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 512, zxs: 21.33, zxf: 40 },
|
jxrwRules: {
|
||||||
{ xzdw: '学员1队', xh: 10, bw: 1, bc: '0159', rs: 38, nj: '2017级秋', xkzy: '专业5', kxrq: '2017-09-03', jsrq: '2018-02-05', xqcc: '第1学期', zyjs: '1-311', jxrw: '2017年下半年教学任务', zs: 24, kcrws: 14, kczs: 512, zxs: 21.33, zxf: 40 },
|
jxrwbh: [{ required: true, message: '请选择教学任务', trigger: 'change' }]
|
||||||
// ---- 教学五系(跨 2 行) ----
|
}
|
||||||
{ xzdw: '教学五系', xh: 11, bw: 2, bc: '0201', rs: 30, nj: '2016级', xkzy: '专业113', kxrq: '2017-08-24', jsrq: '2018-02-05', xqcc: '第3学期', zyjs: '6-202', jxrw: '2017年下半年教学任务', zs: 25, kcrws: 12, kczs: 480, zxs: 19.2, zxf: 36 },
|
|
||||||
{ xzdw: '教学五系', xh: 12, bw: 2, bc: '0202', rs: 30, nj: '2016级', xkzy: '专业113', kxrq: '2017-08-24', jsrq: '2018-02-05', xqcc: '第3学期', zyjs: '6-202', jxrw: '2017年下半年教学任务', zs: 25, kcrws: 12, kczs: 480, zxs: 19.2, zxf: 36 },
|
|
||||||
// ---- 教学七系(跨 3 行) ----
|
|
||||||
{ xzdw: '教学七系', xh: 13, bw: 3, bc: '0203', rs: 36, nj: '2016级', xkzy: '专业115', kxrq: '2017-08-24', jsrq: '2018-02-05', xqcc: '第3学期', zyjs: '8-007', jxrw: '2017年下半年教学任务', zs: 25, kcrws: 13, kczs: 520, zxs: 20.8, zxf: 38 },
|
|
||||||
{ xzdw: '教学七系', xh: 14, bw: 3, bc: '0204', rs: 36, nj: '2016级', xkzy: '专业115', kxrq: '2017-08-24', jsrq: '2018-02-05', xqcc: '第3学期', zyjs: '8-007', jxrw: '2017年下半年教学任务', zs: 25, kcrws: 13, kczs: 520, zxs: 20.8, zxf: 38 },
|
|
||||||
{ xzdw: '教学七系', xh: 15, bw: 3, bc: '0205', rs: 36, nj: '2016级', xkzy: '专业115', kxrq: '2017-08-24', jsrq: '2018-02-05', xqcc: '第3学期', zyjs: '8-008', jxrw: '2017年下半年教学任务', zs: 25, kcrws: 13, kczs: 520, zxs: 20.8, zxf: 38 }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
/** 排序方式标签 */
|
/** 本地按年度过滤(后端 /semester/list 仅支持 xydbh 模糊筛选) */
|
||||||
sortLabel() {
|
|
||||||
return this.sortType === 'bw' ? '波次排序' : '序号排序'
|
|
||||||
},
|
|
||||||
/** 根据排序方式展示列表:波次排序时按波次分组连排 */
|
|
||||||
displayData() {
|
displayData() {
|
||||||
if (this.sortType === 'bw') {
|
if (!this.filterYear) return this.tableData
|
||||||
return [...this.tableData].sort((a, b) => a.bw - b.bw || a.xh - b.xh)
|
return this.tableData.filter(item => String(item.nd) === String(this.filterYear))
|
||||||
}
|
|
||||||
return this.tableData
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 默认选中第一行 班次0150(高亮)
|
this.loadYearOptions()
|
||||||
this.$nextTick(() => {
|
this.loadTaskOptions()
|
||||||
if (this.tableData.length && this.$refs.tableRef) {
|
this.loadSemesterOptions()
|
||||||
this.$refs.tableRef.setCurrentRow(this.tableData[0])
|
this.loadList()
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 2. 校历 / 预设日期 ====================
|
/* ==================== 格式化 ==================== */
|
||||||
/** 吸取日期:将校历日期复制到预设日期 */
|
fmtDate(val) {
|
||||||
handleAbsorbDate() {
|
if (!val) return '-'
|
||||||
this.preset.kxrq = this.semester.kxrq
|
return String(val).slice(0, 10)
|
||||||
this.preset.jsrq = this.semester.jsrq
|
},
|
||||||
this.preset.weeks = this.semester.weeks
|
xqdcLabel(val) {
|
||||||
this.$message.success('已吸取校历日期到预设日期')
|
if (val === 1 || val === '1') return '第1学期'
|
||||||
|
if (val === 2 || val === '2') return '第2学期'
|
||||||
|
if (val === 3 || val === '3') return '第3学期'
|
||||||
|
return val !== undefined && val !== null && val !== '' ? `第${val}学期` : '-'
|
||||||
|
},
|
||||||
|
/** 教学任务编号 → 名称 */
|
||||||
|
taskName(bh) {
|
||||||
|
if (!bh) return '-'
|
||||||
|
const opt = this.taskOptions.find(o => o.bh === bh)
|
||||||
|
return opt ? opt.rwmc : bh
|
||||||
|
},
|
||||||
|
cleanPayload(obj) {
|
||||||
|
const payload = {}
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
payload[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return payload
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 快速设定学期日期 */
|
/* ==================== 下拉数据加载 ==================== */
|
||||||
handleQuickSetDates() {
|
loadYearOptions() {
|
||||||
this.$message.success('快速设定学期日期(前端演示)')
|
listAllSemester().then(res => {
|
||||||
|
const list = (res && res.data) || []
|
||||||
|
const years = list.map(x => x.nd).filter(v => v !== undefined && v !== null && v !== '')
|
||||||
|
this.yearOptions = [...new Set(years)].sort((a, b) => Number(a) - Number(b))
|
||||||
|
}).catch(() => {
|
||||||
|
this.yearOptions = []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadTaskOptions() {
|
||||||
|
listTeachingTask({ pageNum: 1, pageSize: 1000 }).then(res => {
|
||||||
|
const list = (res && res.data && res.data.records) || []
|
||||||
|
this.taskOptions = list.filter(o => o.bh)
|
||||||
|
}).catch(() => {
|
||||||
|
this.taskOptions = []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadSemesterOptions() {
|
||||||
|
allSemester().then(res => {
|
||||||
|
this.semesterOptions = (res && res.data) || []
|
||||||
|
}).catch(() => {
|
||||||
|
this.semesterOptions = []
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 3. 工具栏按钮区 ====================
|
/* ==================== 列表加载 ==================== */
|
||||||
/** 通用操作(前端演示) */
|
loadList() {
|
||||||
handleAction(name) {
|
this.loading = true
|
||||||
this.$message.success(`${name}(前端演示)`)
|
const query = this.cleanPayload({
|
||||||
|
pageNum: this.pageNum,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
xydbh: this.searchForm.xydbh
|
||||||
|
})
|
||||||
|
listSemester(query).then(res => {
|
||||||
|
const data = (res && res.data) || {}
|
||||||
|
this.tableData = data.records || []
|
||||||
|
this.total = data.total || 0
|
||||||
|
this.buildYearFilterOptions()
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
/** 本地年度过滤下拉(从当前数据动态生成,避免硬编码) */
|
||||||
/** 新添:从下拉选择班次后打开明细弹窗 */
|
buildYearFilterOptions() {
|
||||||
handleNewCommand(item) {
|
const years = this.tableData.map(r => r.nd).filter(v => v !== undefined && v !== null && v !== '')
|
||||||
if (typeof item === 'string') return
|
this.yearFilterOptions = [...new Set(years)].sort((a, b) => Number(a) - Number(b))
|
||||||
this.selectedNewClass = item
|
|
||||||
this.detailVisible = true
|
|
||||||
},
|
},
|
||||||
|
handleYearChange() {
|
||||||
handleDetailConfirm() {
|
this.$nextTick(() => {
|
||||||
this.$message.success('已创建班次学期信息(前端演示)')
|
if (this.$refs.tableRef) this.$refs.tableRef.setCurrentRow(null)
|
||||||
|
this.currentRow = null
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
handleSizeChange(size) {
|
||||||
/** 编辑班历 */
|
this.pageSize = size
|
||||||
handleEditCalendar() {
|
this.loadList()
|
||||||
if (!this.currentRow) {
|
|
||||||
this.$message.warning('请先在列表中选择一条班次学期信息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.calendarVisible = true
|
|
||||||
},
|
},
|
||||||
|
handlePageChange(page) {
|
||||||
/** 预设合班 */
|
this.pageNum = page
|
||||||
handleMerge() {
|
this.loadList()
|
||||||
this.teamVisible = true
|
|
||||||
},
|
},
|
||||||
handleTeamConfirm(teams) {
|
handleSelectionChange(rows) {
|
||||||
this.$message.success(`预设合班已应用于 ${teams.length} 个班次(前端演示)`)
|
this.selection = rows
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 配档编辑:选择班次后打开班次学期配档窗口 */
|
|
||||||
handlePeidangEdit() {
|
|
||||||
if (!this.currentRow) {
|
|
||||||
this.$message.warning('请先在列表中选择一个班次')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const row = this.currentRow
|
|
||||||
this.peidangClassLabel = `${row.xzdw}${row.nj}${row.xkzy}班次${row.bc}`
|
|
||||||
this.peidangVisible = true
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSortCommand(command) {
|
|
||||||
this.sortType = command
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 行样式:波次排序时同一波次使用同一背景色 */
|
|
||||||
rowClassName({ row }) {
|
|
||||||
if (this.sortType !== 'bw') return ''
|
|
||||||
const colorIndex = (row.bw - 1) % this.bwColors.length
|
|
||||||
return `bw-row bw-row-${colorIndex}`
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 4. 班次学期信息列表 ====================
|
|
||||||
handleCurrentChange(row) {
|
handleCurrentChange(row) {
|
||||||
this.currentRow = row
|
this.currentRow = row
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 合并单元格:行政队别列(第一列)纵向合并相同值 */
|
/* ==================== 查询 / 重置 ==================== */
|
||||||
spanMethod({ rowIndex, columnIndex }) {
|
handleQuery() {
|
||||||
if (columnIndex === 0) {
|
this.pageNum = 1
|
||||||
const list = this.displayData
|
this.loadList()
|
||||||
const current = list[rowIndex]
|
},
|
||||||
// 非分组首行,隐藏
|
handleReset() {
|
||||||
if (rowIndex > 0 && list[rowIndex - 1].xzdw === current.xzdw) {
|
this.searchForm.xydbh = ''
|
||||||
return { rowspan: 0, colspan: 0 }
|
this.filterYear = undefined
|
||||||
}
|
this.pageNum = 1
|
||||||
// 统计连续相同行政队别的行数
|
this.loadList()
|
||||||
let rowspan = 1
|
|
||||||
for (let i = rowIndex + 1; i < list.length; i++) {
|
|
||||||
if (list[i].xzdw === current.xzdw) rowspan++
|
|
||||||
else break
|
|
||||||
}
|
|
||||||
return { rowspan, colspan: 1 }
|
|
||||||
}
|
|
||||||
return { rowspan: 1, colspan: 1 }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 表头特殊样式:总课程数 / 总课时数列红色框标注 */
|
/* ==================== 新增 / 编辑 ==================== */
|
||||||
headerCellClassName({ column }) {
|
handleAdd() {
|
||||||
if (column.property === 'kcrws' || column.property === 'kczs') {
|
this.detailMode = 'add'
|
||||||
return 'red-header-cell'
|
this.detailSemester = null
|
||||||
|
this.detailTeamInfo = null
|
||||||
|
this.detailVisible = true
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
const target = row || this.currentRow
|
||||||
|
if (!target) {
|
||||||
|
this.$message.warning('请先选择一条班次学期信息')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return ''
|
this.detailMode = 'edit'
|
||||||
|
this.detailSemester = target
|
||||||
|
this.detailTeamInfo = null
|
||||||
|
this.detailVisible = true
|
||||||
|
},
|
||||||
|
handleDetailSubmit(payload) {
|
||||||
|
this.saving = true
|
||||||
|
const req = this.detailMode === 'edit'
|
||||||
|
? updateSemester(payload)
|
||||||
|
: addSemester(payload)
|
||||||
|
req.then(() => {
|
||||||
|
this.saving = false
|
||||||
|
this.detailVisible = false
|
||||||
|
this.$message.success(this.detailMode === 'edit' ? '班次学期已更新' : '班次学期已新增')
|
||||||
|
this.loadList()
|
||||||
|
this.loadSemesterOptions()
|
||||||
|
}).catch(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ==================== 删除 ==================== */
|
||||||
|
handleDelete() {
|
||||||
|
if (!this.selection.length) {
|
||||||
|
this.$message.warning('请先勾选要删除的班次学期')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$confirm(`确定删除选中的 ${this.selection.length} 条班次学期吗?删除后其下班历记录将一并删除。`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const bhList = this.selection.map(r => r.bh)
|
||||||
|
batchDeleteSemester(bhList).then(() => {
|
||||||
|
this.$message.success('已删除')
|
||||||
|
this.loadList()
|
||||||
|
this.loadSemesterOptions()
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
handleDeleteRow(row) {
|
||||||
|
this.$confirm(`确定删除班次学期「${row.xydbh || row.bh}」吗?删除后其下班历记录将一并删除。`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
delSemester(row.bh).then(() => {
|
||||||
|
this.$message.success('已删除')
|
||||||
|
this.loadList()
|
||||||
|
this.loadSemesterOptions()
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ==================== 编辑班历 ==================== */
|
||||||
|
handleEditCalendar(row) {
|
||||||
|
const target = row || this.currentRow
|
||||||
|
if (!target) {
|
||||||
|
this.$message.warning('请先在列表中选择一条班次学期信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.calendarSemester = target
|
||||||
|
this.calendarVisible = true
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ==================== 批量创建班次学期 ==================== */
|
||||||
|
handleBatchAdd() {
|
||||||
|
this.batchAddForm = { nd: this.yearOptions[0] || undefined, xqdc: '', startTime: '', endTime: '' }
|
||||||
|
this.batchAddVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchAddFormRef) this.$refs.batchAddFormRef.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleBatchAddSubmit() {
|
||||||
|
this.$refs.batchAddFormRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
const f = this.batchAddForm
|
||||||
|
this.saving = true
|
||||||
|
batchAddFromElective({
|
||||||
|
nd: f.nd,
|
||||||
|
xqdc: f.xqdc,
|
||||||
|
startTime: f.startTime,
|
||||||
|
endTime: f.endTime
|
||||||
|
}).then(res => {
|
||||||
|
this.saving = false
|
||||||
|
this.batchAddVisible = false
|
||||||
|
const count = (res && res.data) || 0
|
||||||
|
this.$message.success(`已创建 ${count} 个班次学期`)
|
||||||
|
this.loadList()
|
||||||
|
this.loadSemesterOptions()
|
||||||
|
}).catch(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ==================== 快速设定学期日期 ==================== */
|
||||||
|
handleQuickSetDates() {
|
||||||
|
if (!this.selection.length) {
|
||||||
|
this.$message.warning('请先勾选要设定日期的班次学期')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.dateRangeForm = { kxrq: '', jsrq: '' }
|
||||||
|
this.dateRangeVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.dateRangeFormRef) this.$refs.dateRangeFormRef.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleDateRangeSubmit() {
|
||||||
|
this.$refs.dateRangeFormRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
const f = this.dateRangeForm
|
||||||
|
this.saving = true
|
||||||
|
batchUpdateDateRange({
|
||||||
|
bhList: this.selection.map(r => r.bh),
|
||||||
|
xqkssj: f.kxrq,
|
||||||
|
xqjssj: f.jsrq
|
||||||
|
}).then(res => {
|
||||||
|
this.saving = false
|
||||||
|
this.dateRangeVisible = false
|
||||||
|
const count = (res && res.data) || 0
|
||||||
|
this.$message.success(`已更新 ${count} 条班次学期的日期`)
|
||||||
|
this.loadList()
|
||||||
|
}).catch(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ==================== 批量设置教学任务 ==================== */
|
||||||
|
handleSetJxrw() {
|
||||||
|
if (!this.selection.length) {
|
||||||
|
this.$message.warning('请先勾选要设置教学任务的班次学期')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.jxrwForm = { jxrwbh: undefined }
|
||||||
|
this.jxrwVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.jxrwFormRef) this.$refs.jxrwFormRef.clearValidate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleJxrwSubmit() {
|
||||||
|
this.$refs.jxrwFormRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
this.saving = true
|
||||||
|
batchUpdateJxrwbh({
|
||||||
|
bhList: this.selection.map(r => r.bh),
|
||||||
|
jxrwbh: this.jxrwForm.jxrwbh
|
||||||
|
}).then(res => {
|
||||||
|
this.saving = false
|
||||||
|
this.jxrwVisible = false
|
||||||
|
const count = (res && res.data) || 0
|
||||||
|
this.$message.success(`已更新 ${count} 条班次学期的教学任务`)
|
||||||
|
this.loadList()
|
||||||
|
}).catch(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,8 +597,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.shift-semester-page {
|
.shift-semester-page {
|
||||||
// ========== 1. 学年学期标题 ==========
|
// ========== 页面标题 ==========
|
||||||
.list-title {
|
.page-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
@@ -385,44 +607,12 @@ export default {
|
|||||||
border-left: 4px solid var(--edu-green-primary);
|
border-left: 4px solid var(--edu-green-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 2. 校历 / 预设日期信息区 ==========
|
// ========== 1. 查询条件区域 ==========
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
.search-form {
|
|
||||||
.date-group {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 4px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-group-label {
|
|
||||||
flex-shrink: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.absorb-btn {
|
|
||||||
margin-left: auto;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-form-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 3. 工具栏按钮区 ==========
|
// ========== 2. 工具栏按钮区 ==========
|
||||||
.list-toolbar {
|
.list-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -440,46 +630,19 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 新建下拉菜单 ==========
|
// ========== 3. 数据表格区 ==========
|
||||||
.new-class-menu {
|
|
||||||
max-height: 320px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 4. 数据表格区 ==========
|
|
||||||
$bwColors: (#e3f2fd, #e8f5e9, #fff8e1, #f3e5f5, #e0f2f1);
|
|
||||||
|
|
||||||
.table-card {
|
.table-card {
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.class-table {
|
.class-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
// 波次背景色(同一合班波次使用同一背景颜色连在一起显示)
|
.text-danger {
|
||||||
@for $i from 0 through length($bwColors) - 1 {
|
color: #f56c6c;
|
||||||
::v-deep(.el-table__body tr.bw-row-#{$i} > td.el-table__cell) {
|
}
|
||||||
background-color: nth($bwColors, $i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-table__body tr.bw-row-#{$i}:hover > td.el-table__cell) {
|
.list-pagination {
|
||||||
background-color: nth($bwColors, $i + 1);
|
margin-top: 12px;
|
||||||
}
|
text-align: right;
|
||||||
}
|
|
||||||
|
|
||||||
// 当前行高亮(优先于波次背景色)
|
|
||||||
::v-deep(.el-table__body tr.current-row > td.el-table__cell) {
|
|
||||||
background-color: #e1f5ec;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-table__body tr.current-row:hover > td.el-table__cell) {
|
|
||||||
background-color: #e1f5ec;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 表头红色框标注列(总课程数 / 总课时数)
|
|
||||||
::v-deep(th.red-header-cell) {
|
|
||||||
border: 2px solid #f56c6c !important;
|
|
||||||
background: #fdeaea !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container subject-page">
|
<div class="app-container subject-page">
|
||||||
<!-- ==================== 1. 顶部状态提示 ==================== -->
|
|
||||||
<div class="status-tip">{{ statusTip }}</div>
|
|
||||||
|
|
||||||
<!-- ==================== 2. 查询条件区域 ==================== -->
|
<!-- ==================== 2. 查询条件区域 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
@@ -10,152 +8,41 @@
|
|||||||
<!-- 左栏 -->
|
<!-- 左栏 -->
|
||||||
<el-col :xs="24" :md="12">
|
<el-col :xs="24" :md="12">
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<span class="q-label no-check">课程别名</span>
|
<span class="q-label no-check">课名称</span>
|
||||||
<el-input v-model="searchForm.kcbh" placeholder="请输入课程别名" clearable class="q-control" />
|
<el-input v-model="searchForm.kmc" placeholder="请输入课名称" clearable class="q-control" />
|
||||||
</div>
|
</div>
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<span class="q-label no-check">简称</span>
|
<span class="q-label no-check">科目代码</span>
|
||||||
<el-input v-model="searchForm.jc" placeholder="请输入简称" clearable class="q-control" />
|
<el-input v-model="searchForm.kmdm" placeholder="请输入科目代码" clearable class="q-control" />
|
||||||
</div>
|
</div>
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<span class="q-label no-check">学分</span>
|
<span class="q-label no-check">培训层次</span>
|
||||||
<div class="q-control range-control">
|
<el-input v-model="searchForm.pxcc" placeholder="请输入培训层次" clearable class="q-control" />
|
||||||
<el-input v-model="searchForm.xfMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="searchForm.xfMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<span class="q-label no-check">学时</span>
|
<span class="q-label no-check">课程类型</span>
|
||||||
<div class="q-control range-control">
|
<el-input v-model="searchForm.kclx" placeholder="请输入课程类型" clearable class="q-control" />
|
||||||
<el-input v-model="searchForm.xsMin" placeholder="0" />
|
|
||||||
<span class="range-sep">至</span>
|
|
||||||
<el-input v-model="searchForm.xsMax" placeholder="0" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.zcfsEnabled" />
|
|
||||||
<span class="q-label">支持方式</span>
|
|
||||||
<el-select v-model="searchForm.zcfs" class="q-control" :disabled="!searchForm.zcfsEnabled">
|
|
||||||
<el-option v-for="item in zcfsOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.khlxEnabled" />
|
|
||||||
<span class="q-label">考核类型</span>
|
|
||||||
<el-select v-model="searchForm.khlx" class="q-control" :disabled="!searchForm.khlxEnabled">
|
|
||||||
<el-option v-for="item in khlxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<span class="q-label no-check">秘密等级</span>
|
|
||||||
<el-select v-model="searchForm.mmdj" placeholder="请选择" class="q-control">
|
|
||||||
<el-option v-for="item in mmdjOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.dgxzEnabled" />
|
|
||||||
<span class="q-label">大纲性质</span>
|
|
||||||
<el-radio-group v-model="searchForm.dgxz" class="q-control" :disabled="!searchForm.dgxzEnabled">
|
|
||||||
<el-radio :label="'大纲课程'">大纲课程</el-radio>
|
|
||||||
<el-radio :label="'非大纲课程'">非大纲课程</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.zzglEnabled" />
|
|
||||||
<span class="q-label">政治类课程</span>
|
|
||||||
<el-radio-group v-model="searchForm.zzgl" class="q-control" :disabled="!searchForm.zzglEnabled">
|
|
||||||
<el-radio :label="'政治类'">政治类</el-radio>
|
|
||||||
<el-radio :label="'非政治类'">非政治类</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<span class="q-label no-check">备注</span>
|
|
||||||
<el-input v-model="searchForm.bz" placeholder="请输入备注" clearable class="q-control" />
|
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 右栏 -->
|
<!-- 右栏 -->
|
||||||
<el-col :xs="24" :md="12">
|
<el-col :xs="24" :md="12">
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<el-checkbox v-model="searchForm.jysEnabled" />
|
<span class="q-label no-check">简称</span>
|
||||||
<span class="q-label">教研室</span>
|
<el-input v-model="searchForm.jc" placeholder="请输入简称" clearable class="q-control" />
|
||||||
<el-select v-model="searchForm.jys" class="q-control" :disabled="!searchForm.jysEnabled">
|
|
||||||
<el-option v-for="item in jysOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<el-checkbox v-model="searchForm.pxccEnabled" />
|
<span class="q-label no-check">教研室代号</span>
|
||||||
<span class="q-label">培训层次</span>
|
<el-input v-model="searchForm.jysdh" placeholder="请输入教研室代号" clearable class="q-control" />
|
||||||
<el-select v-model="searchForm.pxcc" class="q-control" :disabled="!searchForm.pxccEnabled">
|
|
||||||
<el-option v-for="item in pxccOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="query-field">
|
<div class="query-field">
|
||||||
<el-checkbox v-model="searchForm.pxlxEnabled" />
|
<span class="q-label no-check">培训类型</span>
|
||||||
<span class="q-label">培训类型</span>
|
<el-input v-model="searchForm.pxlx" placeholder="请输入培训类型" clearable class="q-control" />
|
||||||
<el-select v-model="searchForm.pxlx" class="q-control" :disabled="!searchForm.pxlxEnabled">
|
|
||||||
<el-option v-for="item in pxlxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.kclxEnabled" />
|
|
||||||
<span class="q-label">课程类型</span>
|
|
||||||
<el-select v-model="searchForm.kclx" class="q-control" :disabled="!searchForm.kclxEnabled">
|
|
||||||
<el-option v-for="item in kclxOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.jsfsEnabled" />
|
|
||||||
<span class="q-label">建设方式</span>
|
|
||||||
<el-select v-model="searchForm.jsfs" class="q-control" :disabled="!searchForm.jsfsEnabled">
|
|
||||||
<el-option v-for="item in jsfsOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.pjqkEnabled" />
|
|
||||||
<span class="q-label">评选情况</span>
|
|
||||||
<el-select v-model="searchForm.pjqk" class="q-control" :disabled="!searchForm.pjqkEnabled">
|
|
||||||
<el-option v-for="item in pjqkOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.gljgEnabled" />
|
|
||||||
<span class="q-label">管理机构</span>
|
|
||||||
<el-select v-model="searchForm.gljg" class="q-control" :disabled="!searchForm.gljgEnabled">
|
|
||||||
<el-option v-for="item in gljgOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.zyxzEnabled" />
|
|
||||||
<span class="q-label">在用选项</span>
|
|
||||||
<el-radio-group v-model="searchForm.zyxz" class="q-control" :disabled="!searchForm.zyxzEnabled">
|
|
||||||
<el-radio :label="'在用'">在用</el-radio>
|
|
||||||
<el-radio :label="'其他'">其他</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.bbxxEnabled" />
|
|
||||||
<span class="q-label">版本选项</span>
|
|
||||||
<el-radio-group v-model="searchForm.bbxx" class="q-control" :disabled="!searchForm.bbxxEnabled">
|
|
||||||
<el-radio :label="'最新版本'">最新版本</el-radio>
|
|
||||||
<el-radio :label="'存在多版本'">存在多版本</el-radio>
|
|
||||||
<el-radio :label="'全部版本'">全部版本</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="query-field">
|
|
||||||
<el-checkbox v-model="searchForm.bmbhEnabled" />
|
|
||||||
<span class="q-label">别名包含规范名称</span>
|
|
||||||
<el-radio-group v-model="searchForm.bmbh" class="q-control" :disabled="!searchForm.bmbhEnabled">
|
|
||||||
<el-radio :label="'完全包含'">完全包含</el-radio>
|
|
||||||
<el-radio :label="'未完全包含'">未完全包含</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="notice">注意:勾选"选择框"表示启用该项对应的查询条件,输入框非空表示启用查询条件。</div>
|
|
||||||
<div class="query-footer">
|
<div class="query-footer">
|
||||||
<el-button class="gray-btn" @click="handleQuery">查询</el-button>
|
<el-button class="gray-btn" @click="handleQuery">查询</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -189,27 +76,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 5. 红色提示文字 ==================== -->
|
|
||||||
<div class="red-tip">
|
|
||||||
提示:课程体系按"课程-专题-课题"构建的,课程名称的命名格式为"课程名称\专题名称\课题名称"或"课程名称\课题名称"。
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 6. 数据表格区域 ==================== -->
|
<!-- ==================== 6. 数据表格区域 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row
|
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row
|
||||||
@selection-change="handleSelectionChange">
|
@selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column prop="manage" label="管理" width="70" align="center" />
|
<el-table-column prop="kbh" label="课编号" width="130" show-overflow-tooltip />
|
||||||
<el-table-column prop="code" label="编码" width="100" show-overflow-tooltip />
|
<el-table-column prop="kmc" label="课名称" width="200" show-overflow-tooltip />
|
||||||
<el-table-column prop="name" label="课程名称" min-width="130" show-overflow-tooltip />
|
<el-table-column prop="jc" label="简称" width="130" show-overflow-tooltip />
|
||||||
<el-table-column prop="cat" label="分类" width="100" align="center" />
|
<el-table-column prop="jysdh" label="教研室代号" width="150" show-overflow-tooltip />
|
||||||
<el-table-column prop="exam" label="考核类型方式" width="110" align="center" />
|
<el-table-column prop="kclx" label="课程类型" width="150" align="center" />
|
||||||
<el-table-column prop="inClass" label="课内学时" width="90" align="center" />
|
<el-table-column prop="pxlx" label="培训类型" width="150" align="center" />
|
||||||
<el-table-column prop="outClass" label="课外学时" width="90" align="center" />
|
<el-table-column prop="pxcc" label="培训层次" width="200" align="center" />
|
||||||
<el-table-column prop="other" label="其他" width="80" align="center" />
|
<el-table-column prop="xf" label="学分" align="center" />
|
||||||
<el-table-column prop="textbook" label="教材" min-width="120" show-overflow-tooltip />
|
<el-table-column prop="xs" label="学时" width="160" align="center" />
|
||||||
<el-table-column prop="majors" label="开设课程专业名称" min-width="150" show-overflow-tooltip />
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||||
<el-table-column prop="teacher" label="在职主讲教员" min-width="110" show-overflow-tooltip />
|
<template slot-scope="{ row }">
|
||||||
|
<el-button type="text" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button type="text" size="small" class="text-danger" @click="handleDelete(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-pagination
|
<el-pagination
|
||||||
@@ -228,119 +114,178 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
:visible="dialogVisible"
|
:visible="dialogVisible"
|
||||||
:title="dialogTitle"
|
:title="dialogTitle"
|
||||||
width="1100px"
|
width="1000px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
class="add-dialog"
|
class="add-dialog"
|
||||||
@update:visible="val => dialogVisible = val"
|
@update:visible="val => dialogVisible = val"
|
||||||
>
|
>
|
||||||
<el-form ref="addFormRef" :model="addForm" :rules="rules" label-width="120px" class="add-form" :status-icon="false">
|
<el-form ref="addFormRef" :model="addForm" :rules="rules" label-width="120px" class="add-form" :status-icon="false">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="编号" prop="bh">
|
<el-form-item label="课编号" prop="kbh">
|
||||||
<el-input v-model="addForm.bh" placeholder="请输入编号" clearable />
|
<el-input v-model="addForm.kbh" :disabled="isEdit" placeholder="新增时留空自动生成" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="课标号" prop="kbh">
|
<el-form-item label="课名称" prop="kmc">
|
||||||
<el-input v-model="addForm.kbh" placeholder="请输入课标号" clearable />
|
<el-input v-model="addForm.kmc" placeholder="请输入课名称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="课程名称" prop="mc">
|
<el-form-item label="简称" prop="jc">
|
||||||
<el-input v-model="addForm.mc" placeholder="请输入课程名称" clearable />
|
<el-input v-model="addForm.jc" placeholder="请输入简称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="适用专业" prop="syzy">
|
<el-form-item label="教研室代号" prop="jysdh">
|
||||||
<el-input v-model="addForm.syzy" placeholder="请输入适用专业" clearable />
|
<el-input v-model="addForm.jysdh" placeholder="请输入教研室代号" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="课时数" prop="kcs">
|
<el-form-item label="学分" prop="xf">
|
||||||
<el-input-number v-model="addForm.kcs" :min="0" controls-position="right" class="w-full" />
|
<el-input-number v-model="addForm.xf" :min="0" :precision="1" controls-position="right" class="w-full" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="录入人编号" prop="zxrbh">
|
<el-form-item label="学时" prop="xs">
|
||||||
<el-input v-model="addForm.zxrbh" placeholder="请输入录入人编号" clearable />
|
<el-input-number v-model="addForm.xs" :min="0" controls-position="right" class="w-full" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="录入时间">
|
<el-form-item label="培训层次" prop="pxcc">
|
||||||
<el-input v-model="addForm.zxsj" placeholder="请输入录入时间" clearable />
|
<el-input v-model="addForm.pxcc" placeholder="请输入培训层次" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
<el-form-item label="正文">
|
<el-form-item label="培训类型" prop="pxlx">
|
||||||
<el-input v-model="addForm.zw" type="textarea" :rows="3" placeholder="请输入正文" />
|
<el-input v-model="addForm.pxlx" placeholder="请输入培训类型" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="课程类型" prop="kclx">
|
||||||
|
<el-input v-model="addForm.kclx" placeholder="请输入课程类型" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="考试课时" prop="ksks">
|
||||||
|
<el-input-number v-model="addForm.ksks" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="成绩分制" prop="cjfz">
|
||||||
|
<el-input v-model="addForm.cjfz" placeholder="请输入成绩分制" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="不计入学员平均分" prop="bjrxypjf">
|
||||||
|
<el-select v-model="addForm.bjrxypjf" class="w-full">
|
||||||
|
<el-option label="否" :value="0" />
|
||||||
|
<el-option label="是" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="理论学时" prop="llxs">
|
||||||
|
<el-input-number v-model="addForm.llxs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="实践学时" prop="sjxs">
|
||||||
|
<el-input-number v-model="addForm.sjxs" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="周课时" prop="zks">
|
||||||
|
<el-input-number v-model="addForm.zks" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="课类型" prop="klx">
|
||||||
|
<el-input v-model="addForm.klx" placeholder="请输入课类型" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="考试课时不显示" prop="ksksbxs">
|
||||||
|
<el-select v-model="addForm.ksksbxs" class="w-full">
|
||||||
|
<el-option label="否" :value="0" />
|
||||||
|
<el-option label="是" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="课程统一编号" prop="kctybh">
|
||||||
|
<el-input v-model="addForm.kctybh" placeholder="请输入课程统一编号" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="辅导答疑课时" prop="fddyks">
|
||||||
|
<el-input-number v-model="addForm.fddyks" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="自修课时" prop="zxks">
|
||||||
|
<el-input-number v-model="addForm.zxks" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="修订日期" prop="xdrq">
|
||||||
|
<el-input v-model="addForm.xdrq" placeholder="如 2026-08-24" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="节次优选级" prop="jcyxj">
|
||||||
|
<el-input v-model="addForm.jcyxj" placeholder="请输入节次优选级" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="课程支持方式" prop="kczcfs">
|
||||||
|
<el-input v-model="addForm.kczcfs" placeholder="请输入课程支持方式" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="课程建设方式" prop="kcjsfs">
|
||||||
|
<el-input v-model="addForm.kcjsfs" placeholder="请输入课程建设方式" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="政治类课程" prop="zzlkc">
|
||||||
|
<el-select v-model="addForm.zzlkc" class="w-full">
|
||||||
|
<el-option label="否" :value="0" />
|
||||||
|
<el-option label="是" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="考核方式" prop="khfs">
|
||||||
|
<el-input v-model="addForm.khfs" placeholder="请输入考核方式" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="形成性成绩分值" prop="xcxcjfz">
|
||||||
|
<el-input-number v-model="addForm.xcxcjfz" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="终结性成绩分值" prop="zjxcjfz">
|
||||||
|
<el-input-number v-model="addForm.zjxcjfz" :min="0" controls-position="right" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="密级" prop="mj">
|
||||||
|
<el-input v-model="addForm.mj" placeholder="请输入密级" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="8">
|
||||||
|
<el-form-item label="评选情况" prop="pxqk">
|
||||||
|
<el-input v-model="addForm.pxqk" placeholder="请输入评选情况" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="24">
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input v-model="addForm.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
<el-input v-model="addForm.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<div class="classroom-section">
|
|
||||||
<div class="classroom-header">
|
|
||||||
<span class="classroom-title">课堂列表</span>
|
|
||||||
<el-button type="primary" size="small" @click="handleAddClassroom">添加课堂</el-button>
|
|
||||||
</div>
|
|
||||||
<el-table :data="addForm.ktList" border size="small">
|
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
||||||
<el-table-column label="课堂编号" width="140">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input v-model="row.bh" placeholder="课堂编号" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="课堂次序" width="90">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input-number v-model="row.ktjc" :min="1" controls-position="right" class="w-full" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="教学内容" min-width="150">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input v-model="row.jxnr" placeholder="教学内容" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="教学要点" min-width="150">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input v-model="row.jxyd" placeholder="教学要点" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="教学方法" min-width="150">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input v-model="row.jxff" placeholder="教学方法" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="主讲教员数" width="100">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input-number v-model="row.zjjys" :min="0" controls-position="right" class="w-full" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="辅讲教员数" width="100">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input-number v-model="row.fjjys" :min="0" controls-position="right" class="w-full" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="教学目的" min-width="150">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input v-model="row.jxmd" placeholder="教学目的" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="教学要求" min-width="150">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-input v-model="row.jxyq" placeholder="教学要求" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="80" align="center" fixed="right">
|
|
||||||
<template slot-scope="{ $index }">
|
|
||||||
<el-button type="text" class="text-danger" @click="handleDeleteClassroom($index)">删除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
@@ -349,34 +294,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 撤回弹窗 -->
|
|
||||||
<el-dialog
|
|
||||||
:visible="withdrawDialogVisible"
|
|
||||||
title="撤回课程科目"
|
|
||||||
width="500px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
@update:visible="val => withdrawDialogVisible = val"
|
|
||||||
>
|
|
||||||
<el-form :model="withdrawForm" label-width="100px">
|
|
||||||
<el-form-item label="课程编号">
|
|
||||||
<el-input v-model="withdrawForm.bh" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="撤回原因">
|
|
||||||
<el-input v-model="withdrawForm.chyy" type="textarea" :rows="4" placeholder="请输入撤回原因" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer">
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button @click="handleCancelWithdraw">取消</el-button>
|
|
||||||
<el-button type="primary" :loading="withdrawLoading" @click="handleWithdraw">确定撤回</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { listSubject, addSubject, updateSubject, deleteSubject, getSubject } from '@/api/teachOffice/subject'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SubjectIndex',
|
name: 'SubjectIndex',
|
||||||
data() {
|
data() {
|
||||||
@@ -384,68 +307,18 @@ export default {
|
|||||||
// ==================== 1. 顶部状态提示 ====================
|
// ==================== 1. 顶部状态提示 ====================
|
||||||
statusTip: '请输入查询条件',
|
statusTip: '请输入查询条件',
|
||||||
|
|
||||||
// ==================== 下拉选项 ====================
|
|
||||||
zcfsOptions: ['其他', '讲授', '研讨', '实操'],
|
|
||||||
khlxOptions: ['讲座', '考试', '考查', '实操'],
|
|
||||||
mmdjOptions: ['公开', '内部', '秘密', '机密'],
|
|
||||||
jysOptions: ['未确定教研室', '军事基础教研室', '政治工作教研室', '装备保障教研室'],
|
|
||||||
pxccOptions: ['无', '本科', '硕士', '博士'],
|
|
||||||
pxlxOptions: ['军官基础教育', '士兵职业教育', '研究生教育', '其他'],
|
|
||||||
kclxOptions: ['其他类', '公共基础', '专业基础', '专业核心'],
|
|
||||||
jsfsOptions: ['其他', '自建', '共建', '引进'],
|
|
||||||
pjqkOptions: ['无', '国家级', '军队级', '院校级'],
|
|
||||||
gljgOptions: ['教务处', '教研室1', '教研室2'],
|
|
||||||
|
|
||||||
// ==================== 2. 查询条件 ====================
|
// ==================== 2. 查询条件 ====================
|
||||||
searchForm: {
|
searchForm: {
|
||||||
kcbh: '',
|
kmc: '',
|
||||||
jc: '',
|
jc: '',
|
||||||
xfMin: '',
|
kmdm: '',
|
||||||
xfMax: '',
|
jysdh: '',
|
||||||
xsMin: '',
|
kclx: '',
|
||||||
xsMax: '',
|
pxlx: '',
|
||||||
zcfsEnabled: false,
|
pxcc: ''
|
||||||
zcfs: '其他',
|
|
||||||
khlxEnabled: false,
|
|
||||||
khlx: '讲座',
|
|
||||||
mmdj: '',
|
|
||||||
dgxzEnabled: false,
|
|
||||||
dgxz: '大纲课程',
|
|
||||||
zzglEnabled: false,
|
|
||||||
zzgl: '政治类',
|
|
||||||
bz: '',
|
|
||||||
jysEnabled: false,
|
|
||||||
jys: '未确定教研室',
|
|
||||||
pxccEnabled: false,
|
|
||||||
pxcc: '无',
|
|
||||||
pxlxEnabled: false,
|
|
||||||
pxlx: '军官基础教育',
|
|
||||||
kclxEnabled: false,
|
|
||||||
kclx: '其他类',
|
|
||||||
jsfsEnabled: false,
|
|
||||||
jsfs: '其他',
|
|
||||||
pjqkEnabled: false,
|
|
||||||
pjqk: '无',
|
|
||||||
gljgEnabled: false,
|
|
||||||
gljg: '教务处',
|
|
||||||
zyxzEnabled: true,
|
|
||||||
zyxz: '在用',
|
|
||||||
bbxxEnabled: true,
|
|
||||||
bbxx: '最新版本',
|
|
||||||
bmbhEnabled: false,
|
|
||||||
bmbh: '完全包含'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 列表数据 ====================
|
// ==================== 列表数据 ====================
|
||||||
/** 模拟列表数据(后端接口未提供) */
|
|
||||||
mockTableData: [
|
|
||||||
{ id: 1, manage: '编辑', code: 'KCB001', name: '高等数学', cat: '公共基础', exam: '考试', inClass: 48, outClass: 16, other: '—', textbook: '高等数学(上册)', majors: '炮兵装备运用/通信工程', teacher: '张三' },
|
|
||||||
{ id: 2, manage: '编辑', code: 'KCB002', name: '导弹发射原理', cat: '专业核心', exam: '考试', inClass: 40, outClass: 16, other: '—', textbook: '导弹发射原理', majors: '炮兵装备运用', teacher: '李四' },
|
|
||||||
{ id: 3, manage: '编辑', code: 'KCB003', name: '通信原理', cat: '专业核心', exam: '考试', inClass: 48, outClass: 16, other: '—', textbook: '通信原理', majors: '通信工程', teacher: '王五' },
|
|
||||||
{ id: 4, manage: '编辑', code: 'KCB004', name: '军事英语', cat: '公共基础', exam: '考查', inClass: 30, outClass: 8, other: '—', textbook: '军事英语教程', majors: '全军各专业', teacher: '赵六' },
|
|
||||||
{ id: 5, manage: '编辑', code: 'KCB005', name: '联合作战指挥', cat: '专业核心', exam: '综合考核', inClass: 40, outClass: 20, other: '—', textbook: '联合作战指挥', majors: '军事指挥', teacher: '孙七' },
|
|
||||||
{ id: 6, manage: '编辑', code: 'KCB006', name: '装备维修训练', cat: '实践环节', exam: '实操', inClass: 0, outClass: 48, other: '—', textbook: '装备维修手册', majors: '装备保障', teacher: '周八' }
|
|
||||||
],
|
|
||||||
loading: false,
|
loading: false,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
@@ -460,22 +333,34 @@ export default {
|
|||||||
// ==================== 新增/编辑弹窗 ====================
|
// ==================== 新增/编辑弹窗 ====================
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
addLoading: false,
|
addLoading: false,
|
||||||
editLoading: false,
|
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
addForm: this.createEmptyForm(),
|
addForm: this.createEmptyForm(),
|
||||||
rules: {
|
rules: {
|
||||||
bh: [{ required: true, message: '请输入编号', trigger: 'blur' }],
|
kmc: [{ required: true, message: '请输入课名称', trigger: 'blur' }],
|
||||||
kbh: [{ required: true, message: '请输入课标号', trigger: 'blur' }],
|
jysdh: [{ required: true, message: '请输入教研室代号', trigger: 'blur' }],
|
||||||
mc: [{ required: true, message: '请输入课程名称', trigger: 'blur' }],
|
xf: [{ required: true, message: '请输入学分', trigger: 'blur' }],
|
||||||
syzy: [{ required: true, message: '请输入适用专业', trigger: 'blur' }],
|
pxcc: [{ required: true, message: '请输入培训层次', trigger: 'blur' }],
|
||||||
kcs: [{ required: true, message: '请输入课时数', trigger: 'blur' }],
|
pxlx: [{ required: true, message: '请输入培训类型', trigger: 'blur' }],
|
||||||
zxrbh: [{ required: true, message: '请输入录入人编号', trigger: 'blur' }]
|
kclx: [{ required: true, message: '请输入课程类型', trigger: 'blur' }],
|
||||||
},
|
ksks: [{ required: true, message: '请输入考试课时', trigger: 'blur' }],
|
||||||
|
cjfz: [{ required: true, message: '请输入成绩分制', trigger: 'blur' }],
|
||||||
// ==================== 撤回弹窗 ====================
|
llxs: [{ required: true, message: '请输入理论学时', trigger: 'blur' }],
|
||||||
withdrawDialogVisible: false,
|
sjxs: [{ required: true, message: '请输入实践学时', trigger: 'blur' }],
|
||||||
withdrawLoading: false,
|
zks: [{ required: true, message: '请输入周课时', trigger: 'blur' }],
|
||||||
withdrawForm: { bh: '', chyy: '' }
|
klx: [{ required: true, message: '请输入课类型', trigger: 'blur' }],
|
||||||
|
kctybh: [{ required: true, message: '请输入课程统一编号', trigger: 'blur' }],
|
||||||
|
fddyks: [{ required: true, message: '请输入辅导答疑课时', trigger: 'blur' }],
|
||||||
|
zxks: [{ required: true, message: '请输入自修课时', trigger: 'blur' }],
|
||||||
|
xdrq: [{ required: true, message: '请输入修订日期', trigger: 'blur' }],
|
||||||
|
jcyxj: [{ required: true, message: '请输入节次优选级', trigger: 'blur' }],
|
||||||
|
kczcfs: [{ required: true, message: '请输入课程支持方式', trigger: 'blur' }],
|
||||||
|
kcjsfs: [{ required: true, message: '请输入课程建设方式', trigger: 'blur' }],
|
||||||
|
khfs: [{ required: true, message: '请输入考核方式', trigger: 'blur' }],
|
||||||
|
xcxcjfz: [{ required: true, message: '请输入形成性成绩分值', trigger: 'blur' }],
|
||||||
|
zjxcjfz: [{ required: true, message: '请输入终结性成绩分值', trigger: 'blur' }],
|
||||||
|
mj: [{ required: true, message: '请输入密级', trigger: 'blur' }],
|
||||||
|
pxqk: [{ required: true, message: '请输入评选情况', trigger: 'blur' }]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -486,54 +371,69 @@ export default {
|
|||||||
return (this.selectedFile && this.selectedFile.name) || '未选择任何文件'
|
return (this.selectedFile && this.selectedFile.name) || '未选择任何文件'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
// 初始化表单(保证 getCurrentTime 可用)
|
|
||||||
this.addForm = this.createEmptyForm()
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 表单辅助 ====================
|
/** 移除空值 */
|
||||||
getCurrentTime() {
|
cleanPayload(obj) {
|
||||||
return new Date().toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-')
|
const payload = {}
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
payload[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return payload
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 创建空白课程表单(含一条空课堂记录) */
|
/** 创建空白课程科目表单 */
|
||||||
createEmptyForm() {
|
createEmptyForm() {
|
||||||
return {
|
return {
|
||||||
bh: '', kbh: '', mc: '', syzy: '', kcs: 0, bz: '', zxrbh: '', zxsj: this.getCurrentTime(),
|
kbh: '', kmc: '', jysdh: '', bz: '', xh: '', xf: 0, jc: '', xs: 0,
|
||||||
zxzt: '0', sbzt: '0', sbsj: '', sbrbh: '', chyy: '', zw: '', jsonzd: '', ktList: [this.defaultClassroom()]
|
pxcc: '', pxlx: '', kclx: '', ksks: 0, py: '', gfmc: '', cjfz: '',
|
||||||
|
bjrxypjf: 0, jxglbmbh: '', llxs: 0, sjxs: 0, kmdm: '', zks: 0, klx: '',
|
||||||
|
ksksbxs: 0, kctybh: '', sydx: '', fddyks: 0, zxks: 0, bb: '', xdrq: '',
|
||||||
|
jcyxj: '', kczcfs: '', kcjsfs: '', jsonzd: '', zzlkc: 0, khfs: '',
|
||||||
|
xcxcjfz: 0, zjxcjfz: 0, mj: '', pxqk: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 默认课堂项 */
|
|
||||||
defaultClassroom() {
|
|
||||||
return { bh: '', ktjc: 1, jxnr: '', jxyd: '', jxff: '', zjjys: 0, fjjys: 0, bz: '', jxmd: '', jxyq: '' }
|
|
||||||
},
|
|
||||||
|
|
||||||
resetForm() {
|
resetForm() {
|
||||||
this.addForm = this.createEmptyForm()
|
this.addForm = this.createEmptyForm()
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 列表加载 ====================
|
// ==================== 列表加载 ====================
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 getCourseTeachingList
|
buildQuery() {
|
||||||
|
return this.cleanPayload({
|
||||||
|
pageNum: this.pageNum,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
kmc: this.searchForm.kmc,
|
||||||
|
jc: this.searchForm.jc,
|
||||||
|
kmdm: this.searchForm.kmdm,
|
||||||
|
jysdh: this.searchForm.jysdh,
|
||||||
|
kclx: this.searchForm.kclx,
|
||||||
|
pxlx: this.searchForm.pxlx,
|
||||||
|
pxcc: this.searchForm.pxcc
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
fetchList() {
|
fetchList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
setTimeout(() => {
|
listSubject(this.buildQuery())
|
||||||
this.tableData = [...this.mockTableData]
|
.then(res => {
|
||||||
this.total = this.mockTableData.length
|
const data = (res && res.data) || {}
|
||||||
this.loading = false
|
this.tableData = data.records || []
|
||||||
}, 200)
|
this.total = data.total || 0
|
||||||
|
this.statusTip = `共检索到 ${this.total} 条记录`
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 查询 ====================
|
// ==================== 查询 ====================
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
const now = new Date()
|
|
||||||
const hh = String(now.getHours()).padStart(2, '0')
|
|
||||||
const mm = String(now.getMinutes()).padStart(2, '0')
|
|
||||||
const ss = String(now.getSeconds()).padStart(2, '0')
|
|
||||||
this.statusTip = `[${hh}:${mm}:${ss}]查询成功!共检索到${this.total || 982}条记录。`
|
|
||||||
this.pageNum = 1
|
this.pageNum = 1
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
@@ -557,36 +457,54 @@ export default {
|
|||||||
this.$message.warning('请先选择要删除的记录')
|
this.$message.warning('请先选择要删除的记录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const ids = this.selectedRows.map((r) => r.id)
|
const kbhList = this.selectedRows.map(r => r.kbh)
|
||||||
this.tableData = this.tableData.filter((r) => ids.indexOf(r.id) === -1)
|
this.$confirm(`确定删除所选 ${kbhList.length} 条课程科目吗?`, '提示', {
|
||||||
this.total = this.tableData.length
|
confirmButtonText: '确定',
|
||||||
this.$message.success(`已删除所选 ${ids.length} 条记录(前端模拟)`)
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const tasks = kbhList.map(kbh => deleteSubject(kbh))
|
||||||
|
Promise.all(tasks)
|
||||||
|
.then(() => {
|
||||||
|
this.$message.success(`已删除 ${kbhList.length} 条记录`)
|
||||||
|
this.fetchList()
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$message.error('删除失败')
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 下载 ====================
|
/** 单条删除 */
|
||||||
downloadBlob(content, filename) {
|
handleDelete(row) {
|
||||||
const blob = new Blob(['\ufeff' + content], { type: 'text/plain;charset=utf-8;' })
|
this.$confirm(`确定删除课程科目「${row.kmc || row.kbh}」吗?`, '提示', {
|
||||||
const link = document.createElement('a')
|
confirmButtonText: '确定',
|
||||||
link.href = URL.createObjectURL(blob)
|
cancelButtonText: '取消',
|
||||||
link.download = filename
|
type: 'warning'
|
||||||
link.click()
|
}).then(() => {
|
||||||
URL.revokeObjectURL(link.href)
|
return deleteSubject(row.kbh)
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
this.fetchList()
|
||||||
|
}).catch((err) => {
|
||||||
|
if (err && err !== 'cancel') {
|
||||||
|
this.$message.error('删除失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ==================== 下载(后端暂未提供) ====================
|
||||||
handleDownloadCourse() {
|
handleDownloadCourse() {
|
||||||
this.downloadBlob('编码,课程名称,分类,考核类型方式,课内学时,课外学时\n', '课程科目基本信息.txt')
|
this.$message.warning('后端暂未提供该接口')
|
||||||
this.$message.success('课程科目基本信息已下载(前端模拟)')
|
|
||||||
},
|
},
|
||||||
handleDownloadTextbook() {
|
handleDownloadTextbook() {
|
||||||
this.downloadBlob('课程名称,教材,在职主讲教员\n', '课程教材基本信息.txt')
|
this.$message.warning('后端暂未提供该接口')
|
||||||
this.$message.success('课程教材基本信息已下载(前端模拟)')
|
|
||||||
},
|
},
|
||||||
handleDownloadTemplate() {
|
handleDownloadTemplate() {
|
||||||
this.downloadBlob('编码,课程名称,分类,考核类型方式,课内学时,课外学时,教材,开设课程专业名称,在职主讲教员\n', '课程科目数据文件模板.txt')
|
this.$message.warning('后端暂未提供该接口')
|
||||||
this.$message.success('【课程科目数据文件模板】已下载(前端模拟)')
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 文件上传 ====================
|
// ==================== 文件上传(后端暂未提供) ====================
|
||||||
handleSelectFile() {
|
handleSelectFile() {
|
||||||
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
||||||
},
|
},
|
||||||
@@ -597,11 +515,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleUpload() {
|
handleUpload() {
|
||||||
if (!this.selectedFile) {
|
this.$message.warning('后端暂未提供该接口')
|
||||||
this.$message.warning('请先选择文件')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$message.success(`文件「${this.selectedFile.name}」上传成功(前端模拟)`)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 新增/编辑弹窗 ====================
|
// ==================== 新增/编辑弹窗 ====================
|
||||||
@@ -611,49 +525,40 @@ export default {
|
|||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
|
|
||||||
handleAddClassroom() {
|
handleEdit(row) {
|
||||||
this.addForm.ktList.push(this.defaultClassroom())
|
this.addLoading = true
|
||||||
},
|
getKb(row.kbh)
|
||||||
handleDeleteClassroom(index) {
|
.then(res => {
|
||||||
this.addForm.ktList.splice(index, 1)
|
const data = (res && res.data) || row
|
||||||
|
this.isEdit = true
|
||||||
|
this.addForm = Object.assign(this.createEmptyForm(), data)
|
||||||
|
this.dialogVisible = true
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.addLoading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: 后端接口未提供,保存成功后刷新列表为前端模拟;接口就绪后替换为 addCourseTeaching/updateCourseTeaching
|
|
||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
this.$refs.addFormRef.validate((valid) => {
|
this.$refs.addFormRef.validate((valid) => {
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
this.addLoading = true
|
this.addLoading = true
|
||||||
setTimeout(() => {
|
const payload = this.cleanPayload({ ...this.addForm })
|
||||||
this.$message.success(this.isEdit ? '修改成功' : '保存成功')
|
const requestFn = this.isEdit ? updateSubject : addSubject
|
||||||
this.dialogVisible = false
|
requestFn(payload)
|
||||||
this.fetchList()
|
.then(() => {
|
||||||
this.addLoading = false
|
this.$message.success(this.isEdit ? '修改成功' : '保存成功')
|
||||||
}, 300)
|
this.dialogVisible = false
|
||||||
|
this.fetchList()
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.addLoading = false
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 撤回弹窗 ====================
|
|
||||||
// TODO: 后端接口未提供,撤回为前端模拟;接口就绪后替换为 deleteCourseTeaching
|
|
||||||
handleWithdraw() {
|
|
||||||
if (!this.withdrawForm.chyy.trim()) {
|
|
||||||
this.$message.warning('请输入撤回原因')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.withdrawLoading = true
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$message.success('撤回成功')
|
|
||||||
this.withdrawDialogVisible = false
|
|
||||||
this.fetchList()
|
|
||||||
this.withdrawLoading = false
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
|
|
||||||
handleCancelWithdraw() {
|
|
||||||
this.withdrawDialogVisible = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -708,22 +613,6 @@ export default {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.range-control {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
|
|
||||||
.el-input {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.range-sep {
|
|
||||||
flex-shrink: 0;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.notice {
|
.notice {
|
||||||
@@ -811,6 +700,10 @@ export default {
|
|||||||
::v-deep(.el-table .cell) {
|
::v-deep(.el-table .cell) {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 新增/编辑弹窗 ====================
|
// ==================== 新增/编辑弹窗 ====================
|
||||||
@@ -825,29 +718,6 @@ export default {
|
|||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.classroom-section {
|
|
||||||
margin-top: 16px;
|
|
||||||
|
|
||||||
.classroom-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
|
|
||||||
.classroom-title {
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 课堂列表删除按钮红色文字
|
|
||||||
.text-danger {
|
|
||||||
color: #f56c6c;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
|
|||||||
@@ -1,376 +1,440 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container task-plan-page">
|
<div class="app-container task-plan-page">
|
||||||
<!-- ==================== 1. 学期信息区域 ==================== -->
|
<!-- ==================== 页面标题 ==================== -->
|
||||||
|
<div class="page-title">教学任务计划管理</div>
|
||||||
|
|
||||||
|
<!-- ==================== 1. 查询条件区域 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<el-form :inline="true" :model="semester" class="search-form">
|
<el-form :inline="true" :model="searchForm" class="search-form">
|
||||||
<el-form-item label="学期名称">
|
<el-form-item label="任务名称">
|
||||||
<el-input v-model="semester.name" style="width: 160px" />
|
<el-input
|
||||||
</el-form-item>
|
v-model="searchForm.rwmc"
|
||||||
<el-form-item label="校历开学日期">
|
placeholder="请输入任务名称"
|
||||||
<el-date-picker
|
clearable
|
||||||
v-model="semester.kxrq"
|
style="width: 180px"
|
||||||
type="date"
|
@keyup.enter.native="handleQuery"
|
||||||
format="yyyy年M月d日"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
placeholder="选择日期"
|
|
||||||
style="width: 160px"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="结束日期">
|
<el-form-item label="年度">
|
||||||
<el-date-picker
|
<el-select v-model="searchForm.nd" placeholder="请选择年度" clearable style="width: 140px">
|
||||||
v-model="semester.jsrq"
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||||
type="date"
|
</el-select>
|
||||||
format="yyyy年M月d日"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
placeholder="选择日期"
|
|
||||||
style="width: 160px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="学期周数">
|
<el-form-item label="状态">
|
||||||
<el-input v-model="semester.weeks" style="width: 90px" />
|
<el-select v-model="searchForm.zt" placeholder="请选择状态" clearable style="width: 140px">
|
||||||
|
<el-option
|
||||||
|
v-for="opt in statusOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
:label="opt.label"
|
||||||
|
:value="opt.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 2. 数据表格区域 ==================== -->
|
<!-- ==================== 2. 操作区域 ==================== -->
|
||||||
<div class="list-title">教学任务列表:</div>
|
|
||||||
<div class="list-toolbar">
|
<div class="list-toolbar">
|
||||||
<div class="left-group">
|
<div class="left-group">
|
||||||
<el-button type="primary" @click="handleAdd">新建</el-button>
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新建教学任务</el-button>
|
||||||
<el-button type="primary" plain @click="handleEdit">编辑</el-button>
|
|
||||||
<el-button type="danger" plain @click="handleDelete">删除</el-button>
|
|
||||||
<el-button type="primary" plain @click="handlePublish">发布教学任务</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleEndPublish">结束发布</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleManageTeams">管理教学任务所含学员队</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- ==================== 3. 数据表格 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table
|
<el-table v-loading="loading" :data="tableData" border stripe class="task-table">
|
||||||
ref="tableRef"
|
<template slot="empty">
|
||||||
v-loading="loading"
|
<span>无数据!</span>
|
||||||
:data="tableData"
|
</template>
|
||||||
border
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
stripe
|
<el-table-column prop="rwmc" label="任务名称" min-width="180" align="left" header-align="center" show-overflow-tooltip />
|
||||||
highlight-current-row
|
<el-table-column prop="nd" label="年度" width="90" align="center" />
|
||||||
class="task-table"
|
<el-table-column label="状态" width="100" align="center">
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
|
||||||
<el-table-column prop="rwmc" label="任务名称" min-width="170" show-overflow-tooltip />
|
|
||||||
<el-table-column label="状态" width="80" align="center">
|
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
<span class="status-text">{{ row.zt }}</span>
|
<el-tag :type="row.zt === '发布' ? 'success' : 'info'" size="small">
|
||||||
|
{{ row.zt || '-' }}
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="fbsj" label="发布时间" width="130" align="center" />
|
<el-table-column prop="fbsj" label="发布时间" width="150" align="center" :formatter="fmtDateTime" />
|
||||||
<el-table-column prop="cjsj" label="创建时间" width="130" align="center" />
|
<el-table-column prop="jssj" label="结束时间" width="150" align="center" :formatter="fmtDateTime" />
|
||||||
<el-table-column label="结束时间" width="130" align="center">
|
<el-table-column prop="cjsj" label="创建时间" width="150" align="center" :formatter="fmtDateTime" />
|
||||||
|
<el-table-column prop="jcxqscsj" label="教材需求生成时间" width="170" align="center" :formatter="fmtDateTime" />
|
||||||
|
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||||
<template slot-scope="{ row }">
|
<template slot-scope="{ row }">
|
||||||
{{ row.jssj || '' }}
|
<el-button type="text" size="small" @click="handleDetail(row)">详情</el-button>
|
||||||
|
<el-button type="text" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
:disabled="row.zt === '发布'"
|
||||||
|
@click="handlePublish(row)"
|
||||||
|
>发布</el-button>
|
||||||
|
<el-button type="text" size="small" class="text-danger" @click="handleDelete(row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="jysCount" label="教研室数" width="90" align="center" />
|
|
||||||
<el-table-column prop="teamCount" label="学员队数" width="90" align="center" />
|
|
||||||
<el-table-column prop="hbqKcCount" label="合班前课程任务数" width="140" align="center" />
|
|
||||||
<el-table-column prop="hbqXssCount" label="合班前总学时数" width="140" align="center" />
|
|
||||||
<el-table-column prop="hbhKcCount" label="合班后课程任务数" width="140" align="center" />
|
|
||||||
<el-table-column prop="hbhXssCount" label="合班后总学时数" width="140" align="center" />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 教学任务信息弹窗 ==================== -->
|
<!-- ==================== 4. 新增/修改对话框 ==================== -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible="dialogVisible"
|
:visible="dialogVisible"
|
||||||
title="教学任务信息"
|
:title="dialogTitle"
|
||||||
width="900px"
|
width="560px"
|
||||||
class="teaching-task-dialog"
|
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@update:visible="val => (dialogVisible = val)"
|
@update:visible="val => dialogVisible = val"
|
||||||
>
|
>
|
||||||
<!-- ==================== 1. 基本信息区域 ==================== -->
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="140px" class="add-form">
|
||||||
<el-form label-width="86px" class="basic-form">
|
<el-form-item v-if="isEdit" label="编号" prop="bh">
|
||||||
<el-row :gutter="20">
|
<el-input v-model="form.bh" disabled placeholder="编号不可修改" />
|
||||||
<el-col :span="12">
|
</el-form-item>
|
||||||
<el-form-item label="学期">
|
<el-form-item v-else label="编号">
|
||||||
<el-input v-model="form.xq" readonly />
|
<el-input disabled placeholder="新增后由系统自动生成" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
<el-form-item label="任务名称" prop="rwmc">
|
||||||
<el-col :span="12">
|
<el-input v-model="form.rwmc" placeholder="请输入任务名称" clearable />
|
||||||
<el-form-item label="任务名称">
|
</el-form-item>
|
||||||
<el-input v-model="form.rwmc" placeholder="请输入任务名称" />
|
<el-form-item label="年度" prop="nd">
|
||||||
</el-form-item>
|
<el-select v-model="form.nd" placeholder="请选择年度" style="width: 100%">
|
||||||
</el-col>
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||||
</el-row>
|
</el-select>
|
||||||
<el-row :gutter="20">
|
</el-form-item>
|
||||||
<el-col :span="12">
|
<el-form-item label="状态" prop="zt">
|
||||||
<el-form-item label="创建时间">
|
<el-select v-model="form.zt" placeholder="请选择状态" style="width: 100%">
|
||||||
<el-input v-model="form.cjsj" readonly />
|
<el-option
|
||||||
</el-form-item>
|
v-for="opt in statusOptions"
|
||||||
</el-col>
|
:key="opt.value"
|
||||||
<el-col :span="12">
|
:label="opt.label"
|
||||||
<el-form-item label="发布时间">
|
:value="opt.value"
|
||||||
<el-input v-model="form.fbsj" readonly />
|
/>
|
||||||
</el-form-item>
|
</el-select>
|
||||||
</el-col>
|
</el-form-item>
|
||||||
</el-row>
|
<el-form-item label="发布时间">
|
||||||
<el-row :gutter="20">
|
<el-date-picker
|
||||||
<el-col :span="12">
|
v-model="form.fbsj"
|
||||||
<el-form-item label="结束时间">
|
type="datetime"
|
||||||
<el-input v-model="form.jssj" readonly />
|
value-format="yyyy-MM-ddTHH:mm:ss"
|
||||||
</el-form-item>
|
placeholder="请选择发布时间"
|
||||||
</el-col>
|
style="width: 100%"
|
||||||
</el-row>
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.jssj"
|
||||||
|
type="datetime"
|
||||||
|
value-format="yyyy-MM-ddTHH:mm:ss"
|
||||||
|
placeholder="请选择结束时间"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教材需求生成时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.jcxqscsj"
|
||||||
|
type="datetime"
|
||||||
|
value-format="yyyy-MM-ddTHH:mm:ss"
|
||||||
|
placeholder="请选择教材需求生成时间"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- ==================== 2. Tab 标签页区域 ==================== -->
|
|
||||||
<el-tabs v-model="activeTab" class="tt-tabs">
|
|
||||||
<!-- 教研室任务书列表 -->
|
|
||||||
<el-tab-pane label="教研室任务书列表" name="taskbook">
|
|
||||||
<div class="sub-toolbar">
|
|
||||||
<el-button type="primary" plain size="small" @click="handleTaskBookDetail">
|
|
||||||
教研室任务书详细
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<el-table
|
|
||||||
ref="taskBookTable"
|
|
||||||
:data="taskBookRows"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
highlight-current-row
|
|
||||||
class="taskbook-table"
|
|
||||||
@selection-change="handleTaskBookSelection"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
|
||||||
<el-table-column prop="jys" label="教研室" min-width="120" align="center" />
|
|
||||||
<el-table-column prop="zt" label="状态" width="80" align="center" />
|
|
||||||
<el-table-column prop="sbsj" label="上报时间" width="150" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="xydkcCount" label="学员队课程任务数" width="150" align="center" />
|
|
||||||
<el-table-column prop="wczdsCount" label="完成指定数" width="100" align="center" />
|
|
||||||
</el-table>
|
|
||||||
</el-tab-pane>
|
|
||||||
|
|
||||||
<!-- 学员队列表 -->
|
|
||||||
<el-tab-pane label="学员队列表" name="team">
|
|
||||||
<div class="tab-empty">暂无学员队列表数据</div>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
|
|
||||||
<!-- ==================== 3. 底部按钮区域 ==================== -->
|
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
<el-button type="primary" :loading="saving" @click="handleSubmit">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- ==================== 5. 详情对话框 ==================== -->
|
||||||
|
<el-dialog
|
||||||
|
:visible="detailVisible"
|
||||||
|
title="教学任务详情"
|
||||||
|
width="620px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@update:visible="val => detailVisible = val"
|
||||||
|
>
|
||||||
|
<el-descriptions v-if="detailData.bh" :column="2" border>
|
||||||
|
<el-descriptions-item label="编号">{{ detailData.bh || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="任务名称">{{ detailData.rwmc || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="年度">{{ fmtVal(detailData.nd) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">{{ detailData.zt || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="发布时间">{{ fmtVal(detailData.fbsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="结束时间">{{ fmtVal(detailData.jssj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ fmtVal(detailData.cjsj) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="教材需求生成时间">{{ fmtVal(detailData.jcxqscsj) }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div v-else v-loading="detailLoading" class="detail-empty">加载中...</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button type="primary" @click="detailVisible = false">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 教学任务计划管理(完整管理页)
|
||||||
|
* 对应菜单:teachOffice/taskPlan
|
||||||
|
* 提供 teachingTask 全套真实接口操作:分页查询 list、详情 get?bh=、新增 add、编辑 update、
|
||||||
|
* 发布 batchPublish?bh=(需先填写教研室任务书)、删除 delete?bh=(级联删除教研室任务书)
|
||||||
|
* 只读查询视图在 src/views/teachBusiness/teachingTask/index.vue(教学任务列表)提供,避免重复操作同一实体
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
listTeachingTask,
|
||||||
|
getTeachingTask,
|
||||||
|
addTeachingTask,
|
||||||
|
updateTeachingTask,
|
||||||
|
deleteTeachingTask,
|
||||||
|
publishTeachingTask
|
||||||
|
} from '@/api/teachBusiness/teachingTask'
|
||||||
|
import { listAllSemester } from '@/api/teachBusiness/semester'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'TaskPlan',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 1. 学期信息区域 ====================
|
// ==================== 1. 查询条件 ====================
|
||||||
semester: {
|
searchForm: {
|
||||||
name: '2017年秋季学期', // 学期名称
|
rwmc: '',
|
||||||
kxrq: '2017-07-08', // 校历开学日期
|
nd: undefined,
|
||||||
jsrq: '2018-02-11', // 结束日期
|
zt: ''
|
||||||
weeks: 32 // 学期周数
|
|
||||||
},
|
},
|
||||||
|
yearOptions: [],
|
||||||
// ==================== 2. 数据表格 ====================
|
statusOptions: [
|
||||||
loading: false,
|
{ label: '未发布', value: '未发布' },
|
||||||
tableData: [
|
{ label: '发布', value: '发布' }
|
||||||
{
|
|
||||||
bh: 'task-2017-2',
|
|
||||||
rwmc: '2017年下半年教学任务',
|
|
||||||
zt: '发布',
|
|
||||||
fbsj: '2017年12月1日',
|
|
||||||
cjsj: '2017年7月8日',
|
|
||||||
jssj: '',
|
|
||||||
jysCount: 31,
|
|
||||||
teamCount: 78,
|
|
||||||
hbqKcCount: 1126,
|
|
||||||
hbqXssCount: 36050,
|
|
||||||
hbhKcCount: 1058,
|
|
||||||
hbhXssCount: 34050
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bh: 'task-2019-1',
|
|
||||||
rwmc: '研究生下半年教学任务',
|
|
||||||
zt: '发布',
|
|
||||||
fbsj: '2019年12月1日',
|
|
||||||
cjsj: '2017年7月8日',
|
|
||||||
jssj: '',
|
|
||||||
jysCount: 12,
|
|
||||||
teamCount: 2,
|
|
||||||
hbqKcCount: 16,
|
|
||||||
hbqXssCount: 560,
|
|
||||||
hbhKcCount: 16,
|
|
||||||
hbhXssCount: 560
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
selectedRows: [],
|
|
||||||
currentRow: null,
|
|
||||||
|
|
||||||
// ==================== 操作按钮 ====================
|
// ==================== 2. 表格数据 ====================
|
||||||
/** 教学任务信息弹窗 */
|
loading: false,
|
||||||
|
tableData: [],
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
|
||||||
|
// ==================== 3. 新增/修改表单 ====================
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
/** 弹窗模式:新建 / 编辑 */
|
dialogTitle: '新建教学任务',
|
||||||
dialogMode: 'create',
|
isEdit: false,
|
||||||
/** 编辑模式选中的任务行 */
|
saving: false,
|
||||||
editRow: null,
|
form: this.createEmptyForm(),
|
||||||
|
rules: {
|
||||||
// ==================== 弹窗:基本信息 ====================
|
rwmc: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
|
||||||
form: {
|
nd: [{ required: true, message: '请选择年度', trigger: 'change' }],
|
||||||
xq: '2017年秋季学期', // 学期(只读)
|
zt: [{ required: true, message: '请选择状态', trigger: 'change' }]
|
||||||
rwmc: '', // 任务名称(可编辑)
|
|
||||||
cjsj: '', // 创建时间(只读)
|
|
||||||
fbsj: '', // 发布时间(只读)
|
|
||||||
jssj: '' // 结束时间(只读)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 弹窗:Tab 标签页 ====================
|
// ==================== 4. 详情 ====================
|
||||||
activeTab: 'taskbook',
|
detailVisible: false,
|
||||||
|
detailLoading: false,
|
||||||
// ==================== 弹窗:教研室任务书列表 ====================
|
detailData: {}
|
||||||
taskBookRows: [],
|
|
||||||
selectedTaskBookRows: [],
|
|
||||||
/** 编辑模式下的教研室任务书数据(按截图还原) */
|
|
||||||
editTaskBookRows: [
|
|
||||||
{ jys: '军事81教研室', zt: '发布', sbsj: '', xydkcCount: 33, wczdsCount: 0 },
|
|
||||||
{ jys: '翻译室', zt: '发布', sbsj: '', xydkcCount: 2, wczdsCount: 0 },
|
|
||||||
{ jys: '军事共同教研室', zt: '上报', sbsj: '2019-12-13 10:39', xydkcCount: 97, wczdsCount: 8 },
|
|
||||||
{ jys: '作战保障教研室', zt: '发布', sbsj: '', xydkcCount: 47, wczdsCount: 0 },
|
|
||||||
{ jys: '军事10教研室', zt: '发布', sbsj: '', xydkcCount: 21, wczdsCount: 0 },
|
|
||||||
{ jys: '军事83', zt: '发布', sbsj: '', xydkcCount: 2, wczdsCount: 0 },
|
|
||||||
{ jys: '军事09教研室', zt: '发布', sbsj: '', xydkcCount: 52, wczdsCount: 0 }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
mounted() {
|
this.loadYearOptions().then(() => this.fetchList())
|
||||||
// 默认选中第一行(高亮)
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.tableData.length) {
|
|
||||||
this.$refs.tableRef.setCurrentRow(this.tableData[0])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
/* ---------- 年度下拉(数据来自 /semester/all,禁止硬编码) ---------- */
|
||||||
|
loadYearOptions() {
|
||||||
|
return listAllSemester().then(response => {
|
||||||
|
const list = response.data || []
|
||||||
|
const map = {}
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.nd !== null && item.nd !== undefined && item.nd !== '') map[item.nd] = item
|
||||||
|
})
|
||||||
|
const arr = Object.keys(map).sort((a, b) => String(b).localeCompare(String(a)))
|
||||||
|
this.yearOptions = arr
|
||||||
|
// 默认年度:优先当前学期(dqxq=true),否则取最新年度
|
||||||
|
const current = list.find(item => item.dqxq === true)
|
||||||
|
const defaultNd = (current && current.nd) || arr[0]
|
||||||
|
if (!this.searchForm.nd) this.searchForm.nd = defaultNd
|
||||||
|
return arr
|
||||||
|
}).catch(() => {
|
||||||
|
this.yearOptions = []
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
watch: {
|
/* ---------- 通用格式化 ---------- */
|
||||||
// 弹窗打开时按模式初始化
|
fmtDateTime(row, column, cellValue) {
|
||||||
dialogVisible(val) {
|
if (cellValue === null || cellValue === undefined || cellValue === '') return '-'
|
||||||
if (!val) return
|
return String(cellValue).replace('T', ' ').slice(0, 16)
|
||||||
this.form.xq = this.semester.name
|
},
|
||||||
if (this.dialogMode === 'edit') {
|
fmtVal(val) {
|
||||||
this.form.rwmc = (this.editRow && this.editRow.rwmc) || ''
|
if (val === null || val === undefined || val === '') return '-'
|
||||||
this.form.cjsj = '2017-07-14 17:00'
|
return String(val).replace('T', ' ').slice(0, 16)
|
||||||
this.form.fbsj = '2019-12-13 10:39'
|
},
|
||||||
this.form.jssj = ''
|
/** 移除空值(''/null/undefined),保留 0 等有效值 */
|
||||||
this.taskBookRows = [...this.editTaskBookRows]
|
cleanPayload(obj) {
|
||||||
} else {
|
const payload = {}
|
||||||
this.form.rwmc = '新研究生教学任务'
|
Object.keys(obj).forEach(key => {
|
||||||
this.form.cjsj = ''
|
const value = obj[key]
|
||||||
this.form.fbsj = ''
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
this.form.jssj = ''
|
payload[key] = value
|
||||||
this.taskBookRows = []
|
|
||||||
}
|
|
||||||
this.activeTab = 'taskbook'
|
|
||||||
// 默认选中第一行(高亮)
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.taskBookRows.length && this.$refs.taskBookTable) {
|
|
||||||
this.$refs.taskBookTable.setCurrentRow(this.taskBookRows[0])
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
return payload
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
/* ---------- 列表加载 ---------- */
|
||||||
// ==================== 表格 ====================
|
fetchList() {
|
||||||
handleSelectionChange(rows) {
|
this.loading = true
|
||||||
this.selectedRows = rows
|
const params = { pageNum: this.pageNum, pageSize: this.pageSize }
|
||||||
},
|
if (this.searchForm.rwmc && this.searchForm.rwmc.trim()) params.rwmc = this.searchForm.rwmc.trim()
|
||||||
handleCurrentChange(row) {
|
if (this.searchForm.nd !== undefined && this.searchForm.nd !== null && this.searchForm.nd !== '') {
|
||||||
this.currentRow = row
|
params.nd = this.searchForm.nd
|
||||||
},
|
}
|
||||||
/** 获取当前选中行,未选中时提示 */
|
if (this.searchForm.zt && this.searchForm.zt.trim()) params.zt = this.searchForm.zt.trim()
|
||||||
getSelected() {
|
listTeachingTask(params).then(res => {
|
||||||
if (!this.currentRow) {
|
const data = (res && res.data) || {}
|
||||||
this.$message.warning('请先选择一条教学任务')
|
this.tableData = data.records || []
|
||||||
return null
|
this.total = data.total || 0
|
||||||
|
this.loading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.tableData = []
|
||||||
|
this.total = 0
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleQuery() {
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.pageNum = page
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.pageSize = size
|
||||||
|
this.pageNum = 1
|
||||||
|
this.fetchList()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 新增 / 修改 ---------- */
|
||||||
|
createEmptyForm() {
|
||||||
|
return {
|
||||||
|
bh: '',
|
||||||
|
rwmc: '',
|
||||||
|
nd: undefined,
|
||||||
|
zt: '未发布',
|
||||||
|
fbsj: '',
|
||||||
|
jssj: '',
|
||||||
|
jcxqscsj: ''
|
||||||
}
|
}
|
||||||
return this.currentRow
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 操作按钮 ====================
|
|
||||||
/** 新建教学任务 */
|
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.dialogMode = 'create'
|
this.form = this.createEmptyForm()
|
||||||
this.editRow = null
|
if (!this.form.nd && this.searchForm.nd) this.form.nd = this.searchForm.nd
|
||||||
|
this.isEdit = false
|
||||||
|
this.dialogTitle = '新建教学任务'
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/** 编辑教学任务 */
|
|
||||||
handleEdit() {
|
handleEdit(row) {
|
||||||
const row = this.getSelected()
|
this.form = {
|
||||||
if (!row) return
|
bh: row.bh || '',
|
||||||
this.dialogMode = 'edit'
|
rwmc: row.rwmc || '',
|
||||||
this.editRow = row
|
nd: row.nd,
|
||||||
|
zt: row.zt || '未发布',
|
||||||
|
fbsj: row.fbsj || '',
|
||||||
|
jssj: row.jssj || '',
|
||||||
|
jcxqscsj: row.jcxqscsj || ''
|
||||||
|
}
|
||||||
|
this.isEdit = true
|
||||||
|
this.dialogTitle = '修改教学任务'
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/** 弹窗确认保存 */
|
|
||||||
handleDialogConfirm() {
|
handleSubmit() {
|
||||||
// TODO: 调用保存接口
|
this.$refs.formRef.validate(valid => {
|
||||||
this.$message.success('已保存教学任务信息(前端演示)')
|
if (!valid) {
|
||||||
|
this.$message.warning('请完善必填项后再提交')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const payload = this.cleanPayload(this.buildPayload())
|
||||||
|
this.saving = true
|
||||||
|
const req = this.isEdit ? updateTeachingTask(payload) : addTeachingTask(payload)
|
||||||
|
req.then(() => {
|
||||||
|
this.$message.success(this.isEdit ? '修改成功' : '新建成功')
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.fetchList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.saving = false
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/** 删除教学任务 */
|
|
||||||
handleDelete() {
|
/** 构建请求体:年度转数字以匹配后端 Integer,时间字段有值才传 */
|
||||||
const row = this.getSelected()
|
buildPayload() {
|
||||||
if (!row) return
|
const f = this.form
|
||||||
this.$confirm(`确定删除教学任务"${row.rwmc}"吗?删除后不可恢复。`, '删除确认', {
|
const payload = {}
|
||||||
confirmButtonText: '确定删除',
|
if (this.isEdit && f.bh && String(f.bh).trim()) payload.bh = String(f.bh).trim()
|
||||||
|
if (f.rwmc && String(f.rwmc).trim()) payload.rwmc = String(f.rwmc).trim()
|
||||||
|
if (f.nd !== undefined && f.nd !== null && f.nd !== '') payload.nd = Number(f.nd)
|
||||||
|
if (f.zt && String(f.zt).trim()) payload.zt = String(f.zt).trim()
|
||||||
|
if (f.fbsj) payload.fbsj = f.fbsj
|
||||||
|
if (f.jssj) payload.jssj = f.jssj
|
||||||
|
if (f.jcxqscsj) payload.jcxqscsj = f.jcxqscsj
|
||||||
|
return payload
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 详情 ---------- */
|
||||||
|
handleDetail(row) {
|
||||||
|
this.detailVisible = true
|
||||||
|
this.detailLoading = true
|
||||||
|
this.detailData = {}
|
||||||
|
getTeachingTask(row.bh).then(res => {
|
||||||
|
this.detailData = (res && res.data) || {}
|
||||||
|
this.detailLoading = false
|
||||||
|
}).catch(() => {
|
||||||
|
this.detailLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ---------- 删除 ---------- */
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$confirm(`确定要删除「${row.rwmc || row.bh || '该记录'}」吗?删除将级联删除关联的教研室任务书。`, '系统提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
})
|
}).then(() => deleteTeachingTask(row.bh)).then(() => {
|
||||||
.then(() => {
|
this.$message.success('删除成功')
|
||||||
// TODO: 调用删除接口
|
this.fetchList()
|
||||||
this.$message.success('删除成功(前端演示)')
|
}).catch(() => {})
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
},
|
|
||||||
/** 发布教学任务 */
|
|
||||||
handlePublish() {
|
|
||||||
const row = this.getSelected()
|
|
||||||
if (!row) return
|
|
||||||
// TODO: 调用发布接口
|
|
||||||
this.$message.success(`已发布教学任务:${row.rwmc}`)
|
|
||||||
},
|
|
||||||
/** 结束发布 */
|
|
||||||
handleEndPublish() {
|
|
||||||
const row = this.getSelected()
|
|
||||||
if (!row) return
|
|
||||||
// TODO: 调用结束发布接口
|
|
||||||
this.$message.success(`已结束发布:${row.rwmc}`)
|
|
||||||
},
|
|
||||||
/** 管理教学任务所含学员队 */
|
|
||||||
handleManageTeams() {
|
|
||||||
const row = this.getSelected()
|
|
||||||
if (!row) return
|
|
||||||
// TODO: 学员队管理弹窗,待接口接入
|
|
||||||
this.$message.success(`管理教学任务所含学员队:${row.rwmc}`)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 弹窗 ====================
|
/* ---------- 发布 ---------- */
|
||||||
handleTaskBookSelection(rows) {
|
handlePublish(row) {
|
||||||
this.selectedTaskBookRows = rows
|
this.$confirm(`确定要发布教学任务「${row.rwmc || row.bh || '该记录'}」吗?发布前请先填写关联的教研室任务书。`, '系统提示', {
|
||||||
},
|
confirmButtonText: '确定',
|
||||||
/** 打开教研室任务书详细(前端演示) */
|
cancelButtonText: '取消',
|
||||||
handleTaskBookDetail() {
|
type: 'warning'
|
||||||
// TODO: 教研室任务书详细弹窗,待接口接入
|
}).then(() => publishTeachingTask(row.bh)).then(() => {
|
||||||
},
|
this.$message.success('发布成功')
|
||||||
/** 弹窗确定 */
|
this.fetchList()
|
||||||
handleConfirm() {
|
}).catch(() => {})
|
||||||
this.handleDialogConfirm()
|
|
||||||
this.dialogVisible = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,7 +446,15 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.task-plan-page {
|
.task-plan-page {
|
||||||
// ========== 1. 学期信息区域 ==========
|
.page-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 1. 查询条件区域 ==========
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
@@ -394,17 +466,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 2. 列表标题 ==========
|
// ========== 2. 工具栏 ==========
|
||||||
.list-title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-left: 10px;
|
|
||||||
border-left: 4px solid var(--edu-green-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 3. 工具栏 ==========
|
|
||||||
.list-toolbar {
|
.list-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -422,66 +484,30 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 4. 数据表格区域 ==========
|
// ========== 3. 数据表格区域 ==========
|
||||||
.table-card {
|
.table-card {
|
||||||
.task-table {
|
.task-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.status-text {
|
.pagination {
|
||||||
color: var(--edu-green-primary);
|
display: flex;
|
||||||
font-weight: 600;
|
justify-content: flex-end;
|
||||||
}
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
// 当前行高亮
|
.text-danger {
|
||||||
::v-deep(.el-table__body tr.current-row > td.el-table__cell) {
|
color: #f56c6c;
|
||||||
background-color: #e1f5ec;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-table__body tr.current-row:hover > td.el-table__cell) {
|
|
||||||
background-color: #e1f5ec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 4. 教学任务信息弹窗 ==========
|
// ========== 4. 详情 ==========
|
||||||
.teaching-task-dialog {
|
.detail-empty {
|
||||||
.basic-form {
|
min-height: 120px;
|
||||||
padding-bottom: 8px;
|
display: flex;
|
||||||
border-bottom: 1px solid #ebeef5;
|
align-items: center;
|
||||||
margin-bottom: 4px;
|
justify-content: center;
|
||||||
}
|
color: #909399;
|
||||||
|
|
||||||
.tt-tabs {
|
|
||||||
::v-deep(.el-tabs__header) {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-toolbar {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taskbook-table {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
// 当前行高亮
|
|
||||||
::v-deep(.el-table__body tr.current-row > td.el-table__cell) {
|
|
||||||
background-color: #e1f5ec;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-table__body tr.current-row:hover > td.el-table__cell) {
|
|
||||||
background-color: #e1f5ec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-empty {
|
|
||||||
min-height: 200px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
|||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<!-- 查询条件 -->
|
<!-- 查询条件 -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<div class="search-tip">勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
<el-form :model="searchForm" label-width="110px" class="search-form">
|
<el-form :model="searchForm" label-width="110px" class="search-form">
|
||||||
<el-row :gutter="0">
|
<el-row :gutter="0">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<!-- 查询条件 -->
|
<!-- 查询条件 -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<div class="search-tip">勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
<el-form :model="searchForm" label-width="110px" class="search-form">
|
<el-form :model="searchForm" label-width="110px" class="search-form">
|
||||||
<el-row :gutter="0">
|
<el-row :gutter="0">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -221,9 +220,7 @@
|
|||||||
import { formatDate } from '@/utils/index'
|
import { formatDate } from '@/utils/index'
|
||||||
import {
|
import {
|
||||||
getTeachingLogList,
|
getTeachingLogList,
|
||||||
deleteTeachingLog,
|
submitTeachingLog,
|
||||||
batchReportTeachingLog,
|
|
||||||
recheckTeachingLog,
|
|
||||||
exportTeachingLog,
|
exportTeachingLog,
|
||||||
importTeachingLogExcel,
|
importTeachingLogExcel,
|
||||||
downloadTeachingLogTemplate,
|
downloadTeachingLogTemplate,
|
||||||
@@ -380,43 +377,36 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteSelected() {
|
handleDeleteSelected() {
|
||||||
const ids = this.getSelectedBhs()
|
// 后端暂未提供删除接口,仅作提示
|
||||||
if (ids.length === 0) return
|
this.$message.info('后端暂未提供该接口')
|
||||||
this.$confirm(`确定要删除选中的 ${ids.length} 条记录吗?`, '删除确认', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning'
|
|
||||||
})
|
|
||||||
.then(() => deleteTeachingLog(ids))
|
|
||||||
.then(() => {
|
|
||||||
this.$message.success(`已删除 ${ids.length} 条记录`)
|
|
||||||
this.fetchList()
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleBatchReport() {
|
handleBatchReport() {
|
||||||
const ids = this.getSelectedBhs()
|
const ids = this.getSelectedBhs()
|
||||||
if (ids.length === 0) return
|
if (ids.length === 0) return
|
||||||
this.$confirm(`确定要批量上报选中的 ${ids.length} 条记录吗?`, '上报确认', {
|
this.$confirm(`确定要上报选中的 ${ids.length} 条记录吗?`, '上报确认', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
})
|
})
|
||||||
.then(() => batchReportTeachingLog(ids))
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$message.success(`已批量上报 ${ids.length} 条记录`)
|
// 提交教学日志审核,逐条上报至「已上报」状态
|
||||||
|
let settled = Promise.resolve()
|
||||||
|
ids.forEach((bh) => {
|
||||||
|
settled = settled.then(() => submitTeachingLog(bh, '已上报'))
|
||||||
|
})
|
||||||
|
return settled
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$message.success(`已上报 ${ids.length} 条记录`)
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleRecheck() {
|
handleRecheck() {
|
||||||
recheckTeachingLog()
|
// 后端暂未提供重新检查接口,仅作提示
|
||||||
.then(() => {
|
this.$message.info('后端暂未提供该接口')
|
||||||
this.$message.success('重新检查完成')
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadBlob(blob, fileName) {
|
downloadBlob(blob, fileName) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<!-- 查询条件 -->
|
<!-- 查询条件 -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-card shadow="never" class="search-card">
|
||||||
<div class="search-tip">勾选"选择框"表示启用该项对应的查询条件。</div>
|
|
||||||
<el-form :model="searchForm" label-width="110px" class="search-form">
|
<el-form :model="searchForm" label-width="110px" class="search-form">
|
||||||
<el-row :gutter="0">
|
<el-row :gutter="0">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -208,10 +207,8 @@
|
|||||||
import { formatDate } from '@/utils/index'
|
import { formatDate } from '@/utils/index'
|
||||||
import {
|
import {
|
||||||
getReportedTeachingLogList,
|
getReportedTeachingLogList,
|
||||||
deleteTeachingLog,
|
approveTeachingLog,
|
||||||
batchAuditTeachingLog,
|
|
||||||
rejectTeachingLog,
|
rejectTeachingLog,
|
||||||
recheckTeachingLog,
|
|
||||||
exportTeachingLog,
|
exportTeachingLog,
|
||||||
getTeachingLogByBh
|
getTeachingLogByBh
|
||||||
} from '@/api/log'
|
} from '@/api/log'
|
||||||
@@ -375,19 +372,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleDelete() {
|
handleDelete() {
|
||||||
const ids = this.getSelectedBhs()
|
// 后端暂未提供删除接口,仅作提示
|
||||||
if (ids.length === 0) return
|
this.$message.info('后端暂未提供该接口')
|
||||||
this.$confirm(`确定要删除选中的 ${ids.length} 条记录吗?`, '删除确认', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning'
|
|
||||||
})
|
|
||||||
.then(() => deleteTeachingLog(ids))
|
|
||||||
.then(() => {
|
|
||||||
this.$message.success(`已删除 ${ids.length} 条记录`)
|
|
||||||
this.fetchList()
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleAudit() {
|
handleAudit() {
|
||||||
@@ -398,7 +384,14 @@ export default {
|
|||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
})
|
})
|
||||||
.then(() => batchAuditTeachingLog(ids))
|
.then(() => {
|
||||||
|
// 审核通过教学日志,逐条审核
|
||||||
|
let settled = Promise.resolve()
|
||||||
|
ids.forEach((bh) => {
|
||||||
|
settled = settled.then(() => approveTeachingLog(bh, ''))
|
||||||
|
})
|
||||||
|
return settled
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$message.success(`已审核通过 ${ids.length} 条记录`)
|
this.$message.success(`已审核通过 ${ids.length} 条记录`)
|
||||||
this.fetchList()
|
this.fetchList()
|
||||||
@@ -432,11 +425,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleRecheck() {
|
handleRecheck() {
|
||||||
recheckTeachingLog()
|
// 后端暂未提供重新检查接口,仅作提示
|
||||||
.then(() => {
|
this.$message.info('后端暂未提供该接口')
|
||||||
this.$message.success('重新检查变更情况完成')
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadBlob(blob, fileName) {
|
downloadBlob(blob, fileName) {
|
||||||
|
|||||||
+1122
-369
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user