Browse Source

排班视图增加班次排班

zhonghuizhen 1 year ago
parent
commit
e18f9591e4

+ 13 - 6
src/views/business/​scheduleManage/components/context-menu.vue

@@ -10,7 +10,7 @@
                 <el-checkbox
                 <el-checkbox
                     v-for="(shift, index) in shiftList"
                     v-for="(shift, index) in shiftList"
                     :key="index"
                     :key="index"
-                    :label="shift.alias"
+                    :label="viewType === 'users' ? shift.alias : shift.userName"
                     class="shift-item ibps-ellipsis"
                     class="shift-item ibps-ellipsis"
                 >
                 >
                     <!-- <el-popover
                     <!-- <el-popover
@@ -28,7 +28,7 @@
                             class="shift-item"
                             class="shift-item"
                         >{{ shift.alias }}</div>
                         >{{ shift.alias }}</div>
                     </el-popover> -->
                     </el-popover> -->
-                    {{ shift.alias }}
+                    {{ viewType === 'users' ? shift.alias : shift.userName }}
                 </el-checkbox>
                 </el-checkbox>
             </el-checkbox-group>
             </el-checkbox-group>
             <el-button
             <el-button
@@ -45,6 +45,10 @@
 <script>
 <script>
 export default {
 export default {
     props: {
     props: {
+        viewType: {
+            type: String,
+            default: 'users'
+        },
         visible: {
         visible: {
             type: Boolean,
             type: Boolean,
             default: false
             default: false
@@ -68,13 +72,13 @@ export default {
     },
     },
     data () {
     data () {
         return {
         return {
-            selectedShift: this.itemData.map(i => i.alias) || []
+            selectedShift: this.viewType === 'users' ? (this.itemData.map(i => i.alias) || []) : (this.itemData.map(i => i.userName) || [])
         }
         }
     },
     },
     watch: {
     watch: {
         itemData: {
         itemData: {
             handler (val) {
             handler (val) {
-                this.selectedShift = val.map(i => i.alias) || []
+                this.selectedShift = this.viewType === 'users' ? (val.map(i => i.alias) || []) : (val.map(i => i.userName) || [])
             },
             },
             deep: true,
             deep: true,
             immediate: true
             immediate: true
@@ -82,7 +86,7 @@ export default {
     },
     },
     methods: {
     methods: {
         handleSubmit () {
         handleSubmit () {
-            const selected = this.shiftList.filter(i => this.selectedShift.includes(i.alias))
+            const selected = this.viewType === 'users' ? this.shiftList.filter(i => this.selectedShift.includes(i.alias)) : this.shiftList.filter(i => this.selectedShift.includes(i.userName))
             this.$emit('select', { selected, params: this.params })
             this.$emit('select', { selected, params: this.params })
             this.$emit('close')
             this.$emit('close')
         }
         }
@@ -104,14 +108,17 @@ export default {
             align-items: center;
             align-items: center;
             flex-direction: column;
             flex-direction: column;
             height: 200px;
             height: 200px;
-            overflow-y: auto;
+            overflow-y: scroll;
             .shift-item {
             .shift-item {
                 padding: 8px 12px;
                 padding: 8px 12px;
                 cursor: pointer;
                 cursor: pointer;
                 margin: 0;
                 margin: 0;
+                height: 35px;
                 // width: calc(100% - 24px);
                 // width: calc(100% - 24px);
                 width: 100px;
                 width: 100px;
                 text-align: left;
                 text-align: left;
+                //flex-shrink: 0;
+                min-height: 15px;
             }
             }
             .shift-actived {
             .shift-actived {
                 background-color: #007BFF;
                 background-color: #007BFF;

+ 107 - 13
src/views/business/​scheduleManage/edit.vue

@@ -279,7 +279,12 @@
                 </el-popover>
                 </el-popover>
                 <div ref="scheduleContent" class="schedule-content">
                 <div ref="scheduleContent" class="schedule-content">
                     <div ref="sidebar" class="ordinate" :style="{ top: topOffset + 'px' }">
                     <div ref="sidebar" class="ordinate" :style="{ top: topOffset + 'px' }">
-                        <div v-for="item in ordinateList" :key="item.value" class="ordinate-item">
+                        <div
+                            v-for="item in ordinateList"
+                            :key="item.value"
+                            class="ordinate-item"
+                            :style="{ color: viewType === 'users' ? '#606266' : `${item.color}`, height:viewType === 'users' ? '60px' : '130px' }"
+                        >
                             {{ item.label }}
                             {{ item.label }}
                         </div>
                         </div>
                     </div>
                     </div>
@@ -292,6 +297,7 @@
                                 :key="cIndex"
                                 :key="cIndex"
                                 ref="shiftItem"
                                 ref="shiftItem"
                                 class="shift-item"
                                 class="shift-item"
+                                :style="{ display: viewType === 'users' ? 'grid' : 'flex', height:viewType === 'users' ? '59px' : '129px'}"
                                 @mouseenter="hoveredIndex = `${row.value}-${cIndex}`"
                                 @mouseenter="hoveredIndex = `${row.value}-${cIndex}`"
                                 @mouseleave="hoveredIndex = null"
                                 @mouseleave="hoveredIndex = null"
                                 @click.prevent="handleShiftClick($event, {row, rIndex, column, cIndex})"
                                 @click.prevent="handleShiftClick($event, {row, rIndex, column, cIndex})"
@@ -300,9 +306,9 @@
                                     v-for="(shift, sIndex) in scheduleData[row.value][cIndex]"
                                     v-for="(shift, sIndex) in scheduleData[row.value][cIndex]"
                                     :key="sIndex"
                                     :key="sIndex"
                                     class="shift"
                                     class="shift"
-                                    :style="{ color: `${shift.color}` }"
+                                    :style="{ color: viewType === 'users' ? `${shift.color}` : `${ordinateList[rIndex].color}`}"
                                 >
                                 >
-                                    {{ shift.alias }}
+                                    {{ viewType === 'users'? shift.alias : shift.userName }}
                                     <!-- <div :style="{ color: `${shift.color}` }">{{ shift.alias }}</div> -->
                                     <!-- <div :style="{ color: `${shift.color}` }">{{ shift.alias }}</div> -->
                                 </div>
                                 </div>
                                 <div v-if="hoveredIndex === `${row.value}-${cIndex}` && !readonly" class="overlay">
                                 <div v-if="hoveredIndex === `${row.value}-${cIndex}` && !readonly" class="overlay">
@@ -324,9 +330,10 @@
             />
             />
         </div>
         </div>
         <context-menu
         <context-menu
+            :viewType="viewType"
             :visible.sync="contextMenuVisible"
             :visible.sync="contextMenuVisible"
             :params="shiftParams"
             :params="shiftParams"
-            :shift-list="shiftList"
+            :shift-list="viewType === 'users' ? shiftList : userNameList"
             :position="itemPosition"
             :position="itemPosition"
             :item-data="selectItem"
             :item-data="selectItem"
             :readonly="readonly"
             :readonly="readonly"
@@ -354,6 +361,9 @@ import { previewFile } from '@/api/platform/file/attachment'
 import { mapValues, keyBy } from 'lodash'
 import { mapValues, keyBy } from 'lodash'
 import html2canvas from 'html2canvas'
 import html2canvas from 'html2canvas'
 import ActionUtils from '@/utils/action'
 import ActionUtils from '@/utils/action'
+import Json from '@/business/platform/serv/components/json.vue'
+import color from '@/store/modules/ibps/modules/color'
+import height from '@/mixins/height'
 
 
 export default {
 export default {
     name: 'schedule',
     name: 'schedule',
@@ -420,6 +430,8 @@ export default {
             ],
             ],
             viewType: 'users',
             viewType: 'users',
             scheduleData: {},
             scheduleData: {},
+            responseData: {},
+            userNameList: [],
             scheduleRecord: [],
             scheduleRecord: [],
             leftOffset: '',
             leftOffset: '',
             topOffset: '',
             topOffset: '',
@@ -465,11 +477,19 @@ export default {
     },
     },
     computed: {
     computed: {
         ordinateList () {
         ordinateList () {
-            const { scheduleStaff } = this.formData
-            return this.userList.filter(u => scheduleStaff.includes(u.userId)).map(u => ({
-                label: u.userName,
-                value: u.userId
-            }))
+            if (this.viewType === 'users') {
+                const { scheduleStaff } = this.formData
+                return this.userList.filter(u => scheduleStaff.includes(u.userId)).map(u => ({
+                    label: u.userName,
+                    value: u.userId
+                }))
+            } else {
+                return this.formData.scheduleShift.map(s => ({
+                    label: s.name,
+                    value: s.alias,
+                    color: s.color
+                }))
+            }
         }
         }
         // scheduleData () {
         // scheduleData () {
         //     return mapValues(keyBy(this.ordinateList, 'value'), () => Array.from({ length: this.dateList.length }, () => []))
         //     return mapValues(keyBy(this.ordinateList, 'value'), () => Array.from({ length: this.dateList.length }, () => []))
@@ -550,6 +570,7 @@ export default {
                 const response = await getStaffSchedule({ id: this.pageParams.id })
                 const response = await getStaffSchedule({ id: this.pageParams.id })
                 const { staffScheduleDetailPoList: records, title, endDate, startDate, type, overview, config, status } = response.data
                 const { staffScheduleDetailPoList: records, title, endDate, startDate, type, overview, config, status } = response.data
                 const temp = config ? JSON.parse(config) : {}
                 const temp = config ? JSON.parse(config) : {}
+                this.responseData = response.data
                 console.log('responseData:', response.data)
                 console.log('responseData:', response.data)
                 console.log('configData:', temp)
                 console.log('configData:', temp)
                 this.formData = {
                 this.formData = {
@@ -558,6 +579,7 @@ export default {
                     config: temp.id,
                     config: temp.id,
                     dateRange: [startDate, endDate],
                     dateRange: [startDate, endDate],
                     approver: temp.approver || [],
                     approver: temp.approver || [],
+                    overview: overview,
                     scheduleType: type,
                     scheduleType: type,
                     scheduleRule: temp.scheduleRule || [],
                     scheduleRule: temp.scheduleRule || [],
                     scheduleShift: temp.scheduleShift || [],
                     scheduleShift: temp.scheduleShift || [],
@@ -574,6 +596,10 @@ export default {
                 this.scheduleData = this.transformScheduleData(records, overview, temp)
                 this.scheduleData = this.transformScheduleData(records, overview, temp)
                 console.log('scheduleData', this.scheduleData)
                 console.log('scheduleData', this.scheduleData)
                 this.loading = false
                 this.loading = false
+                this.userNameList = this.ordinateList.map(item => ({ // 存起user对应id和name
+                    userName: item.label,
+                    userId: item.value
+                }))
             }).catch(() => {
             }).catch(() => {
                 this.loading = false
                 this.loading = false
             })
             })
@@ -623,6 +649,58 @@ export default {
             })
             })
             return result
             return result
         },
         },
+        /* 切换ScheduleData为人员排班数据格式(人员排班->班次排班)
+         */
+        transformScheduleDataForShiftsView (data, userList, scheduleShift, overview) {
+            const result = []
+            const temp = overview ? JSON.parse(overview) : {}
+            // 先创建以排班班次为键的空二维数组
+            scheduleShift.forEach(shift => {
+                result[shift.alias] = Array.from({ length: temp.dateCount }, () => [])
+            })
+            // 再次遍历用户列表,填充每个排班班次对应的用户信息
+            userList.forEach(({ userId, userName }) => {
+                data[userId].forEach((day, dayIndex) => {
+                    day.forEach(({ alias }) => {
+                        result[alias][dayIndex].push({
+                            userId,
+                            userName
+                        })
+                    })
+                })
+            })
+            return result
+        },
+        /* 复原ScheduleData为人员排班数据格式(班次排班->人员排班)
+        */
+        reverseForScheduleData (data, userList, scheduleShift, overview) {
+            const result = []
+            // 先创建以userId为键的空二维数组
+            const temp = overview ? JSON.parse(overview) : {}
+            userList.forEach(({ userId }) => {
+                result[userId] = Array.from({ length: temp.dateCount }, () => [])
+            })
+            const scheduleShiftMap = scheduleShift.reduce((acc, item) => {
+                acc[item.alias] = item
+                return acc
+            }, {})
+
+            // 遍历转换后的数据格式中的每个排班班次
+            Object.keys(data).forEach(alias => {
+                const days = data[alias]
+                const aliasData = scheduleShiftMap[alias]
+                // 遍历每一天的数据
+                days.forEach((users, dayIndex) => {
+                    // 遍历当天该班次上的每个用户
+                    users.forEach(({ userId }) => {
+                        // 将当天该用户在该班次的信息添加到对应的用户数据中
+                        result[userId][dayIndex].push(aliasData)
+                    })
+                })
+            })
+
+            return result
+        },
         handleConfigChange (val) {
         handleConfigChange (val) {
             const temp = this.configList.find(i => i.id === val)
             const temp = this.configList.find(i => i.id === val)
             this.formData = {
             this.formData = {
@@ -666,8 +744,18 @@ export default {
             return dates
             return dates
         },
         },
         changeView () {
         changeView () {
-            console.log('changeView')
-            debugger
+            // 关闭可能存在的弹出框(如果有的话),确保视图切换时界面整洁
+            this.$refs.popover.showPopper = false
+            this.handleClose()
+            // 判断当前视图类型,如果是'users'则切换为'shifts',如果是'shifts'则切换为'users'
+            this.viewType = this.viewType === 'users' ? 'shifts' : 'users'
+            // 重新计算scheduleData的结构以适应新视图
+            if (this.viewType === 'users') {
+                this.scheduleData = this.reverseForScheduleData(this.scheduleData, this.userNameList, this.formData.scheduleShift, this.formData.overview)
+            } else {
+                this.scheduleData = this.transformScheduleDataForShiftsView(this.scheduleData, this.userNameList, this.formData.scheduleShift, this.formData.overview)
+            }
+            console.log('changeView', this.scheduleData)
         },
         },
         handleShiftClick (event, { row, rIndex, column, cIndex }) {
         handleShiftClick (event, { row, rIndex, column, cIndex }) {
             this.selectItem = []
             this.selectItem = []
@@ -815,6 +903,9 @@ export default {
         //     return result
         //     return result
         // },
         // },
         dealData (data) {
         dealData (data) {
+            if (this.viewType === 'shifts') { // 班次排班需还原数据
+                data = this.reverseForScheduleData(this.scheduleData, this.userNameList, this.formData.scheduleShift, this.formData.overview)
+            }
             var dateCount = 0
             var dateCount = 0
             const result = Object.entries(data).map(([userId, days]) => {
             const result = Object.entries(data).map(([userId, days]) => {
                 const userObj = { userId, statistics: {}}
                 const userObj = { userId, statistics: {}}
@@ -842,6 +933,7 @@ export default {
                     statistics: JSON.stringify(userObj.statistics)
                     statistics: JSON.stringify(userObj.statistics)
                 }
                 }
             })
             })
+
             console.log(result)
             console.log(result)
 
 
             // 统计所有userId中各个alias的平均出现次数
             // 统计所有userId中各个alias的平均出现次数
@@ -1013,6 +1105,8 @@ export default {
             this.shiftForm.current = date
             this.shiftForm.current = date
             this.popoverReference = e.target
             this.popoverReference = e.target
             this.$refs.popover.showPopper = true
             this.$refs.popover.showPopper = true
+            // 先把编辑菜单关闭
+            this.handleClose()
 
 
             // 手动更改弹窗位置
             // 手动更改弹窗位置
             setTimeout(() => {
             setTimeout(() => {
@@ -1250,11 +1344,11 @@ export default {
                             border-bottom: none;
                             border-bottom: none;
                             border-right: none;
                             border-right: none;
                             cursor: context-menu;
                             cursor: context-menu;
-
+                            /*filter: saturate(0.8);*/
                             display: flex;
                             display: flex;
                             flex-direction: column;
                             flex-direction: column;
                             justify-content: center;
                             justify-content: center;
-                            align-items: center;
+                            align-items: center ;
                             .shift {
                             .shift {
                                 text-align: center;
                                 text-align: center;
                             }
                             }