educationTrainingPlanManagementDeptDetail.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <template>
  2. <main class="safety-platform-container__main">
  3. <div class="page-container">
  4. <!-- 标题 -->
  5. <el-card shadow="never" class="mb-16">
  6. <h2 class="title">
  7. {{ details.trainingPlanName }}
  8. </h2>
  9. <div class="meta">
  10. <span>分类名称:{{ details.categoryName }}</span>
  11. <span>创建人:{{ details.createdByName }}</span>
  12. <span>创建时间:{{ details.createdAt }}</span>
  13. </div>
  14. </el-card>
  15. <!-- 基本信息 -->
  16. <el-card shadow="never" class="mb-16">
  17. <template #header>
  18. <strong>基本信息</strong>
  19. </template>
  20. <el-descriptions :column="2" border>
  21. <el-descriptions-item label="教育培训计划名称">
  22. {{ details.trainingPlanName }}
  23. </el-descriptions-item>
  24. <el-descriptions-item label="状态">
  25. <el-tag type="success">{{ details.statusName }}</el-tag>
  26. </el-descriptions-item>
  27. <el-descriptions-item label="培训对象">
  28. {{ details.trainingObject }}
  29. </el-descriptions-item>
  30. <el-descriptions-item label="培训人数"> {{ details.trainingCount }}人 </el-descriptions-item>
  31. <el-descriptions-item label="培训时间">
  32. {{ details.trainingTime }}
  33. </el-descriptions-item>
  34. <el-descriptions-item label="培训方式">
  35. {{ details.trainingMethod }}
  36. </el-descriptions-item>
  37. <el-descriptions-item label="考核方式">
  38. {{ details.assessmentMethod }}
  39. </el-descriptions-item>
  40. <el-descriptions-item label="培训责任部门">
  41. {{ details.deptName }}
  42. </el-descriptions-item>
  43. <el-descriptions-item label="学时"> {{ details.studyHours }} </el-descriptions-item>
  44. <el-descriptions-item label="培训分组">
  45. {{ details.groupName }}
  46. </el-descriptions-item>
  47. </el-descriptions>
  48. </el-card>
  49. <!-- 培训课程信息 -->
  50. <el-card shadow="never">
  51. <template #header>
  52. <strong>培训课程信息</strong>
  53. </template>
  54. <!-- 查询区 -->
  55. <el-form :inline="true" class="mb-12">
  56. <el-form-item>
  57. <el-input v-model="tableQuery.queryParam.courseName" placeholder="搜索培训课程名称" clearable />
  58. </el-form-item>
  59. <el-form-item>
  60. <el-date-picker
  61. v-model="dateRange"
  62. type="daterange"
  63. range-separator="至"
  64. start-placeholder="开始时间"
  65. end-placeholder="结束时间"
  66. />
  67. </el-form-item>
  68. <el-form-item>
  69. <el-button type="primary" @click="handleSearch"> 查询 </el-button>
  70. <el-button type="primary" @click="handleAdd"> 新增课程 </el-button>
  71. <el-button @click="handleExport"> 导出 </el-button>
  72. </el-form-item>
  73. </el-form>
  74. <!-- 表格 -->
  75. <el-table :data="tableData" border stripe>
  76. <el-table-column prop="id" label="编号" width="80" fixed="left" />
  77. <el-table-column prop="courseName" label="培训课程名称" width="240" fixed="left" />
  78. <el-table-column prop="trainingDate" width="230" label="培训时间" />
  79. <el-table-column prop="courseTypeName" label="课程所属分类" width="180" />
  80. <el-table-column prop="trainingMethod" label="培训方式" width="120" />
  81. <!-- <el-table-column prop="courseIntroduction" label="培训课程简述" /> -->
  82. <el-table-column prop="trainingTeacher" label="培训课程讲师" width="140" />
  83. <el-table-column prop="groupOfParticipantsDesc" label="计划参与人数所属分组" width="200" />
  84. <el-table-column prop="planNumOfParticipants" label="计划参与人数" width="140" />
  85. <el-table-column prop="signInNum" label="签到人数" width="120" />
  86. <el-table-column label="操作" width="280" fixed="right">
  87. <template #default="{ row }">
  88. <el-button link type="primary" @click="handleEdit(row)"> 编辑 </el-button>
  89. <el-button link type="danger" @click="handleDelete(row)"> 删除 </el-button>
  90. <el-button link @click="handleView(row)"> 查看 </el-button>
  91. </template>
  92. </el-table-column>
  93. </el-table>
  94. <div class="pagination">
  95. <el-pagination
  96. v-model:current-page="page.current"
  97. v-model:page-size="page.size"
  98. :page-sizes="[10, 20, 50, 100]"
  99. :total="page.total"
  100. layout="total, sizes, prev, pager, next, jumper"
  101. @current-change="handlePageChange"
  102. @size-change="handleSizeChange"
  103. />
  104. </div>
  105. </el-card>
  106. </div>
  107. <AddTrainingInformation :state="type" v-model:visible="showAddTrainingInfo" :currentId="currentTableId" @save-success="handleSearch" />
  108. </main>
  109. </template>
  110. <script setup lang="ts">
  111. import { computed, onMounted, reactive, ref } from 'vue';
  112. import { useRoute, useRouter } from 'vue-router';
  113. import { ElMessage, ElMessageBox } from 'element-plus';
  114. import {
  115. queryTrainingTableData,
  116. queryEducationAndTrainingProgramDetail,
  117. deleteTrainingInformation,
  118. type TableParamsType,
  119. } from '@/api/production-education-training-plan-dept';
  120. import AddTrainingInformation from './addTrainingInformation.vue';
  121. import type { QueryPageRequest } from '@/types/basic-query';
  122. import { id, pa } from 'element-plus/es/locale';
  123. const router = useRouter();
  124. const route = useRoute();
  125. const operate = computed(() => (route.query.operate as string) || 'education-training-plan-management-dept-view');
  126. const currentId = computed(() => Number(route.query.id));
  127. const isViewMode = computed(() => operate.value === 'education-training-plan-management-dept-view');
  128. const query = ref({
  129. name: '',
  130. time: [],
  131. });
  132. const details = reactive({
  133. trainingPlanName: '',
  134. categoryName: '',
  135. trainingObject: '',
  136. trainingCount: '',
  137. trainingTime: '',
  138. trainingMethod: '',
  139. assessmentMethod: '',
  140. responsibleNames: '',
  141. studyHours: '',
  142. groupName: '',
  143. statusName: '',
  144. createdByName: '',
  145. createdAt: '',
  146. deptName: '',
  147. });
  148. const page = ref({
  149. current: 1,
  150. size: 10,
  151. total: 0,
  152. });
  153. const tableData = ref([]);
  154. const type = ref('add');
  155. const showAddTrainingInfo = ref(false);
  156. const currentTableId = ref('');
  157. // 搜索和筛选相关
  158. const dateRange = ref([]);
  159. const tableQuery = reactive<QueryPageRequest<TableParamsType>>({
  160. pageNumber: page.value.current,
  161. pageSize: page.value.size,
  162. queryParam: {
  163. petpiId: currentId.value,
  164. courseName: '',
  165. dateStart: dateRange.value[0],
  166. dateEnd: dateRange.value[1],
  167. },
  168. });
  169. const handlePageChange = (current) => {
  170. page.value.current = current;
  171. getTableList();
  172. };
  173. const handleSizeChange = (size) => {
  174. page.value.size = size;
  175. page.value.current = 1;
  176. getTableList();
  177. };
  178. const handleSearch = () => {
  179. page.value.current = 1;
  180. tableQuery.pageNumber = 1;
  181. getTableList();
  182. };
  183. const handleExport = () => {
  184. ElMessage.success('点击了导出');
  185. };
  186. const handleAdd = () => {
  187. type.value = 'add';
  188. currentTableId.value = String(currentId.value);
  189. showAddTrainingInfo.value = true;
  190. };
  191. const handleEdit = (row) => {
  192. type.value = 'edit';
  193. currentTableId.value = row.id;
  194. showAddTrainingInfo.value = true;
  195. };
  196. const handleView = (row) => {
  197. type.value = 'view';
  198. currentTableId.value = row.id;
  199. showAddTrainingInfo.value = true;
  200. };
  201. const handleDelete = (row) => {
  202. ElMessageBox.confirm(`确认删除课程「${row.courseName}」吗?`, '提示', { type: 'warning' }).then(async () => {
  203. await deleteTrainingInformation(row.id);
  204. // 删除操作逻辑
  205. ElMessage.success('删除成功');
  206. getTableList(); // 重新获取列表数据
  207. });
  208. };
  209. const getTableList = async () => {
  210. if (!currentId.value) return;
  211. try {
  212. const res = await queryTrainingTableData(tableQuery);
  213. if (res) {
  214. tableData.value = res.records || [];
  215. page.value.total = res.total || 0;
  216. }
  217. } catch (e) {
  218. ElMessage.error('获取培训课程列表失败');
  219. }
  220. };
  221. const getDetail = async () => {
  222. if (!currentId.value) return;
  223. try {
  224. const res = await queryEducationAndTrainingProgramDetail(currentId.value);
  225. if (res) {
  226. Object.assign(details, res);
  227. }
  228. } catch (e) {
  229. ElMessage.error('获取详情失败');
  230. }
  231. };
  232. onMounted(() => {
  233. getDetail();
  234. getTableList();
  235. });
  236. </script>
  237. <style scoped lang="scss">
  238. @use '@/styles/page-details-layout.scss' as *;
  239. .page-container {
  240. padding: 16px;
  241. }
  242. .pagination {
  243. width: 100%;
  244. margin-top: 20px;
  245. display: flex;
  246. justify-content: flex-end;
  247. }
  248. .title {
  249. margin: 0 0 8px;
  250. }
  251. .meta {
  252. font-size: 13px;
  253. color: #666;
  254. display: flex;
  255. gap: 24px;
  256. margin-top: 20px;
  257. }
  258. .mb-12 {
  259. margin-bottom: 12px;
  260. }
  261. .mb-16 {
  262. margin-bottom: 16px;
  263. }
  264. </style>