Files
klp-oa/klp-ui/src/views/aps/planSheet/PlanSheetList.vue
砂糖 5b38ef734a feat(排产单): 新增排产单追踪页面和钢卷列表查询功能
- 添加排产单追踪页面,展示排产单详情和对应钢卷信息
- 新增listPlanCoils接口用于查询排产单对应的钢卷列表
- 在PlanSheetList组件中添加readonly属性控制操作按钮显示
- 优化CoilTable组件中钢卷号的列名显示
2026-04-27 18:36:23 +08:00

492 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div class="tab-container">
<div class="select-button" @click="openPlanSheetDialog">
<i class="el-icon-setting"></i>
</div>
<div class="custom-tabs">
<div class="tab-header">
<div
v-for="planSheet in planSheetList"
:key="planSheet.planSheetId"
class="tab-item"
:class="{ active: activeTab === planSheet.planSheetId.toString() }"
@click="handleTabClick(planSheet)"
>
<div class="tab-title">{{ planSheet.planCode }}</div>
<div class="tab-info">
<span>{{ planSheet.lineName }}</span>
<span class="date">{{ parseTime(planSheet.planDate, '{y}-{m}-{d}') }}</span>
</div>
</div>
<div v-if="planSheetList.length === 0" class="tab-item disabled">
<div class="tab-title">暂无排产单</div>
<div class="tab-info">请点击齿轮图标选择排产单</div>
</div>
</div>
</div>
</div>
<!-- 排产单选择对话框 -->
<el-dialog :title="'选择排产单'" :visible.sync="planSheetDialogVisible" width="900px" append-to-body>
<div class="dialog-toolbar">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
<el-form-item label="排产日期" prop="planDate">
<el-date-picker clearable v-model="queryParams.planDate" type="date" value-format="yyyy-MM-dd"
placeholder="请选择排产日期">
</el-date-picker>
</el-form-item>
<el-form-item label="产线名称" prop="lineName">
<el-input v-model="queryParams.lineName" placeholder="请输入产线名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="排产单号" prop="planCode">
<el-input v-model="queryParams.planCode" placeholder="请输入排产单号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="排产人" prop="scheduler">
<el-input v-model="queryParams.scheduler" placeholder="请输入排产人" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-if="!readonly">新增</el-button>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-table v-loading="loading" :data="allPlanSheetList" height="350px" @row-click="handleTabClick">
<el-table-column label="排产日期" align="center" prop="planDate" width="140">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.planDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="产线名称" align="center" prop="lineName" />
<el-table-column label="排产单号" align="center" prop="planCode" />
<el-table-column label="排产人" align="center" prop="scheduler" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-download" @click.stop="handleExport(scope.row)">导出</el-button>
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(scope.row)">修改</el-button>
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
</el-dialog>
<!-- 添加或修改排产单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="排产日期" prop="planDate">
<el-date-picker clearable v-model="form.planDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择排产日期">
</el-date-picker>
</el-form-item>
<el-form-item label="产线名称" prop="lineName">
<el-select v-model="form.lineName" placeholder="请选择产线名称" filterable clearable>
<el-option v-for="item in dict.type.sys_lines" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="排产单号" prop="planCode">
<el-input v-model="form.planCode" placeholder="请输入排产单号" />
</el-form-item>
<el-form-item label="排产人" prop="scheduler">
<el-input v-model="form.scheduler" placeholder="请输入排产人" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listPlanSheet, getPlanSheet, delPlanSheet, addPlanSheet, updatePlanSheet } from "@/api/aps/planSheet";
export default {
name: "PlanSheetList",
dicts: ['sys_lines'],
props: {
selectFirst: {
type: Boolean,
default: true
},
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 总条数
total: 0,
// 排产单表格数据用于tab展示
planSheetList: [],
// 所有排产单数据(用于选择对话框)
allPlanSheetList: [],
// 弹出层标题
title: "",
// 是否显示添加/修改弹出层
open: false,
// 是否显示排产单选择弹出层
planSheetDialogVisible: false,
// 当前激活的tab
activeTab: '',
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 6,
planDate: undefined,
lineId: undefined,
lineName: undefined,
planCode: undefined,
planType: undefined,
scheduler: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
planSheetId: [
{ required: true, message: "排产单键ID不能为空", trigger: "blur" }
],
planDate: [
{ required: true, message: "排产日期不能为空", trigger: "blur" }
],
lineId: [
{ required: true, message: "产线ID不能为空", trigger: "blur" }
],
lineName: [
{ required: true, message: "产线名称不能为空", trigger: "blur" }
],
planCode: [
{ required: true, message: "排产单号不能为空", trigger: "blur" }
],
planType: [
{ required: true, message: "排产类型不能为空", trigger: "change" }
],
scheduler: [
{ required: true, message: "排产人不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList().then((list) => {
// 如果有数据,选中第一个
if (list.length > 0) {
this.activeTab = list[0].planSheetId.toString();
if (this.selectFirst) {
this.handleRowClick(list[0]);
}
}
});
},
methods: {
parseTime(time, pattern) {
if (!time) return '';
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
const date = new Date(time);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
return format.replace('{y}', year)
.replace('{m}', month.toString().padStart(2, '0'))
.replace('{d}', day.toString().padStart(2, '0'))
.replace('{h}', hour.toString().padStart(2, '0'))
.replace('{i}', minute.toString().padStart(2, '0'))
.replace('{s}', second.toString().padStart(2, '0'));
},
/** 查询排产单列表 */
async getList() {
this.loading = true;
const response = await listPlanSheet(this.queryParams);
this.allPlanSheetList = response.rows;
this.total = response.total;
// 默认显示所有排产单
this.planSheetList = response.rows;
this.loading = false;
return this.planSheetList;
},
// 点击排产单行
handleRowClick(row) {
this.$emit('row-click', row);
},
// 点击tab
handleTabClick(planSheet) {
this.activeTab = planSheet.planSheetId.toString();
this.planSheetDialogVisible = false;
this.handleRowClick(planSheet);
},
// 打开排产单选择对话框
openPlanSheetDialog() {
this.getList();
this.planSheetDialogVisible = true;
},
// 选择排产单行
handlePlanSheetSelect(row) {
this.$refs['queryForm'].$refs.table.toggleRowSelection(row);
},
// 确认选择排产单
confirmSelect() {
const selectedRows = this.$refs['queryForm'].$refs.table.selection;
if (selectedRows.length > 0) {
this.planSheetList = selectedRows;
this.activeTab = selectedRows[0].planSheetId.toString();
this.handleRowClick(selectedRows[0]);
}
this.planSheetDialogVisible = false;
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
// 日期默认选中今天 yyyy-MM-dd格式北京时间
// planCode与日期格式一致添加-HHmmss
// 排产人默认当前登录用户 this.$store.getters.nickName
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const dateStr = `${year}-${month}-${day}`;
const timeStr = `${hours}${minutes}${seconds}`;
this.form = {
planSheetId: undefined,
planDate: dateStr,
lineId: undefined,
lineName: undefined,
planCode: `${dateStr}-${timeStr}`,
planType: undefined,
scheduler: this.$store.getters.nickName || undefined,
remark: undefined,
delFlag: undefined,
createBy: undefined,
updateBy: undefined,
createTime: undefined,
updateTime: undefined
};
this.resetForm("form");
},
// 重置表单
resetForm(formName) {
if (this.$refs[formName]) {
this.$refs[formName].resetFields();
}
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加排产单";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const planSheetId = row.planSheetId;
getPlanSheet(planSheetId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改排产单";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.planSheetId != null) {
updatePlanSheet(this.form).then(response => {
this.$message({
message: "修改成功",
type: "success"
});
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addPlanSheet(this.form).then(response => {
this.$message({
message: "新增成功",
type: "success"
});
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const planSheetIds = row.planSheetId;
this.$confirm('是否确认删除排产单编号为"' + planSheetIds + '"的数据项?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.loading = true;
return delPlanSheet(planSheetIds);
}).then(() => {
this.loading = false;
this.getList();
this.$message({
message: "删除成功",
type: "success"
});
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport(row) {
this.download('aps/planSheet/exportAll', {
...this.queryParams,
planSheetId: row.planSheetId,
}, `planSheet_${new Date().getTime()}.xlsx`);
},
}
};
</script>
<style scoped>
.tab-container {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.select-button {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
border: 1px solid #e4e7ed;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
background-color: #f9f9f9;
color: #606266;
font-size: 14px;
user-select: none;
margin-right: 10px;
color: #409eff;
}
.select-button:hover {
background-color: #ecf5ff;
border-color: #c6e2ff;
color: #409eff;
}
.custom-tabs {
flex: 1;
border-bottom: 1px solid #e4e7ed;
}
.tab-header {
display: flex;
flex-wrap: wrap;
gap: 4px;
}
.tab-item {
padding: 4px 4px;
border: 1px solid #e4e7ed;
border-bottom: none;
border-radius: 4px 4px 0 0;
cursor: pointer;
transition: all 0.3s ease;
background-color: #f9f9f9;
min-width: 200px;
}
.tab-item:hover {
background-color: #ecf5ff;
border-color: #c6e2ff;
}
.tab-item.active {
background-color: #ffffff;
border-color: #409eff;
border-bottom-color: #ffffff;
color: #409eff;
box-shadow: 0 -2px 0 0 #409eff inset;
}
.tab-item.disabled {
cursor: not-allowed;
background-color: #f5f7fa;
color: #c0c4cc;
border-color: #ebeef5;
}
.tab-title {
font-size: 14px;
font-weight: 500;
margin-bottom: 1px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tab-info {
font-size: 12px;
color: #909399;
display: flex;
justify-content: space-between;
align-items: center;
}
.tab-info .date {
color: #606266;
font-weight: 400;
}
.empty-content {
padding: 40px;
text-align: center;
color: #999;
}
.dialog-toolbar {
display: flex;
align-items: center;
margin-bottom: 15px;
}
</style>