<template>
|
<div class="app-container">
|
<div class="search_form">
|
<div class="search-row">
|
<div class="search-item">
|
<span class="search_title">工单编号:</span>
|
<el-input v-model="searchForm.workOrderNo"
|
style="width: 240px"
|
placeholder="请输入"
|
@change="handleQuery"
|
clearable
|
prefix-icon="Search" />
|
</div>
|
<div class="search-item">
|
<span class="search_title">报工人:</span>
|
<el-select v-model="searchForm.workerName"
|
style="width: 240px"
|
placeholder="请选择"
|
clearable
|
filterable
|
@change="handleQuery">
|
<el-option v-for="item in userOptions"
|
:key="item.userId"
|
:label="item.nickName"
|
:value="item.nickName" />
|
</el-select>
|
</div>
|
<div class="search-item">
|
<el-button type="primary"
|
@click="handleQuery">搜索</el-button>
|
</div>
|
</div>
|
</div>
|
<div class="table_list">
|
<PIMTable rowKey="id"
|
:column="tableColumn"
|
:tableData="tableData"
|
:page="page"
|
:tableLoading="tableLoading"
|
@pagination="pagination">
|
<template #completionStatus="{ row }">
|
<el-progress :percentage="toProgressPercentage(row?.completionStatus)"
|
:color="progressColor(toProgressPercentage(row?.completionStatus))"
|
:status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
|
</template>
|
</PIMTable>
|
</div>
|
|
<!-- 编辑时间弹窗 -->
|
<el-dialog v-model="editDialogVisible"
|
title="编辑计划时间"
|
width="500px">
|
<el-form :model="editrow"
|
label-width="120px">
|
<el-form-item label="计划开始时间">
|
<el-date-picker v-model="editrow.planStartTime"
|
type="date"
|
placeholder="请选择"
|
value-format="YYYY-MM-DD"
|
style="width: 300px" />
|
</el-form-item>
|
<el-form-item label="计划结束时间">
|
<el-date-picker v-model="editrow.planEndTime"
|
type="date"
|
placeholder="请选择"
|
value-format="YYYY-MM-DD"
|
style="width: 300px" />
|
</el-form-item>
|
<el-form-item label="报工人">
|
<el-select v-model="editrow.workerId"
|
placeholder="请选择"
|
style="width: 100%"
|
@change="handleWorkerChange">
|
<el-option v-for="item in userOptions"
|
:key="item.userId"
|
:label="item.nickName"
|
:value="item.userId" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="交接人">
|
<el-select v-model="editrow.handoverUserId"
|
placeholder="请选择"
|
style="width: 100%"
|
@change="handleHandoverUserChange">
|
<el-option v-for="item in userOptions"
|
:key="item.userId"
|
:label="item.nickName"
|
:value="item.userId" />
|
</el-select>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button type="primary"
|
@click="handleUpdate">确定</el-button>
|
<el-button @click="editDialogVisible = false">取消</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { onMounted, ref, nextTick } from "vue";
|
import { ElMessageBox } from "element-plus";
|
import dayjs from "dayjs";
|
import {
|
productWorkOrderPage,
|
updateProductWorkOrder,
|
} from "@/api/productionManagement/workOrder.js";
|
import { getCurrentInstance, reactive, toRefs } from "vue";
|
import { userListAll } from '@/api/publicApi'
|
|
const { proxy } = getCurrentInstance();
|
|
const tableColumn = ref([
|
{
|
label: "工单类型",
|
prop: "workOrderType",
|
width: "80",
|
},
|
{
|
label: "工单编号",
|
prop: "workOrderNo",
|
width: "140",
|
},
|
{
|
label: "生产订单号",
|
prop: "productOrderNpsNo",
|
width: "140",
|
},
|
{
|
label: "产品名称",
|
prop: "productName",
|
width: "140",
|
},
|
{
|
label: "规格",
|
prop: "model",
|
},
|
{
|
label: "单位",
|
prop: "unit",
|
},
|
{
|
label: "工序名称",
|
prop: "processName",
|
},
|
{
|
label: "需求数量",
|
prop: "planQuantity",
|
width: "140",
|
},
|
{
|
label: "完成数量",
|
prop: "completeQuantity",
|
width: "140",
|
},
|
{
|
label: "完成进度",
|
prop: "completionStatus",
|
dataType: "slot",
|
slot: "completionStatus",
|
width: "140",
|
},
|
{
|
label: "计划开始时间",
|
prop: "planStartTime",
|
width: "140",
|
},
|
{
|
label: "计划结束时间",
|
prop: "planEndTime",
|
width: "140",
|
},
|
{
|
label: "实际开始时间",
|
prop: "actualStartTime",
|
width: "140",
|
},
|
{
|
label: "实际结束时间",
|
prop: "actualEndTime",
|
width: "140",
|
},
|
{
|
label: "报工人",
|
prop: "workerName",
|
width: "120",
|
formatter: row => row?.workerName || (row?.workerId ? row.workerId : "-"),
|
},
|
{
|
label: "交接人",
|
prop: "handoverUserName",
|
width: "120",
|
formatter: row => row?.handoverUserName || (row?.handoverUserId ? row.handoverUserId : "-"),
|
},
|
{
|
label: "操作",
|
width: "100",
|
align: "center",
|
dataType: "action",
|
fixed: "right",
|
operation: [
|
{
|
name: "指派",
|
clickFun: row => {
|
handleEdit(row);
|
},
|
},
|
],
|
},
|
]);
|
|
const tableData = ref([]);
|
const tableLoading = ref(false);
|
const editDialogVisible = ref(false);
|
let editrow = ref(null);
|
const page = reactive({
|
current: 1,
|
size: 100,
|
total: 0,
|
});
|
|
const data = reactive({
|
searchForm: {
|
workOrderNo: "",
|
workerName: "",
|
},
|
});
|
const { searchForm } = toRefs(data);
|
const toProgressPercentage = val => {
|
const n = Number(val);
|
if (!Number.isFinite(n)) return 0;
|
if (n <= 0) return 0;
|
if (n >= 100) return 100;
|
return Math.round(n);
|
};
|
const progressColor = percentage => {
|
const p = toProgressPercentage(percentage);
|
if (p < 30) return "#f56c6c";
|
if (p < 50) return "#e6a23c";
|
if (p < 80) return "#409eff";
|
return "#67c23a";
|
};
|
|
const userOptions = ref([]);
|
const loadUserOptions = async () => {
|
try {
|
const res = await userListAll();
|
userOptions.value = res.data;
|
} catch (error) {
|
console.error("获取用户列表失败", error);
|
}
|
};
|
|
const handleWorkerChange = val => {
|
const user = (userOptions.value || []).find(item => item.userId === val);
|
if (editrow.value) {
|
editrow.value.workerName = user ? (user.nickName || user.userName || "") : "";
|
}
|
};
|
|
const handleHandoverUserChange = val => {
|
const user = (userOptions.value || []).find(item => item.userId === val);
|
if (editrow.value) {
|
editrow.value.handoverUserName = user ? (user.nickName || user.userName || "") : "";
|
}
|
};
|
|
const normalizeNullableUserId = value => {
|
if (value === undefined || value === null || value === "") return null;
|
const n = Number(value);
|
if (!Number.isFinite(n) || n <= 0) return null;
|
return n;
|
};
|
// 查询列表
|
/** 搜索按钮操作 */
|
const handleQuery = () => {
|
page.current = 1;
|
getList();
|
};
|
const pagination = obj => {
|
page.current = obj.page;
|
page.size = obj.limit;
|
getList();
|
};
|
const getList = () => {
|
tableLoading.value = true;
|
const params = { ...searchForm.value, ...page };
|
productWorkOrderPage(params)
|
.then(res => {
|
tableLoading.value = false;
|
tableData.value = res.data.records;
|
page.total = res.data.total;
|
})
|
.catch(() => {
|
tableLoading.value = false;
|
});
|
};
|
|
const handleEdit = row => {
|
editrow.value = JSON.parse(JSON.stringify(row));
|
editrow.value.workerId = normalizeNullableUserId(editrow.value.workerId);
|
editrow.value.handoverUserId = normalizeNullableUserId(editrow.value.handoverUserId);
|
editDialogVisible.value = true;
|
};
|
|
const handleUpdate = () => {
|
editrow.value.workerId = normalizeNullableUserId(editrow.value.workerId);
|
editrow.value.handoverUserId = normalizeNullableUserId(editrow.value.handoverUserId);
|
if (!editrow.value.workerId) editrow.value.workerName = null;
|
if (!editrow.value.handoverUserId) editrow.value.handoverUserName = null;
|
updateProductWorkOrder(editrow.value)
|
.then(res => {
|
proxy.$modal.msgSuccess("提交成功");
|
editDialogVisible.value = false;
|
getList();
|
})
|
.catch(() => {
|
ElMessageBox.alert("修改失败", "提示", {
|
confirmButtonText: "确定",
|
});
|
});
|
};
|
|
onMounted(() => {
|
getList();
|
loadUserOptions();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.search-row {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
}
|
.search-item {
|
display: flex;
|
align-items: center;
|
}
|
.search_title {
|
margin-right: 8px;
|
font-size: 14px;
|
color: #606266;
|
}
|
</style>
|