602 lines
13 KiB
Vue
602 lines
13 KiB
Vue
<!--
|
|
* @Author: zwq
|
|
* @Date: 2025-10-13 15:07:24
|
|
* @LastEditors: zwq
|
|
* @LastEditTime: 2025-11-05 08:51:13
|
|
* @Description:
|
|
-->
|
|
<template>
|
|
<div class="app-container">
|
|
<div class="searchBarBox">
|
|
<el-form
|
|
:inline="true"
|
|
ref="searchBarForm"
|
|
:model="formInline"
|
|
class="searchBar">
|
|
<span class="blue-block" />
|
|
<el-form-item label="计划编号" prop="code">
|
|
<el-input
|
|
v-model="formInline.code"
|
|
clearable
|
|
size="small"
|
|
placeholder="请输入计划编号" />
|
|
</el-form-item>
|
|
<el-form-item label="计划名称" prop="name">
|
|
<el-input
|
|
v-model="formInline.name"
|
|
clearable
|
|
size="small"
|
|
placeholder="请输入计划名称" />
|
|
</el-form-item>
|
|
<el-form-item label="开始时间" prop="startDay">
|
|
<el-date-picker
|
|
v-model="formInline.startDay"
|
|
size="small"
|
|
type="datetime"
|
|
placeholder="选择日期时间"></el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item label="结束时间" prop="endDay">
|
|
<el-date-picker
|
|
v-model="formInline.endDay"
|
|
size="small"
|
|
type="datetime"
|
|
placeholder="选择日期时间"></el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item label="部门" prop="deptId">
|
|
<dept-select
|
|
style="width: 200px"
|
|
ref="deptSelect"
|
|
@DeptId="setDeptId"></dept-select>
|
|
</el-form-item>
|
|
<el-form-item label="状态" prop="status">
|
|
<el-select
|
|
v-model="formInline.status"
|
|
size="small"
|
|
clearable
|
|
placeholder="请选择状态">
|
|
<el-option
|
|
v-for="item in options"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
v-hasPermi="['base:group-scheduling-plan:query']"
|
|
@click="buttonClick({ btnName: 'search' })">
|
|
查询
|
|
</el-button>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<span
|
|
class="separateStyle"
|
|
v-hasPermi="['base:group-scheduling-plan:query']"></span>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button size="small" @click="buttonClick({ btnName: 'reset' })">
|
|
重置
|
|
</el-button>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<span
|
|
class="separateStyle"
|
|
v-hasPermi="['base:group-scheduling-plan:create']"></span>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button
|
|
type="success"
|
|
size="small"
|
|
:plain="true"
|
|
v-hasPermi="['base:group-scheduling-plan:create']"
|
|
@click="buttonClick({ btnName: 'add' })">
|
|
新增
|
|
</el-button>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button
|
|
type="warning"
|
|
plain
|
|
size="small"
|
|
@click="handleExport"
|
|
:loading="exportLoading"
|
|
v-hasPermi="['base:group-scheduling-plan:export']">
|
|
导出
|
|
</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
<base-table
|
|
v-loading="dataListLoading"
|
|
:table-props="tableProps"
|
|
:page="listQuery.pageNo"
|
|
:limit="listQuery.pageSize"
|
|
:table-data="tableData"
|
|
@emitFun="getDataList">
|
|
<method-btn
|
|
v-if="tableBtn.length"
|
|
slot="handleBtn"
|
|
:width="270"
|
|
label="操作"
|
|
:method-list="tableBtn"
|
|
@clickBtn="handleClick" />
|
|
</base-table>
|
|
<pagination
|
|
:limit.sync="listQuery.pageSize"
|
|
:page.sync="listQuery.pageNo"
|
|
:total="listQuery.total"
|
|
@pagination="getDataList" />
|
|
<base-dialog
|
|
:dialogTitle="addOrEditTitle"
|
|
:dialogVisible="addOrUpdateVisible"
|
|
@cancel="handleCancel"
|
|
@confirm="handleConfirm"
|
|
:before-close="handleCancel"
|
|
:destroy-on-close="true"
|
|
append-to-body
|
|
width="60%">
|
|
<add-or-update
|
|
ref="addOrUpdate"
|
|
@setSN="setStepNum"
|
|
@refreshDataList="successSubmit"></add-or-update>
|
|
<template #footer>
|
|
<slot name="footer">
|
|
<el-row slot="footer" type="flex" justify="end">
|
|
<el-col :span="24">
|
|
<el-button
|
|
v-if="stepNum > 1"
|
|
size="small"
|
|
class="btnTextStyle"
|
|
@click="handleConfirm('up')">
|
|
上一步
|
|
</el-button>
|
|
<el-button
|
|
size="small"
|
|
class="btnTextStyle"
|
|
@click="handleCancel">
|
|
取消
|
|
</el-button>
|
|
<el-button
|
|
v-if="stepNum == 3"
|
|
type="primary"
|
|
class="btnTextStyle"
|
|
size="small"
|
|
plain
|
|
@click="successSubmit">
|
|
保存草稿
|
|
</el-button>
|
|
<el-button
|
|
type="primary"
|
|
class="btnTextStyle"
|
|
size="small"
|
|
@click="handleConfirm">
|
|
{{ stepNum < 3 ? '下一步' : '确认并执行' }}
|
|
</el-button>
|
|
</el-col>
|
|
</el-row>
|
|
</slot>
|
|
</template>
|
|
</base-dialog>
|
|
<base-dialog
|
|
:dialogTitle="'排班计划详情'"
|
|
:dialogVisible="detailVisible"
|
|
@cancel="detailCancel"
|
|
:before-close="detailCancel"
|
|
:destroy-on-close="true"
|
|
append-to-body
|
|
width="50%">
|
|
<detail ref="detailRef"></detail>
|
|
<template #footer>
|
|
<slot name="footer">
|
|
<el-row slot="footer" type="flex" justify="end">
|
|
<el-col :span="24">
|
|
<el-button
|
|
size="small"
|
|
class="btnTextStyle"
|
|
@click="detailCancel">
|
|
取消
|
|
</el-button>
|
|
</el-col>
|
|
</el-row>
|
|
</slot>
|
|
</template>
|
|
</base-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import AddOrUpdate from './add-or-updata';
|
|
import deptSelect from './../deptSelect.vue';
|
|
import basicPage from '@/mixins/basic-page';
|
|
import subSpan from './subSpan.vue';
|
|
import subStatus from './subStatus.vue';
|
|
import detail from './detail.vue';
|
|
import { parseTime } from '@/filter/code-filter';
|
|
import {
|
|
getGroupPlanPage,
|
|
deleteGroupPlan,
|
|
copyPlan,
|
|
disablePlan,
|
|
updateScheduleLater,
|
|
exportExcel,
|
|
} from '@/api/group/Schedule';
|
|
|
|
const tableProps = [
|
|
{
|
|
prop: 'code',
|
|
label: '计划编号',
|
|
width: 140,
|
|
},
|
|
{
|
|
prop: 'name',
|
|
label: '计划名称',
|
|
width: 100,
|
|
},
|
|
{
|
|
prop: 'startDay',
|
|
label: '开始时间',
|
|
filter: parseTime,
|
|
width: 150,
|
|
},
|
|
{
|
|
prop: 'endDay',
|
|
label: '结束时间',
|
|
filter: parseTime,
|
|
width: 150,
|
|
},
|
|
{
|
|
prop: 'shiftType',
|
|
label: '倒班方式',
|
|
filter: (val) => {
|
|
return val ? ['', '长白班', '两班倒', '三班倒'][val] : '-';
|
|
},
|
|
width: 110,
|
|
},
|
|
{
|
|
prop: 'shiftSustainedNum',
|
|
label: '同班次连排',
|
|
width: 110,
|
|
subcomponent: subSpan,
|
|
},
|
|
{
|
|
prop: 'deptName',
|
|
label: '部门',
|
|
},
|
|
{
|
|
prop: 'status',
|
|
label: '计划状态',
|
|
width: 110,
|
|
subcomponent: subStatus,
|
|
},
|
|
{
|
|
prop: 'createTime',
|
|
label: '创建时间',
|
|
filter: parseTime,
|
|
width: 150,
|
|
},
|
|
];
|
|
|
|
export default {
|
|
mixins: [basicPage],
|
|
data() {
|
|
return {
|
|
urlOptions: {
|
|
getDataListURL: getGroupPlanPage,
|
|
deleteURL: deleteGroupPlan,
|
|
},
|
|
tableProps,
|
|
tableBtn: [
|
|
this.$auth.hasPermi('base:group-scheduling-plan:update')
|
|
? {
|
|
type: 'edit',
|
|
btnName: '编辑',
|
|
showParam: {
|
|
type: '&',
|
|
data: [
|
|
{
|
|
type: 'equal',
|
|
name: 'status',
|
|
value: 1,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: undefined,
|
|
this.$auth.hasPermi('base:group-scheduling-plan:delete')
|
|
? {
|
|
type: 'delete',
|
|
btnName: '删除',
|
|
showParam: {
|
|
type: '&',
|
|
data: [
|
|
{
|
|
type: 'equal',
|
|
name: 'status',
|
|
value: 1,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: undefined,
|
|
this.$auth.hasPermi('base:group-scheduling-plan:query')
|
|
? {
|
|
type: 'detail',
|
|
btnName: '查看',
|
|
showParam: {
|
|
type: '&',
|
|
data: [
|
|
{
|
|
type: 'unequal',
|
|
name: 'status',
|
|
value: 1,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: undefined,
|
|
this.$auth.hasPermi('base:group-scheduling-plan:delete')
|
|
? {
|
|
type: 'cancel',
|
|
btnName: '作废',
|
|
showParam: {
|
|
type: '&',
|
|
data: [
|
|
{
|
|
type: 'equal',
|
|
name: 'status',
|
|
value: 2,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: undefined,
|
|
this.$auth.hasPermi('base:group-holiday:update')
|
|
? {
|
|
type: 'sync',
|
|
btnName: '同步节假日',
|
|
showParam: {
|
|
type: '&',
|
|
data: [
|
|
{
|
|
type: 'equal',
|
|
name: 'status',
|
|
value: 2,
|
|
},
|
|
{
|
|
type: 'equal',
|
|
name: 'updateFlag',
|
|
value: true,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: undefined,
|
|
this.$auth.hasPermi('base:group-scheduling-plan:create')
|
|
? {
|
|
type: 'copy',
|
|
btnName: '复制',
|
|
}
|
|
: undefined,
|
|
].filter((v) => v),
|
|
tableData: [],
|
|
options: [
|
|
{
|
|
value: '1',
|
|
label: '草稿',
|
|
},
|
|
{
|
|
value: '2',
|
|
label: '已确认',
|
|
},
|
|
{
|
|
value: '3',
|
|
label: '已作废',
|
|
},
|
|
],
|
|
formInline: {
|
|
code: '',
|
|
name: '',
|
|
startDay: '',
|
|
endDay: '',
|
|
deptId: '',
|
|
status: '',
|
|
},
|
|
stepNum: 1, // 新增编辑时当前第几步
|
|
detailVisible: false,
|
|
// 导出遮罩层
|
|
exportLoading: false,
|
|
};
|
|
},
|
|
components: {
|
|
AddOrUpdate,
|
|
deptSelect,
|
|
detail,
|
|
},
|
|
created() {},
|
|
methods: {
|
|
buttonClick(val) {
|
|
switch (val.btnName) {
|
|
case 'search':
|
|
const date1 = new Date(this.formInline.startDay).getTime();
|
|
const date2 = new Date(this.formInline.endDay).getTime();
|
|
|
|
if (date1 > date2) {
|
|
this.$message('开始时间不得晚于结束时间');
|
|
return;
|
|
}
|
|
this.listQuery = {
|
|
pageNo: 1,
|
|
pageSize: 10,
|
|
total: 1,
|
|
...this.formInline,
|
|
};
|
|
this.getDataList();
|
|
break;
|
|
case 'reset':
|
|
this.formInline.name = null;
|
|
this.formInline.code = null;
|
|
this.formInline.deptId = null;
|
|
this.$refs.deptSelect.clear();
|
|
this.formInline.status = null;
|
|
this.listQuery = {
|
|
pageSize: 10,
|
|
pageNo: 1,
|
|
total: 1,
|
|
};
|
|
this.getDataList();
|
|
break;
|
|
case 'add':
|
|
this.addOrEditTitle = '添加排班计划';
|
|
this.addOrUpdateVisible = true;
|
|
this.$nextTick(() => {
|
|
this.$refs.addOrUpdate.init();
|
|
});
|
|
break;
|
|
case 'export':
|
|
this.handleExport();
|
|
break;
|
|
default:
|
|
console.log(val);
|
|
}
|
|
},
|
|
setDeptId(val) {
|
|
this.formInline.deptId = val;
|
|
},
|
|
setStepNum(val) {
|
|
this.stepNum = val;
|
|
},
|
|
successSubmit() {
|
|
this.addOrUpdateVisible = false;
|
|
this.addOrEditTitle = '';
|
|
this.stepNum = 1;
|
|
this.getDataList();
|
|
},
|
|
// dialog取消
|
|
handleCancel() {
|
|
this.$refs.addOrUpdate.cancelStep();
|
|
},
|
|
handleConfirm(val) {
|
|
if (val == 'up') {
|
|
this.$refs.addOrUpdate.upSubmit();
|
|
} else {
|
|
this.$refs.addOrUpdate.nextSubmit();
|
|
}
|
|
},
|
|
//tableBtn点击
|
|
handleClick(val) {
|
|
if (val.type === 'edit') {
|
|
this.addOrUpdateVisible = true;
|
|
this.addOrEditTitle = '编辑';
|
|
this.$nextTick(() => {
|
|
this.$refs.addOrUpdate.init(val.data.id);
|
|
});
|
|
} else if (val.type === 'delete') {
|
|
this.deleteHandle(val.data.id, val.data.name, val.data._pageIndex);
|
|
} else if (val.type === 'detail') {
|
|
this.detailVisible = true;
|
|
this.$nextTick(() => {
|
|
this.$refs.detailRef.init(val.data.id);
|
|
});
|
|
} else if (val.type === 'cancel') {
|
|
disablePlan(val.data.id).then((res) => {
|
|
this.$modal.msgSuccess('作废成功');
|
|
this.getDataList();
|
|
});
|
|
} else if (val.type === 'sync') {
|
|
updateScheduleLater({
|
|
planId: val.data.id,
|
|
logId: val.data.updateLogId,
|
|
}).then((res) => {
|
|
this.$modal.msgSuccess('同步节假日成功');
|
|
this.getDataList();
|
|
});
|
|
} else if (val.type === 'copy') {
|
|
copyPlan(val.data.id).then((res) => {
|
|
this.$modal.msgSuccess('复制成功');
|
|
this.getDataList();
|
|
});
|
|
}
|
|
},
|
|
detailCancel() {
|
|
this.detailVisible = false;
|
|
},
|
|
/** 导出按钮操作 */
|
|
handleExport() {
|
|
// 处理查询参数
|
|
let params = { ...this.formInline };
|
|
params.pageNo = undefined;
|
|
params.pageSize = undefined;
|
|
this.$modal
|
|
.confirm('是否确认导出所有数据项?')
|
|
.then(() => {
|
|
this.exportLoading = true;
|
|
return exportExcel(params);
|
|
})
|
|
.then((response) => {
|
|
this.$download.excel(response, '排班计划.xls');
|
|
this.exportLoading = false;
|
|
})
|
|
.catch(() => {});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scope>
|
|
.searchBarBox {
|
|
width: 100%;
|
|
position: relative;
|
|
margin-bottom: 8px;
|
|
}
|
|
.searchBarBox::after {
|
|
content: '';
|
|
display: block;
|
|
clear: both;
|
|
}
|
|
.searchBar .blue-block {
|
|
display: inline-block;
|
|
float: left;
|
|
width: 4px;
|
|
height: 16px;
|
|
background-color: #0b58ff;
|
|
border-radius: 1px;
|
|
margin-right: 8px;
|
|
margin-top: 12px;
|
|
}
|
|
.searchBar .el-form-item {
|
|
margin-bottom: 4px;
|
|
}
|
|
.searchBar .separateStyle {
|
|
display: inline-block;
|
|
width: 1px;
|
|
height: 24px;
|
|
background: #e8e8e8;
|
|
vertical-align: middle;
|
|
}
|
|
.searchBar .vue-treeselect__control {
|
|
height: 32px !important;
|
|
line-height: 32px !important;
|
|
margin: 4px 0;
|
|
}
|
|
body .el-dialog__header {
|
|
font-size: 16px;
|
|
color: rgba(0, 0, 0, 0.85);
|
|
font-weight: 500;
|
|
padding: 13px 24px;
|
|
border-bottom: 1px solid #e9e9e9;
|
|
}
|
|
body .el-dialog__header .titleStyle::before {
|
|
content: '';
|
|
display: inline-block;
|
|
width: 4px;
|
|
height: 16px;
|
|
background-color: #0b58ff;
|
|
border-radius: 1px;
|
|
margin-right: 8px;
|
|
position: relative;
|
|
top: 2px;
|
|
}
|
|
</style>
|