forked from liweijie/education
1 line
38 KiB
JSON
1 line
38 KiB
JSON
{"remainingRequest":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\views\\teachBusiness\\timetableAdjust\\index.vue?vue&type=style&index=0&id=3427efa2&scoped=true&lang=scss","dependencies":[{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\views\\teachBusiness\\timetableAdjust\\index.vue","mtime":1787652092740},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\css-loader\\dist\\cjs.js","mtime":1787309792478},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\loaders\\stylePostLoader.js","mtime":1787309794547},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\postcss-loader\\src\\index.js","mtime":1787309793084},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\sass-loader\\dist\\cjs.js","mtime":1787309791955},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\cache-loader\\dist\\cjs.js","mtime":1787309791955},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\index.js","mtime":1787309793790}],"contextDependencies":[],"result":[{"type":"Buffer","data":"base64:CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg0KLnBhZ2UtY29udGFpbmVyIHsNCiAgcGFkZGluZzogMTZweDsNCg0KICAuc2VjdGlvbi1jYXJkIHsNCiAgICBiYWNrZ3JvdW5kOiAjZmZmOw0KICAgIGJvcmRlcjogMXB4IHNvbGlkICNlYmVlZjU7DQogICAgYm9yZGVyLXJhZGl1czogNnB4Ow0KICAgIHBhZGRpbmc6IDE2cHggMjBweDsNCiAgICBtYXJnaW4tYm90dG9tOiAxNnB4Ow0KDQogICAgLnNlY3Rpb24tdGl0bGUgew0KICAgICAgZm9udC1zaXplOiAxNnB4Ow0KICAgICAgZm9udC13ZWlnaHQ6IDcwMDsNCiAgICAgIGNvbG9yOiAjMzAzMTMzOw0KICAgIH0NCg0KICAgIC5zZWN0aW9uLWhlYWRlciB7DQogICAgICBkaXNwbGF5OiBmbGV4Ow0KICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjsNCiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsNCiAgICAgIGZsZXgtd3JhcDogd3JhcDsNCiAgICAgIGdhcDogMTJweDsNCiAgICAgIG1hcmdpbi1ib3R0b206IDE2cHg7DQoNCiAgICAgIC5oZWFkZXItYWN0aW9ucyB7DQogICAgICAgIGRpc3BsYXk6IGZsZXg7DQogICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7DQogICAgICAgIGdhcDogMTJweDsNCiAgICAgIH0NCiAgICB9DQogIH0NCg0KICAvKiDnu5/orqHljaHniYcgKi8NCiAgLnN0YXQtZ3JpZCB7DQogICAgZGlzcGxheTogZ3JpZDsNCiAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdCg0LCAxZnIpOw0KICAgIGdhcDogMTZweDsNCiAgICBtYXJnaW4tdG9wOiAxNHB4Ow0KICB9DQoNCiAgLnN0YXQtY2FyZCB7DQogICAgZGlzcGxheTogZmxleDsNCiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOw0KICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOw0KICAgIHBhZGRpbmc6IDE2cHggMjBweDsNCiAgICBib3JkZXItcmFkaXVzOiA2cHg7DQogICAgY29sb3I6ICNmZmY7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjJzIGVhc2UsIGJveC1zaGFkb3cgMC4ycyBlYXNlOw0KDQogICAgJjpob3ZlciB7DQogICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTJweCk7DQogICAgICBib3gtc2hhZG93OiAwIDZweCAxNnB4IHJnYmEoMCwgMCwgMCwgMC4xMik7DQogICAgfQ0KDQogICAgLnN0YXQtdGV4dCB7DQogICAgICBmb250LXNpemU6IDEzcHg7DQogICAgICBvcGFjaXR5OiAwLjkyOw0KICAgIH0NCg0KICAgIC5zdGF0LXZhbHVlIHsNCiAgICAgIG1hcmdpbi10b3A6IDhweDsNCiAgICAgIGZvbnQtc2l6ZTogMjZweDsNCiAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7DQogICAgICBsaW5lLWhlaWdodDogMTsNCiAgICB9DQogIH0NCg0KICAvKiDmn6Xor6LljLrln58gKi8NCiAgLnNlYXJjaC1mb3JtIHsNCiAgICBtYXJnaW4tYm90dG9tOiAtMTZweDsNCg0KICAgIDo6di1kZWVwIC5lbC1mb3JtLWl0ZW0gew0KICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDsNCiAgICB9DQogIH0NCg0KICAuY29tcGFjdC10YWJsZSB7DQogICAgd2lkdGg6IDEwMCU7DQogIH0NCg0KICAuZGFuZ2VyLWJ0biB7DQogICAgY29sb3I6ICNmNTZjNmM7DQoNCiAgICAmOmhvdmVyIHsNCiAgICAgIGNvbG9yOiAjZjc4OTg5Ow0KICAgIH0NCiAgfQ0KDQogIC5vcHMtY2VsbCB7DQogICAgZGlzcGxheTogZmxleDsNCiAgICBhbGlnbi1pdGVtczogY2VudGVyOw0KICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOw0KICAgIGZsZXgtd3JhcDogd3JhcDsNCiAgICBnYXA6IDAgNHB4Ow0KICB9DQoNCiAgLnBpY2stbGVzc29uLWJ0biB7DQogICAgbWFyZ2luLXRvcDogNnB4Ow0KICAgIHdpZHRoOiAxMDAlOw0KICB9DQoNCiAgLnN1Yi1zZWN0aW9uIHsNCiAgICBtYXJnaW4tdG9wOiAxNnB4Ow0KDQogICAgLnN1Yi10aXRsZSB7DQogICAgICBmb250LXNpemU6IDE0cHg7DQogICAgICBmb250LXdlaWdodDogNzAwOw0KICAgICAgY29sb3I6ICMzMDMxMzM7DQogICAgICBtYXJnaW4tYm90dG9tOiA4cHg7DQogICAgfQ0KICB9DQp9DQoNCkBtZWRpYSAobWF4LXdpZHRoOiA5OTJweCkgew0KICAucGFnZS1jb250YWluZXIgLnN0YXQtZ3JpZCB7DQogICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiByZXBlYXQoMiwgMWZyKTsNCiAgfQ0KfQ0K"},{"version":3,"sources":["index.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAulBA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA","file":"index.vue","sourceRoot":"src/views/teachBusiness/timetableAdjust","sourcesContent":["<template>\r\n <div class=\"page-container\">\r\n <!-- 统计卡片 -->\r\n <div class=\"section-card\">\r\n <div class=\"stat-grid\">\r\n <div\r\n v-for=\"card in statCards\"\r\n :key=\"card.title\"\r\n class=\"stat-card\"\r\n :style=\"{ background: card.gradient }\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n @click=\"handleStatClick(card)\"\r\n @keydown.enter=\"handleStatClick(card)\"\r\n >\r\n <span class=\"stat-text\">{{ card.title }}</span>\r\n <span class=\"stat-value\">{{ card.value }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 查询条件 -->\r\n <div class=\"section-card\">\r\n <el-form :model=\"queryParams\" :inline=\"true\" size=\"small\" class=\"search-form\" @submit.native.prevent>\r\n <el-form-item label=\"年度\">\r\n <el-select v-model=\"queryParams.nd\" placeholder=\"请选择年度\" clearable style=\"width: 140px\">\r\n <el-option v-for=\"y in yearOptions\" :key=\"y\" :label=\"y\" :value=\"y\" />\r\n </el-select>\r\n </el-form-item>\r\n <el-form-item label=\"申请教员编号\">\r\n <el-input v-model=\"queryParams.sqjybh\" placeholder=\"请输入申请教员编号\" clearable style=\"width: 180px\" @keyup.enter.native=\"handleQuery\" />\r\n </el-form-item>\r\n <el-form-item label=\"教研室审批状态\">\r\n <el-select v-model=\"queryParams.jyspzzt\" placeholder=\"请选择\" clearable style=\"width: 150px\">\r\n <el-option v-for=\"item in auditStatusOptions\" :key=\"item.value\" :label=\"item.label\" :value=\"item.value\" />\r\n </el-select>\r\n </el-form-item>\r\n <el-form-item>\r\n <el-button type=\"primary\" icon=\"el-icon-search\" @click=\"handleQuery\">查询</el-button>\r\n <el-button icon=\"el-icon-refresh\" @click=\"resetQuery\">重置</el-button>\r\n </el-form-item>\r\n </el-form>\r\n </div>\r\n\r\n <!-- 调课调整申请列表 -->\r\n <div class=\"section-card\">\r\n <div class=\"section-header\">\r\n <div class=\"section-title\">调停补课申请列表</div>\r\n <div class=\"header-actions\">\r\n <el-button type=\"primary\" plain icon=\"el-icon-plus\" size=\"small\" @click=\"openAdd\">新增申请</el-button>\r\n </div>\r\n </div>\r\n\r\n <el-table :data=\"tableData\" v-loading=\"loading\" size=\"small\" border stripe class=\"compact-table\" max-height=\"520\">\r\n <el-table-column type=\"index\" label=\"序号\" width=\"55\" align=\"center\" />\r\n <el-table-column prop=\"kcmc\" label=\"课程名称\" width=\"200\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column label=\"申请教员\" width=\"150\" align=\"center\" show-overflow-tooltip>\r\n <template slot-scope=\"scope\">{{ scope.row.sqjyxm || scope.row.sqjybh || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"sy\" label=\"调课事由\" width=\"230\" show-overflow-tooltip header-align=\"center\" />\r\n <el-table-column label=\"拟调整时间\" width=\"200\" align=\"center\" show-overflow-tooltip>\r\n <template slot-scope=\"scope\">{{ fmtRqJc(scope.row.rq, scope.row.jc) }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"nd\" label=\"年度\" width=\"150\" align=\"center\" />\r\n <el-table-column label=\"教研室审批状态\" width=\"150\" align=\"center\">\r\n <template slot-scope=\"scope\">\r\n <el-tag :type=\"auditStatusTag(scope.row.jyspzzt).type\" size=\"mini\">{{ auditStatusTag(scope.row.jyspzzt).label }}</el-tag>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"教研室查收状态\" width=\"150\" align=\"center\">\r\n <template slot-scope=\"scope\">\r\n <el-tag :type=\"receiveStatusTag(scope.row.jyscszt).type\" size=\"mini\">{{ receiveStatusTag(scope.row.jyscszt).label }}</el-tag>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建时间\" width=\"150\" align=\"center\">\r\n <template slot-scope=\"scope\">{{ fmtDateTime(scope.row.cjsj) }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"操作\" width=\"180\" align=\"center\" fixed=\"right\">\r\n <template slot-scope=\"scope\">\r\n <div class=\"ops-cell\">\r\n <el-button type=\"text\" size=\"mini\" icon=\"el-icon-view\" @click=\"openDetail(scope.row)\">详情</el-button>\r\n <el-button v-if=\"showAuditMenu(scope.row)\" type=\"text\" size=\"mini\" @click=\"openAudit(scope.row)\">审批</el-button>\r\n <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>\r\n </div>\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n <el-empty v-show=\"!loading && tableData.length === 0\" description=\"暂无调整申请\" />\r\n <pagination\r\n v-show=\"total > 0\"\r\n :total=\"total\"\r\n :page.sync=\"queryParams.pageNum\"\r\n :limit.sync=\"queryParams.pageSize\"\r\n @pagination=\"loadList\"\r\n />\r\n </div>\r\n\r\n <!-- 新增申请弹窗 -->\r\n <el-dialog title=\"新增课表调整申请\" :visible.sync=\"addVisible\" width=\"640px\" append-to-body>\r\n <el-form ref=\"addForm\" :model=\"addForm\" :rules=\"addRules\" label-width=\"110px\">\r\n <el-form-item label=\"年度\" prop=\"nd\">\r\n <el-select v-model=\"addForm.nd\" placeholder=\"请选择年度\" style=\"width: 100%\">\r\n <el-option v-for=\"y in yearOptions\" :key=\"y\" :label=\"y\" :value=\"y\" />\r\n </el-select>\r\n </el-form-item>\r\n <el-form-item label=\"课次编号\" prop=\"sskcbbh\">\r\n <el-input v-model=\"addForm.sskcbbh\" placeholder=\"请输入课次编号\" />\r\n <el-button type=\"primary\" plain size=\"mini\" class=\"pick-lesson-btn\" :loading=\"lessonLoading\" @click=\"loadAdjustableLessons\">选择可供调课课次</el-button>\r\n </el-form-item>\r\n <el-form-item label=\"调课事由\" prop=\"sy\">\r\n <el-input v-model=\"addForm.sy\" type=\"textarea\" :rows=\"2\" placeholder=\"请输入调课事由\" />\r\n </el-form-item>\r\n <el-form-item label=\"拟调整日期\" prop=\"rq\">\r\n <el-date-picker v-model=\"addForm.rq\" type=\"date\" value-format=\"yyyy-MM-dd\" placeholder=\"请选择日期\" style=\"width: 100%\" />\r\n </el-form-item>\r\n <el-form-item label=\"拟调整节次\" prop=\"jc\">\r\n <el-select v-model=\"addForm.jc\" placeholder=\"请选择节次\" style=\"width: 100%\">\r\n <el-option v-for=\"n in jcOptions\" :key=\"n\" :label=\"jcLabel(n)\" :value=\"n\" />\r\n </el-select>\r\n </el-form-item>\r\n <el-form-item label=\"申请教员编号\" prop=\"sqjybh\">\r\n <el-input v-model=\"addForm.sqjybh\" placeholder=\"请输入申请教员编号\" />\r\n </el-form-item>\r\n <el-form-item label=\"学员队名称\">\r\n <el-input v-model=\"addForm.xydmc\" placeholder=\"选择可供调课课次后自动带出\" />\r\n </el-form-item>\r\n <el-form-item label=\"原教室编号\">\r\n <el-input v-model=\"addForm.yjsbh\" placeholder=\"选择可供调课课次后自动带出\" />\r\n </el-form-item>\r\n <el-form-item label=\"拟调整教室编号\">\r\n <el-input v-model=\"addForm.xjsbh\" placeholder=\"选填\" />\r\n </el-form-item>\r\n <el-form-item label=\"原上课时间\">\r\n <el-input v-model=\"addForm.ydsjap\" placeholder=\"选择可供调课课次后自动带出\" />\r\n </el-form-item>\r\n </el-form>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <el-button type=\"primary\" :loading=\"addLoading\" @click=\"submitAdd\">提交申请</el-button>\r\n <el-button @click=\"addVisible = false\">取消</el-button>\r\n </div>\r\n </el-dialog>\r\n\r\n <!-- 可供调课课次选择弹窗 -->\r\n <el-dialog title=\"选择可供调课课次\" :visible.sync=\"lessonDialogVisible\" width=\"760px\" append-to-body>\r\n <el-table :data=\"lessonOptions\" v-loading=\"lessonLoading\" size=\"small\" border stripe max-height=\"420\">\r\n <el-table-column prop=\"kcmc\" label=\"课程名称\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column label=\"原上课时间\" width=\"160\" align=\"center\">\r\n <template slot-scope=\"scope\">{{ fmtRqJc(scope.row.rq, scope.row.jc) }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"xydmc\" label=\"学员队\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"kcxh\" label=\"课次序号\" width=\"90\" align=\"center\" />\r\n <el-table-column prop=\"jsbh\" label=\"教室编号\" width=\"110\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column label=\"操作\" width=\"90\" align=\"center\">\r\n <template slot-scope=\"scope\">\r\n <el-button type=\"text\" size=\"mini\" @click=\"pickLesson(scope.row)\">选择</el-button>\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n <el-empty v-show=\"!lessonLoading && lessonOptions.length === 0\" description=\"暂无可供调课课次\" />\r\n </el-dialog>\r\n\r\n <!-- 审批弹窗 -->\r\n <el-dialog title=\"教研室审批\" :visible.sync=\"auditVisible\" width=\"520px\" append-to-body>\r\n <el-form ref=\"auditForm\" :model=\"auditForm\" label-width=\"100px\">\r\n <el-form-item label=\"审批结果\" required>\r\n <el-radio-group v-model=\"auditForm.spzt\">\r\n <el-radio :label=\"1\">同意</el-radio>\r\n <el-radio :label=\"2\">发回</el-radio>\r\n <el-radio :label=\"3\">拒绝</el-radio>\r\n </el-radio-group>\r\n <div class=\"form-tip\">点审批即已查收</div>\r\n </el-form-item>\r\n <el-form-item label=\"审批意见\">\r\n <el-input v-model=\"auditForm.fhyj\" type=\"textarea\" :rows=\"3\" placeholder=\"请输入审批意见(发回/拒绝时必填)\" />\r\n </el-form-item>\r\n <el-form-item label=\"审批人编号\">\r\n <el-input v-model=\"auditForm.sprbh\" placeholder=\"不填默认取当前登录人\" />\r\n </el-form-item>\r\n </el-form>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <el-button type=\"primary\" :loading=\"auditLoading\" @click=\"submitAudit\">确定</el-button>\r\n <el-button @click=\"auditVisible = false\">取消</el-button>\r\n </div>\r\n </el-dialog>\r\n\r\n <!-- 查看详情弹窗 -->\r\n <el-dialog title=\"申请详情\" :visible.sync=\"detailVisible\" width=\"760px\" append-to-body>\r\n <div v-loading=\"detailLoading\">\r\n <el-descriptions v-if=\"detailData\" :column=\"2\" border size=\"small\">\r\n <el-descriptions-item label=\"课程名称\">{{ detailData.kcmc || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"申请教员\">{{ detailData.sqjyxm || detailData.sqjybh || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"调课事由\" :span=\"2\">{{ detailData.sy || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"原上课时间\">{{ detailData.ydsjap || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"拟调整时间\">{{ fmtRqJc(detailData.rq, detailData.jc) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"年度\">{{ detailData.nd || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"创建时间\">{{ fmtDateTime(detailData.cjsj) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教研室审批状态\">\r\n <el-tag :type=\"auditStatusTag(detailData.jyspzzt).type\" size=\"mini\">{{ auditStatusTag(detailData.jyspzzt).label }}</el-tag>\r\n </el-descriptions-item>\r\n <el-descriptions-item label=\"教研室查收状态\">\r\n <el-tag :type=\"receiveStatusTag(detailData.jyscszt).type\" size=\"mini\">{{ receiveStatusTag(detailData.jyscszt).label }}</el-tag>\r\n </el-descriptions-item>\r\n <el-descriptions-item label=\"教研室审批人\">{{ detailData.jyspzrbh || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教研室审批时间\">{{ fmtDateTime(detailData.jyspzsj) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教研室查收人\">{{ detailData.jyscsrbh || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教研室查收时间\">{{ fmtDateTime(detailData.jyscssj) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教学内容\" :span=\"2\">{{ detailData.jxnr || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教学要点\" :span=\"2\">{{ detailData.jxyd || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教学方法\" :span=\"2\">{{ detailData.jxff || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教学保障备注\" :span=\"2\">{{ detailData.jxbzbz || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"用车信息\" :span=\"2\">{{ detailData.ycxx || '-' }}</el-descriptions-item>\r\n <el-descriptions-item label=\"备注\" :span=\"2\">{{ detailData.bz || '-' }}</el-descriptions-item>\r\n </el-descriptions>\r\n\r\n <!-- 新教室 -->\r\n <div v-if=\"detailData && detailData.roomList && detailData.roomList.length\" class=\"sub-section\">\r\n <div class=\"sub-title\">新教室</div>\r\n <el-table :data=\"detailData.roomList\" size=\"small\" border stripe>\r\n <el-table-column prop=\"jsbh\" label=\"教室编号\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"jsmc\" label=\"教室名称\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"bz\" label=\"备注\" min-width=\"160\" show-overflow-tooltip header-align=\"center\" />\r\n </el-table>\r\n </div>\r\n\r\n <!-- 新辅助教员 -->\r\n <div v-if=\"detailData && detailData.teacherList && detailData.teacherList.length\" class=\"sub-section\">\r\n <div class=\"sub-title\">新辅助教员</div>\r\n <el-table :data=\"detailData.teacherList\" size=\"small\" border stripe>\r\n <el-table-column prop=\"fzjybh\" label=\"教员编号\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"fzjyxm\" label=\"教员姓名\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column label=\"是否主教员\" width=\"100\" align=\"center\">\r\n <template slot-scope=\"scope\">{{ scope.row.zjy === 1 ? '是' : '否' }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"bz\" label=\"备注\" min-width=\"140\" show-overflow-tooltip header-align=\"center\" />\r\n </el-table>\r\n </div>\r\n\r\n <!-- 新学员队 -->\r\n <div v-if=\"detailData && detailData.teamList && detailData.teamList.length\" class=\"sub-section\">\r\n <div class=\"sub-title\">新学员队</div>\r\n <el-table :data=\"detailData.teamList\" size=\"small\" border stripe>\r\n <el-table-column prop=\"xydbh\" label=\"学员队编号\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"xydmc\" label=\"学员队名称\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n </el-table>\r\n </div>\r\n\r\n <!-- 新保障明细 -->\r\n <div v-if=\"detailData && detailData.supportList && detailData.supportList.length\" class=\"sub-section\">\r\n <div class=\"sub-title\">新保障明细</div>\r\n <el-table :data=\"detailData.supportList\" size=\"small\" border stripe>\r\n <el-table-column prop=\"bztgmxbh\" label=\"保障编号\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"bztgmxmc\" label=\"保障名称\" min-width=\"160\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"sl\" label=\"数量\" width=\"80\" align=\"center\" />\r\n <el-table-column prop=\"bz\" label=\"备注\" min-width=\"140\" show-overflow-tooltip header-align=\"center\" />\r\n </el-table>\r\n </div>\r\n\r\n <!-- 机关审批记录 -->\r\n <div v-if=\"detailData && detailData.auditList && detailData.auditList.length\" class=\"sub-section\">\r\n <div class=\"sub-title\">机关审批记录</div>\r\n <el-table :data=\"detailData.auditList\" size=\"small\" border stripe>\r\n <el-table-column prop=\"jgmc\" label=\"机关\" min-width=\"140\" align=\"center\" show-overflow-tooltip>\r\n <template slot-scope=\"scope\">{{ scope.row.jgmc || scope.row.jgbh || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"审批状态\" width=\"100\" align=\"center\">\r\n <template slot-scope=\"scope\">\r\n <el-tag :type=\"auditStatusTag(scope.row.spzt).type\" size=\"mini\">{{ auditStatusTag(scope.row.spzt).label }}</el-tag>\r\n </template>\r\n </el-table-column>\r\n <el-table-column prop=\"sprxm\" label=\"审批人\" min-width=\"110\" align=\"center\" show-overflow-tooltip>\r\n <template slot-scope=\"scope\">{{ scope.row.sprxm || scope.row.sprbh || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"审批时间\" width=\"150\" align=\"center\">\r\n <template slot-scope=\"scope\">{{ fmtDateTime(scope.row.spsj) }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"fhyj\" label=\"发回意见\" min-width=\"140\" show-overflow-tooltip header-align=\"center\" />\r\n </el-table>\r\n </div>\r\n </div>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <el-button @click=\"detailVisible = false\">关闭</el-button>\r\n </div>\r\n </el-dialog>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport {\r\n listScheduleAdjust,\r\n listAdjustableLessons,\r\n getScheduleAdjustDetail,\r\n submitScheduleAdjust,\r\n auditByTeachingOffice,\r\n cancelScheduleAdjust\r\n} from '@/api/teachBusiness/courseRunning'\r\nimport { listAllSemester } from '@/api/teachBusiness/semester'\r\n\r\n// 节次 -> 节次区间映射\r\nconst JC_SECTION = {\r\n 1: '1-2节', 2: '3-4节', 3: '5-6节', 4: '7-8节', 5: '9-10节', 6: '11-12节'\r\n}\r\n\r\n// 审批状态:0-未审批,1-已同意,2-已发回,3-已拒绝\r\nconst AUDIT_STATUS = {\r\n 0: { label: '未审批', type: 'info' },\r\n 1: { label: '已同意', type: 'success' },\r\n 2: { label: '已发回', type: 'warning' },\r\n 3: { label: '已拒绝', type: 'danger' }\r\n}\r\n\r\n// 查收状态:0-未查收,1-已查收\r\nconst RECEIVE_STATUS = {\r\n 0: { label: '未查收', type: 'info' },\r\n 1: { label: '已查收', type: 'success' }\r\n}\r\n\r\nexport default {\r\n name: 'TimetableAdjust',\r\n data() {\r\n const curUserName = (this.$store.state.user && this.$store.state.user.name) || ''\r\n return {\r\n curUserName: curUserName,\r\n loading: false,\r\n tableData: [],\r\n total: 0,\r\n queryParams: {\r\n nd: undefined,\r\n sqjybh: undefined,\r\n jyspzzt: undefined,\r\n pageNum: 1,\r\n pageSize: 20\r\n },\r\n // 年度下拉数据来自 /semester/all(真实后端数据)\r\n yearOptions: [],\r\n defaultNd: undefined,\r\n jcOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\r\n auditStatusOptions: [\r\n { label: '未审批', value: 0 },\r\n { label: '已同意', value: 1 },\r\n { label: '已发回', value: 2 },\r\n { label: '已拒绝', value: 3 }\r\n ],\r\n statCards: [],\r\n // 新增申请\r\n addVisible: false,\r\n addLoading: false,\r\n addForm: {},\r\n addRules: {\r\n nd: [{ required: true, message: '请选择年度', trigger: 'change' }],\r\n sskcbbh: [{ required: true, message: '请输入课次编号', trigger: 'blur' }],\r\n sy: [{ required: true, message: '请输入调课事由', trigger: 'blur' }],\r\n rq: [{ required: true, message: '请选择拟调整日期', trigger: 'change' }],\r\n jc: [{ required: true, message: '请选择拟调整节次', trigger: 'change' }],\r\n sqjybh: [{ required: true, message: '请输入申请教员编号', trigger: 'blur' }]\r\n },\r\n // 可供调课课次\r\n lessonDialogVisible: false,\r\n lessonLoading: false,\r\n lessonOptions: [],\r\n // 审批\r\n auditVisible: false,\r\n auditLoading: false,\r\n auditForm: { ssdksqbh: '', spzt: 1, fhyj: '', sprbh: '' },\r\n // 详情\r\n detailVisible: false,\r\n detailLoading: false,\r\n detailData: null\r\n }\r\n },\r\n created() {\r\n this.loadYearOptions().then(() => this.loadList())\r\n },\r\n methods: {\r\n /* ---------- 年度下拉(数据来自 /semester/all) ---------- */\r\n loadYearOptions() {\r\n return listAllSemester().then(response => {\r\n const list = response.data || []\r\n // 去重并按年度倒序\r\n const map = {}\r\n list.forEach(item => {\r\n if (item.nd !== null && item.nd !== undefined && item.nd !== '') map[item.nd] = item\r\n })\r\n const arr = Object.keys(map).sort((a, b) => String(b).localeCompare(String(a)))\r\n this.yearOptions = arr\r\n // 默认年度:优先当前学期(dqxq=true),否则取最新年度\r\n const current = list.find(item => item.dqxq === true)\r\n this.defaultNd = (current && current.nd) || arr[0]\r\n if (!this.queryParams.nd) this.queryParams.nd = this.defaultNd\r\n return arr\r\n }).catch(() => {\r\n this.yearOptions = []\r\n this.defaultNd = undefined\r\n return []\r\n })\r\n },\r\n /* ---------- 通用格式化 ---------- */\r\n fmtDateTime(v) {\r\n if (!v) return '-'\r\n return String(v).replace('T', ' ').substring(0, 16)\r\n },\r\n fmtRqJc(rq, jc) {\r\n if (!rq) return '-'\r\n const date = String(rq).substring(0, 10)\r\n const sec = jc === null || jc === undefined || jc === '' ? '第?节' : (JC_SECTION[jc] || '第' + jc + '节')\r\n return date + ' ' + sec\r\n },\r\n jcLabel(n) {\r\n return JC_SECTION[n] || ('第' + n + '节')\r\n },\r\n auditStatusTag(v) {\r\n return AUDIT_STATUS[v] || { label: '-', type: 'info' }\r\n },\r\n receiveStatusTag(v) {\r\n return RECEIVE_STATUS[v] || { label: '-', type: 'info' }\r\n },\r\n /* ---------- 列表查询 ---------- */\r\n loadList() {\r\n const params = {\r\n pageNum: this.queryParams.pageNum,\r\n pageSize: this.queryParams.pageSize\r\n }\r\n if (this.queryParams.nd) params.nd = this.queryParams.nd\r\n if (this.queryParams.sqjybh) params.sqjybh = this.queryParams.sqjybh\r\n if (this.queryParams.jyspzzt !== undefined && this.queryParams.jyspzzt !== '') {\r\n params.jyspzzt = this.queryParams.jyspzzt\r\n }\r\n this.loading = true\r\n listScheduleAdjust(params).then(response => {\r\n const data = response.data || {}\r\n this.tableData = data.records || []\r\n this.total = data.total || 0\r\n this.refreshStatCards()\r\n this.loading = false\r\n }).catch(() => {\r\n this.tableData = []\r\n this.total = 0\r\n this.refreshStatCards()\r\n this.loading = false\r\n })\r\n },\r\n handleQuery() {\r\n this.queryParams.pageNum = 1\r\n this.loadList()\r\n },\r\n resetQuery() {\r\n this.queryParams = {\r\n nd: this.defaultNd,\r\n sqjybh: undefined,\r\n jyspzzt: undefined,\r\n pageNum: 1,\r\n pageSize: 20\r\n }\r\n this.loadList()\r\n },\r\n refreshStatCards() {\r\n const list = this.tableData\r\n this.statCards = [\r\n { title: '本页申请', value: list.length, gradient: 'linear-gradient(135deg, #00875a 0%, #00b877 100%)', filter: undefined },\r\n { title: '教研室待审批', value: list.filter(i => i.jyspzzt === 0).length, gradient: 'linear-gradient(135deg, #e6a23c 0%, #f8b04c 100%)', filter: 0 },\r\n { title: '教研室已同意', value: list.filter(i => i.jyspzzt === 1).length, gradient: 'linear-gradient(135deg, #409eff 0%, #66b1ff 100%)', filter: 1 },\r\n { title: '教研室已拒绝', value: list.filter(i => i.jyspzzt === 3).length, gradient: 'linear-gradient(135deg, #f56c6c 0%, #f78989 100%)', filter: 3 }\r\n ]\r\n },\r\n handleStatClick(card) {\r\n if (card.filter === undefined) return\r\n this.queryParams.jyspzzt = this.queryParams.jyspzzt === card.filter ? undefined : card.filter\r\n this.handleQuery()\r\n },\r\n /* ---------- 新增申请 ---------- */\r\n openAdd() {\r\n this.addForm = {\r\n nd: this.defaultNd || this.yearOptions[0],\r\n sskcbbh: '',\r\n sy: '',\r\n rq: '',\r\n jc: 1,\r\n sqjybh: this.curUserName,\r\n xydmc: '',\r\n yjsbh: '',\r\n xjsbh: '',\r\n ydsjap: ''\r\n }\r\n this.$nextTick(() => this.$refs.addForm && this.$refs.addForm.clearValidate())\r\n this.addVisible = true\r\n },\r\n loadAdjustableLessons() {\r\n if (!this.addForm.nd) {\r\n this.$message.warning('请先选择年度')\r\n return\r\n }\r\n this.lessonLoading = true\r\n listAdjustableLessons({ nd: this.addForm.nd }).then(response => {\r\n this.lessonOptions = response.data || []\r\n this.lessonLoading = false\r\n this.lessonDialogVisible = true\r\n }).catch(() => {\r\n this.lessonLoading = false\r\n this.$message.info('后端暂未提供可供调课课次接口,请手动填写课次编号')\r\n })\r\n },\r\n pickLesson(row) {\r\n this.addForm.sskcbbh = row.sskcbbh\r\n // 自动带出课次关联字段(若接口返回则回填)\r\n ;['xydmc', 'yjsbh', 'ydsjap', 'kbh', 'kcbbh', 'xydrwbh', 'jysdh', 'xjsbh', 'kcmc', 'sqjyxm'].forEach(key => {\r\n if (row[key] !== undefined && row[key] !== null) this.addForm[key] = row[key]\r\n })\r\n if (!this.addForm.ydsjap && row.rq) this.addForm.ydsjap = this.fmtRqJc(row.rq, row.jc)\r\n this.lessonDialogVisible = false\r\n this.$message.success('已选择课次:' + (row.kcmc || row.sskcbbh))\r\n },\r\n submitAdd() {\r\n this.$refs.addForm.validate(valid => {\r\n if (!valid) return\r\n const payload = {\r\n sskcbbh: this.addForm.sskcbbh,\r\n sy: this.addForm.sy,\r\n rq: this.addForm.rq + 'T00:00:00',\r\n jc: this.addForm.jc,\r\n nd: this.addForm.nd,\r\n sqjybh: this.addForm.sqjybh\r\n }\r\n ;['xydmc', 'yjsbh', 'xjsbh', 'ydsjap', 'kbh', 'kcbbh', 'xydrwbh', 'jysdh', 'kcmc', 'sqjyxm'].forEach(key => {\r\n if (this.addForm[key]) payload[key] = this.addForm[key]\r\n })\r\n this.addLoading = true\r\n submitScheduleAdjust(payload).then(() => {\r\n this.addLoading = false\r\n this.addVisible = false\r\n this.$message.success('申请提交成功')\r\n this.loadList()\r\n }).catch(() => {\r\n this.addLoading = false\r\n })\r\n })\r\n },\r\n /* ---------- 审批 ---------- */\r\n showAuditMenu(row) {\r\n return row.sczt === 0 && (row.jyspzzt === 0 || row.jyspzzt === 2 || row.jyspzzt === 3)\r\n },\r\n openAudit(row) {\r\n this.auditForm = {\r\n ssdksqbh: row.ssdksqbh,\r\n spzt: 1,\r\n fhyj: '',\r\n sprbh: ''\r\n }\r\n this.auditVisible = true\r\n },\r\n submitAudit() {\r\n const f = this.auditForm\r\n if (f.spzt !== 1 && !f.fhyj) {\r\n this.$message.warning('发回/拒绝时请填写审批意见')\r\n return\r\n }\r\n const payload = {\r\n ssdksqbh: f.ssdksqbh,\r\n spzt: f.spzt,\r\n fhyj: f.fhyj\r\n }\r\n if (f.sprbh) payload.sprbh = f.sprbh\r\n this.auditLoading = true\r\n auditByTeachingOffice(payload).then(() => {\r\n this.auditLoading = false\r\n this.auditVisible = false\r\n this.$message.success('审批成功')\r\n this.loadList()\r\n }).catch(() => {\r\n this.auditLoading = false\r\n })\r\n },\r\n /* ---------- 撤销 ---------- */\r\n handleCancel(row) {\r\n this.$confirm('确认撤销该调课申请?', '提示', { type: 'warning' })\r\n .then(() => {\r\n cancelScheduleAdjust({ ssdksqbh: row.ssdksqbh }).then(() => {\r\n this.$message.success('撤销成功')\r\n this.loadList()\r\n }).catch(() => {})\r\n })\r\n .catch(() => {})\r\n },\r\n /* ---------- 详情 ---------- */\r\n openDetail(row) {\r\n this.detailVisible = true\r\n this.detailLoading = true\r\n this.detailData = null\r\n getScheduleAdjustDetail(row.ssdksqbh).then(response => {\r\n this.detailData = response.data || {}\r\n this.detailLoading = false\r\n }).catch(() => {\r\n this.detailData = null\r\n this.detailLoading = false\r\n })\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n.page-container {\r\n padding: 16px;\r\n\r\n .section-card {\r\n background: #fff;\r\n border: 1px solid #ebeef5;\r\n border-radius: 6px;\r\n padding: 16px 20px;\r\n margin-bottom: 16px;\r\n\r\n .section-title {\r\n font-size: 16px;\r\n font-weight: 700;\r\n color: #303133;\r\n }\r\n\r\n .section-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n flex-wrap: wrap;\r\n gap: 12px;\r\n margin-bottom: 16px;\r\n\r\n .header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n }\r\n }\r\n\r\n /* 统计卡片 */\r\n .stat-grid {\r\n display: grid;\r\n grid-template-columns: repeat(4, 1fr);\r\n gap: 16px;\r\n margin-top: 14px;\r\n }\r\n\r\n .stat-card {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n padding: 16px 20px;\r\n border-radius: 6px;\r\n color: #fff;\r\n cursor: pointer;\r\n transition: transform 0.2s ease, box-shadow 0.2s ease;\r\n\r\n &:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);\r\n }\r\n\r\n .stat-text {\r\n font-size: 13px;\r\n opacity: 0.92;\r\n }\r\n\r\n .stat-value {\r\n margin-top: 8px;\r\n font-size: 26px;\r\n font-weight: 700;\r\n line-height: 1;\r\n }\r\n }\r\n\r\n /* 查询区域 */\r\n .search-form {\r\n margin-bottom: -16px;\r\n\r\n ::v-deep .el-form-item {\r\n margin-bottom: 16px;\r\n }\r\n }\r\n\r\n .compact-table {\r\n width: 100%;\r\n }\r\n\r\n .danger-btn {\r\n color: #f56c6c;\r\n\r\n &:hover {\r\n color: #f78989;\r\n }\r\n }\r\n\r\n .ops-cell {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-wrap: wrap;\r\n gap: 0 4px;\r\n }\r\n\r\n .pick-lesson-btn {\r\n margin-top: 6px;\r\n width: 100%;\r\n }\r\n\r\n .sub-section {\r\n margin-top: 16px;\r\n\r\n .sub-title {\r\n font-size: 14px;\r\n font-weight: 700;\r\n color: #303133;\r\n margin-bottom: 8px;\r\n }\r\n }\r\n}\r\n\r\n@media (max-width: 992px) {\r\n .page-container .stat-grid {\r\n grid-template-columns: repeat(2, 1fr);\r\n }\r\n}\r\n</style>\r\n"]}]} |