|
|
|
@ -1,9 +1,9 @@ |
|
|
|
<template> |
|
|
|
<!-- 操作员切换模块 --> |
|
|
|
<div class="customer-css"> |
|
|
|
<el-dialog :title="titleCon" v-bind="$attrs" v-on="$listeners" width="600px" :close-on-click-modal="false"> |
|
|
|
<el-dialog :title="titleCon" v-bind="$attrs" v-on="$listeners" width="800px" :close-on-click-modal="false"> |
|
|
|
<!-- 上部分:添加操作员 --> |
|
|
|
<el-form :inline="true" @submit.native.prevent label-position="top" label-width="100px" style="margin-bottom: 15px;"> |
|
|
|
<el-form v-if="!isAttendanceMode" :inline="true" @submit.native.prevent label-position="top" label-width="100px" style="margin-bottom: 15px;"> |
|
|
|
<el-row> |
|
|
|
<el-col :span="8"> |
|
|
|
<el-form-item> |
|
|
|
@ -11,7 +11,7 @@ |
|
|
|
<el-input |
|
|
|
ref="operatorId" |
|
|
|
@keyup.enter.native="addOperator" |
|
|
|
@blur="checkOperatorId" |
|
|
|
|
|
|
|
v-model="newOperator.operatorId" |
|
|
|
style="width: 150px"> |
|
|
|
</el-input> |
|
|
|
@ -37,47 +37,74 @@ |
|
|
|
|
|
|
|
<!-- 中间:操作员列表 --> |
|
|
|
<div class="operator-list"> |
|
|
|
<el-table |
|
|
|
:data="operatorList" |
|
|
|
border |
|
|
|
stripe |
|
|
|
height="300" |
|
|
|
style="width: 100%"> |
|
|
|
<el-table-column |
|
|
|
type="index" |
|
|
|
label="序号" |
|
|
|
width="60" |
|
|
|
align="center"> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
prop="operator" |
|
|
|
label="操作员编码" |
|
|
|
align="center"> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
prop="operatorName" |
|
|
|
label="操作员名称" |
|
|
|
align="center"> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
prop="onDutyTime" |
|
|
|
label="上岗时间" |
|
|
|
align="center" |
|
|
|
width="160"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
{{ formatDateTime(scope.row.onDutyTime) }} |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
label="操作" |
|
|
|
align="center" |
|
|
|
width="100"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-link style="cursor: pointer" @click="removeOperator(scope.row)">下岗</el-link> |
|
|
|
<el-link style="cursor: pointer" @click="deleteOperator(scope.row)">删除</el-link> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table> |
|
|
|
<div class="rq"> |
|
|
|
<el-table |
|
|
|
:data="operatorList" |
|
|
|
border |
|
|
|
stripe |
|
|
|
height="300" |
|
|
|
style="width: 100%"> |
|
|
|
<el-table-column |
|
|
|
type="index" |
|
|
|
label="序号" |
|
|
|
width="50" |
|
|
|
align="center"> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
prop="operator" |
|
|
|
label="操作员编码" |
|
|
|
align="left" |
|
|
|
header-align="center" |
|
|
|
min-width="100"> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
prop="operatorName" |
|
|
|
label="操作员名称" |
|
|
|
align="left" |
|
|
|
header-align="center" |
|
|
|
min-width="150"> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
label="上岗时间" |
|
|
|
align="center" |
|
|
|
width="180"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-date-picker |
|
|
|
v-model="scope.row.onDutyTime" |
|
|
|
type="datetime" |
|
|
|
placeholder="选择上岗时间" |
|
|
|
value-format="yyyy-MM-dd HH:mm:ss" |
|
|
|
format="yyyy-MM-dd HH:mm:ss" |
|
|
|
style="width: 170px;"> |
|
|
|
</el-date-picker> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
label="下岗时间" |
|
|
|
align="center" |
|
|
|
width="180"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-date-picker |
|
|
|
v-model="scope.row.offDutyTime" |
|
|
|
type="datetime" |
|
|
|
placeholder="选择下岗时间" |
|
|
|
value-format="yyyy-MM-dd HH:mm:ss" |
|
|
|
format="yyyy-MM-dd HH:mm:ss" |
|
|
|
style="width: 170px;"> |
|
|
|
</el-date-picker> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column |
|
|
|
label="操作" |
|
|
|
align="center" |
|
|
|
width="100"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-link style="cursor: pointer" @click="updateOperatorTime(scope.row)">下岗</el-link> |
|
|
|
<el-link style="cursor: pointer" @click="deleteOperator(scope.row)">删除</el-link> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 底部:保存和关闭按钮 --> |
|
|
|
@ -98,7 +125,9 @@ import { |
|
|
|
getOperatorList2, |
|
|
|
addOperatorOnDuty, |
|
|
|
removeOperatorOnDuty, |
|
|
|
deleteOperatorData |
|
|
|
deleteOperatorData, |
|
|
|
updateOperatorTime, |
|
|
|
batchUpdateOperatorTime |
|
|
|
} from '@/api/yieldReport/produce_order.js'; |
|
|
|
|
|
|
|
import { |
|
|
|
@ -143,6 +172,8 @@ export default { |
|
|
|
operatorList: [], |
|
|
|
// 当前派工单信息 |
|
|
|
currentSchedule: {}, |
|
|
|
// 是否为考勤修改模式(不显示添加操作员功能) |
|
|
|
isAttendanceMode: false, |
|
|
|
buttons: { |
|
|
|
saveButton: '保存', |
|
|
|
closeButton: '关闭', |
|
|
|
@ -244,23 +275,32 @@ export default { |
|
|
|
|
|
|
|
/*关闭modal*/ |
|
|
|
closeDialog() { |
|
|
|
// 即使用户不点击保存,也应该使用默认的当前登录人作为操作员 |
|
|
|
// 设置默认操作员信息 |
|
|
|
// 关闭弹窗 |
|
|
|
this.$emit('update:visible', false); |
|
|
|
|
|
|
|
// 如果是考勤修改模式,只关闭对话框,不进入机台工作台 |
|
|
|
if (this.isAttendanceMode) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 非考勤模式:即使用户不点击保存,也应该使用默认的当前登录人作为操作员 |
|
|
|
// 设置默认操作员信息,并进入机台工作台 |
|
|
|
this.operatorData.operatorId = this.$store.state.user.name; |
|
|
|
this.operatorData.operatorName = this.$store.state.user.userDisplay; |
|
|
|
this.operatorData.status = 'Y'; |
|
|
|
|
|
|
|
// 关闭弹窗并传递操作员信息 |
|
|
|
this.$emit('update:visible', false); |
|
|
|
// 调用初始化的方法,进入机台工作台 |
|
|
|
this.$emit('initOperatorData', this.operatorData); |
|
|
|
}, |
|
|
|
|
|
|
|
//初始化的 |
|
|
|
init(val, scheduleRow) { |
|
|
|
init(val, scheduleRow, isAttendanceMode = false) { |
|
|
|
// 保存派工单信息 |
|
|
|
this.currentSchedule = scheduleRow || {}; |
|
|
|
|
|
|
|
// 设置是否为考勤修改模式 |
|
|
|
this.isAttendanceMode = isAttendanceMode; |
|
|
|
|
|
|
|
// 设置默认操作员为当前登录人 |
|
|
|
this.operatorData.operatorName = this.$store.state.user.userDisplay; |
|
|
|
this.operatorData.operatorId = this.$store.state.user.name; |
|
|
|
@ -278,11 +318,13 @@ export default { |
|
|
|
|
|
|
|
//判断是否启用多语言 |
|
|
|
// this.getMultiLanguageList(); //刷新多语言的信息 |
|
|
|
//自动获取焦点 |
|
|
|
this.$nextTick(() => { |
|
|
|
this.$refs.operatorId.focus(); |
|
|
|
}); |
|
|
|
this.titleCon = this.labels.componentTitle;//重置标题 |
|
|
|
//自动获取焦点(仅非考勤模式需要) |
|
|
|
if (!isAttendanceMode) { |
|
|
|
this.$nextTick(() => { |
|
|
|
this.$refs.operatorId && this.$refs.operatorId.focus(); |
|
|
|
}); |
|
|
|
} |
|
|
|
this.titleCon = isAttendanceMode ? '考勤修改' : this.labels.componentTitle;//重置标题 |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载操作员列表 |
|
|
|
@ -366,38 +408,78 @@ export default { |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 移除操作员(下岗) |
|
|
|
removeOperator(row) { |
|
|
|
this.$confirm('确定让该操作员下岗吗?', '提示', { |
|
|
|
// 更新单行操作员时间(下岗) |
|
|
|
updateOperatorTime(row) { |
|
|
|
// 校验时间 |
|
|
|
const validateResult = this.validateOperatorTime(row); |
|
|
|
if (!validateResult.valid) { |
|
|
|
this.$message.error(validateResult.message); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.$confirm('确定更新该操作员的上下岗时间吗?', '提示', { |
|
|
|
confirmButtonText: '确定', |
|
|
|
cancelButtonText: '取消', |
|
|
|
type: 'warning' |
|
|
|
}).then(() => { |
|
|
|
const params = { |
|
|
|
id: row.id, |
|
|
|
site: this.$store.state.user.site, |
|
|
|
orderNo: this.currentSchedule.orderNo, |
|
|
|
itemNo: this.currentSchedule.itemNo, |
|
|
|
seqNo: this.currentSchedule.seqNo, |
|
|
|
operator: row.operator, |
|
|
|
id: row.id |
|
|
|
onDutyTime: row.onDutyTime, |
|
|
|
offDutyTime: row.offDutyTime |
|
|
|
}; |
|
|
|
|
|
|
|
removeOperatorOnDuty(params).then(({ data }) => { |
|
|
|
updateOperatorTime(params).then(({ data }) => { |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.$message.success('操作员下岗成功!'); |
|
|
|
this.$message.success('操作员时间更新成功!'); |
|
|
|
// 刷新列表 |
|
|
|
this.loadOperatorList(); |
|
|
|
} else { |
|
|
|
this.$message.error(data.msg || '操作员下岗失败!'); |
|
|
|
this.$message.error(data.msg || '操作员时间更新失败!'); |
|
|
|
} |
|
|
|
}).catch(() => { |
|
|
|
this.$message.error('操作员下岗失败!'); |
|
|
|
this.$message.error('操作员时间更新失败!'); |
|
|
|
}); |
|
|
|
}).catch(() => { |
|
|
|
// 取消操作 |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 校验操作员时间 |
|
|
|
validateOperatorTime(row) { |
|
|
|
// 允许上岗时间为空(跳过校验) |
|
|
|
if (!row.onDutyTime) { |
|
|
|
return { valid: true }; |
|
|
|
} |
|
|
|
|
|
|
|
const now = new Date(); |
|
|
|
const onDutyTime = new Date(row.onDutyTime); |
|
|
|
|
|
|
|
// 上岗时间不能超过当前时间 |
|
|
|
if (onDutyTime > now) { |
|
|
|
return { valid: false, message: '上岗时间不能超过当前时间!' }; |
|
|
|
} |
|
|
|
|
|
|
|
// 下岗时间可以为空,如果有下岗时间则需要校验 |
|
|
|
if (row.offDutyTime) { |
|
|
|
const offDutyTime = new Date(row.offDutyTime); |
|
|
|
// 下岗时间不能早于上岗时间 |
|
|
|
if (offDutyTime < onDutyTime) { |
|
|
|
return { valid: false, message: '下岗时间不能早于上岗时间!' }; |
|
|
|
} |
|
|
|
// 下岗时间不能超过当前时间 |
|
|
|
if (offDutyTime > now) { |
|
|
|
return { valid: false, message: '下岗时间不能超过当前时间!' }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return { valid: true }; |
|
|
|
}, |
|
|
|
|
|
|
|
// 删除操作员 |
|
|
|
deleteOperator(row) { |
|
|
|
this.$confirm('确定删除该操作员数据吗? 此操作不可恢复!', '提示', { |
|
|
|
@ -429,18 +511,77 @@ export default { |
|
|
|
// 取消操作 |
|
|
|
}); |
|
|
|
}, |
|
|
|
// 保存并进入机台工作台 |
|
|
|
// 保存并进入机台工作台(或批量更新考勤时间) |
|
|
|
saveOperatorData() { |
|
|
|
// 使用默认的当前登录人 |
|
|
|
this.operatorData.operatorId = this.$store.state.user.name; |
|
|
|
this.operatorData.operatorName = this.$store.state.user.userDisplay; |
|
|
|
this.operatorData.status = 'Y'; |
|
|
|
this.operatorFlag = true; |
|
|
|
// 先批量更新所有行的上下岗时间 |
|
|
|
this.batchUpdateOperatorTimeSync().then(() => { |
|
|
|
// 如果是考勤修改模式,更新完成后不进入机台工作台 |
|
|
|
if (this.isAttendanceMode) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 校验没有问题 关闭弹窗 |
|
|
|
this.closeDialog(); |
|
|
|
// 调用初始化的方法,进入机台工作台 |
|
|
|
this.$emit('initOperatorData', this.operatorData); |
|
|
|
// 非考勤模式:使用默认的当前登录人,进入机台工作台 |
|
|
|
this.operatorData.operatorId = this.$store.state.user.name; |
|
|
|
this.operatorData.operatorName = this.$store.state.user.userDisplay; |
|
|
|
this.operatorData.status = 'Y'; |
|
|
|
this.operatorFlag = true; |
|
|
|
|
|
|
|
// 关闭弹窗并进入机台工作台 |
|
|
|
this.closeDialog(); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 批量更新操作员时间(返回Promise) |
|
|
|
batchUpdateOperatorTimeSync() { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
// 如果列表为空,直接返回 |
|
|
|
if (!this.operatorList || this.operatorList.length === 0) { |
|
|
|
resolve(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 校验所有行的时间 |
|
|
|
for (let i = 0; i < this.operatorList.length; i++) { |
|
|
|
const row = this.operatorList[i]; |
|
|
|
const validateResult = this.validateOperatorTime(row); |
|
|
|
if (!validateResult.valid) { |
|
|
|
this.$message.error(`第 ${i + 1} 行:${validateResult.message}`); |
|
|
|
reject(); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 准备批量更新的数据 |
|
|
|
const operatorListData = this.operatorList.map(row => ({ |
|
|
|
id: row.id, |
|
|
|
operator: row.operator, |
|
|
|
onDutyTime: row.onDutyTime, |
|
|
|
offDutyTime: row.offDutyTime |
|
|
|
})); |
|
|
|
|
|
|
|
const params = { |
|
|
|
site: this.$store.state.user.site, |
|
|
|
orderNo: this.currentSchedule.orderNo, |
|
|
|
itemNo: this.currentSchedule.itemNo, |
|
|
|
seqNo: this.currentSchedule.seqNo, |
|
|
|
operatorList: operatorListData |
|
|
|
}; |
|
|
|
|
|
|
|
batchUpdateOperatorTime(params).then(({ data }) => { |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.$message.success('考勤信息批量更新成功!'); |
|
|
|
// 刷新列表 |
|
|
|
this.loadOperatorList(); |
|
|
|
resolve(); |
|
|
|
} else { |
|
|
|
this.$message.error(data.msg || '考勤信息批量更新失败!'); |
|
|
|
reject(); |
|
|
|
} |
|
|
|
}).catch(() => { |
|
|
|
this.$message.error('考勤信息批量更新失败!'); |
|
|
|
reject(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
/*检查操作员的信息(用于添加操作员时验证)*/ |
|
|
|
|