adjust-edit.vue 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. <template>
  2. <el-dialog
  3. v-loading="loading"
  4. :visible.sync="dialogVisible"
  5. :close-on-click-modal="false"
  6. :close-on-press-escape="false"
  7. :show-close="false"
  8. append-to-body
  9. class="dialog adjust-dialog"
  10. top="5vh"
  11. width="60%"
  12. :title="title"
  13. @open="loadData"
  14. @close="closeDialog"
  15. >
  16. <el-form
  17. ref="adjustForm"
  18. :label-width="formLabelWidth"
  19. label-position="left"
  20. :model.sync="formData"
  21. :rules="rules"
  22. class="adjust-form"
  23. @submit.native.prevent
  24. >
  25. <el-form-item label="调班方式">
  26. <template slot="label">
  27. <span>调班方式</span>
  28. <el-tooltip content="调班方式为调班时目标人员、目标日期、目标班次必填。调班方式为排班变更时,目标人员、日期不可填写。" placement="top">
  29. <i class="el-icon-question"></i>
  30. </el-tooltip>
  31. </template>
  32. <el-select
  33. v-model="reScheduleValue"
  34. :disabled="readonly"
  35. filterable
  36. clearable
  37. :placeholder=" readonly ? '' : '请选择调班方式'"
  38. >
  39. <el-option
  40. v-for="item in reScheduleOptions"
  41. :key="item.value"
  42. :label="item.label"
  43. :value="item.value"
  44. />
  45. </el-select>
  46. </el-form-item>
  47. <el-form-item label="选择排班" prop="scheduleId">
  48. <template slot="label">
  49. <span>选择排班</span>
  50. <el-tooltip content="只能选择已发布状态的排班" placement="top">
  51. <i class="el-icon-question"></i>
  52. </el-tooltip>
  53. </template>
  54. <el-select
  55. v-model="formData.scheduleId"
  56. :disabled="readonly"
  57. filterable
  58. clearable
  59. :placeholder=" readonly ? '' : '请选择排班'"
  60. @clear="clearSchedule"
  61. @change="handleScheduleChange"
  62. >
  63. <el-option
  64. v-for="item in scheduleOptions"
  65. :key="item.value"
  66. :label="item.label"
  67. :value="item.value"
  68. />
  69. </el-select>
  70. </el-form-item>
  71. <el-form-item label="调班原因" prop="reason">
  72. <el-input
  73. v-model="formData.reason"
  74. type="textarea"
  75. :rows="4"
  76. clearable
  77. show-word-limit
  78. :maxlength="1024"
  79. :disabled="readonly"
  80. :placeholder=" readonly ? '' : '请输入调班原因'"
  81. />
  82. </el-form-item>
  83. <el-form-item v-if="params.action == 'view' && formData.status == '已拒绝'" label="拒绝原因" prop="rejectReason">
  84. <el-input
  85. v-model="formData.rejectReason"
  86. type="textarea"
  87. :rows="4"
  88. clearable
  89. show-word-limit
  90. :maxlength="1024"
  91. :disabled="readonly"
  92. :placeholder="params.action + formData.status"
  93. />
  94. </el-form-item>
  95. <el-form-item label="调班班次">
  96. <div v-if="!readonly" class="operate-btn">
  97. <el-button
  98. v-for="btn in tableToolbars"
  99. :key="btn.key"
  100. :type="btn.type"
  101. :icon="btn.icon"
  102. :size="btn.size || 'mini'"
  103. plain
  104. @click="handleTableAction(btn.key)"
  105. >
  106. {{ btn.label }}
  107. </el-button>
  108. </div>
  109. <el-table
  110. ref="adjustTable"
  111. :key="reScheduleValue"
  112. :data="formData.adjustList"
  113. border
  114. stripe
  115. highlight-current-row
  116. style="width: 100%"
  117. :max-height="maxHeight"
  118. class="adjust-table"
  119. @selection-change="selection => handleSelectionChange(selection)"
  120. >
  121. <el-table-column type="selection" width="45" v-if=!readonly header-align="center" align="center" />
  122. <el-table-column type="index" label="序号" width="50" header-align="center" align="center" />
  123. <el-table-column
  124. prop="beforeDate"
  125. label="调班日期"
  126. width="150"
  127. header-align="center"
  128. align="center"
  129. >
  130. <template slot="header">
  131. <span>调班日期</span>
  132. <el-tooltip content="仅可选择当前排班范围内且您有可选班次的日期" placement="top">
  133. <i class="el-icon-question"></i>
  134. </el-tooltip>
  135. </template>
  136. <template slot-scope="scope">
  137. <el-select
  138. v-model="scope.row.beforeDate"
  139. :disabled="readonly"
  140. :placeholder=" readonly ? '' : '请选择调班日期'"
  141. @change="handleDateChange($event, scope.$index, 'beforeShiftList')"
  142. >
  143. <el-option
  144. v-for="item in beforeDateList"
  145. :key="item.value"
  146. :label="item.label"
  147. :value="item.value"
  148. :disabled="item.disabled"
  149. />
  150. </el-select>
  151. </template>
  152. </el-table-column>
  153. <el-table-column
  154. prop="beforeAdjust"
  155. label="调班班次"
  156. min-width="150"
  157. header-align="center"
  158. align="center"
  159. >
  160. <template slot="header">
  161. <span>调班班次</span>
  162. <el-tooltip content="仅展示您的可选班次" placement="top">
  163. <i class="el-icon-question"></i>
  164. </el-tooltip>
  165. </template>
  166. <template slot-scope="scope">
  167. <el-select
  168. v-model="scope.row.beforeAdjust"
  169. :disabled="readonly"
  170. multiple
  171. filterable
  172. multiple-limit="3"
  173. :placeholder=" readonly ? '' : '请选择调班班次'"
  174. @change="vaildBanci($event, scope.row, beforeDateList, 'before')"
  175. >
  176. <el-option
  177. v-for="item in scope.row.beforeShiftList"
  178. :key="item.alias"
  179. :label="item.name"
  180. :value="item.alias"
  181. />
  182. </el-select>
  183. </template>
  184. </el-table-column>
  185. <el-table-column
  186. v-if= "reScheduleValue!=='paiban'"
  187. prop="party"
  188. label="目标人员"
  189. width="130"
  190. header-align="center"
  191. align="center"
  192. >
  193. <template slot-scope="scope">
  194. <el-select
  195. v-model="scope.row.party"
  196. :disabled="readonly || reScheduleValue==='paiban'"
  197. filterable
  198. :placeholder=" readonly ? '' : '请选择目标人员'"
  199. @change="handlePartyChange($event, scope.row, scope.$index, 'change')"
  200. >
  201. <el-option
  202. v-for="item in scheduleInfo.scheduleStaff"
  203. :key="item.userId"
  204. :label="item.userName"
  205. :value="item.userId"
  206. />
  207. </el-select>
  208. </template>
  209. </el-table-column>
  210. <el-table-column
  211. prop="afterDate"
  212. label="目标日期"
  213. width="150"
  214. header-align="center"
  215. align="center"
  216. >
  217. <template slot="header">
  218. <span>目标日期</span>
  219. <el-tooltip content="仅可选择当前排班范围内且目标人员有可选班次的日期" placement="top">
  220. <i class="el-icon-question"></i>
  221. </el-tooltip>
  222. </template>
  223. <template slot-scope="scope">
  224. <el-select
  225. v-model="scope.row.afterDate"
  226. :disabled="readonly"
  227. :placeholder=" readonly ? '' : '请选择目标日期'"
  228. @change="handleDateChange($event, scope.$index, 'afterShiftList')"
  229. @visible-change="(visible) => {getPaiBanDate(visible,scope.$index)}"
  230. >
  231. <el-option
  232. v-for="item in afterDateList"
  233. :key="item.value"
  234. :label="item.label"
  235. :value="item.value"
  236. :disabled="item.disabled"
  237. />
  238. </el-select>
  239. </template>
  240. </el-table-column>
  241. <el-table-column
  242. prop="afterAdjust"
  243. label="目标班次"
  244. min-width="150"
  245. header-align="center"
  246. align="center"
  247. >
  248. <template slot="header">
  249. <span>目标班次</span>
  250. <el-tooltip content="仅展示目标人员可选班次" placement="top">
  251. <i class="el-icon-question"></i>
  252. </el-tooltip>
  253. </template>
  254. <template slot-scope="scope">
  255. <el-select
  256. v-model="scope.row.afterAdjust"
  257. :disabled="readonly"
  258. multiple
  259. filterable
  260. multiple-limit="3"
  261. :placeholder=" readonly ? '' : '请选择目标班次'"
  262. @change="vaildBanci($event, scope.row, afterDateList, 'after')"
  263. >
  264. <el-option
  265. v-for="item in scope.row.afterShiftList"
  266. :key="item.alias"
  267. :label="item.name"
  268. :value="item.alias"
  269. />
  270. </el-select>
  271. </template>
  272. </el-table-column>
  273. </el-table>
  274. </el-form-item>
  275. </el-form>
  276. <div slot="footer" class="el-dialog--center">
  277. <ibps-toolbar :actions="toolbars" @action-event="handleFormAction" />
  278. </div>
  279. </el-dialog>
  280. </template>
  281. <script>
  282. // import { } from '@/views/constants/schedule'
  283. import { getAdjustment, saveAdjustment, queryStaffSchedule, getStaffSchedule, sendMessage, saveStaffSchedule } from '@/api/business/schedule'
  284. export default {
  285. props: {
  286. visible: {
  287. type: Boolean,
  288. default: false
  289. },
  290. params: {
  291. type: Object,
  292. default: () => {}
  293. },
  294. readonly: {
  295. type: Boolean,
  296. default: false
  297. }
  298. },
  299. data () {
  300. const { isSuper, userId, userList = [], deptList = [] } = this.$store.getters || {}
  301. return {
  302. isSuper,
  303. userId,
  304. userList,
  305. deptList,
  306. title: '调班申请',
  307. maxHeight: document.body.clientHeight - 438 + 'px',
  308. dialogVisible: this.visible,
  309. formLabelWidth: '110px',
  310. getAdjustmentData: null,
  311. formData: {
  312. scheduleId: '',
  313. reason: '',
  314. adjustList: []
  315. },
  316. rules: {},
  317. loading: false,
  318. scheduleList: [],
  319. scheduleInfo: {},
  320. currentShift: {},
  321. targetShift: {},
  322. beforeDateList: [], // 调班日期下拉数据
  323. afterDateList: [], // 目标日期下拉数据
  324. blockList: [], // 被锁定数据
  325. scheduleOptions: [],
  326. reScheduleOptions: [{ key: 'diaoban', value: 'diaoban', label: '调班' }, { key: 'paiban', value: 'paiban', label: '排班变更' }],
  327. reScheduleValue: '',
  328. selectionIndex: [],
  329. toolbars: [
  330. { key: 'save', icon: 'ibps-icon-save', label: '提交', type: 'success', visible: !this.readonly },
  331. { key: 'tempSave', icon: 'ibps-icon-save', label: '暂存', type: 'primary', visible: !this.readonly },
  332. { key: 'cancel', icon: 'el-icon-close', label: '关闭', type: 'danger' }
  333. ],
  334. tableToolbars: [
  335. { key: 'add', icon: 'ibps-icon-plus', label: '添加', type: 'success' },
  336. { key: 'remove', icon: 'ibps-icon-trash', label: '删除', type: 'danger' }
  337. ],
  338. pickerOptions: {}
  339. }
  340. },
  341. watch: {
  342. visible: {
  343. handler (val, oldVal) {
  344. this.dialogVisible = this.visible
  345. }
  346. },
  347. reScheduleValue (newValue, oldValue) {
  348. if (oldValue !== '') { // 当reScheduleValue发生变化时,清空调班数组(初始化除外)
  349. this.formData.adjustList = []
  350. }
  351. }
  352. },
  353. async mounted () {
  354. await this.loadData(this)
  355. },
  356. methods: {
  357. // 获取数据
  358. async loadData (self) {
  359. const { id, scheduleId } = self.params || {}
  360. self.formData.scheduleId = scheduleId
  361. if (self.$utils.isEmpty(scheduleId)) {
  362. await self.getScheduleList(self)
  363. } else {
  364. await self.getScheduleInfo(scheduleId, self)
  365. if (self.params.action === 'edit') { // 编辑时获取排版列表
  366. await self.getScheduleList(self)
  367. }
  368. }
  369. if (self.$utils.isEmpty(id)) {
  370. return
  371. }
  372. // 初始化表单数据的方法
  373. const initializeFormData = (data) => {
  374. const { scheduleId, reason, status, rejectReason, executor, executeDate, adjustmentDetailPoList } = data || {}
  375. this.reScheduleValue = data.type
  376. // this.reScheduleValue = 'paiban'
  377. self.formData = {
  378. scheduleId,
  379. reason,
  380. status,
  381. rejectReason,
  382. adjustList: adjustmentDetailPoList.map((i, index) => ({
  383. ...i,
  384. beforeAdjust: i.beforeAdjust ? i.beforeAdjust.split(',') : [],
  385. afterAdjust: i.afterAdjust ? i.afterAdjust.split(',') : [],
  386. beforeShiftList: self.handleDateInit(i.beforeDate, index, 'beforeShiftList', i.createBy, i.beforeAdjust),
  387. afterShiftList: self.handleDateInit(i.afterDate, index, 'afterShiftList', i.party, i.afterAdjust)
  388. }))
  389. }
  390. console.log('formData', self.formData)
  391. }
  392. self.loading = true
  393. try {
  394. // const res = await getAdjustment({ id: self.params.id })
  395. this.getAdjustmentData = await getAdjustment({ id: self.params.id })
  396. if (this.getAdjustmentData.data) {
  397. initializeFormData(this.getAdjustmentData.data)
  398. }
  399. } catch (error) {
  400. console.error('加载排班配置失败', error)
  401. } finally {
  402. self.loading = false
  403. }
  404. },
  405. getScheduleList (self) { // 获取排班下拉的列表
  406. const { first, second } = this.$store.getters.level || {}
  407. const params = {
  408. parameters: [{
  409. key: 'Q^di_dian_^S',
  410. value: second || first
  411. }],
  412. requestPage: {
  413. pageNo: 1,
  414. limit: 99999
  415. },
  416. sorts: []
  417. }
  418. queryStaffSchedule(params).then((res) => {
  419. self.scheduleList = res.data.dataResult
  420. self.scheduleOptions = self.scheduleList.filter(s => s.status === '已发布').map(s => ({
  421. label: s.title,
  422. value: s.id
  423. }))
  424. })
  425. },
  426. async getScheduleInfo (id, self) { // 获取排班下拉的列表
  427. await getStaffSchedule({ id }).then(async (res) => {
  428. const { data } = res
  429. self.scheduleList = [data]
  430. const config = data.config ? JSON.parse(data.config) : {}
  431. self.scheduleInfo = {
  432. startDate: data.startDate,
  433. scheduleShift: config.scheduleShift,
  434. scheduleStaff: this.params.action === 'view' ? self.userList : self.userList.filter(u => config.scheduleStaff.includes(u.userId) && u.userId !== this.userId),
  435. shiftList: data.staffScheduleDetailPoList,
  436. executor: JSON.stringify(config.approver) || ''
  437. }
  438. self.scheduleOptions = self.scheduleList.map(s => ({
  439. label: s.title,
  440. value: s.id
  441. }))
  442. if (this.params.action !== 'view') {
  443. self.handleScheduleChange(id)
  444. }
  445. })
  446. },
  447. async getBlockAdjustRequest (self) { // 获取锁定班次
  448. const scheduleId = self.scheduleInfo.id
  449. const sql = 'select * from t_adjustment_detail where status_ in ( "待审核", "审核中", "待审批") and parent_id_ in (select id_ from t_adjustment where schedule_id_ = ' + scheduleId + ' )'
  450. const res = await self.$common.request('sql', sql) // 获取当前审核状态中的申请单数据
  451. self.blockList = self.getBlockResult(res.variables.data || [], 'default')
  452. // 清除列表中被申请数据
  453. this.vaildExpireData(self.blockList)
  454. },
  455. clearSchedule () { // 清空操作 清空排班数据
  456. this.formData.adjustList = []
  457. },
  458. async handleScheduleChange (val) { // 排班改变刷新数据
  459. const self = this
  460. if (val) {
  461. await getStaffSchedule({ id: val }).then((res) => {
  462. const schedule = res.data
  463. if (self.$utils.isEmpty(schedule)) {
  464. return self.$message.error('数据有误!所选排班不存在!')
  465. }
  466. const config = schedule.config ? JSON.parse(schedule.config) : {}
  467. self.scheduleInfo = {
  468. id: schedule.id,
  469. startDate: schedule.startDate,
  470. endDate: schedule.endDate,
  471. scheduleShift: config.scheduleShift,
  472. scheduleStaff: self.userList.filter(u => config.scheduleStaff.includes(u.userId) && u.userId !== self.userId),
  473. shiftList: schedule.staffScheduleDetailPoList,
  474. executor: JSON.stringify(config.approver) || ''
  475. }
  476. self.currentShift = self.scheduleInfo.shiftList.find(s => s.userId === self.userId) // 当前排班中我的排版表
  477. if (!self.currentShift) {
  478. return self.$message.warning('所选排班中未含有您的信息,请重新选择!')
  479. }
  480. self.$set(self, 'pickerOptions', {
  481. disableDate: (time) => {
  482. const startDate = new Date(schedule.startDate)
  483. const endDate = new Date(schedule.endDate)
  484. return time < startDate || time > endDate
  485. }
  486. })
  487. if (self.formData.adjustList.length < 1) { // 编辑新增状态初始化
  488. self.formData.adjustList = []
  489. }
  490. if (this.params.action !== 'view') {
  491. self.getBlockAdjustRequest(self).then(() => { // 获取被锁定的班次
  492. self.beforeDateList = self.initDateOptions(schedule.startDate, self.currentShift)
  493. const filterid = self.$store.getters.userId || ''
  494. if (self.beforeDateList.length > 0 && Object.keys(self.blockList).length > 0) {
  495. // 过滤当前自己被占用的日期和班次
  496. self.beforeDateList = self.filterBlockList(self.blockList, self.beforeDateList, filterid)
  497. }
  498. })
  499. }
  500. })
  501. }
  502. // this.scheduleList.find(i => i.id === val)
  503. // this.pickerOptions = {
  504. // disableDate: (time) => {
  505. // const startDate = new Date(schedule.startDate)
  506. // const endDate = new Date(schedule.endDate)
  507. // console.log('startDate:', startDate, 'endDate:', endDate, 'time:', time);
  508. // return time < startDate || time > endDate
  509. // }
  510. // }
  511. },
  512. /** 校验数据中有无日期过期或班次被锁定数据,有则清空该条数据
  513. *
  514. * @param dateList 已经过滤的数据
  515. * */
  516. vaildExpireData (blockList) {
  517. this.formData.adjustList.forEach((adjustItem) => {
  518. const createBy = adjustItem.createBy
  519. if (blockList[createBy]) {
  520. const blockListForUser = blockList[createBy] // 锁定数据中用户数据
  521. const beforeDate = adjustItem.beforeDate
  522. blockListForUser.forEach((blockEntry) => {
  523. if (blockEntry.value === beforeDate) {
  524. const banci = blockEntry.banci
  525. if (adjustItem.beforeAdjust.includes(banci)) {
  526. const nameObj = this.scheduleInfo.scheduleShift.find(obj => obj.alias === banci)
  527. this.$message.warning(adjustItem.beforeDate + '调班班次【' + nameObj?.name + '】已被申请,请重新选择')
  528. adjustItem.beforeAdjust = adjustItem.beforeAdjust.filter(item => item !== banci)
  529. }
  530. }
  531. })
  532. }
  533. const party = adjustItem.party
  534. if (blockList[party]) {
  535. const blockListForUser = blockList[party] // 锁定数据中用户数据
  536. const afterDate = adjustItem.afterDate
  537. blockListForUser.forEach((blockEntry) => {
  538. if (blockEntry.value === afterDate) {
  539. const banci = blockEntry.banci
  540. if (adjustItem.afterAdjust.includes(banci)) {
  541. const nameObj = this.scheduleInfo.scheduleShift.find(obj => obj.alias === banci)
  542. this.$message.warning(adjustItem.afterDate + '目标班次【' + nameObj?.name + '】已被申请,请重新选择')
  543. adjustItem.afterAdjust = adjustItem.afterAdjust.filter(item => item !== banci)
  544. }
  545. }
  546. })
  547. }
  548. })
  549. },
  550. vaildBanci (chooseArr, row) {
  551. // 校验调班那天是否有重复班次
  552. if (this.reScheduleValue === 'diaoban' && chooseArr.length > 0) {
  553. const duplicateElements = [] // 用户重复班次数组
  554. const userAfterData = this.beforeDateList.find(obj => obj.value === row.afterDate)
  555. row.afterAdjust.some(element => {
  556. if (userAfterData.banci.includes(element)) {
  557. duplicateElements.push(element)
  558. }
  559. })
  560. if (duplicateElements.length > 0) { // 用户当天有目标班次 不能换
  561. const val = duplicateElements.map(el => {
  562. const nameObj = this.scheduleInfo.scheduleShift.find(obj => obj.alias === el)
  563. return nameObj?.name
  564. }).filter(Boolean).join(', ')
  565. // 把该重复元素从目标班次删除
  566. row.afterAdjust = row.afterAdjust.filter(item => !duplicateElements.includes(item))
  567. this.$message.warning(row.afterDate + '您已有【' + val + '】班次,不能作为目标班次!')
  568. return true
  569. }
  570. const partyElements = []// 目标人员重复班次数组
  571. const partyBeforeData = this.afterDateList.find(obj => obj.value === row.beforeDate)
  572. row.beforeAdjust.some(element => {
  573. if (partyBeforeData.banci.includes(element)) {
  574. partyElements.push(element)
  575. }
  576. return false
  577. })
  578. if (partyElements.length > 0) { // 目标人员有重复班次 也不能换
  579. const val = partyElements.map(el => {
  580. const nameObj = this.scheduleInfo.scheduleShift.find(obj => obj.alias === el)
  581. return nameObj?.name
  582. }).filter(Boolean).join(', ')
  583. // 把该重复元素从目标班次删除
  584. row.beforeAdjust = row.beforeAdjust.filter(item => !partyElements.includes(item))
  585. this.$message.warning(row.beforeDate + '目标人员已有【' + val + '】班次,不能作为调班班次!')
  586. return true
  587. }
  588. }
  589. },
  590. rowValidate (row, index) { // 行必填检验
  591. if (!row.beforeDate) {
  592. this.$message.warning(`第${index}行` + '调班日期未选择!')
  593. return true
  594. }
  595. if (row.beforeAdjust.length < 1) {
  596. this.$message.warning(`第${index}行` + '调班班次未选择!')
  597. return true
  598. }
  599. if (this.reScheduleValue === 'diaoban') { // 排班变更目标人员不用填
  600. if (!row.afterDate) {
  601. this.$message.warning(`第${index}行` + '目标人员未选择!')
  602. return true
  603. }
  604. if (!row.party) {
  605. this.$message.warning(`第${index}行` + '目标日期未选择!')
  606. return true
  607. }
  608. if (row.afterAdjust.length < 1) {
  609. this.$message.warning(`第${index}行` + '目标班次未选择!')
  610. return true
  611. }
  612. }
  613. },
  614. initDateOptions (startDateStr, obj) { // 初始化日期下拉数据
  615. const result = []
  616. const startDate = new Date(startDateStr)
  617. // 筛选出以'd'开头且后面跟数字的键组成数组
  618. const dKeysArray = Object.keys(obj).filter(key => /^d\d+$/.test(key))
  619. dKeysArray.forEach(key => {
  620. const banci = obj[key]
  621. const date = new Date(startDate)
  622. const daysToAdd = parseInt(key.slice(1))
  623. date.setDate(startDate.getDate() + (daysToAdd - 1))
  624. if (banci) {
  625. result.push({
  626. key,
  627. banci,
  628. // date: date.toISOString().split('T')[0],
  629. value: date.toISOString().split('T')[0],
  630. label: date.toISOString().split('T')[0]
  631. })
  632. } else { // 没有班次的日期禁用
  633. result.push({
  634. key,
  635. banci,
  636. // date: date.toISOString().split('T')[0],
  637. value: date.toISOString().split('T')[0],
  638. label: date.toISOString().split('T')[0],
  639. disabled: true
  640. })
  641. }
  642. })
  643. return result
  644. },
  645. /**
  646. * 过滤锁定班次,返回被过滤后的排班van数据
  647. * @param bList 锁定班次数组
  648. * @param dateList 需要过滤的用户数组
  649. * @param filterid 需要过滤的用户id
  650. */
  651. filterBlockList (bList, dateList, filterid) { // 根据锁定数据,过滤当前列表
  652. const filterBList = bList[filterid] || []
  653. const { startDate } = this.scheduleInfo
  654. // 将日期在今天之前的排班也锁定
  655. // dateList.forEach((el) => {
  656. // if (this.equalDate(el.value)) {
  657. // el.disabled = true
  658. // }
  659. // })
  660. filterBList.forEach((el) => {
  661. const index = this.getDays(startDate, el.value)
  662. if (dateList[index].value === el.value && dateList[index].disabled !== true) {
  663. const arr1 = dateList[index].banci.split(',')
  664. const arr2 = el.banci.split(',')
  665. const result = arr2.some(item => arr1.includes(item))
  666. if (result) { // 包含被锁定班次
  667. // dateList[index].banci = dateList[index].banci.replace(el.banci, '')
  668. arr2.forEach(item => { // 替换班次为空格
  669. const index = arr1.indexOf(item)
  670. if (index !== -1) {
  671. arr1[index] = ''
  672. }
  673. })
  674. // if (dateList[index].banci === '') {
  675. if (arr1.length > 0 && arr1.join('') === '') { // 全被替换为空格说明当天班次已锁定完,该日期不可用
  676. dateList[index].disabled = true
  677. } else {
  678. dateList[index].banci = arr1.join(',')
  679. }
  680. }
  681. }
  682. })
  683. console.log('已过滤日期班次:', dateList)
  684. return dateList
  685. },
  686. /**
  687. * @param data 被锁定的数据
  688. * @param type 类型区分是初始化时还是编辑中,因为初始化数据的字段和编辑行的不一致
  689. */
  690. getBlockResult (data, type) {
  691. if (data.length < 1) {
  692. return {}
  693. }
  694. const blockResult = []
  695. const tempMap = {}
  696. data.forEach(item => {
  697. let { create_by_, before_date_, before_adjust_ } = item
  698. let key = `${create_by_}-${before_date_}`
  699. if (type === 'adjustList') { // 如果是给编辑行分组
  700. create_by_ = item.createBy || this.$store.getters.userId
  701. before_date_ = item.beforeDate
  702. before_adjust_ = item.beforeAdjust.join(',')
  703. key = `${create_by_}-${before_date_}`
  704. }
  705. if (!tempMap[key]) {
  706. tempMap[key] = {
  707. userid: create_by_,
  708. value: before_date_,
  709. banci: before_adjust_
  710. }
  711. blockResult.push(tempMap[key])
  712. } else {
  713. tempMap[key].banci += `,${before_adjust_}`
  714. }
  715. })
  716. data.forEach(item => {
  717. let { party_, after_date_, after_adjust_ } = item
  718. let key2 = `${party_}-${after_date_}`
  719. if (type === 'adjustList') { // 如果是给编辑行分组
  720. party_ = item.party
  721. after_date_ = item.afterDate
  722. after_adjust_ = item.afterAdjust.join(',')
  723. key2 = `${party_}-${after_date_}`
  724. }
  725. if (!tempMap[key2]) {
  726. tempMap[key2] = {
  727. userid: party_,
  728. value: after_date_,
  729. banci: after_adjust_
  730. }
  731. blockResult.push(tempMap[key2])
  732. } else {
  733. tempMap[key2].banci += `,${after_adjust_}`
  734. }
  735. })
  736. // 按userid分组
  737. const blockGrouped = {}
  738. blockResult.forEach((item) => {
  739. const userid = item.userid
  740. if (!blockGrouped[userid]) {
  741. blockGrouped[userid] = []
  742. }
  743. blockGrouped[userid].push(item)
  744. })
  745. return blockGrouped
  746. },
  747. getDays (start, end) { // 根据日期获取排序 d1、d2、d3...
  748. if (!start || !end) {
  749. return 0
  750. }
  751. return Math.ceil((new Date(end) - new Date(start)) / (1000 * 60 * 60 * 24))
  752. },
  753. handleDateInit (val, index, type, userid, Adjust) { // 编辑、详情状态时给行初始化
  754. const shiftMap = {
  755. beforeShiftList: 'beforeAdjust',
  756. afterShiftList: 'afterAdjust'
  757. }
  758. // 更新日期时,同步清除班次及option
  759. // this.formData.adjustList[index][type] = []
  760. if (!this.formData.adjustList[index]) { // 页面初始化时
  761. this.formData.adjustList[index] = {}
  762. this.formData.adjustList[index][type] = []
  763. }
  764. if (!this.formData.adjustList[index][shiftMap[type]]) { // 页面初始化时
  765. this.formData.adjustList[index][shiftMap[type]] = Adjust ? Adjust.split(',') : []
  766. }
  767. const { scheduleShift } = this.scheduleInfo
  768. if (this.params.action === 'view') { // 详情状态初始化beforeShiftList,afterShiftList,不用过滤数据
  769. this.formData.adjustList[index][type] = scheduleShift
  770. return this.formData.adjustList[index][type]
  771. } else { // 编辑状态初始化beforeShiftList,afterShiftList
  772. // 获取所选日期对应数据
  773. let selectObj = this.beforeDateList.filter(item => item.value === val) // 调班人自己的数据
  774. if (type === 'afterShiftList') {
  775. if (this.reScheduleValue === 'paiban') { // 排班变更模式下 日期 班次初始化为全部日期班次
  776. this.afterDateList = this.getDateArray(this.scheduleInfo.startDate, this.scheduleInfo.endDate)
  777. const shiftArr = this.scheduleInfo.scheduleShift
  778. shiftArr.push({})
  779. return shiftArr
  780. }
  781. this.handlePartyChange(userid, this.formData.adjustList[index], index, 'init')
  782. selectObj = this.afterDateList.filter(item => item.value === val) // 目标人员数据
  783. }
  784. const shifts = selectObj[0]?.banci?.split(',') || []
  785. const temp = scheduleShift.filter(i => shifts.includes(i.alias))
  786. this.formData.adjustList[index].recordId = this.currentShift.id
  787. this.formData.adjustList[index][type] = temp
  788. return temp
  789. }
  790. },
  791. handleDateChange (val, index, type) {
  792. console.log(val, index, type)
  793. const shiftMap = {
  794. beforeShiftList: 'beforeAdjust',
  795. afterShiftList: 'afterAdjust'
  796. }
  797. // 更新日期时,同步清除班次及option
  798. // this.formData.adjustList[index][type] = []
  799. this.formData.adjustList[index][type] = []
  800. this.formData.adjustList[index][shiftMap[type]] = []
  801. if (!val) {
  802. // 第一次选目标人/切换目标人,目标日期班次清空,不用再往下走了
  803. return
  804. }
  805. const { startDate, scheduleShift } = this.scheduleInfo
  806. // 获取所选日期对应数据
  807. let selectObj = this.afterDateList.filter(item => item.value === val) // 目标人员数据
  808. if (type === 'beforeShiftList') {
  809. selectObj = this.beforeDateList.filter(item => item.value === val) // 调班人自己的数据
  810. }
  811. const shifts = selectObj[0].banci.split(',')
  812. const temp = scheduleShift.filter(i => shifts.includes(i.alias))
  813. this.formData.adjustList[index].recordId = this.currentShift.id
  814. this.formData.adjustList[index][type] = temp
  815. },
  816. handlePartyChange (val, row, index, type) {
  817. this.targetShift = this.scheduleInfo.shiftList.find(i => i.userId === val) // 获取目标人班次
  818. this.afterDateList = this.initDateOptions(this.scheduleInfo.startDate, this.targetShift) // 转换目标人能选择的日期
  819. this.formData.adjustList[index]['afterDate'] = '' // 更换目标人时刷新目标日期
  820. const filterid = val || ''
  821. if (this.afterDateList.length > 0 && Object.keys(this.blockList).length > 0 && this.params.action !== 'view') {
  822. // 过滤当前目标人被占用的日期和班次
  823. this.afterDateList = this.filterBlockList(this.blockList, this.afterDateList, filterid)
  824. }
  825. if (type === 'change') {
  826. this.handleDateChange(row.afterDate, index, 'afterShiftList')
  827. }
  828. },
  829. getPaiBanDate (visible, index, afterAdjust) { // 排班变更方式,日期全部可选,目标人员不可选
  830. if (this.reScheduleValue === 'paiban' && visible === true) {
  831. const startDate = this.scheduleInfo.startDate
  832. const endDate = this.scheduleInfo.endDate
  833. const datearr = this.getDateArray(startDate, endDate)
  834. this.afterDateList = datearr
  835. }
  836. },
  837. handleFormAction ({ key }) {
  838. switch (key) {
  839. case 'save':
  840. this.handleSave(key)
  841. break
  842. case 'tempSave':
  843. this.handleSave(key)
  844. break
  845. case 'cancel':
  846. this.handleCancel()
  847. break
  848. default:
  849. break
  850. }
  851. },
  852. handleTableAction (key, type, data) {
  853. switch (key) {
  854. case 'add':
  855. this.handleAddParam(type)
  856. break
  857. case 'edit':
  858. this.handleAddParam(type, data)
  859. break
  860. case 'remove':
  861. if (!this.selectionIndex.length) {
  862. return this.$message.warning('请选择要删除的数据')
  863. }
  864. this.handleRemove(this.selectionIndex, type)
  865. break
  866. default:
  867. break
  868. }
  869. },
  870. handleSave (key) {
  871. const getOverview = (data) => {
  872. const result = []
  873. data.forEach(i => {
  874. const partyName = this.transformData(this.userList, i.party, 'userId', 'userName')
  875. const beforeAdjust = i.beforeAdjust.map(item => `【${item}】`).join('')
  876. const afterAdjust = i.afterAdjust.map(item => `【${item}】`).join('')
  877. let desc = ''
  878. if (i.party && i.party !== this.$store.getters.userId) {
  879. desc = `${i.beforeDate}班次${beforeAdjust}与${partyName}${i.afterDate}班次${afterAdjust}调换`
  880. } else {
  881. desc = `${i.beforeDate}班次${beforeAdjust}调换到${i.afterAdjust}`
  882. }
  883. result.push(desc)
  884. })
  885. return result.join('\n')
  886. }
  887. this.$refs.adjustForm.validate((valid) => {
  888. if (!valid) {
  889. return this.$message.warning('请完善表单必填项信息!')
  890. }
  891. const { first, second } = this.$store.getters.level || {}
  892. const { scheduleId, reason, adjustList, rejectReason } = this.formData || {}
  893. let statusVal = '已暂存'
  894. const executorVal = this.scheduleInfo.executor.replace(/\[|\]|\"/g, '').replace(/,/g, ',') || ''
  895. if (key === 'tempSave') { // 暂存
  896. } else { // 提交
  897. // 对最后一行进行行校验
  898. if (this.formData.adjustList.length < 1) { // 校验不通过则返回true
  899. this.$message.warning('调班表未填写数据!')
  900. return
  901. }
  902. if (this.rowValidate(this.formData.adjustList[this.formData.adjustList.length - 1], this.formData.adjustList.length)) {
  903. return
  904. }
  905. statusVal = adjustList.some((i) => { return this.$utils.isNotEmpty(i.party) && this.reScheduleValue !== 'paiban' }) ? '待审核' : (executorVal === '' ? '已通过' : '待审批')
  906. }
  907. // return
  908. const submitData = {
  909. id: this.params.id,
  910. pk: this.params.id,
  911. scheduleId,
  912. reason,
  913. diDian: second || first,
  914. overview: getOverview(adjustList),
  915. status: statusVal,
  916. type: this.reScheduleValue,
  917. rejectReason,
  918. /*
  919. dataStatus: "string",
  920. delBeforeSave: true,
  921. dsAlias: "string",
  922. executeDate: '',
  923. "type": "string",
  924. */
  925. executor: executorVal,
  926. // type: this.reScheduleValue,
  927. adjustmentDetailPoList: adjustList.map(i => ({
  928. recordId: i.recordId,
  929. beforeDate: i.beforeDate,
  930. rejectReason: i.rejectReason,
  931. beforeAdjust: i.beforeAdjust ? i.beforeAdjust.join(',') : '',
  932. party: i.party ? i.party : this.$store.getters.userId,
  933. status: statusVal,
  934. afterDate: i.afterDate ? i.afterDate : i.beforeDate,
  935. afterAdjust: i.afterAdjust ? i.afterAdjust.join(',') : ''
  936. }))
  937. }
  938. this.submitForm(submitData)
  939. // sendMessage(submitData, '1169304256906264576')
  940. })
  941. },
  942. // 提交数据
  943. submitForm (data) {
  944. const self = this
  945. saveAdjustment(data).then(async (res) => {
  946. self.$message.success(`${self.params.action === 'edit' ? '提交' : '申请'}成功`)
  947. self.closeDialog()
  948. self.$emit('refresh')
  949. // 提交后通知审核人、审批人
  950. if (data.status === '待审核') {
  951. const partyArray = data.adjustmentDetailPoList.map(obj => obj.party)
  952. partyArray.forEach(el => {
  953. sendMessage(data, el)
  954. })
  955. } else if (data.status === '待审批') {
  956. const executorList = data.executor.split(',')
  957. executorList.forEach(el => {
  958. sendMessage(data, el)
  959. })
  960. } else if (data.status === '已通过') { // 通过申请修改排班数据(只有排版变更且无排版审批人才可能在提交时变为已通过)
  961. self.handleAccess(self)
  962. }
  963. })
  964. },
  965. /**
  966. * 处理已通过的申请单,修改排班数据
  967. * */
  968. async handleAccess (self) {
  969. const response = await getStaffSchedule({ id: self.formData.scheduleId })
  970. const submitData = response.data
  971. const { staffScheduleDetailPoList, startDate } = response.data
  972. const getIndexByDate = (date) => this.getDays(startDate, date)
  973. self.formData.adjustList.forEach(async (el) => {
  974. const userId = this.$store.getters.userId || ''
  975. const userResIndex = staffScheduleDetailPoList.findIndex(item => item.userId === userId)
  976. const index = getIndexByDate(el.afterDate)
  977. const partyIndex = getIndexByDate(el.beforeDate)
  978. this.removeScheduleDataForPaibanWithRegex(userResIndex, partyIndex, el.beforeAdjust, staffScheduleDetailPoList)
  979. this.updateScheduleDataForPaibanWithRegex(userResIndex, index, el.afterAdjust, staffScheduleDetailPoList)
  980. })
  981. submitData.staffScheduleDetailPoList = staffScheduleDetailPoList
  982. saveStaffSchedule(submitData).then(() => console.log('排班已更新')).catch(err => console.log(err))
  983. },
  984. // 用于排班变更时使用正则表达式更新排班数据的函数(避免重复添加班次),确保无多余逗号
  985. updateScheduleDataForPaibanWithRegex (index, targetIndex, adjustData, scheduleList) {
  986. const currentData = scheduleList[index][`d${targetIndex + 1}`] || ''
  987. const dataToAdd = adjustData.filter(item => !currentData.includes(item))
  988. const newData = [currentData, dataToAdd.join(',')].filter(Boolean).join(',')
  989. scheduleList[index][`d${targetIndex + 1}`] = newData.replace(/,$/, '')
  990. },
  991. // 用于排班变更时使用正则表达式移除排班数据的函数,确保无多余逗号
  992. removeScheduleDataForPaibanWithRegex (index, targetIndex, adjustData, scheduleList) {
  993. const targetData = scheduleList[index][`d${targetIndex + 1}`] || ''
  994. const updatedData = adjustData.reduce((acc, item) => {
  995. const pattern = new RegExp(`,?${item}(,|$)`, 'g') // 匹配逗号+要移除的项或者要移除的项+结尾逗号或结尾(全局匹配)
  996. return acc.replace(pattern, '')
  997. }, targetData)
  998. scheduleList[index][`d${targetIndex + 1}`] = updatedData.replace(/,$/, '') // 去除末尾可能出现的多余逗号
  999. },
  1000. handleAddParam () {
  1001. // 把前面填写的行加入班次日期锁定
  1002. if (this.formData.adjustList.length > 0) {
  1003. this.addFilterList(this.formData.adjustList)
  1004. }
  1005. // 对上一行进行行校验
  1006. if (this.formData.adjustList.length > 0 && this.rowValidate(this.formData.adjustList[this.formData.adjustList.length - 1], this.formData.adjustList.length)) { // 校验不通过则返回true
  1007. return
  1008. }
  1009. this.formData.adjustList.push({
  1010. recordId: '',
  1011. beforeDate: '',
  1012. beforeAdjust: '',
  1013. beforeShiftList: [],
  1014. afterDate: '',
  1015. afterAdjust: '',
  1016. afterShiftList: [],
  1017. status: '',
  1018. party: ''
  1019. })
  1020. },
  1021. addOrDelBlockItem (blockList, blockGrouped, type) {
  1022. if (type === 'add') {
  1023. blockGrouped.forEach((itemB) => {
  1024. let found = false
  1025. blockList.forEach((itemA, index) => {
  1026. if (itemA.value === itemB.value) {
  1027. // 合并banci并去重
  1028. let mergedBanci = Array.from(new Set([...itemA.banci.split(','), ...itemB.banci.split(',')]))
  1029. blockList[index].banci = mergedBanci.join(',')
  1030. found = true
  1031. }
  1032. })
  1033. if (!found) {
  1034. // 如果没找到相同的value,直接添加新项
  1035. blockList.push(itemB)
  1036. }
  1037. })
  1038. } else if (type === 'del') {
  1039. blockGrouped.forEach((itemB) => {
  1040. let toDeleteIndex = []
  1041. blockList.forEach((itemA, index) => {
  1042. if (itemA.value === itemB.value) {
  1043. // 获取a中子项banci删除掉含有b中子项banci的部分后的新banci
  1044. let newBanci = itemA.banci.split(',').filter((banciA) => !itemB.banci.split(',').includes(banciA))
  1045. if (newBanci.length === 0) {
  1046. // 如果新banci为空,标记该项需要删除
  1047. toDeleteIndex.push(index)
  1048. } else {
  1049. // 更新a中的banci
  1050. blockList[index].banci = newBanci.join(',')
  1051. }
  1052. }
  1053. })
  1054. // 根据标记删除相应的项
  1055. toDeleteIndex.reverse().forEach((index) => {
  1056. blockList.splice(index, 1)
  1057. })
  1058. })
  1059. }
  1060. return blockList
  1061. },
  1062. addFilterList (adjustList) { // 把前面填写的行加入班次日期锁定
  1063. const blockGrouped = this.getBlockResult(adjustList, 'adjustList') // 每次把前面的行数据分组
  1064. // 加入锁定数据
  1065. for (const key in blockGrouped) {
  1066. if (!this.blockList[key]) {
  1067. this.blockList[key] = blockGrouped[key] // key不存在直接新增
  1068. } else { // key存在则合并新旧数据
  1069. this.blockList[key] = this.addOrDelBlockItem(this.blockList[key], blockGrouped[key], 'add')
  1070. }
  1071. }
  1072. // 刷新当前用户的过滤数据
  1073. const filterid = this.$store.getters.userId || ''
  1074. if (this.beforeDateList.length > 0 && Object.keys(this.blockList).length > 0) {
  1075. // 过滤当前自己被占用的日期和班次
  1076. this.beforeDateList = this.filterBlockList(this.blockList, this.beforeDateList, filterid)
  1077. }
  1078. },
  1079. delFilterList (adjustList) { // 把删除的行从班次日期锁定删除
  1080. const blockGrouped = this.getBlockResult(adjustList, 'adjustList') // 数据分组
  1081. // 加入锁定数据
  1082. for (const key in blockGrouped) {
  1083. this.blockList[key] = this.addOrDelBlockItem(this.blockList[key], blockGrouped[key], 'del')
  1084. }
  1085. // 刷新当前用户的过滤数据
  1086. const filterid = this.$store.getters.userId || ''
  1087. if (this.beforeDateList.length > 0 && Object.keys(this.blockList).length > 0) {
  1088. // 过滤当前自己被占用的日期和班次
  1089. this.beforeDateList = this.filterBlockList(this.blockList, this.beforeDateList, filterid)
  1090. }
  1091. },
  1092. handleSelectionChange (v) {
  1093. this.selectionIndex = v.map(item => this.formData.adjustList.indexOf(item))
  1094. },
  1095. /** 返回一个从开始日期到结束日期的日期数组(今天之前的不可用)
  1096. * @param startDate
  1097. * @param endDate
  1098. * */
  1099. getDateArray (startDate, endDate) {
  1100. const dateArray = []
  1101. const start = new Date(startDate)
  1102. const end = new Date(endDate)
  1103. // const currentDateNow = new Date() // 获取当前日期
  1104. const aliasList = this.scheduleInfo.scheduleShift.map(item => item.alias)
  1105. const banci = aliasList.join(',')
  1106. for (let currentDate = start; currentDate <= end; currentDate.setDate(currentDate.getDate() + 1)) {
  1107. const dateObj = {
  1108. banci: banci + ',休息',
  1109. disabled: false,
  1110. // currentDate < currentDateNow, // 修改此处判断,若日期小于当前日期则设为disabled:true,
  1111. key: `d${currentDate.getDate()}`,
  1112. label: currentDate.toISOString().split('T')[0],
  1113. value: currentDate.toISOString().split('T')[0]
  1114. }
  1115. dateArray.push(dateObj)
  1116. }
  1117. return dateArray
  1118. },
  1119. equalDate (dateStr) { // 比较传参是否在今天日期之前,是则返回true
  1120. // 获取今天的日期,只保留年月日部分
  1121. const today = new Date()
  1122. today.setHours(0, 0, 0, 0)
  1123. // 要比较的日期字符串
  1124. // 将日期字符串解析为日期对象
  1125. const dateObj = new Date(dateStr.split('-')[0], parseInt(dateStr.split('-')[1]) - 1, dateStr.split('-')[2])
  1126. // 进行比较
  1127. if (dateObj >= today) {
  1128. return false
  1129. } else {
  1130. return true
  1131. }
  1132. },
  1133. handleRemove (removeIndex, type) {
  1134. const self = this
  1135. let indexList = []
  1136. if (typeof removeIndex === 'number') {
  1137. indexList = [removeIndex]
  1138. } else {
  1139. indexList = removeIndex
  1140. }
  1141. indexList.sort((a, b) => b - a)
  1142. this.$confirm('确定要删除选中数据吗?', '提示', {
  1143. confirmButtonText: '确定',
  1144. cancelButtonText: '取消',
  1145. type: 'warning'
  1146. }).then(() => {
  1147. const delList = []
  1148. indexList.forEach((i) => {
  1149. delList.push(self.formData.adjustList[i])
  1150. self.formData.adjustList.splice(i, 1)
  1151. })
  1152. this.delFilterList(delList) // 删除的数据解除班次锁定
  1153. }).catch(() => {})
  1154. },
  1155. transformData (dataset, data, from, to) {
  1156. if (!data) {
  1157. return ''
  1158. }
  1159. const list = data.split(',')
  1160. const names = list.map(item => {
  1161. const temp = dataset.find(i => i[from] === item)
  1162. return temp ? temp[to] : ''
  1163. })
  1164. return names.filter(i => i).join(',')
  1165. },
  1166. handleCancel () {
  1167. this.closeDialog()
  1168. },
  1169. closeDialog () {
  1170. this.$emit('close', false)
  1171. }
  1172. }
  1173. }
  1174. </script>
  1175. <style lang="scss" scoped>
  1176. .adjust-dialog {
  1177. ::v-deep {
  1178. .el-dialog {
  1179. min-width: 1024px;
  1180. &__header {
  1181. padding: 15px 20px 16px;
  1182. }
  1183. }
  1184. .adjust-table {
  1185. .el-input, .el-select {
  1186. width: 100%;
  1187. }
  1188. }
  1189. }
  1190. .adjust-form {
  1191. padding: 20px;
  1192. background: #f5f5f5;
  1193. border-radius: 4px;
  1194. overflow: hidden;
  1195. min-Height: 400px;
  1196. height: 60vh;
  1197. .operate-btn {
  1198. text-align: right;
  1199. margin-bottom: 5px;
  1200. }
  1201. }
  1202. }
  1203. </style>