forked from liweijie/education
1 line
32 KiB
JSON
1 line
32 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\\trainingPlan\\index.vue?vue&type=style&index=0&id=6f1813fa&scoped=true&lang=scss","dependencies":[{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\views\\teachBusiness\\trainingPlan\\index.vue","mtime":1787652512653},{"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:CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg0KLmFwcC1jb250YWluZXIgew0KICBwYWRkaW5nOiAyMHB4Ow0KfQ0KDQoudHJhaW5pbmctcGxhbi1wYWdlIHsNCiAgLnNlYXJjaC1jYXJkIHsNCiAgICBtYXJnaW4tYm90dG9tOiAxNnB4Ow0KDQogICAgLnNlYXJjaC1mb3JtIHsNCiAgICAgIC53LWZ1bGwgew0KICAgICAgICB3aWR0aDogMTAwJTsNCiAgICAgIH0NCg0KICAgICAgLnNlYXJjaC1hY3Rpb25zIHsNCiAgICAgICAgcGFkZGluZy10b3A6IDRweDsNCiAgICAgIH0NCiAgICB9DQogIH0NCg0KICAuYWN0aW9uLWNhcmQgew0KICAgIG1hcmdpbi1ib3R0b206IDE2cHg7DQoNCiAgICAuYWN0aW9uLXJvdyB7DQogICAgICBtYXJnaW4tYm90dG9tOiAxMnB4Ow0KDQogICAgICAmOmxhc3Qtb2YtdHlwZSB7DQogICAgICAgIG1hcmdpbi1ib3R0b206IDA7DQogICAgICB9DQogICAgfQ0KDQogICAgLnVwbG9hZC1yb3cgew0KICAgICAgZGlzcGxheTogZmxleDsNCiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7DQogICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47DQogICAgICBmbGV4LXdyYXA6IHdyYXA7DQogICAgICBnYXA6IDEycHg7DQogICAgICBwYWRkaW5nOiAxMnB4Ow0KICAgICAgYmFja2dyb3VuZDogI2ZhZmFmYTsNCiAgICAgIGJvcmRlcjogMXB4IGRhc2hlZCAjZGNkZmU2Ow0KICAgICAgYm9yZGVyLXJhZGl1czogNHB4Ow0KDQogICAgICAudXBsb2FkLWxlZnQgew0KICAgICAgICBkaXNwbGF5OiBmbGV4Ow0KICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyOw0KICAgICAgICBnYXA6IDEycHg7DQoNCiAgICAgICAgLmZpbGUtbmFtZSB7DQogICAgICAgICAgZm9udC1zaXplOiAxM3B4Ow0KICAgICAgICAgIGNvbG9yOiAjOTA5Mzk5Ow0KDQogICAgICAgICAgJi5oYXMtZmlsZSB7DQogICAgICAgICAgICBjb2xvcjogIzQwOWVmZjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCg0KICAudGFibGUtY2FyZCB7DQogICAgLmxpc3QtaGVhZGVyIHsNCiAgICAgIGRpc3BsYXk6IGZsZXg7DQogICAgICBhbGlnbi1pdGVtczogY2VudGVyOw0KICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOw0KICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDsNCg0KICAgICAgLmxpc3QtdGl0bGUgew0KICAgICAgICBmb250LXNpemU6IDE2cHg7DQogICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7DQogICAgICAgIGNvbG9yOiAjMzAzMTMzOw0KICAgICAgfQ0KICAgIH0NCg0KICAgIC5wYWdpbmF0aW9uIHsNCiAgICAgIG1hcmdpbi10b3A6IDE2cHg7DQogICAgICB0ZXh0LWFsaWduOiByaWdodDsNCiAgICB9DQogIH0NCg0KICAuZGV0YWlsLWJvZHkgew0KICAgIG1pbi1oZWlnaHQ6IDYwcHg7DQogIH0NCn0NCg0KLmRhbmdlci10ZXh0LWJ0biB7DQogIGNvbG9yOiAjZjU2YzZjOw0KDQogICY6aG92ZXIgew0KICAgIGNvbG9yOiAjZjc4OTg5Ow0KICB9DQp9DQoNCi50cmFpbmluZy1kaWN0LXNlbGVjdCB7DQogIHdpZHRoOiAxMDAlOw0KfQ0K"},{"version":3,"sources":["index.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqkBA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA","file":"index.vue","sourceRoot":"src/views/teachBusiness/trainingPlan","sourcesContent":["<template>\r\n <div class=\"app-container training-plan-page\">\r\n <!-- ==================== 1. 查询条件区域 ==================== -->\r\n <el-card shadow=\"never\" class=\"search-card\">\r\n <el-form :model=\"searchForm\" label-width=\"100px\" class=\"search-form\" @submit.native.prevent>\r\n <el-row :gutter=\"24\">\r\n <el-col :xs=\"24\" :md=\"8\">\r\n <el-form-item label=\"专业名称\">\r\n <el-input v-model=\"searchForm.zymc\" placeholder=\"请输入专业名称\" clearable />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :xs=\"24\" :md=\"8\">\r\n <el-form-item label=\"专业代码\">\r\n <el-input v-model=\"searchForm.zydm\" placeholder=\"请输入专业代码\" clearable />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :xs=\"24\" :md=\"8\">\r\n <el-form-item label=\"培训类型\">\r\n <el-select\r\n v-model=\"searchForm.pxlx\"\r\n placeholder=\"请选择培训类型\"\r\n clearable\r\n filterable\r\n class=\"w-full\"\r\n >\r\n <el-option\r\n v-for=\"item in trainingTypeOptions\"\r\n :key=\"item.dictCode || item.dictValue\"\r\n :label=\"item.dictLabel\"\r\n :value=\"item.dictLabel\"\r\n />\r\n </el-select>\r\n </el-form-item>\r\n </el-col>\r\n <el-col :xs=\"24\" :md=\"8\">\r\n <el-form-item label=\"培训层次\">\r\n <el-select\r\n v-model=\"searchForm.pxcc\"\r\n placeholder=\"请选择培训层次\"\r\n clearable\r\n filterable\r\n class=\"w-full\"\r\n >\r\n <el-option\r\n v-for=\"item in trainingLevelOptions\"\r\n :key=\"item.dictCode || item.dictValue\"\r\n :label=\"item.dictLabel\"\r\n :value=\"item.dictLabel\"\r\n />\r\n </el-select>\r\n </el-form-item>\r\n </el-col>\r\n <el-col :xs=\"24\" :md=\"8\">\r\n <div class=\"search-actions\">\r\n <el-button type=\"primary\" icon=\"el-icon-search\" @click=\"handleQuery\">查询</el-button>\r\n <el-button icon=\"el-icon-refresh\" @click=\"handleReset\">重置</el-button>\r\n </div>\r\n </el-col>\r\n </el-row>\r\n </el-form>\r\n </el-card>\r\n\r\n <!-- ==================== 2. 操作与上传区域 ==================== -->\r\n <el-card shadow=\"never\" class=\"action-card\">\r\n <div class=\"action-row\">\r\n <el-button type=\"primary\" icon=\"el-icon-plus\" @click=\"handleAdd\">新建</el-button>\r\n <el-button icon=\"el-icon-download\" @click=\"handleDownload\">下载</el-button>\r\n </div>\r\n <div class=\"action-row\">\r\n <el-button icon=\"el-icon-download\" @click=\"handleTemplateDownload\">【人才培养方案目录模板】下载</el-button>\r\n </div>\r\n <div class=\"upload-row\">\r\n <div class=\"upload-left\">\r\n <el-button icon=\"el-icon-folder-opened\" @click=\"handleChooseFile\">选择文件</el-button>\r\n <span class=\"file-name\" :class=\"{ 'has-file': selectedFile }\">\r\n <template v-if=\"selectedFile\">{{ fileName }}</template>\r\n <template v-else>请选择要上传的文件</template>\r\n </span>\r\n <input ref=\"fileInputRef\" type=\"file\" style=\"display: none\" @change=\"handleFileChange\" />\r\n </div>\r\n <div class=\"upload-right\">\r\n <el-button type=\"primary\" icon=\"el-icon-upload2\" :disabled=\"!selectedFile\" @click=\"handleUpload\">上传数据</el-button>\r\n </div>\r\n </div>\r\n </el-card>\r\n\r\n <!-- ==================== 3. 数据表格区域 ==================== -->\r\n <el-card shadow=\"never\" class=\"table-card\">\r\n <div class=\"list-header\">\r\n <div class=\"list-title\">人才培养方案列表</div>\r\n </div>\r\n <el-table v-loading=\"loading\" :data=\"tableData\" border stripe highlight-current-row>\r\n <el-table-column type=\"index\" label=\"序号\" width=\"60\" align=\"center\" />\r\n <el-table-column prop=\"zydh\" label=\"专业代号\" width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"zymc\" label=\"专业名称\" width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"zyfx\" label=\"专业方向\" width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"zydm\" label=\"专业代码\" width=\"110\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"pxlx\" label=\"培训类型\" width=\"110\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"pxcc\" label=\"培训层次\" width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"pxlx2\" label=\"培训类型2\" width=\"110\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"xylb\" label=\"学员类别\" width=\"100\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"xnz\" label=\"学年制\" width=\"80\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"xqs\" label=\"学期数\" width=\"80\" align=\"center\" />\r\n <el-table-column prop=\"zybb\" label=\"专业版本\" width=\"100\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column label=\"主干专业\" width=\"90\" align=\"center\">\r\n <template slot-scope=\"scope\">{{ fmtYesNo(scope.row.zgzy) }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"状态\" width=\"80\" align=\"center\">\r\n <template slot-scope=\"scope\">\r\n <el-tag :type=\"isTrue(scope.row.ty) ? 'danger' : 'success'\" size=\"mini\">\r\n {{ isTrue(scope.row.ty) ? '停用' : '启用' }}\r\n </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.qysj) }}</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.tysj) }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"操作\" width=\"240\" align=\"center\" fixed=\"right\">\r\n <template slot-scope=\"scope\">\r\n <el-button type=\"text\" size=\"mini\" icon=\"el-icon-view\" @click=\"handleDetail(scope.row)\">详情</el-button>\r\n <el-button type=\"text\" size=\"mini\" icon=\"el-icon-edit\" @click=\"handleEdit(scope.row)\">编辑</el-button>\r\n <el-button type=\"text\" size=\"mini\" icon=\"el-icon-circle-close\" class=\"danger-text-btn\"\r\n :disabled=\"isTrue(scope.row.ty)\" @click=\"handleDisable(scope.row)\">停用</el-button>\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n\r\n <el-pagination\r\n class=\"pagination\"\r\n background\r\n layout=\"total, sizes, prev, pager, next, jumper\"\r\n :current-page=\"pageNum\"\r\n :page-size=\"pageSize\"\r\n :total=\"total\"\r\n :page-sizes=\"[10, 20, 50, 100]\"\r\n @size-change=\"handleSizeChange\"\r\n @current-change=\"handlePageChange\"\r\n />\r\n </el-card>\r\n\r\n <!-- 新增/编辑弹窗 -->\r\n <el-dialog :title=\"dialog.title\" :visible.sync=\"dialog.visible\" width=\"860px\" append-to-body\r\n :close-on-click-modal=\"false\">\r\n <el-form ref=\"trainingForm\" :model=\"dialog.form\" :rules=\"rules\" label-width=\"130px\">\r\n <el-row :gutter=\"20\">\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业代号\" prop=\"zydh\">\r\n <el-input v-model=\"dialog.form.zydh\" placeholder=\"请输入专业代号\" :disabled=\"dialog.isEdit\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业名称\" prop=\"zymc\">\r\n <el-input v-model=\"dialog.form.zymc\" placeholder=\"请输入专业名称\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业代码\" prop=\"zydm\">\r\n <el-input v-model=\"dialog.form.zydm\" placeholder=\"请输入专业代码\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业方向\">\r\n <el-input v-model=\"dialog.form.zyfx\" placeholder=\"请输入专业方向\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"培训层次\" prop=\"pxcc\">\r\n <el-select\r\n v-model=\"dialog.form.pxcc\"\r\n placeholder=\"请选择培训层次\"\r\n filterable\r\n class=\"training-dict-select\"\r\n >\r\n <el-option\r\n v-for=\"item in trainingLevelOptions\"\r\n :key=\"item.dictCode || item.dictValue\"\r\n :label=\"item.dictLabel\"\r\n :value=\"item.dictLabel\"\r\n />\r\n </el-select>\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"培训类型\" prop=\"pxlx\">\r\n <el-select\r\n v-model=\"dialog.form.pxlx\"\r\n placeholder=\"请选择培训类型\"\r\n filterable\r\n class=\"training-dict-select\"\r\n >\r\n <el-option\r\n v-for=\"item in trainingTypeOptions\"\r\n :key=\"item.dictCode || item.dictValue\"\r\n :label=\"item.dictLabel\"\r\n :value=\"item.dictLabel\"\r\n />\r\n </el-select>\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"培训类型2\">\r\n <el-input v-model=\"dialog.form.pxlx2\" placeholder=\"请输入培训类型2\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"学员类别\">\r\n <el-input v-model=\"dialog.form.xylb\" placeholder=\"请输入学员类别\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"学年制\">\r\n <el-input v-model=\"dialog.form.xnz\" placeholder=\"请输入学年制\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"学期数\">\r\n <el-input-number v-model=\"dialog.form.xqs\" :min=\"1\" :max=\"20\" controls-position=\"right\" class=\"w-full\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业版本\">\r\n <el-input v-model=\"dialog.form.zybb\" placeholder=\"请输入专业版本\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"自定义分类\">\r\n <el-input v-model=\"dialog.form.zdyfl\" placeholder=\"请输入自定义分类\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"教学管理机构编号\">\r\n <el-input v-model=\"dialog.form.jxgljgbh\" placeholder=\"请输入教学管理机构编号\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"规范名称\">\r\n <el-input v-model=\"dialog.form.gfmc\" placeholder=\"请输入规范名称\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业规范\">\r\n <el-input v-model=\"dialog.form.zygf\" placeholder=\"请输入专业规范\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"简称\">\r\n <el-input v-model=\"dialog.form.jc\" placeholder=\"请输入简称\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"主干专业\">\r\n <el-radio-group v-model=\"dialog.form.zgzy\">\r\n <el-radio :label=\"true\">是</el-radio>\r\n <el-radio :label=\"false\">否</el-radio>\r\n </el-radio-group>\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"12\">\r\n <el-form-item label=\"专业备注\">\r\n <el-input v-model=\"dialog.form.zybz\" placeholder=\"请输入专业备注\" />\r\n </el-form-item>\r\n </el-col>\r\n <el-col :span=\"24\">\r\n <el-form-item label=\"培养目标\">\r\n <el-input v-model=\"dialog.form.pymb\" type=\"textarea\" :rows=\"3\" placeholder=\"请输入培养目标\" />\r\n </el-form-item>\r\n </el-col>\r\n </el-row>\r\n </el-form>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <el-button @click=\"dialog.visible = false\">取 消</el-button>\r\n <el-button type=\"primary\" :loading=\"dialog.submitting\" @click=\"submitDialog\">确 定</el-button>\r\n </div>\r\n </el-dialog>\r\n\r\n <!-- 详情弹窗 -->\r\n <el-dialog title=\"人才培养方案详情\" :visible.sync=\"detail.visible\" width=\"760px\" append-to-body\r\n :close-on-click-modal=\"false\">\r\n <div v-loading=\"detail.loading\" class=\"detail-body\">\r\n <el-descriptions :column=\"2\" border>\r\n <el-descriptions-item label=\"专业代号\">{{ fmtVal(detail.data.zydh) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业名称\">{{ fmtVal(detail.data.zymc) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业代码\">{{ fmtVal(detail.data.zydm) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业方向\">{{ fmtVal(detail.data.zyfx) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"培训类型\">{{ fmtVal(detail.data.pxlx) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"培训层次\">{{ fmtVal(detail.data.pxcc) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"培训类型2\">{{ fmtVal(detail.data.pxlx2) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"学员类别\">{{ fmtVal(detail.data.xylb) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"学年制\">{{ fmtVal(detail.data.xnz) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"学期数\">{{ fmtVal(detail.data.xqs) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业版本\">{{ fmtVal(detail.data.zybb) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"主干专业\">{{ fmtYesNo(detail.data.zgzy) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"自定义分类\">{{ fmtVal(detail.data.zdyfl) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教学管理机构编号\">{{ fmtVal(detail.data.jxgljgbh) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"规范名称\">{{ fmtVal(detail.data.gfmc) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业规范\">{{ fmtVal(detail.data.zygf) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"简称\">{{ fmtVal(detail.data.jc) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业标识号\">{{ fmtVal(detail.data.zybsh) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"学科专业信息标识号\">{{ fmtVal(detail.data.xkzyxxbsh) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"教学大纲编号\">{{ fmtVal(detail.data.jxdgbh) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"人培编号\">{{ fmtVal(detail.data.rpbh) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"节次类别\">{{ fmtVal(detail.data.jclb) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"系统模式\">{{ fmtVal(detail.data.xtms) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"启用时间\">{{ fmtDateTime(detail.data.qysj) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"停用时间\">{{ fmtDateTime(detail.data.tysj) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"专业备注\" :span=\"2\">{{ fmtVal(detail.data.zybz) }}</el-descriptions-item>\r\n <el-descriptions-item label=\"培养目标\" :span=\"2\">{{ fmtVal(detail.data.pymb) }}</el-descriptions-item>\r\n </el-descriptions>\r\n </div>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <el-button @click=\"detail.visible = 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 addTraining,\r\n disableTraining,\r\n updateTraining,\r\n getTraining,\r\n listTraining\r\n} from '@/api/teachBusiness/training'\r\nimport { getDicts } from '@/api/system/dict/data'\r\n\r\nconst TRAINING_TYPE_DICT_CODE = 'train_type'\r\nconst TRAINING_LEVEL_DICT_CODE = 'train_level'\r\n\r\nexport default {\r\n name: 'TrainingPlan',\r\n data() {\r\n return {\r\n loading: false,\r\n // 查询条件(仅传后端 ZYBMapper 支持的字段)\r\n searchForm: {\r\n zymc: '',\r\n zydm: '',\r\n pxlx: '',\r\n pxcc: ''\r\n },\r\n trainingTypeOptions: [],\r\n trainingLevelOptions: [],\r\n // 列表\r\n tableData: [],\r\n total: 0,\r\n pageNum: 1,\r\n pageSize: 20,\r\n // 上传\r\n selectedFile: null,\r\n fileName: '',\r\n // 新增/编辑弹窗\r\n dialog: {\r\n visible: false,\r\n title: '',\r\n isEdit: false,\r\n submitting: false,\r\n form: this.createEmptyForm()\r\n },\r\n // 详情弹窗\r\n detail: {\r\n visible: false,\r\n loading: false,\r\n data: {}\r\n },\r\n rules: {\r\n zydh: [{ required: true, message: '请输入专业代号', trigger: 'blur' }],\r\n zymc: [{ required: true, message: '请输入专业名称', trigger: 'blur' }],\r\n zydm: [{ required: true, message: '请输入专业代码', trigger: 'blur' }],\r\n pxcc: [{ required: true, message: '请选择培训层次', trigger: 'change' }],\r\n pxlx: [{ required: true, message: '请选择培训类型', trigger: 'change' }]\r\n }\r\n }\r\n },\r\n created() {\r\n this.loadTrainingDictionaries()\r\n this.fetchList()\r\n },\r\n methods: {\r\n /**\r\n * 从系统字典加载培训类型和培训层次,提交标签以匹配现有业务数据。\r\n */\r\n loadTrainingDictionaries() {\r\n return Promise.all([\r\n getDicts(TRAINING_TYPE_DICT_CODE),\r\n getDicts(TRAINING_LEVEL_DICT_CODE)\r\n ]).then(([typeResponse, levelResponse]) => {\r\n this.trainingTypeOptions = typeResponse.data || []\r\n this.trainingLevelOptions = levelResponse.data || []\r\n }).catch(() => {\r\n this.trainingTypeOptions = []\r\n this.trainingLevelOptions = []\r\n })\r\n },\r\n\r\n /* ---------- 列表加载 ---------- */\r\n fetchList() {\r\n this.loading = true\r\n const params = {\r\n pageNum: this.pageNum,\r\n pageSize: this.pageSize\r\n }\r\n Object.keys(this.searchForm).forEach(key => {\r\n const value = this.searchForm[key]\r\n if (value !== '' && value !== null && value !== undefined) {\r\n params[key] = value\r\n }\r\n })\r\n listTraining(params).then(response => {\r\n const data = response.data || {}\r\n this.tableData = data.records || []\r\n this.total = data.total || 0\r\n }).catch(() => {\r\n this.tableData = []\r\n this.total = 0\r\n }).finally(() => {\r\n this.loading = false\r\n })\r\n },\r\n\r\n /* ---------- 查询 / 重置 ---------- */\r\n handleQuery() {\r\n this.pageNum = 1\r\n this.fetchList()\r\n },\r\n handleReset() {\r\n this.searchForm = { zymc: '', zydm: '', pxlx: '', pxcc: '' }\r\n this.pageNum = 1\r\n this.fetchList()\r\n },\r\n\r\n /* ---------- 分页 ---------- */\r\n handleSizeChange(size) {\r\n this.pageSize = size\r\n this.pageNum = 1\r\n this.fetchList()\r\n },\r\n handlePageChange(page) {\r\n this.pageNum = page\r\n this.fetchList()\r\n },\r\n\r\n /* ---------- 新增 / 编辑 ---------- */\r\n handleAdd() {\r\n this.dialog.title = '新建人才培养方案'\r\n this.dialog.isEdit = false\r\n this.dialog.form = this.createEmptyForm()\r\n this.dialog.visible = true\r\n this.$nextTick(() => {\r\n if (this.$refs.trainingForm) this.$refs.trainingForm.clearValidate()\r\n })\r\n },\r\n handleEdit(row) {\r\n this.dialog.title = '编辑人才培养方案'\r\n this.dialog.isEdit = true\r\n this.dialog.form = Object.assign({}, this.createEmptyForm(), row)\r\n this.dialog.visible = true\r\n this.$nextTick(() => {\r\n if (this.$refs.trainingForm) this.$refs.trainingForm.clearValidate()\r\n })\r\n },\r\n submitDialog() {\r\n this.$refs.trainingForm.validate(valid => {\r\n if (!valid) return\r\n this.dialog.submitting = true\r\n const payload = this.cleanPayload(this.dialog.form)\r\n const isEdit = this.dialog.isEdit\r\n const req = isEdit ? updateTraining(payload) : addTraining(payload)\r\n req.then(() => {\r\n this.$message.success(isEdit ? '修改成功' : '新增成功')\r\n this.dialog.visible = false\r\n this.fetchList()\r\n }).catch(() => {}).finally(() => {\r\n this.dialog.submitting = false\r\n })\r\n })\r\n },\r\n\r\n /* ---------- 详情 ---------- */\r\n handleDetail(row) {\r\n this.detail.visible = true\r\n this.detail.loading = true\r\n this.detail.data = {}\r\n getTraining(row.zydh).then(response => {\r\n this.detail.data = response.data || {}\r\n }).catch(() => {\r\n this.detail.data = {}\r\n }).finally(() => {\r\n this.detail.loading = false\r\n })\r\n },\r\n\r\n /* ---------- 停用(逻辑删除) ---------- */\r\n handleDisable(row) {\r\n this.$confirm('确定停用人才培养方案「' + (row.zymc || row.zydh) + '」吗?停用后列表不再展示。', '提示', {\r\n confirmButtonText: '确定',\r\n cancelButtonText: '取消',\r\n type: 'warning'\r\n }).then(() => {\r\n return disableTraining(row.zydh)\r\n }).then(() => {\r\n this.$message.success('停用成功')\r\n this.fetchList()\r\n }).catch(() => {})\r\n },\r\n\r\n /* ---------- 下载 / 模板下载 / 上传(后端未提供接口) ---------- */\r\n handleDownload() {\r\n this.$message.warning('后端暂未提供该接口')\r\n },\r\n handleTemplateDownload() {\r\n this.$message.warning('后端暂未提供该接口')\r\n },\r\n handleChooseFile() {\r\n this.$refs.fileInputRef && this.$refs.fileInputRef.click()\r\n },\r\n handleFileChange(e) {\r\n const file = e.target.files && e.target.files[0]\r\n this.selectedFile = file || null\r\n this.fileName = file ? file.name : ''\r\n },\r\n handleUpload() {\r\n this.$message.warning('后端暂未提供该接口')\r\n },\r\n\r\n /* ---------- 工具 ---------- */\r\n createEmptyForm() {\r\n return {\r\n zydh: '',\r\n zymc: '',\r\n zyfx: '',\r\n zydm: '',\r\n pxcc: '',\r\n pxlx: '',\r\n pxlx2: '',\r\n xylb: '',\r\n xnz: '',\r\n xqs: null,\r\n zybb: '',\r\n zdyfl: '',\r\n jxgljgbh: '',\r\n gfmc: '',\r\n zygf: '',\r\n jc: '',\r\n zgzy: false,\r\n zybz: '',\r\n pymb: ''\r\n }\r\n },\r\n /** 移除空值(''/null/undefined),保留 0/false 等有效值 */\r\n cleanPayload(obj) {\r\n const payload = {}\r\n Object.keys(obj).forEach(key => {\r\n const value = obj[key]\r\n if (value !== '' && value !== null && value !== undefined) {\r\n payload[key] = value\r\n }\r\n })\r\n return payload\r\n },\r\n isTrue(val) {\r\n return val === true || val === 1 || val === '1' || val === 'true'\r\n },\r\n fmtYesNo(val) {\r\n return this.isTrue(val) ? '是' : '否'\r\n },\r\n fmtDateTime(val) {\r\n const s = (val || '').substring(0, 10)\r\n return s || '-'\r\n },\r\n fmtVal(val) {\r\n return val === '' || val === null || val === undefined ? '-' : val\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n.app-container {\r\n padding: 20px;\r\n}\r\n\r\n.training-plan-page {\r\n .search-card {\r\n margin-bottom: 16px;\r\n\r\n .search-form {\r\n .w-full {\r\n width: 100%;\r\n }\r\n\r\n .search-actions {\r\n padding-top: 4px;\r\n }\r\n }\r\n }\r\n\r\n .action-card {\r\n margin-bottom: 16px;\r\n\r\n .action-row {\r\n margin-bottom: 12px;\r\n\r\n &:last-of-type {\r\n margin-bottom: 0;\r\n }\r\n }\r\n\r\n .upload-row {\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 padding: 12px;\r\n background: #fafafa;\r\n border: 1px dashed #dcdfe6;\r\n border-radius: 4px;\r\n\r\n .upload-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n\r\n .file-name {\r\n font-size: 13px;\r\n color: #909399;\r\n\r\n &.has-file {\r\n color: #409eff;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n .table-card {\r\n .list-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n margin-bottom: 16px;\r\n\r\n .list-title {\r\n font-size: 16px;\r\n font-weight: 600;\r\n color: #303133;\r\n }\r\n }\r\n\r\n .pagination {\r\n margin-top: 16px;\r\n text-align: right;\r\n }\r\n }\r\n\r\n .detail-body {\r\n min-height: 60px;\r\n }\r\n}\r\n\r\n.danger-text-btn {\r\n color: #f56c6c;\r\n\r\n &:hover {\r\n color: #f78989;\r\n }\r\n}\r\n\r\n.training-dict-select {\r\n width: 100%;\r\n}\r\n</style>\r\n"]}]} |