jabin 3 سال پیش
والد
کامیت
8e9c10fb14

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 15407 - 1
package-lock.json


+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "core-js": "^3.25.0",
     "countup.js": "^2.3.2",
     "cropperjs": "^1.5.12",
+    "dayjs": "^1.11.8",
     "echarts": "^5.3.3",
     "echarts-wordcloud": "^2.0.0",
     "ele-admin": "^1.11.2",

+ 9 - 1
src/api/workforceManagement/classes.js

@@ -1,5 +1,5 @@
 import request from '@/utils/request';
-// 保存班
+// 保存班
 export async function saveteamtime(data) {
     const res = await request.post(`/main/teamtime/save`, data);
     if (res.data.code == 0) {
@@ -27,4 +27,12 @@ export async function deleteteamtime(data) {
         return res.data.message;
     }
     return Promise.reject(new Error(res.data.message));
+}
+// 修改班组
+export async function updateteamtime(data) {
+    const res = await request.put(`/main/teamtime/update`, data);
+    if (res.data.code == 0) {
+        return res.data.message;
+    }
+    return Promise.reject(new Error(res.data.message));
 }

+ 64 - 0
src/api/workforceManagement/schedule.js

@@ -0,0 +1,64 @@
+import request from '@/utils/request';
+// 获取班次
+export async function getpullDown() {
+    const res = await request.get(`/main/teamtime/pullDown`, {});
+    if (res.data.code == 0) {
+        return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
+}
+// 假保存
+export async function teamqueuesave(data) {
+    const res = await request.post(`/main/teamqueue/save`, data);
+    if (res.data.code == 0) {
+        return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
+}
+// 保存
+export async function teamqueuedetailSave(data) {
+    const res = await request.post(`/main/teamqueuedetail/save`, data);
+    if (res.data.code == 0) {
+        return res.data.message;
+    }
+    return Promise.reject(new Error(res.data.message));
+}
+// 修改
+export async function teamqueuedetailupdate(data) {
+    const res = await request.put(`/main/teamqueuedetail/update`, data);
+    if (res.data.code == 0) {
+        return res.data.message;
+    }
+    return Promise.reject(new Error(res.data.message));
+}
+// 列表
+export async function teamqueuepage(data) {
+    const res = await request.get(`/main/teamqueue/page`, {
+        params: data
+    });
+    console.log(res.data.code == 0)
+    if (res.data.code == 0) {
+        return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
+}
+// 删除
+export async function deleteteamtime(data) {
+    const res = await request.delete(`/main/teamqueue/delete`, {
+        data
+    });
+    if (res.data.code == 0) {
+        return res.data.message;
+    }
+    return Promise.reject(new Error(res.data.message));
+}
+// 排班详情
+export async function getByIdteamqueue(id) {
+    const res = await request.get(`/main/teamqueue/getById/${id}`, {
+
+    });
+    if (res.data.code == 0) {
+        return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
+}

+ 3 - 1
src/store/index.js

@@ -7,6 +7,7 @@ import getters from './getters';
 import dict from './modules/dict';
 import user from './modules/user';
 import theme from './modules/theme';
+import team from './modules/team';
 import createPersistedState from 'vuex-persistedstate';
 
 Vue.use(Vuex);
@@ -18,7 +19,8 @@ export default new Vuex.Store({
   modules: {
     dict,
     user,
-    theme
+    theme,
+    team
   },
   getters,
   plugins: [

+ 12 - 0
src/store/modules/team.js

@@ -0,0 +1,12 @@
+export default {
+    namespaced: true,
+    state: {
+
+        addInfo: null,
+    },
+    mutations: {
+        setAddInfo(state, info) {
+            state.addInfo = info;
+        },
+    }
+};

+ 21 - 6
src/views/workforceManagement/classes/components/edit.vue

@@ -46,7 +46,7 @@
               prop="totalWorkHour"
               style="margin-bottom: 22px"
             >
-              {{ form.totalWorkHour }}
+              {{ form.totalWorkHour }}
             </el-form-item>
           </el-col>
         </el-row>
@@ -69,7 +69,10 @@
 </template>
 
 <script>
-import { saveteamtime } from '@/api/workforceManagement/classes';
+import {
+  saveteamtime,
+  updateteamtime
+} from '@/api/workforceManagement/classes';
 import timeTable from './timeTable.vue';
 export default {
   components: {
@@ -109,7 +112,7 @@ export default {
           return '新增班次';
           break;
         case 'edit':
-          return '新增班次';
+          return '修改班次';
           break;
         default:
           break;
@@ -129,7 +132,9 @@ export default {
         }
         this.$nextTick(() => {
           // 反显时间段
-          this.$refs.timeTable.form.datasource = row.details;
+          if (row.details) {
+            this.$refs.timeTable.form.datasource = row.details;
+          }
         });
       }
     },
@@ -146,8 +151,18 @@ export default {
         this.$refs.timeTable.verification().then((res) => {
           this.loading = true;
           this.form.details = this.$refs.timeTable.form.datasource;
-          console.log(this.form);
-          saveteamtime(this.form)
+          let fn;
+          switch (this.type) {
+            case 'add':
+              fn = saveteamtime;
+              break;
+            case 'edit':
+              fn = updateteamtime;
+              break;
+            default:
+              break;
+          }
+          fn(this.form)
             .then((msg) => {
               this.loading = false;
               this.$message.success(msg);

+ 44 - 20
src/views/workforceManagement/classes/components/timeTable.vue

@@ -48,9 +48,7 @@
             v-model="scope.row.startTime"
             format="HH:mm"
             value-format="HH:mm:ss"
-            :picker-options="{
-              selectableRange: setStartTime(scope)
-            }"
+            @change="changeStartTime"
           >
           </el-time-picker>
         </el-form-item>
@@ -74,6 +72,7 @@
             :picker-options="{
               selectableRange: setEndTime(scope)
             }"
+            @change="changeEndTime"
           >
           </el-time-picker>
         </el-form-item>
@@ -115,7 +114,7 @@
 export default {
   data() {
     const defaultForm = {
-      id: null,
+      key: null,
       endTime: '',
       isFirst: 0,
       name: '',
@@ -175,7 +174,7 @@ export default {
   methods: {
     remove(row) {
       console.log(row);
-      let index = this.form.datasource.findIndex((n) => n.id == row.id);
+      let index = this.form.datasource.findIndex((n) => n.key == row.key);
       if (index !== -1) {
         this.form.datasource.splice(index, 1);
         this.setSort();
@@ -188,13 +187,13 @@ export default {
     // 重新排序
     setSort() {
       this.form.datasource.forEach((n, index) => {
-        n.id = index + 1;
+        n.key = index + 1;
       });
     },
     // 添加
     handlAdd() {
       let item = JSON.parse(JSON.stringify(this.defaultForm));
-      item.id = this.form.datasource.length + 1;
+      item.key = this.form.datasource.length + 1;
       this.form.datasource.push(item);
     },
     // 设为首班
@@ -204,17 +203,6 @@ export default {
       });
       row.isFirst = 1;
     },
-    setStartTime(scope) {
-      if (scope.$index > 0) {
-        let Pitem = this.form.datasource[scope.$index - 1];
-        if (Pitem.endTime) {
-          return `${Pitem.endTime} - 23:59:59`;
-        } else {
-          return '00:00:00 - 23:59:59';
-        }
-      }
-      return '00:00:00 - 23:59:59';
-    },
     setEndTime(scope) {
       if (scope.row.startTime) {
         return `${scope.row.startTime} - 23:59:59`;
@@ -232,10 +220,10 @@ export default {
       }
       var reDate = /\d{4}-\d{1,2}-\d{1,2} /;
       s1 = new Date(
-        (reDate.test(s1) ? s1 : '2018-1-1 ' + s1).replace(/-/g, '/')
+        (reDate.test(s1) ? s1 : '1970-01-01 ' + s1).replace(/-/g, '/')
       );
       s2 = new Date(
-        (reDate.test(s2) ? s2 : '2018-1-1 ' + s2).replace(/-/g, '/')
+        (reDate.test(s2) ? s2 : '1970-01-01 ' + s2).replace(/-/g, '/')
       );
       var ms = s2.getTime() - s1.getTime();
       if (ms < 0) return 0;
@@ -259,9 +247,45 @@ export default {
             reject();
             return false;
           }
+          if (this.isOverlap()) {
+            reject();
+            return false;
+          }
           resolve();
         });
       });
+    },
+    // 判断时间段是否重叠
+    isOverlap() {
+      let timeRanges = JSON.parse(JSON.stringify(this.form.datasource));
+
+      // 按开始时间排序
+      timeRanges.sort(function (a, b) {
+        return (
+          new Date(`1970-01-01 ${a.startTime}`) -
+          new Date(`1970-01-01 ${b.startTime}`)
+        );
+      });
+      console.log(timeRanges);
+      for (var i = 0; i < timeRanges.length - 1; i++) {
+        let endTime = timeRanges[i].endTime;
+        let NstartTime = timeRanges[i + 1].startTime;
+        if (endTime > NstartTime) {
+          // 出现重叠
+          this.$message.error(
+            `上班时间${NstartTime}与下班时间${endTime}存在重叠`
+          );
+          return true;
+        }
+      }
+
+      return false;
+    },
+    changeStartTime(val) {
+      this.isOverlap();
+    },
+    changeEndTime(val) {
+      this.isOverlap();
     }
   }
 };

+ 386 - 0
src/views/workforceManagement/schedule/components/ManagementTable.vue

@@ -0,0 +1,386 @@
+<template>
+  <ele-pro-table
+    ref="table"
+    :needPage="false"
+    :columns="columns"
+    :datasource="tableData"
+    @cell-click="cellClick"
+    @row-click="rowClick"
+    @header-click="headerClick"
+    cache-key="systemRoleTable"
+  >
+    <!-- 表头工具栏 -->
+    <template v-slot:toolbar>
+      <el-form class="ele-form-search">
+        <el-row :gutter="15">
+          <el-col :span="4">
+            <el-form-item style="margin-bottom: 0">
+              <el-input
+                clearable
+                :placeholder="type == 'person' ? '搜索人员' : '搜索班组'"
+                v-model.trim="searchKey"
+                @input="search"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="4">
+            <el-form-item style="margin-bottom: 0">
+              <el-date-picker
+                v-model="time"
+                type="month"
+                @change="timeChange"
+                value-format="yyyy-MM"
+                placeholder="选择月"
+              >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="16">
+            <el-form-item class="btn-wrap" style="margin-bottom: 0">
+              <el-button @click="save">保存</el-button>
+              <el-button @click="rest">重置</el-button>
+              <el-button @click="anbp">{{
+                type == 'person' ? '按班排' : '按人排'
+              }}</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </template>
+    <template v-slot:item="{ row }">
+      {{ row.item.name }}
+    </template>
+    <template v-slot:bcHeader="{ column }">
+      <div v-html="showheaderName(column.label)"></div>
+    </template>
+    <template v-slot:bc="{ column, row }">
+      <div
+        class="tabel-cell-item"
+        :style="`background-color: ${showColor(el)};`"
+        v-for="el in showName(row, column)"
+        :key="el.id"
+      >
+        {{ el.name }}
+      </div>
+    </template>
+  </ele-pro-table>
+</template>
+<script>
+import * as dayjs from 'dayjs';
+import { debounce } from 'throttle-debounce';
+export default {
+  props: ['selectedClasses', 'classesColor'],
+  data() {
+    const columnsDefault = {
+      person: {
+        prop: 'item',
+        label: '姓名',
+        slot: 'item'
+      },
+      team: {
+        prop: 'item',
+        label: '班组',
+        slot: 'item'
+      }
+    };
+    return {
+      type: 'person', // team 班次 person 人员
+      columnsDefault,
+      tableData: [],
+      //按人排数据
+      personData: [],
+      //按班排数据
+      teamData: [],
+      time: '',
+      columns: [],
+      searchKey: '',
+      dict: {
+        week: {
+          0: '周末',
+          1: '周一',
+          2: '周二',
+          3: '周三',
+          4: '周四',
+          5: '周五',
+          6: '周六'
+        }
+      }
+    };
+  },
+  created() {
+    this.search = debounce(500, this.search);
+    this.time = dayjs(new Date()).format('YYYY-MM');
+    this.initColumns();
+  },
+  methods: {
+    // 人员班次数据切换
+    setTableData() {
+      switch (this.type) {
+        case 'person':
+          this.tableData = this.personData;
+          break;
+        case 'team':
+          this.tableData = this.teamData;
+          break;
+        default:
+          break;
+      }
+    },
+    // 初始化columns
+    initColumns() {
+      let Month = dayjs(this.time).month() + 1;
+      let MonthNum = dayjs(this.time).daysInMonth();
+      let columns = [];
+      for (let index = 1; index <= MonthNum; index++) {
+        let week = dayjs(`${this.time}-${index}`).day();
+        columns.push({
+          prop: `${this.time}-${this.setNUm(index)} 00:00:00`,
+          label: `${Month}-${index}/${week}`,
+          slot: 'bc',
+          headerSlot: 'bcHeader',
+          width: 60
+        });
+      }
+      this.columns = [];
+      switch (this.type) {
+        case 'person':
+          this.columns.push(this.columnsDefault.person);
+          break;
+        case 'team':
+          this.columns.push(this.columnsDefault.team);
+          break;
+        default:
+          break;
+      }
+
+      this.columns = [].concat(this.columns, columns);
+    },
+    // 设置数据
+    setData(personData, teamData) {
+      this.personData = personData;
+      this.teamData = teamData;
+      this.setTableData();
+    },
+    showName(row, column) {
+      let list = row[column.property];
+      if (list) {
+        list.forEach((n) => {
+          n.name = n.name.slice(0, 4);
+        });
+        return list;
+      } else {
+        return [];
+      }
+    },
+    showheaderName(label) {
+      let list = label.split('/');
+      let week = this.dict.week[list[1]];
+      return `${list[0]}</br>${week}`;
+    },
+    // 设置颜色
+    showColor(item) {
+      return this.classesColor[item.id];
+    },
+    // 单元格点击
+    cellClick(row, column) {
+      const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
+      if (column.property !== 'item' && selectedClasses.length > 0) {
+        if (selectedClasses[0].id == 'clear') {
+          this.$delete(row, column.property);
+        } else {
+          this.$set(row, column.property, selectedClasses);
+        }
+        // 按班排同步人员
+        if (this.type == 'team') {
+          this.SyncCellClick(row, column);
+        }
+      }
+    },
+    // 行点击
+    rowClick(row, column) {
+      const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
+      if (column.property == 'item' && selectedClasses.length > 0) {
+        if (selectedClasses[0].id == 'clear') {
+          this.columns.forEach((n) => {
+            if (n.prop !== 'item') {
+              this.$delete(row, n.prop);
+            }
+          });
+        } else {
+          this.columns.forEach((n) => {
+            if (n.prop !== 'item') {
+              this.$set(row, n.prop, selectedClasses);
+            }
+          });
+        }
+        // 按班排同步人员
+        if (this.type == 'team') {
+          this.SyncRowClick(row, column);
+        }
+      }
+    },
+    // 列点击
+    headerClick(column) {
+      const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
+      if (column.property !== 'item' && selectedClasses.length > 0) {
+        if (selectedClasses[0].id == 'clear') {
+          this.tableData.forEach((n) => {
+            this.$delete(n, column.property);
+          });
+        } else {
+          this.tableData.forEach((n) => {
+            this.$set(n, column.property, selectedClasses);
+          });
+        }
+        // 按班排同步人员
+        if (this.type == 'team') {
+          this.SyncHeaderClick(column);
+        }
+      }
+    },
+    // 按班排同步人员-单元格点击
+    SyncCellClick(row, column) {
+      const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
+      let Person = this.getid_Person(row.item.teamId);
+      if (selectedClasses[0].id == 'clear') {
+        Person.forEach((n) => {
+          this.$delete(n, column.property);
+        });
+      } else {
+        Person.forEach((n) => {
+          this.$set(n, column.property, selectedClasses);
+        });
+      }
+    },
+    // 按班排同步人员-行点击
+    SyncRowClick(row, column) {
+      const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
+      let Person = this.getid_Person(row.item.teamId);
+      if (selectedClasses[0].id == 'clear') {
+        Person.forEach((n) => {
+          this.columns.forEach((nl) => {
+            if (nl.prop !== 'item') {
+              this.$delete(n, nl.prop);
+            }
+          });
+        });
+      } else {
+        Person.forEach((n) => {
+          this.columns.forEach((nl) => {
+            if (nl.prop !== 'item') {
+              this.$set(n, nl.prop, selectedClasses);
+            }
+          });
+        });
+      }
+    },
+    // 按班排同步人员-列点击
+    SyncHeaderClick(column) {
+      const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
+      if (selectedClasses[0].id == 'clear') {
+        this.personData.forEach((n) => {
+          this.$delete(n, column.property);
+        });
+      } else {
+        this.personData.forEach((n) => {
+          this.$set(n, column.property, selectedClasses);
+        });
+      }
+    },
+    // 根据班组id查询人员
+    getid_Person(id) {
+      let list = this.personData.filter((n) => {
+        return n.item.teamId == id;
+      });
+      return list;
+    },
+    // 保存
+    save() {
+      this.$emit('save');
+    },
+    // 重置
+    rest() {
+      this.$emit('rest');
+    },
+    // 按人/班排
+    anbp() {
+      this.type = this.type == 'person' ? 'team' : 'person';
+      this.initColumns();
+      this.setTableData();
+    },
+    // 切换按班排班
+    changanbp() {
+      this.type = 'team';
+      this.initColumns();
+      this.setTableData();
+    },
+    // 选择时间
+    timeChange() {
+      this.initColumns();
+    },
+    // 补零
+    setNUm(num) {
+      let length = 2;
+      return (num / Math.pow(10, length)).toFixed(length).substr(2);
+    },
+    // 搜索
+    search(val) {
+      switch (this.type) {
+        case 'person':
+          if (val !== '') {
+            setTimeout(() => {
+              this.tableData = this.personData.filter((n) => {
+                return (
+                  n.item.name.toLowerCase().indexOf(val.toLowerCase()) > -1
+                );
+              });
+            }, 200);
+          } else {
+            this.tableData = this.personData;
+          }
+          break;
+        case 'team':
+          if (val !== '') {
+            setTimeout(() => {
+              this.tableData = this.teamData.filter((n) => {
+                return (
+                  n.item.name.toLowerCase().indexOf(val.toLowerCase()) > -1
+                );
+              });
+            }, 200);
+          } else {
+            this.tableData = this.teamData;
+          }
+          break;
+        default:
+          break;
+      }
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+:deep(.el-table .el-table__cell) {
+  cursor: pointer;
+  height: 60px;
+}
+.tabel-cell-item {
+  color: #fff;
+  height: 60px;
+  overflow: hidden;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 15px !important;
+}
+:deep(.el-table td.el-table__cell) {
+  padding: 0;
+  div {
+    padding: 0;
+  }
+}
+.btn-wrap {
+  text-align: right;
+  padding-right: 20px;
+}
+</style>

+ 120 - 0
src/views/workforceManagement/schedule/components/SchedulingGroup.vue

@@ -0,0 +1,120 @@
+<template>
+  <el-dialog
+    class="ele-dialog-form"
+    :title="'排班组'"
+    :visible.sync="visible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    width="500px"
+  >
+    <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+      <el-form-item label="排班组名称" prop="name" style="margin-bottom: 22px">
+        <el-input v-model="form.name"></el-input>
+      </el-form-item>
+      <el-form-item label="班组" prop="teamIds" style="margin-bottom: 22px">
+        <el-select
+          v-model="form.teamIds"
+          placeholder="请选择"
+          style="width: 100%"
+          multiple
+        >
+          <el-option
+            v-for="item in options"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <template v-slot:footer>
+      <el-button @click="handleClose">取消</el-button>
+      <el-button type="primary" :loading="loading" @click="save">
+        确定
+      </el-button>
+    </template>
+  </el-dialog>
+</template>
+  
+  <script>
+import { getteampage } from '@/api/workforceManagement/team';
+import { teamqueuesave } from '@/api/workforceManagement/schedule';
+export default {
+  data() {
+    const defaultForm = {
+      name: '',
+      teamIds: []
+    };
+    return {
+      defaultForm,
+      // 表单数据
+      form: { ...defaultForm },
+      // 表单验证规则
+      rules: {
+        name: [{ required: true, message: '请输入', trigger: 'blur' }],
+        teamIds: [{ required: true, message: '请输入', trigger: 'change' }]
+      },
+      visible: false,
+      loading: false,
+      options: []
+    };
+  },
+  methods: {
+    open() {
+      this.visible = true;
+      this.getteampage();
+    },
+    /* 保存编辑 */
+    save() {
+      this.$refs.form.validate((valid) => {
+        if (!valid) {
+          return false;
+        }
+        this.loading = true;
+        teamqueuesave(this.form)
+          .then((data) => {
+            this.handleClose();
+            this.$store.commit('team/setAddInfo', data);
+            this.$router.push({
+              path: '/workforceManagement/schedule/detail',
+              query: {
+                type: 'add'
+              }
+            });
+          })
+          .catch((e) => {
+            this.$message.error(e.message);
+          })
+          .finally(() => {
+            this.loading = false;
+          });
+      });
+    },
+    // 重置表单
+    restForm() {
+      this.$refs.form.clearValidate();
+      this.form = { ...this.defaultForm };
+    },
+    handleClose() {
+      this.restForm();
+      this.visible = false;
+    },
+    getteampage() {
+      getteampage().then((res) => {
+        this.options = res.list;
+      });
+    }
+  }
+};
+</script>
+  <style lang="scss" scoped>
+.location-warp {
+  display: flex;
+  .detail {
+    margin-left: 10px;
+  }
+}
+</style>
+  

+ 481 - 0
src/views/workforceManagement/schedule/detail.vue

@@ -0,0 +1,481 @@
+<template>
+  <div class="ele-body">
+    <el-form ref="form" :model="form" :rules="rules">
+      <el-card shadow="never">
+        <template v-slot:header>
+          <div class="top-search-group">
+            <el-input
+              placeholder="搜索班次"
+              v-model="form.bc"
+              clearable
+              @input="search"
+            />
+            <el-button type="primary">搜索</el-button>
+          </div>
+        </template>
+        <el-form-item label="可选班次:" prop="code" style="margin-bottom: 22px">
+          <div class="bc-warp">
+            <div
+              class="item"
+              @click="handlselected(item)"
+              :style="`background-color:${classesColor[item.id]}`"
+              v-for="item in showClassesList"
+              :key="item.id"
+              >{{ item.name }}</div
+            >
+            <div
+              class="item"
+              @click="handlselected(item)"
+              :style="`background-color:${classesColor[item.id]}`"
+              v-for="item in defaultbtn"
+              :key="item.id"
+              >{{ item.name }}</div
+            >
+          </div>
+        </el-form-item>
+        <el-form-item label="已选班次:" prop="code" style="margin-bottom: 22px">
+          <div class="bc-warp">
+            <el-tag
+              v-for="tag in selectedClasses"
+              class="tag"
+              :style="`background-color:${classesColor[tag.id]}`"
+              :key="tag.name"
+              closable
+              :type="tag.id"
+              @close="handleClose(tag)"
+            >
+              {{ tag.name }}
+            </el-tag>
+          </div>
+        </el-form-item>
+      </el-card>
+      <el-card shadow="never">
+        <ManagementTable
+          ref="ManagementTable"
+          :classesColor="classesColor"
+          :selectedClasses="selectedClasses"
+          @save="save"
+          @rest="rest"
+        ></ManagementTable>
+      </el-card>
+    </el-form>
+  </div>
+</template>
+<script>
+import {
+  getpullDown,
+  teamqueuedetailSave,
+  getByIdteamqueue,
+  teamqueuedetailupdate
+} from '@/api/workforceManagement/schedule';
+import ManagementTable from './components/ManagementTable.vue';
+import { finishPageTab } from '@/utils/page-tab-util';
+import { debounce } from 'throttle-debounce';
+export default {
+  components: {
+    ManagementTable
+  },
+  data() {
+    const defaultForm = {
+      bc: '',
+      checked_bc: ''
+    };
+    return {
+      defaultForm,
+      // 表单数据
+      form: { ...defaultForm },
+      // 表单验证规则
+      rules: {},
+      type: '', // add/edit
+      loading: false,
+      colorList: [
+        '#fb6f7b',
+        '#f59a23',
+        '#4672ca',
+        '#2196f3',
+        '#00bcd4',
+        '#009688',
+
+        '#fb6f7b',
+        '#f59a23',
+        '#4672ca',
+        '#2196f3',
+        '#00bcd4',
+        '#009688'
+      ],
+      showClassesList: [],
+      classesList: [],
+      defaultbtn: [
+        {
+          name: '休息',
+          id: '1'
+        },
+        {
+          name: '清除单元格',
+          id: 'clear'
+        }
+      ],
+      selectedClasses: [],
+      classesColor: {
+        1: '#979d9d',
+        clear: '#979d9d'
+      }
+    };
+  },
+  computed: {
+    title() {
+      switch (this.type) {
+        case 'add':
+          return '排班';
+          break;
+        case 'edit':
+          return '排班';
+          break;
+        default:
+          break;
+      }
+    }
+  },
+  async created() {
+    this.search = debounce(500, this.search);
+    this.init();
+    await this.getBc();
+    this.configColor();
+  },
+  methods: {
+    // 初始化数据
+    init() {
+      if (this.$route.query.type) {
+        this.type = this.$route.query.type;
+        if (this.type == 'add') {
+          let addInfo = this.$store.state.team.addInfo;
+          if (addInfo) {
+            // 人员数据
+            let personDetails = addInfo.personDetails.map((n) => {
+              return {
+                item: {
+                  name: n.userName,
+                  ...n
+                }
+              };
+            });
+            // 班组数据
+            let teamDetails = addInfo.teamDetails.map((n) => {
+              return {
+                item: {
+                  name: n.teamName,
+                  ...n
+                }
+              };
+            });
+            this.$nextTick(() => {
+              this.$refs.ManagementTable.setData(personDetails, teamDetails);
+            });
+          }
+        } else if (this.type == 'edit') {
+          // 按班排班
+          let isSchedule = this.$route.query.isSchedule;
+          if (isSchedule == '1') {
+            this.$nextTick(() => {
+              this.$refs.ManagementTable.changanbp();
+            });
+          }
+          this.getByIdteamqueue(this.$route.query.id);
+        }
+      }
+    },
+    /* 保存 */
+    save() {
+      switch (this.type) {
+        case 'add':
+          this.add();
+          break;
+        case 'edit':
+          this.update();
+          break;
+        default:
+          break;
+      }
+    },
+    // 修改
+    update() {
+      // 源数据
+      let personData = this.$refs.ManagementTable.personData;
+      let teamData = this.$refs.ManagementTable.teamData;
+
+      let personDetails = [];
+      let teamDetails = [];
+      // 处理人员数据
+      personData.forEach((n) => {
+        // 时间数据
+        let teamQueueTime = [];
+        for (const [key, value] of Object.entries(n)) {
+          if (key !== 'item') {
+            teamQueueTime.push({
+              date: key,
+              teamTimeSimple: value.map((el) => {
+                return {
+                  id: el.id
+                };
+              })
+            });
+          }
+        }
+
+        personDetails.push({
+          id: n.item.id,
+          userId: n.item.userId,
+          type: n.item.type,
+          teamId: n.item.teamId,
+          teamQueueTime
+        });
+      });
+      // 处理班组数据
+      teamData.forEach((n) => {
+        let teamQueueTime = [];
+        for (const [key, value] of Object.entries(n)) {
+          if (key !== 'item') {
+            teamQueueTime.push({
+              date: key,
+              teamTimeSimple: value.map((el) => {
+                return {
+                  id: el.id
+                };
+              })
+            });
+          }
+        }
+        teamDetails.push({
+          id: n.item.id,
+          type: n.item.type,
+          teamId: n.item.teamId,
+          teamQueueTime
+        });
+      });
+      let par = {
+        id: this.$route.query.id,
+        personDetails,
+        teamDetails
+      };
+      teamqueuedetailupdate(par).then((msg) => {
+        this.$message.success(msg);
+        this.rest();
+      });
+    },
+    // 新增
+    add() {
+      let addInfo = this.$store.state.team.addInfo;
+      // 源数据
+      let personData = this.$refs.ManagementTable.personData;
+      let teamData = this.$refs.ManagementTable.teamData;
+
+      let personDetails = [];
+      let teamDetails = [];
+      // 处理人员数据
+      personData.forEach((n) => {
+        // 时间数据
+        let teamQueueTime = [];
+        for (const [key, value] of Object.entries(n)) {
+          if (key !== 'item') {
+            teamQueueTime.push({
+              date: key,
+              teamTimeSimple: value.map((el) => {
+                return {
+                  id: el.id
+                };
+              })
+            });
+          }
+        }
+
+        personDetails.push({
+          userId: n.item.userId,
+          type: n.item.type,
+          teamId: n.item.teamId,
+          teamQueueTime
+        });
+      });
+      // 处理班组数据
+      teamData.forEach((n) => {
+        let teamQueueTime = [];
+        for (const [key, value] of Object.entries(n)) {
+          if (key !== 'item') {
+            teamQueueTime.push({
+              date: key,
+              teamTimeSimple: value.map((el) => {
+                return {
+                  id: el.id
+                };
+              })
+            });
+          }
+        }
+        teamDetails.push({
+          type: n.item.type,
+          teamId: n.item.teamId,
+          teamQueueTime
+        });
+      });
+      let par = {
+        name: addInfo.name,
+        totalPersonNumber: addInfo.totalPersonNumber,
+        personDetails,
+        teamDetails
+      };
+      teamqueuedetailSave(par).then((msg) => {
+        this.$message.success(msg);
+        finishPageTab();
+      });
+    },
+    // 重置
+    rest() {
+      this.getByIdteamqueue(this.$route.query.id);
+    },
+    // 配置颜色
+    configColor() {
+      this.classesList.forEach((element, index) => {
+        this.$set(this.classesColor, element.id, this.colorList[index]);
+      });
+    },
+    handleClose() {
+      this.visible = false;
+    },
+    handlselected(val) {
+      if (val.id == '1' || val.id == 'clear') {
+        this.selectedClasses = [val];
+      } else {
+        let result = this.selectedClasses.find((n) => {
+          return ['1', 'clear'].includes(n.id);
+        });
+        if (result) {
+          this.selectedClasses = [];
+        }
+        this.selectedClasses.push(val);
+      }
+      // 去重
+      this.selectedClasses = Array.from(new Set(this.selectedClasses));
+    },
+    // 删除标签
+    handleClose(tag) {
+      this.selectedClasses.splice(this.selectedClasses.indexOf(tag), 1);
+    },
+    // 获取班次
+    getBc() {
+      return getpullDown().then((res) => {
+        this.classesList = res.map((n) => {
+          return {
+            id: n.id,
+            name: `${n.name}(${n.startTime.slice(0, 5)}-${n.endTime.slice(
+              0,
+              5
+            )})`
+          };
+        });
+        this.showClassesList = this.classesList;
+      });
+    },
+    // 搜索
+    search(val) {
+      if (val !== '') {
+        this.showClassesList = this.classesList.filter((n) => {
+          return n.name.toLowerCase().indexOf(val.toLowerCase()) > -1;
+        });
+      } else {
+        this.showClassesList = this.classesList;
+      }
+    },
+    // 获取排班详情
+    getByIdteamqueue(id) {
+      getByIdteamqueue(id).then((res) => {
+        // 回显数据
+        //人员数据
+        let personDetails = res.personDetails.map((n) => {
+          let item = {
+            name: n.userName,
+            ...n
+          };
+          delete item.teamQueueTime;
+          let teamQueueTime = {};
+          if (n.teamQueueTime) {
+            n.teamQueueTime.forEach((el) => {
+              teamQueueTime[el.date] = el.teamTimeSimple;
+            });
+          }
+
+          return {
+            item,
+            ...teamQueueTime
+          };
+        });
+        // 班组数据
+        let teamDetails = res.teamDetails.map((n) => {
+          let item = {
+            name: n.teamName,
+            ...n
+          };
+          delete item.teamQueueTime;
+          let teamQueueTime = {};
+          if (n.teamQueueTime) {
+            n.teamQueueTime.forEach((el) => {
+              teamQueueTime[el.date] = el.teamTimeSimple;
+            });
+          }
+
+          return {
+            item,
+            ...teamQueueTime
+          };
+        });
+        this.$nextTick(() => {
+          this.$refs.ManagementTable.setData(personDetails, teamDetails);
+        });
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.location-warp {
+  display: flex;
+  .detail {
+    margin-left: 10px;
+  }
+}
+.top-search-group {
+  max-width: 400px;
+  display: flex;
+
+  :deep(.el-input input) {
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+    border-right-width: 0;
+  }
+
+  .el-button {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+  }
+}
+.bc-warp {
+  display: flex;
+  .item {
+    height: 34px;
+    padding: 0 10px;
+    color: #fff;
+    border-radius: 4px;
+    cursor: pointer;
+  }
+  .item + .item {
+    margin-left: 10px;
+  }
+  .tag {
+    color: #fff;
+    height: 34px;
+    border: none;
+    line-height: 34px;
+    :deep(.el-tag__close) {
+      color: #fff;
+    }
+  }
+}
+</style>

+ 167 - 0
src/views/workforceManagement/schedule/index.vue

@@ -0,0 +1,167 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never">
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        cache-key="systemRoleTable"
+      >
+        <!-- 表头工具栏 -->
+        <template v-slot:toolbar>
+          <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-plus"
+            class="ele-btn-icon"
+            @click="openAdd('add')"
+          >
+            新建
+          </el-button>
+        </template>
+        <!-- 操作列 -->
+        <template v-slot:action="{ row }">
+          <el-link
+            type="primary"
+            :underline="false"
+            icon="el-icon-edit"
+            @click="SchedulingGroupPeople(row)"
+          >
+            按人排班
+          </el-link>
+          <el-link
+            type="primary"
+            :underline="false"
+            icon="el-icon-edit"
+            @click="bpb(row)"
+          >
+            按班排班
+          </el-link>
+          <el-popconfirm
+            class="ele-action"
+            title="确定要删除此角色吗?"
+            @confirm="remove(row)"
+          >
+            <template v-slot:reference>
+              <el-link type="danger" :underline="false" icon="el-icon-delete">
+                删除
+              </el-link>
+            </template>
+          </el-popconfirm>
+        </template>
+      </ele-pro-table>
+    </el-card>
+    <SchedulingGroup ref="SchedulingGroup"></SchedulingGroup>
+  </div>
+</template>
+<script>
+import SchedulingGroup from './components/SchedulingGroup.vue';
+import {
+  teamqueuepage,
+  deleteteamtime
+} from '@/api/workforceManagement/schedule';
+export default {
+  components: {
+    SchedulingGroup
+  },
+  data() {
+    return {
+      columns: [
+        {
+          width: 45,
+          type: 'index',
+          columnKey: 'index',
+          align: 'center'
+        },
+        {
+          prop: 'name',
+          label: '排班组名称'
+        },
+        {
+          label: '总人数',
+          prop: 'totalPersonNumber'
+        },
+        {
+          label: '创建人',
+          prop: 'createUserName'
+        },
+        {
+          label: '创建时间',
+          prop: 'createTime'
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 220,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true
+        }
+      ],
+      dict: {
+        enabled: {
+          1: '生效',
+          0: '未生效'
+        },
+        groupId: []
+      }
+    };
+  },
+  methods: {
+    datasource({ page, where, limit }) {
+      let data = teamqueuepage({
+        ...where,
+        pageNum: page,
+        size: limit
+      });
+      console.log(data);
+      return data;
+    },
+    // 按人排班
+    SchedulingGroupPeople(row) {
+      this.$router.push({
+        path: '/workforceManagement/schedule/detail',
+        query: {
+          type: 'edit',
+          id: row.id
+        }
+      });
+    },
+    // 按班排班
+    bpb(row) {
+      this.$router.push({
+        path: '/workforceManagement/schedule/detail',
+        query: {
+          type: 'edit',
+          id: row.id,
+          isSchedule: '1'
+        }
+      });
+    },
+    // 排版组
+    openAdd() {
+      this.$refs.SchedulingGroup.open();
+    },
+    remove(row) {
+      let par = [row.id];
+      deleteteamtime(par)
+        .then((message) => {
+          this.$message.success(message);
+          this.done();
+        })
+        .catch((e) => {
+          this.$message.error(e.message);
+        });
+    },
+    done() {
+      this.$refs.table.reload({
+        page: 1
+      });
+    },
+    openclass() {
+      this.$refs.setclasses.open();
+    }
+  }
+};
+</script>

+ 5 - 1
src/views/workforceManagement/team/components/edit.vue

@@ -197,7 +197,11 @@ export default {
         }
         // 人员反显
         this.$nextTick(() => {
-          this.$refs.userTable.confirmStaffSelection(row.userVOList);
+          if (row.userVOList) {
+            this.$refs.userTable.confirmStaffSelection(
+              JSON.parse(JSON.stringify(row.userVOList))
+            );
+          }
           // 班组长
           this.$refs.userTable.setLeaderId(row.leaderUserId);
         });

+ 3 - 5
src/views/workforceManagement/team/components/setclasses.vue

@@ -11,7 +11,7 @@
   >
     <el-form ref="form" :model="form" :rules="rules" label-width="100px">
       <el-form-item label="班次" prop="code" style="margin-bottom: 22px">
-        <el-select v-model="form.teamTimeDetailId" placeholder="请选择">
+        <el-select v-model="form.teamTimeId" placeholder="请选择">
           <el-option
             v-for="item in options"
             :key="item.id"
@@ -37,7 +37,7 @@ export default {
   data() {
     const defaultForm = {
       teamIds: [],
-      teamTimeDetailId: ''
+      teamTimeId: ''
     };
     return {
       defaultForm,
@@ -45,9 +45,7 @@ export default {
       form: { ...defaultForm },
       // 表单验证规则
       rules: {
-        teamTimeDetailId: [
-          { required: true, message: '请输入', trigger: 'blur' }
-        ]
+        teamTimeId: [{ required: true, message: '请输入', trigger: 'blur' }]
       },
       visible: false,
       loading: false,

+ 2 - 6
src/views/workforceManagement/team/index.vue

@@ -19,14 +19,14 @@
           >
             新建
           </el-button>
-          <el-button
+          <!-- <el-button
             size="small"
             type="primary"
             class="ele-btn-icon"
             @click="openclass"
           >
             设置班次
-          </el-button>
+          </el-button> -->
         </template>
         <!-- 操作列 -->
         <template v-slot:action="{ row }">
@@ -101,10 +101,6 @@ export default {
           label: '人数',
           prop: 'userNumber'
         },
-        {
-          label: '当前班次',
-          prop: 'teamTimeDetailName'
-        },
         {
           columnKey: 'action',
           label: '操作',

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است