responsibility-agree-manage-dept.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <template>
  2. <div class="safety-platform-container">
  3. <header class="safety-platform-container__header">
  4. <div class="breadcrumb-title"> 安全责任书管理 (部门侧)</div>
  5. <!-- <el-tabs v-model="activeTab">
  6. <el-tab-pane label="全部" name="" />
  7. <el-tab-pane label="院领导" name="院领导" />
  8. <el-tab-pane label="部门" name="部门" />
  9. <el-tab-pane label="科室" name="科室" />
  10. <el-tab-pane label="员工" name="员工" />
  11. <el-tab-pane label="常驻供应商" name="常驻供应商" />
  12. </el-tabs> -->
  13. </header>
  14. <main class="safety-platform-container__main">
  15. <div class="search-form">
  16. <el-form :inline="true">
  17. <el-form-item label="安全责任书">
  18. <el-input
  19. v-model="queryParams.queryParam.responsibilityName"
  20. placeholder="搜索安全责任书名称"
  21. style="width: 170px"
  22. />
  23. </el-form-item>
  24. <el-form-item label="状态">
  25. <el-select v-model="queryParams.queryParam.status" clearable placeholder="状态" style="width: 170px">
  26. <el-option :value="1" label="未下发" />
  27. <el-option :value="2" label="待签署" />
  28. <el-option :value="3" label="待反馈材料" />
  29. <el-option :value="4" label="待审核" />
  30. <el-option :value="5" label="已完成" />
  31. <el-option :value="6" label="已作废" />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item v-if="activeTab" label="所属部门">
  35. <el-select
  36. v-model="queryParams.queryParam.departmentName"
  37. clearable
  38. placeholder="所属部门"
  39. style="width: 170px"
  40. >
  41. <el-option value="院领导">院领导</el-option>
  42. <el-option value="所/中心/职能部门/直属研究部/分公司">所/中心/职能部门/直属研究部/分公司</el-option>
  43. <el-option value="所/中心级部门">所/中心级部门</el-option>
  44. <el-option value="科室">科室</el-option>
  45. <el-option value="员工">员工</el-option>
  46. <el-option value="常驻供应商">常驻供应商</el-option>
  47. </el-select>
  48. </el-form-item>
  49. <el-form-item label="计划日期">
  50. <el-date-picker
  51. v-model="queryParams.queryParam.date"
  52. clearable
  53. type="daterange"
  54. start-placeholder="开始时间"
  55. end-placeholder="结束时间"
  56. style="width: 230px"
  57. />
  58. </el-form-item>
  59. </el-form>
  60. <div>
  61. <el-button type="primary" @click="queryTableList">查询</el-button>
  62. <el-button @click="handleRestParams">重置</el-button>
  63. </div>
  64. </div>
  65. <div style="margin-bottom: 20px">
  66. <el-button type="primary" @click="handleOpenBatchSign">批量签署</el-button>
  67. </div>
  68. <div class="table-content">
  69. <el-table ref="multipleTableRef" :data="tableData.data" @selection-change="handleSelectionChange">
  70. <el-table-column type="selection" :selectable="selectable" width="55" />
  71. <el-table-column label="责任书名称" prop="responsibilityName" width="180">
  72. <template #default="scope">
  73. <el-button
  74. link
  75. type="primary"
  76. @click.prevent="
  77. $router.push({
  78. name: 'responsibilityFeedback',
  79. query: {
  80. id: scope.row.id,
  81. status: scope.row.status,
  82. mode: 'view',
  83. },
  84. })
  85. "
  86. >{{ scope.row.responsibilityName }}
  87. </el-button>
  88. </template>
  89. </el-table-column>
  90. <el-table-column label="状态" prop="statusName" width="100" />
  91. <el-table-column label="类别" prop="departmentName" width="180" />
  92. <el-table-column label="下发数" prop="issuedQuantity" width="120" />
  93. <el-table-column label="签署人数" prop="signedQuantity" width="120" />
  94. <el-table-column label="签署比例" prop="signedRatio" width="120" />
  95. <el-table-column label="分组名称" prop="userGroupName" width="150" />
  96. <el-table-column label="计划完成时间" prop="planEndTime" width="150" />
  97. <el-table-column fixed="right" min-width="200" label="操作">
  98. <template #default="scope">
  99. <div style="display: flex">
  100. <el-button
  101. v-if="
  102. scope.row.status === 2 &&
  103. (scope.row.departmentName !== '员工' || scope.row.departmentName !== '常驻供应商')
  104. "
  105. type="primary"
  106. link
  107. @click="
  108. $router.push({
  109. name: 'signAgreeDept',
  110. query: {
  111. id: scope.row.id,
  112. status: scope.row.status,
  113. },
  114. })
  115. "
  116. >
  117. 签署
  118. </el-button>
  119. <el-button
  120. v-if="
  121. scope.row.status === 2 &&
  122. (scope.row.departmentName === '员工' || scope.row.departmentName === '常驻供应商')
  123. "
  124. type="primary"
  125. link
  126. @click="handleConfirm(scope)"
  127. >
  128. 确认
  129. </el-button>
  130. <el-dropdown trigger="click">
  131. <el-button
  132. type="primary"
  133. link
  134. @click="
  135. $router.push({
  136. name: 'responsibilityFeedback',
  137. query: {
  138. id: scope.row.id,
  139. status: scope.row.status,
  140. },
  141. })
  142. "
  143. >
  144. 反馈
  145. </el-button>
  146. <!-- <template #dropdown>
  147. <el-dropdown-menu>
  148. <el-dropdown-item
  149. @click="
  150. $router.push({
  151. name: 'signAgreeDept',
  152. query: {
  153. id: scope.row.id,
  154. status: scope.row.status,
  155. },
  156. })
  157. "
  158. >待反馈材料</el-dropdown-item
  159. >
  160. <el-dropdown-item
  161. @click="
  162. $router.push({
  163. name: 'signAgreeDept',
  164. query: {
  165. id: scope.row.id,
  166. status: scope.row.status,
  167. },
  168. })
  169. "
  170. >审核不通过</el-dropdown-item
  171. >
  172. </el-dropdown-menu>
  173. </template> -->
  174. </el-dropdown>
  175. <el-button type="primary" link @click="handleDownloadLink(scope)">下载</el-button>
  176. </div>
  177. </template>
  178. </el-table-column>
  179. </el-table>
  180. </div>
  181. <div class="pagination-container" v-if="tableData.total > 0">
  182. <el-pagination
  183. background
  184. :current-page="queryParams.pageNumber"
  185. :page-size="queryParams.pageSize"
  186. :total="tableData.total"
  187. @size-change="handleSizeChange"
  188. @current-change="handleCurrentChange"
  189. />
  190. </div>
  191. </main>
  192. </div>
  193. <!-- <IssueSafetyResponsibility
  194. :groupList="groupList"
  195. :currentRowData="currentRowData"
  196. ref="issueSafetyResponsibilityRef"
  197. @submit="handleSubmit"
  198. /> -->
  199. <el-dialog title="批量签署" v-if="batchSignDialogVisible" v-model="batchSignDialogVisible" width="600">
  200. <el-form-item label="">
  201. <UploadFiles label="上传附件" :maxCount="1" @uploadSuccess="handleUploadSuccess" :fileList="attachment" />
  202. </el-form-item>
  203. <template #footer>
  204. <div class="dialog-footer">
  205. <el-button @click="handleCloseBatchSign">取消</el-button>
  206. <el-button type="primary" @click="handleSafetyResponsibilityDeptBatchSign" :loading="submitLoading">
  207. 保存
  208. </el-button>
  209. </div>
  210. </template>
  211. </el-dialog>
  212. </template>
  213. <script lang="ts" setup>
  214. import { onMounted, ref, reactive } from 'vue';
  215. import dayjs from 'dayjs';
  216. import { ElMessage } from 'element-plus';
  217. import { useRouter } from 'vue-router';
  218. import {
  219. safetyResponsibilityDeptQueryPage,
  220. safetyResponsibilityAdminDelete,
  221. safetyResponsibilityAdminIssuedSafety,
  222. safetyResponsibilityDeptSignOrFeedback,
  223. safetyResponsibilityDeptBatchSign,
  224. } from '@/api/production-safety/responsibility-implementation';
  225. import { omit } from 'lodash-es';
  226. import { queryUserGroupPage } from '@/api/system/person-group';
  227. import { formatAttachmentList } from '@/components/UploadFiles/utils';
  228. import { useUserInfoHook } from '@/hooks/useUserInfoHook';
  229. import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
  230. import { unformatAttachment } from '@/components/UploadFiles/utils';
  231. import { downloadFile } from '@/views/disaster/utils';
  232. // import IssueSafetyResponsibility from './components/IssueSafetyResponsibility.vue';
  233. const router = useRouter();
  234. const batchSignDialogVisible = ref(false);
  235. const selectedRows = ref([]);
  236. const activeTab = ref('');
  237. const groupList = ref<any[]>([]);
  238. const submitLoading = ref(false);
  239. const { id: userId } = useUserInfoHook();
  240. const queryParams = reactive<any>({
  241. pageNumber: 1,
  242. pageSize: 10,
  243. queryParam: {
  244. responsibilityName: '',
  245. departmentName: '',
  246. status: '',
  247. date: '',
  248. responsibilityPersonId: userId,
  249. },
  250. });
  251. const multipleTableRef = ref<any>();
  252. const tableData = reactive({
  253. data: [],
  254. total: 0,
  255. });
  256. const attachment = ref<any[]>([]);
  257. const selectable = (row) => {
  258. return row.status === 2 && (row.departmentName !== '员工' || row.departmentName !== '常驻供应商');
  259. };
  260. const handleSelectionChange = (val) => {
  261. selectedRows.value = val;
  262. console.log('当前勾选的数据:', selectedRows.value);
  263. };
  264. const handleUploadSuccess = (fileList) => {
  265. attachment.value = fileList;
  266. };
  267. const handleQueryUserGroupPage = () => {
  268. queryUserGroupPage({
  269. pageNumber: 1,
  270. pageSize: 500,
  271. }).then((res) => {
  272. groupList.value = res.records;
  273. });
  274. };
  275. const handleOpenBatchSign = () => {
  276. if (!selectedRows.value.length) {
  277. ElMessage.warning('请选择需要批量签署的责任书');
  278. return;
  279. }
  280. if (!selectedRows.value.every((item: any, i, data: any[]) => item.departmentName === data[0]?.departmentName)) {
  281. ElMessage.warning('请选择相同类别的责任书');
  282. return;
  283. }
  284. batchSignDialogVisible.value = true;
  285. };
  286. const handleCloseBatchSign = () => {
  287. attachment.value = [];
  288. selectedRows.value = [];
  289. batchSignDialogVisible.value = false;
  290. multipleTableRef.value.clearSelection();
  291. };
  292. const handleSafetyResponsibilityDeptBatchSign = async () => {
  293. if (!attachment.value.length) {
  294. ElMessage.warning('请上传附件');
  295. return;
  296. }
  297. submitLoading.value = true;
  298. const attachments = await formatAttachmentList(attachment.value);
  299. safetyResponsibilityDeptBatchSign({
  300. ids: selectedRows.value.map((item: any) => item.id)?.join(','),
  301. attachment: JSON.stringify(attachments),
  302. })
  303. .then(() => {
  304. ElMessage.success('批量签署成功');
  305. queryTableList();
  306. handleCloseBatchSign();
  307. })
  308. .finally(() => {
  309. submitLoading.value = false;
  310. });
  311. };
  312. const handleConfirm = (scope) => {
  313. safetyResponsibilityDeptSignOrFeedback({
  314. id: scope.row.id,
  315. updateType: 0,
  316. })
  317. .then(() => {
  318. ElMessage.success('确认成功');
  319. router.push({
  320. name: 'responsibilityAgreeManageDept',
  321. });
  322. })
  323. .finally(() => {});
  324. };
  325. // const handleIssueSafetyResponsibility = (scope) => {
  326. // currentRowData.value = scope.row;
  327. // issueSafetyResponsibilityRef.value.dialogShow();
  328. // };
  329. const handleSizeChange = (value) => {};
  330. const handleCurrentChange = (value) => {
  331. queryParams.pageNumber = value;
  332. queryTableList();
  333. };
  334. const handleDownloadLink = (scope) => {
  335. const attachment = unformatAttachment(scope.row.attachment);
  336. attachment?.forEach((item: any) => {
  337. downloadFile(item.fileUrl, item.fileName);
  338. });
  339. };
  340. // const handleConfirmDeleteRow = (scope) => {
  341. // safetyResponsibilityAdminDelete(scope.row.id).then(() => {
  342. // ElMessage.success('删除成功!');
  343. // queryTableList();
  344. // });
  345. // };
  346. const queryTableList = () => {
  347. safetyResponsibilityDeptQueryPage({
  348. ...queryParams,
  349. queryParam: {
  350. ...omit(queryParams.queryParam, 'date'),
  351. startTime: queryParams.queryParam.date?.[0]
  352. ? dayjs(queryParams.queryParam.date?.[0]).format('YYYY-MM-DD')
  353. : undefined,
  354. endTime: queryParams.queryParam.date?.[1]
  355. ? dayjs(queryParams.queryParam.date?.[1]).format('YYYY-MM-DD')
  356. : undefined,
  357. },
  358. }).then((res) => {
  359. tableData.data = res.records;
  360. tableData.total = res.totalRow;
  361. });
  362. };
  363. const handleRestParams = () => {
  364. Object.assign(queryParams, {
  365. pageNumber: 1,
  366. pageSize: 10,
  367. queryParam: {
  368. responsibilityName: '',
  369. departmentName: '',
  370. status: '',
  371. date: '',
  372. responsibilityPersonId: '',
  373. },
  374. });
  375. queryTableList();
  376. };
  377. // const handleSubmit = (formData) => {
  378. // issueSafetyResponsibilityRef.value.submitLoading = true;
  379. // safetyResponsibilityAdminIssuedSafety({
  380. // ...formData,
  381. // userGroupId: formData.userGroupId.join(','),
  382. // // planStartTime: dayjs(formData.planStartTime).format('YYYY-MM-DD'),
  383. // // planEndTime: dayjs(formData.planEndTime).format('YYYY-MM-DD'),
  384. // id: currentRowData.value.id,
  385. // })
  386. // .then(() => {
  387. // queryTableList();
  388. // issueSafetyResponsibilityRef.value.dialogHide();
  389. // currentRowData.value = {};
  390. // })
  391. // .finally(() => {
  392. // issueSafetyResponsibilityRef.value.submitLoading = false;
  393. // });
  394. // };
  395. onMounted(async () => {
  396. await handleQueryUserGroupPage();
  397. queryTableList();
  398. });
  399. </script>
  400. <style lang="scss" scoped>
  401. @use '@/styles/page-details-layout.scss' as *;
  402. @use '@/styles/page-main-layout.scss' as *;
  403. @use '@/styles/basic-table-action.scss' as *;
  404. :deep(.el-tabs__header) {
  405. margin: 0;
  406. }
  407. :deep(.el-tabs__item) {
  408. font-size: 14px !important;
  409. }
  410. :deep(.flexContent) {
  411. display: flex;
  412. }
  413. :deep(.breadcrumb .title) {
  414. margin-left: 0;
  415. }
  416. :deep(.el-form) {
  417. flex: 1;
  418. display: flex;
  419. row-gap: 15px;
  420. flex-wrap: wrap;
  421. }
  422. :deep(.el-form-item) {
  423. margin-bottom: 0;
  424. }
  425. :deep(main) {
  426. display: flex;
  427. flex-direction: column;
  428. }
  429. .search-form {
  430. min-width: 800px;
  431. display: flex;
  432. justify-content: space-between;
  433. align-items: center;
  434. margin-bottom: 20px;
  435. }
  436. .button-content {
  437. margin-bottom: 20px;
  438. }
  439. .table-content {
  440. flex: 1;
  441. overflow: hidden;
  442. overflow-y: auto;
  443. }
  444. .page-content {
  445. display: flex;
  446. justify-content: flex-end;
  447. }
  448. </style>