更新班组

This commit is contained in:
2025-10-19 00:38:48 +08:00
parent 6c46083d4a
commit 4e801873b9
23 changed files with 3332 additions and 0 deletions

View File

@@ -0,0 +1,806 @@
<!--
* @Author: zwq
* @Date: 2025-10-13 15:07:24
* @LastEditors: zwq
* @LastEditTime: 2025-10-17 17:01:35
* @Description:
-->
<template>
<div>
<!-- 产线信息-工艺工序圆圈 -->
<div class="circle-container">
<div v-for="(item, index) in dotArr" :key="index" class="circle-wrapper">
<div
class="circle"
:style="{
background: stepNum == index + 1 ? '#0B58FF' : '',
}">
{{ index + 1 }}
</div>
<div
class="circle-text"
:style="{
color: stepNum == index + 1 ? '#0B58FF' : '',
}">
{{ item.name }}
</div>
<!-- 圆点后面的虚线 -->
<div v-if="index < 2" class="connector" />
</div>
</div>
<div v-if="stepNum == 1">
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-position="top"
label-width="80px">
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="计划编号" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入计划编号" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划名称" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入计划名称" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="部门">
<dept-select
style="width: 100%"
ref="deptSelect"
@DeptId="setDeptId"></dept-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="周末休假方式" prop="weekType">
<el-select
style="width: 100%"
v-model="dataForm.weekType"
placeholder="请选择周末休假方式">
<el-option
v-for="item in options1"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="开始时间" prop="startDay">
<el-date-picker
style="width: 100%"
v-model="dataForm.startDay"
type="datetime"
value-format="timestamp"
placeholder="选择日期时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="结束时间" prop="endDay">
<el-date-picker
style="width: 100%"
v-model="dataForm.endDay"
type="datetime"
value-format="timestamp"
placeholder="选择日期时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="倒班方式" prop="shiftType">
<el-select
style="width: 100%"
v-model="dataForm.shiftType"
placeholder="请选择倒班方式">
<el-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="同班次连排" prop="shiftSustainedNum">
<el-input
v-model="dataForm.shiftSustainedNum"
oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
<el-select
style="width: 80px"
v-model="dataForm.shiftSustainedType"
slot="append">
<el-option label="日" :value="1"></el-option>
<el-option label="周" :value="2"></el-option>
<el-option label="月" :value="3"></el-option>
<el-option label="季" :value="4"></el-option>
</el-select>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
clearable
placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div v-if="stepNum == 2">
<small-title style="margin: 16px 0" size="sm" :no-padding="true">
班次
</small-title>
<base-table
:table-props="tableProps1"
:page="1"
:limit="10"
:table-data="tableData1">
<method-btn
v-if="tableBtn1.length"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn1"
@clickBtn="handleClick1" />
</base-table>
<small-title style="margin: 16px 0" size="sm" :no-padding="true">
班组
</small-title>
<base-table
:table-props="tableProps2"
:page="1"
:limit="10"
:table-data="tableData2"
:add-button-show="'新增'"
@emitButtonClick="addNewGroup">
<method-btn
v-if="tableBtn2.length"
slot="handleBtn"
:width="110"
label="操作"
:method-list="tableBtn2"
@clickBtn="handleClick2" />
</base-table>
</div>
<div v-if="stepNum == 3">
<small-title style="margin: 16px 0" size="sm" :no-padding="true">
排班计划预览
<span style="font-size: 14px; color: #ff1c15">
系统将根据以下设置按班组轮班顺序依次循环每日班次生成正式排班计划请确认
<el-popover
placement="right"
title="比如三班两倒同班次连排2天不休周末排班如下"
width="300"
trigger="hover">
<el-table :data="gridData">
<el-table-column property="date"></el-table-column>
<el-table-column
property="class1"
label="班次一"></el-table-column>
<el-table-column
property="class2"
label="班次二"></el-table-column>
</el-table>
<i
slot="reference"
class="el-icon-warning-outline"
style="color: #ff1c15"></i>
</el-popover>
</span>
</small-title>
<el-tag>
{{
'计划时间:' +
parseTime(dataForm.startDay) +
' 至 ' +
parseTime(dataForm.endDay)
}}
</el-tag>
<div
style="
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 10px;
margin: 15px;
">
<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
<div class="daobanpng" />
<div>
<div style="color: rgba(0, 0, 0, 0.6)">倒班方式</div>
<div style="color: #000000">
{{ ['长白班', '两班倒', '三班倒'][dataForm.shiftType - 1] }}
</div>
</div>
</div>
<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
<div class="lianpaipng" />
<div>
<div style="color: rgba(0, 0, 0, 0.6)">同班次连排</div>
<div style="color: #000000">
{{
dataForm.shiftSustainedNum +
['日', '周', '月', '季'][dataForm.shiftSustainedType - 1]
}}
</div>
</div>
</div>
<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
<div class="xiujiapng" />
<div>
<div style="color: rgba(0, 0, 0, 0.6)">周末休假方式</div>
<div style="color: #000000">
{{ ['双休', '周六休', '周日休', '不休'][dataForm.weekType - 1] }}
</div>
</div>
</div>
<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
<div class="banzupng" />
<div>
<div style="color: rgba(0, 0, 0, 0.6)">参与班组</div>
<div style="color: #000000">
{{
tableData2
.map((item) => {
return item.name;
})
.join('/')
}}
</div>
</div>
</div>
</div>
</div>
<base-dialog
:dialogTitle="'修改班次'"
:dialogVisible="addOrUpdateVisible1"
@cancel="cancel1"
@confirm="handleConfirm1"
:destroy-on-close="true"
append-to-body
width="40%">
<edit-class
ref="editClassRef"
@refreshTableData="refreshTableData1"></edit-class>
</base-dialog>
<base-dialog
:dialogTitle="'班组选择'"
:dialogVisible="addOrUpdateVisible2"
@cancel="cancel2"
@confirm="handleConfirm2"
:destroy-on-close="true"
append-to-body
width="40%">
<add-group
ref="addGroupRef"
@refreshTableData="refreshTableData2"></add-group>
</base-dialog>
<base-dialog
:dialogTitle="'绑定产线'"
:dialogVisible="addOrUpdateVisible3"
@cancel="cancel3"
@confirm="handleConfirm3"
:destroy-on-close="true"
append-to-body
width="50%">
<bind-line
ref="bindLineRef"
@refreshTableData="refreshTableData3"></bind-line>
</base-dialog>
</div>
</template>
<script>
import deptSelect from './../deptSelect.vue';
import SmallTitle from './SmallTitle';
import { parseTime } from '@/filter/code-filter';
import editClass from './edit-class.vue';
import addGroup from './add-group.vue';
import bindLine from './bind-line.vue';
import { getCode, createStepOne, returnStepOne } from '@/api/group/Schedule';
const tableProps1 = [
{
prop: 'name',
label: '班次名称',
},
{
prop: 'startDay',
label: '开始时间',
// filter: (val) => {
// parseTime(val, '{H}:{mm}');
// },
},
{
prop: 'endDay',
label: '结束时间',
// filter: (val) => {
// parseTime(val, '{H}:{mm}');
// },
},
{
prop: 'remark',
label: '备注',
},
];
const tableProps2 = [
{
prop: 'code',
label: '班组编号',
width: 140,
},
{
prop: 'name',
label: '班组名称',
},
{
prop: 'isProduction',
label: '是否生产班组',
filter: (val) => {
return val ? '是' : '否';
},
width: 110,
},
{
prop: 'code1',
label: '产线及工段',
},
];
export default {
components: {
deptSelect,
SmallTitle,
editClass,
addGroup,
bindLine,
},
data() {
return {
dotArr: [
{
name: '基础信息',
},
{
name: '班组班次',
},
{
name: '计划确认',
},
],
stepNum: 1, // 当前第几步
//第一步参数
dataForm: {
id: undefined,
code: undefined,
name: undefined,
startDay: undefined,
endDay: undefined,
deptId: undefined,
weekType: undefined,
shiftType: undefined,
shiftSustainedNum: undefined,
shiftSustainedType: 1,
remark: undefined,
},
options1: [
{
value: 1,
label: '双休',
},
{
value: 2,
label: '周六休',
},
{
value: 3,
label: '周日休',
},
{
value: 4,
label: '不休',
},
],
options2: [
{
value: 1,
label: '长白班',
},
{
value: 2,
label: '两班倒',
},
{
value: 3,
label: '三班倒',
},
],
dataRule: {
code: [
{ required: true, message: '计划编号不能为空', trigger: 'blur' },
],
name: [
{ required: true, message: '计划名称不能为空', trigger: 'blur' },
],
startDay: [
{ required: true, message: '开始时间不能为空', trigger: 'change' },
],
endDay: [
{ required: true, message: '结束时间不能为空', trigger: 'change' },
],
weekType: [
{
required: true,
message: '周末休假方式不能为空',
trigger: 'change',
},
],
shiftType: [
{
required: true,
message: '倒班方式方式不能为空',
trigger: 'change',
},
],
shiftSustainedNum: [
{ required: true, message: '同班次连排不能为空', trigger: 'blur' },
],
},
//第二步参数
tableProps1,
tableBtn1: [
{
type: 'edit',
btnName: '编辑',
},
].filter((v) => v),
tableData1: [],
tableProps2,
tableBtn2: [
{
type: 'bind',
btnName: '绑定产线',
},
{
type: 'delete',
btnName: '删除',
},
].filter((v) => v),
tableData2: [],
addOrUpdateVisible1: false,
addOrUpdateVisible2: false,
addOrUpdateVisible3: false,
//第三步参数
gridData: [
{
date: '第1天',
class1: 'A',
class2: 'B',
},
{
date: '第2天',
class1: 'A',
class2: 'B',
},
{
date: '第3天',
class1: 'C',
class2: 'A',
},
{
date: '第4天',
class1: 'C',
class2: 'A',
},
{
date: '第5天',
class1: 'B',
class2: 'C',
},
{
date: '第6天',
class1: 'B',
class2: 'C',
},
{
date: '第7天',
class1: 'A',
class2: 'B',
},
{
date: '第8天',
class1: 'A',
class2: 'B',
},
],
};
},
methods: {
//子组件获取的部门id
setDeptId(val) {
this.dataForm.deptId = val;
},
//详情时传给子组件的部门id
setDataForm() {
this.$refs.deptSelect.setID(this.dataForm.deptId);
},
init() {
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
getCode().then((res) => {
this.dataForm.code = res.data;
});
});
},
handleClick1(val) {
this.addOrUpdateVisible1 = true;
this.$nextTick(() => {
this.$refs.editClassRef.init(val.data);
});
},
handleClick2(val) {
if (val.type === 'bind') {
this.addOrUpdateVisible3 = true;
this.$nextTick(() => {
this.$refs.bindLineRef.init(val.data.id);
});
} else if (val.type === 'delete') {
this.tableData2.splice(val.data._pageIndex - 1, 1);
}
},
upSubmit() {
if (this.stepNum == 2) {
returnStepOne(this.dataForm.id).then((res) => {
this.stepNum -= 1;
this.$emit('setSN', this.stepNum);
this.$nextTick(() => {
this.setDataForm();
});
});
}
},
nextSubmit() {
if (this.stepNum == 1) {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
if (!this.dataForm.deptId) {
this.$message('部门不能为空');
return;
}
createStepOne(this.dataForm).then((res) => {
this.dataForm.id = res.data;
this.stepNum += 1;
this.$emit('setSN', this.stepNum);
this.setTWOclass(); // 第一步提交后,根据倒班方式设置第二部班次
});
});
return;
}
if (this.stepNum == 2) {
let data = {}
data.planId = this.dataForm.id
data.groupPlanClassesBaseVOList = [] //排班-班次信息list
this.tableData1.forEach((item,index)=>{
const obj = {
sort: index+1,
name : item.name,
remark: item.remark,
startTime: {
hour:item.startDay.split(':')[0],
minute:item.startDay.split(':')[1],
},
endTime: {
hour:item.endDay.split(':')[0],
minute:item.endDay.split(':')[1],
}
}
data.groupPlanClassesBaseVOList.push(obj)
})
data.groupPlanTeamBaseVOList = [] //排班-班组信息list
this.tableData2.forEach(item=>{
const obj = {
teamId:item.id,
bindData: ''
}
data.groupPlanTeamBaseVOList.push(obj)
})
this.stepNum += 1;
this.$emit('setSN', this.stepNum);
return;
}
if (this.stepNum == 3) {
this.stepNum = 1;
this.$emit('setSN', this.stepNum);
return;
}
},
//设置第二部班次
setTWOclass() {
this.tableData1 = [];
if (this.dataForm.shiftType == 1) {
const obj = {
name: '长白班',
startDay: '8:00',
endDay: '17:00',
};
this.tableData1.push(obj);
} else if (this.dataForm.shiftType == 2) {
const obj1 = {
name: '白班',
startDay: '8:00',
endDay: '20:00',
};
const obj2 = {
name: '夜班',
startDay: '20:00',
endDay: '8:00',
};
this.tableData1.push(obj1, obj2);
} else if (this.dataForm.shiftType == 3) {
const obj1 = {
name: '早班',
startDay: '8:00',
endDay: '16:00',
};
const obj2 = {
name: '中班',
startDay: '16:00',
endDay: '00:00',
};
const obj3 = {
name: '夜班',
startDay: '00:00',
endDay: '8:00',
};
this.tableData1.push(obj1, obj2, obj3);
}
},
// 新增班组
addNewGroup() {
this.addOrUpdateVisible2 = true;
this.$nextTick(() => {
this.$refs.addGroupRef.init(this.dataForm.deptId);
});
},
cancel1() {
this.addOrUpdateVisible1 = false;
},
cancel2() {
this.addOrUpdateVisible2 = false;
},
cancel3() {
this.addOrUpdateVisible3 = false;
},
handleConfirm1() {
this.$refs.editClassRef.dataFormSubmit();
},
handleConfirm2() {
this.$refs.addGroupRef.dataFormSubmit();
},
handleConfirm3() {
this.$refs.bindLineRef.dataFormSubmit();
},
refreshTableData1(index, val) {
this.tableData1.splice(index, 1, val);
this.cancel1();
},
refreshTableData2(val) {
this.tableData2.push(...val);
this.cancel2();
},
refreshTableData3(val) {
console.log(val);
this.cancel3();
},
},
};
</script>
<style scoped>
.daobanpng {
width: 40px;
height: 40px;
background-image: url('~@/assets/images/daoban.png');
background-size: 100% 100%;
}
.lianpaipng {
width: 40px;
height: 40px;
background-image: url('~@/assets/images/lianpai.png');
background-size: 100% 100%;
}
.xiujiapng {
width: 40px;
height: 40px;
background-image: url('~@/assets/images/xiujia.png');
background-size: 100% 100%;
}
.banzupng {
width: 40px;
height: 40px;
background-image: url('~@/assets/images/banzu.png');
background-size: 100% 100%;
}
</style>
<!-- //序号圆点 -->
<style scoped>
.circle-container {
height: 110px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
width: 90%;
overflow-x: auto;
margin: auto;
}
.circle-wrapper {
position: relative;
display: flex;
align-items: center;
}
.circle {
width: 52px;
height: 52px;
border-radius: 50%;
background: #8db1ff;
font-weight: 500;
font-size: 31px;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
position: relative;
z-index: 2;
cursor: pointer;
}
.circle-text {
position: absolute;
top: 60px;
left: -15px;
color: #8db1ff;
width: 82px;
text-align: center;
}
/* 下半圆虚线边框 */
.circle::after {
content: '';
position: absolute;
bottom: -6px; /* 2px边框 + 2px间隙 */
left: -4px;
right: -4px;
height: 30px; /* 半圆高度 */
border-radius: 0 0 60px 60px;
border: 1px dashed #0b58ff;
border-top: none;
z-index: 1;
}
.connector {
width: 160px; /* 计算连接线长度 */
height: 2px;
border-bottom: 1px dashed rgb(11, 88, 255, 1);
margin: 0 5px;
z-index: 1;
}
</style>