index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. <template>
  2. <div class="app-container">
  3. <TextSearch/>
  4. <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
  5. <el-form-item label="主题" prop="topic">
  6. <el-input
  7. v-model="queryParams.topic"
  8. placeholder="请输入主题"
  9. clearable
  10. @keyup.enter.native="handleQuery"
  11. />
  12. </el-form-item>
  13. <el-form-item label="培训人" prop="trainer">
  14. <el-input
  15. v-model="queryParams.trainer"
  16. placeholder="请输入培训人"
  17. clearable
  18. @keyup.enter.native="handleQuery"
  19. />
  20. </el-form-item>
  21. <el-form-item label="参加培训人员" prop="participants">
  22. <el-input
  23. v-model="queryParams.participants"
  24. placeholder="请输入参加培训人员"
  25. clearable
  26. @keyup.enter.native="handleQuery"
  27. />
  28. </el-form-item>
  29. <el-form-item label="日期" prop="trainDate">
  30. <el-date-picker clearable
  31. v-model="queryParams.trainDate"
  32. type="date"
  33. value-format="yyyy-MM-dd"
  34. placeholder="请选择日期">
  35. </el-date-picker>
  36. </el-form-item>
  37. <el-form-item>
  38. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  39. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  40. </el-form-item>
  41. </el-form>
  42. <el-row :gutter="10" class="mb8">
  43. <el-col :span="1.5">
  44. <el-button
  45. type="primary"
  46. plain
  47. icon="el-icon-plus"
  48. size="mini"
  49. @click="handleAdd"
  50. v-hasPermi="['training:roster:add']"
  51. >新增
  52. </el-button>
  53. </el-col>
  54. <el-col :span="1.5">
  55. <el-button
  56. type="success"
  57. plain
  58. icon="el-icon-edit"
  59. size="mini"
  60. :disabled="single"
  61. @click="handleUpdate"
  62. v-hasPermi="['training:roster:edit']"
  63. >修改
  64. </el-button>
  65. </el-col>
  66. <el-col :span="1.5">
  67. <el-button
  68. type="danger"
  69. plain
  70. icon="el-icon-delete"
  71. size="mini"
  72. :disabled="multiple"
  73. @click="handleDelete"
  74. v-hasPermi="['training:roster:remove']"
  75. >删除
  76. </el-button>
  77. </el-col>
  78. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  79. </el-row>
  80. <el-table v-loading="loading" :data="rosterList" @selection-change="handleSelectionChange" :height="clientHeight"
  81. border>
  82. <el-table-column type="selection" width="55" align="center"/>
  83. <el-table-column label="主题" align="center" prop="topic"/>
  84. <el-table-column label="培训材料" align="center" prop="material"/>
  85. <el-table-column label="培训人" align="center" prop="trainer"/>
  86. <el-table-column label="参加培训人员" align="center" prop="participants"/>
  87. <el-table-column label="日期" align="center" width="180">
  88. <template slot-scope="scope">
  89. <span>{{
  90. parseTime(scope.row.trainStartDate, '{y}-{m}-{d}')
  91. }} ~ {{ parseTime(scope.row.trainEndDate, '{y}-{m}-{d}') }}</span>
  92. </template>
  93. </el-table-column>
  94. <el-table-column label="时间" align="center" prop="trainDuration" width="180"/>
  95. <el-table-column label="培训内容" align="center" prop="content"/>
  96. <el-table-column label="备注" align="center" prop="remarks"/>
  97. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  98. <template slot-scope="scope">
  99. <el-button
  100. size="mini"
  101. type="text"
  102. icon="el-icon-download"
  103. @click="getReport(scope.row)"
  104. v-hasPermi="['training:roster:edit']"
  105. >导出
  106. </el-button>
  107. <el-button
  108. icon="el-icon-folder"
  109. size="mini"
  110. type="text"
  111. @click="openFileDialog(scope.row)"
  112. >附件
  113. </el-button>
  114. <el-button
  115. size="mini"
  116. type="text"
  117. icon="el-icon-edit"
  118. @click="handleUpdate(scope.row)"
  119. v-hasPermi="['training:roster:edit']"
  120. >修改
  121. </el-button>
  122. <el-button
  123. size="mini"
  124. type="text"
  125. icon="el-icon-delete"
  126. @click="handleDelete(scope.row)"
  127. v-hasPermi="['training:roster:remove']"
  128. >删除
  129. </el-button>
  130. </template>
  131. </el-table-column>
  132. </el-table>
  133. <pagination
  134. v-show="total>0"
  135. :total="total"
  136. :page.sync="queryParams.pageNum"
  137. :limit.sync="queryParams.pageSize"
  138. @pagination="getList"
  139. />
  140. <!-- 添加或修改培训签字对话框 -->
  141. <el-dialog :close-on-click-modal="false" :title="title" :visible.sync="open" width="700px" append-to-body>
  142. <el-form ref="form" :model="form" :rules="rules" label-width="140px">
  143. <el-form-item label="主题" prop="topic">
  144. <el-input v-model="form.topic" placeholder="请输入主题"/>
  145. </el-form-item>
  146. <el-form-item label="培训材料" prop="material">
  147. <el-input v-model="form.material" placeholder="请输入培训材料(若有)"/>
  148. </el-form-item>
  149. <el-form-item label="培训人" prop="trainer">
  150. <el-input v-model="form.trainer" placeholder="请输入培训人"/>
  151. </el-form-item>
  152. <el-form-item label="参加培训人员" prop="participants">
  153. <el-input v-model="form.participants" placeholder="请输入参加培训人员"/>
  154. </el-form-item>
  155. <el-form-item label="培训日期" prop="trainDateTmpl">
  156. <el-date-picker
  157. v-model="form.trainDateTmpl"
  158. type="daterange"
  159. align="right"
  160. unlink-panels
  161. value-format="yyyy-MM-dd"
  162. range-separator="至"
  163. start-placeholder="开始日期"
  164. end-placeholder="结束日期"
  165. :picker-options="pickerOptions">
  166. </el-date-picker>
  167. </el-form-item>
  168. <el-form-item label="培训时间" prop="trainDuration">
  169. <el-input v-model="form.trainDuration" placeholder="请输入培训时间"/>
  170. </el-form-item>
  171. <el-form-item label="导出方式" prop="exportType">
  172. <el-radio-group v-model="form.exportType">
  173. <el-radio :label="1">预输入</el-radio>
  174. <el-radio :label="2">手动填写</el-radio>
  175. </el-radio-group>
  176. </el-form-item>
  177. <el-form-item label="班组名单" prop="teams" v-if="form.exportType==1">
  178. <el-select v-model="form.teams" placeholder="请选择参与培训的班组" multiple clearable size="small"
  179. style="width: 100%;">
  180. <el-option
  181. v-for="dict in teamOptions"
  182. :key="dict.dictValue"
  183. :label="dict.dictLabel"
  184. :value="dict.dictValue"
  185. />
  186. </el-select>
  187. </el-form-item>
  188. <el-form-item label="参与培训的人员名单" prop="nameList" v-if="form.exportType==1">
  189. <el-input v-model="form.nameList" type="textarea"
  190. placeholder="请输入参与培训的人员名单(每个人名之间请务必使用中文输入法下的逗号隔开。例如:张三,李四,王五)"/>
  191. </el-form-item>
  192. <el-form-item label="培训内容">
  193. <el-input type="textarea" v-model="form.content" placeholder="请输入培训内容概述" :min-height="192"/>
  194. </el-form-item>
  195. <el-form-item label="备注" prop="remarks">
  196. <el-input v-model="form.remarks" type="textarea" placeholder="请输入备注"/>
  197. </el-form-item>
  198. </el-form>
  199. <div slot="footer" class="dialog-footer">
  200. <el-button type="primary" @click="submitForm">确 定</el-button>
  201. <el-button @click="cancel">取 消</el-button>
  202. </div>
  203. </el-dialog>
  204. <el-dialog :close-on-click-modal="false" :visible.sync="file.open" append-to-body title="附件管理" width="60%">
  205. <el-row :gutter="10" class="mb8">
  206. <el-col :span="1.5">
  207. <el-button
  208. icon="el-icon-plus"
  209. plain
  210. size="mini"
  211. type="primary"
  212. @click="handleFileAdd"
  213. >新增
  214. </el-button>
  215. </el-col>
  216. </el-row>
  217. <el-table :data="file.fileList" :height="clientHeight-100"
  218. border>
  219. <el-table-column align="center" label="附件名称" prop="fileName">
  220. <template slot-scope="scope">
  221. <el-button
  222. size="mini"
  223. type="text"
  224. @click="previewFile(scope.row.fileUrl)"
  225. >{{ scope.row.fileName }}
  226. </el-button>
  227. </template>
  228. </el-table-column>
  229. <el-table-column align="center" label="上传时间" prop="uploadDate" width="180">
  230. <template slot-scope="scope">
  231. <span>{{ parseTime(scope.row.uploadDate, '{y}-{m}-{d}') }}</span>
  232. </template>
  233. </el-table-column>
  234. <el-table-column align="center" label="上传人" prop="uploader">
  235. </el-table-column>
  236. <el-table-column align="center" class-name="small-padding fixed-width" label="操作">
  237. <template slot-scope="scope">
  238. <el-button
  239. icon="el-icon-delete"
  240. size="mini"
  241. type="text"
  242. @click="handleFileRemove(scope.row)"
  243. >删除
  244. </el-button>
  245. </template>
  246. </el-table-column>
  247. </el-table>
  248. <pagination
  249. v-show="file.total>0"
  250. :limit.sync="file.queryParams.pageSize"
  251. :page.sync="file.queryParams.pageNum"
  252. :total="file.total"
  253. @pagination="getFileList"
  254. />
  255. </el-dialog>
  256. <el-dialog :close-on-click-modal="false" :visible.sync="doc.open" append-to-body title="附件上传" width="400px">
  257. <el-upload
  258. ref="doc"
  259. :action="doc.url"
  260. :auto-upload="false"
  261. :file-list="doc.fileList"
  262. :headers="doc.headers"
  263. :on-progress="handleFileDocProgress"
  264. :on-success="handleFileDocSuccess"
  265. drag
  266. multiple>
  267. <i class="el-icon-upload"></i>
  268. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  269. </el-upload>
  270. <div slot="footer" class="dialog-footer">
  271. <el-button type="primary" @click="submitUpload">确 定</el-button>
  272. <el-button @click="cancelUpload">取 消</el-button>
  273. </div>
  274. </el-dialog>
  275. </div>
  276. </template>
  277. <script>
  278. import {addRoster, delRoster, getRoster, listRoster, updateRoster, wordView} from "@/api/training/roster";
  279. import {getToken} from "../../../utils/auth";
  280. import {delFile, listFile} from "../../../api/file/file";
  281. export default {
  282. name: "Roster",
  283. data() {
  284. return {
  285. file: {
  286. open: false,
  287. fileList: [],
  288. queryParams: {
  289. pageNum: 1,
  290. pageSize: 10,
  291. linkId: null,
  292. linkName: 'roster',
  293. },
  294. total: 0,
  295. },
  296. doc: {
  297. id: null,
  298. file: "",
  299. fileList: [],
  300. // 是否显示弹出层
  301. open: false,
  302. // 设置上传的请求头部
  303. headers: {Authorization: "Bearer " + getToken()},
  304. // 上传的地址
  305. url: process.env.VUE_APP_BASE_API + "/file/file/uploadFile",
  306. },
  307. pickerOptions: {
  308. shortcuts: [{
  309. text: '最近一周',
  310. onClick(picker) {
  311. const end = new Date();
  312. const start = new Date();
  313. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
  314. picker.$emit('pick', [start, end]);
  315. }
  316. }, {
  317. text: '最近一个月',
  318. onClick(picker) {
  319. const end = new Date();
  320. const start = new Date();
  321. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
  322. picker.$emit('pick', [start, end]);
  323. }
  324. }, {
  325. text: '最近三个月',
  326. onClick(picker) {
  327. const end = new Date();
  328. const start = new Date();
  329. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
  330. picker.$emit('pick', [start, end]);
  331. }
  332. }]
  333. },
  334. //字典
  335. teamOptions: [],
  336. // 页面高度
  337. clientHeight: 300,
  338. // 遮罩层
  339. loading: true,
  340. // 选中数组
  341. ids: [],
  342. // 非单个禁用
  343. single: true,
  344. // 非多个禁用
  345. multiple: true,
  346. // 显示搜索条件
  347. showSearch: false,
  348. // 总条数
  349. total: 0,
  350. // 培训签字表格数据
  351. rosterList: [],
  352. // 弹出层标题
  353. title: "",
  354. // 是否显示弹出层
  355. open: false,
  356. // 查询参数
  357. queryParams: {
  358. pageNum: 1,
  359. pageSize: 10,
  360. topic: null,
  361. material: null,
  362. trainer: null,
  363. participants: null,
  364. trainDate: null,
  365. teams: null,
  366. content: null,
  367. createrCode: null,
  368. createdate: null,
  369. updaterCode: null,
  370. updatedate: null,
  371. deptId: null,
  372. remarks: null
  373. },
  374. // 表单参数
  375. form: {},
  376. // 表单校验
  377. rules: {
  378. topic: [
  379. {required: true, message: "主题不能为空", trigger: "blur"}
  380. ],
  381. trainer: [
  382. {required: true, message: "培训人不能为空", trigger: "blur"}
  383. ],
  384. exportType: [
  385. {required: true, message: "请选择导出方式", trigger: "blur"}
  386. ],
  387. participants: [
  388. {required: true, message: "参加培训人员不能为空", trigger: "blur"}
  389. ],
  390. trainDateTmpl: [
  391. {required: true, message: "培训日期不能为空", trigger: "blur"}
  392. ],
  393. }
  394. };
  395. },
  396. created() {
  397. this.getList();
  398. //设置表格高度对应屏幕高度
  399. this.$nextTick(() => {
  400. this.clientHeight = (document.body.clientHeight - 80) * 0.8
  401. });
  402. this.getDicts("team_divide").then(res => {
  403. this.teamOptions = res.data;
  404. });
  405. },
  406. methods: {
  407. previewFile(url) {
  408. window.open(process.env.VUE_APP_BASE_API + url);
  409. },
  410. submitUpload() {
  411. this.$refs.doc.submit();
  412. this.doc.open = false;
  413. this.doc.fileList = [];
  414. this.getFileList();
  415. },
  416. //附件上传中处理
  417. handleFileDocProgress(event, file, fileList) {
  418. this.doc.file = file;
  419. },
  420. //附件上传成功处理
  421. handleFileDocSuccess(response, file, fileList) {
  422. this.$modal.msgSuccess("上传成功");
  423. this.doc.open = false;
  424. this.doc.fileList = [];
  425. this.getFileList();
  426. },
  427. cancelUpload() {
  428. this.doc.open = false;
  429. this.doc.fileList = [];
  430. },
  431. openFileDialog(row) {
  432. this.$router.push({path: '/system/file', query: {linkId: row.id, linkName: 'roster'}})
  433. },
  434. getFileList() {
  435. listFile(this.file.queryParams).then(response => {
  436. this.file.fileList = response.rows;
  437. this.file.total = response.total;
  438. })
  439. },
  440. handleFileAdd() {
  441. this.doc.open = true;
  442. this.doc.url = process.env.VUE_APP_BASE_API + "/file/file/uploadFile?linkId=" + this.file.queryParams.linkId + "&linkName=" + this.file.queryParams.linkName;
  443. },
  444. handleFileRemove(row) {
  445. delFile(row.id).then(res => {
  446. this.$modal.msgSuccess("删除成功");
  447. this.getFileList();
  448. });
  449. },
  450. /** 查询培训签字列表 */
  451. getList() {
  452. this.loading = true;
  453. listRoster(this.queryParams).then(response => {
  454. this.rosterList = response.rows;
  455. this.total = response.total;
  456. this.loading = false;
  457. });
  458. },
  459. // 取消按钮
  460. cancel() {
  461. this.open = false;
  462. this.reset();
  463. },
  464. // 表单重置
  465. reset() {
  466. this.form = {
  467. id: null,
  468. topic: null,
  469. material: null,
  470. trainer: null,
  471. participants: null,
  472. trainDate: null,
  473. trainDateTmpl: null,
  474. teams: null,
  475. content: null,
  476. delFlag: null,
  477. createrCode: null,
  478. createdate: null,
  479. updaterCode: null,
  480. updatedate: null,
  481. deptId: null,
  482. remarks: null
  483. };
  484. this.resetForm("form");
  485. },
  486. /** 搜索按钮操作 */
  487. handleQuery() {
  488. this.queryParams.pageNum = 1;
  489. this.getList();
  490. },
  491. /** 重置按钮操作 */
  492. resetQuery() {
  493. this.resetForm("queryForm");
  494. this.handleQuery();
  495. },
  496. // 多选框选中数据
  497. handleSelectionChange(selection) {
  498. this.ids = selection.map(item => item.id)
  499. this.single = selection.length !== 1
  500. this.multiple = !selection.length
  501. },
  502. /** 新增按钮操作 */
  503. handleAdd() {
  504. this.reset();
  505. this.open = true;
  506. this.title = "添加培训签字";
  507. },
  508. /** 修改按钮操作 */
  509. handleUpdate(row) {
  510. this.reset();
  511. const id = row.id || this.ids
  512. getRoster(id).then(response => {
  513. if (response.data.teams) {
  514. response.data.teams = response.data.teams.split(',');
  515. }
  516. response.data.trainDateTmpl = [];
  517. response.data.trainDateTmpl[0] = new Date(response.data.trainStartDate);
  518. response.data.trainDateTmpl[1] = new Date(response.data.trainEndDate);
  519. this.form = response.data;
  520. this.open = true;
  521. this.title = "修改培训签字";
  522. });
  523. },
  524. /** 提交按钮 */
  525. submitForm() {
  526. this.$refs["form"].validate(valid => {
  527. if (valid) {
  528. this.form.trainStartDate = this.form.trainDateTmpl[0];
  529. this.form.trainEndDate = this.form.trainDateTmpl[1];
  530. if (this.form.teams)
  531. this.form.teams = this.form.teams.join(',')
  532. if (this.form.id != null) {
  533. updateRoster(this.form).then(response => {
  534. this.$modal.msgSuccess("修改成功");
  535. this.open = false;
  536. this.getList();
  537. });
  538. } else {
  539. addRoster(this.form).then(response => {
  540. this.$modal.msgSuccess("新增成功");
  541. this.open = false;
  542. this.getList();
  543. });
  544. }
  545. }
  546. });
  547. },
  548. /** 删除按钮操作 */
  549. handleDelete(row) {
  550. const ids = row.id || this.ids;
  551. this.$confirm('是否确认删除培训签字编号为"' + ids + '"的数据项?').then(function () {
  552. return delRoster(ids);
  553. }).then(() => {
  554. this.getList();
  555. this.$modal.msgSuccess("删除成功");
  556. }).catch(() => {
  557. });
  558. },
  559. /** 导出按钮操作 */
  560. handleExport() {
  561. this.download('training/roster/export', {
  562. ...this.queryParams
  563. }, `roster_${new Date().getTime()}.xlsx`)
  564. },
  565. /** 生成报告按钮操作 */
  566. getReport(row) {
  567. // this.meetingId = row.id
  568. // console.log(row.id)
  569. // this.$nextTick(() => {
  570. // this.$refs['downloadFileForm'].submit()
  571. // })
  572. wordView(row.id).then(res => {
  573. window.open(process.env.VUE_APP_BASE_API + res.msg)
  574. })
  575. },
  576. }
  577. };
  578. </script>