heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/partpurchase/index.vue
2025-07-10 13:16:34 +08:00

406 lines
16 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>
<el-card class="hl-card">
<template #header>
<span>零件采购</span>
</template>
<ContentWrap class="borderxx">
<!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="120px">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="子项目名称" prop="projectSubName">
<el-input v-model="queryParams.projectSubName" placeholder="请输入子项目名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="零件名称" prop="matName">
<el-input v-model="queryParams.matName" placeholder="请输入零件名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="项目编码" prop="projectCode">
<el-input v-model="queryParams.projectCode" placeholder="请输入项目编号" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="责任人" prop="duEmpName">
<el-input v-model="queryParams.duEmpName" placeholder="请输入责任人" clearable @keyup.enter="handleQuery" class="!w-240px"/>
</el-form-item>
<el-form-item label="采购状态" prop="mplanStatus">
<el-select v-model="queryParams.mplanStatus" placeholder="请选择采购状态" clearable class="!w-240px">
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.MATERIAL_PLAN_BOOM_MPLAN_STATUS)" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="物料需求单号" prop="projectMaterialPlanNo">
<el-input v-model="queryParams.projectMaterialPlanNo" placeholder="请输入物料需求单号" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item style="margin-left:30px">
<el-button @click="handleQuery" type="primary">
<Icon icon="ep:search" class="mr-5px" /> 搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> 重置
</el-button>
<el-button
type="success"
plain
@click="handleExportDetail"
:loading="exportLoading"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">零件明细</span>
<el-button style="margin-left: 18px" @click="singleSubmissions()" type="success" size="large">送 审</el-button>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-form ref="multipleTable" :model="list" v-loading="formLoading" label-width="0" >
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" class="hl-table" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column fixed label="序号" align="center" type="index" width="60" />
<el-table-column label="工序" align="center" prop="procedureName" min-width="100" fixed>
<template #default="scope">
<el-button text type="primary">
{{ scope.row.procedureName }}
</el-button>
</template>
</el-table-column>
<el-table-column label="客户简称" align="center" prop="brief" min-width="180" fixed />
<el-table-column label="项目名称" align="center" prop="projectName" min-width="180" fixed />
<el-table-column label="子项目名称" align="center" prop="projectSubName" min-width="180" />
<el-table-column label="泡沫" align="center" prop="isFoams">
<template #default="{ row }">
<el-checkbox v-model="row.isFoams" @change="handleOutsourcingChange(row)" disabled/>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>泡沫费用</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.foamPrice`" class="mb-0px!" v-if="row.isFoams == 'Y'||row.isFoams==true">
<el-input-number v-model="row.foamPrice" type="number" :precision="0" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="零件名称" align="center" prop="matName" min-width="180" />
<el-table-column label="材质" align="center" prop="compositionName" min-width="120" />
<el-table-column label="图号" align="center" prop="blueprintNo" min-width="120" />
<el-table-column label="需求数量" align="center" prop="boomAmount" min-width="120" />
<el-table-column label="单位" align="center" prop="unit" min-width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_MATERIAL_UNIT" :value="scope.row.unit" />
</template>
</el-table-column>
<el-table-column min-width="200px" align="center">
<template #header><span class="hl-table_header">*</span>采购数量</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.purchaseAmount`" class="mb-0px!" >
<el-input-number v-model="row.purchaseAmounts" type="number" :precision="0" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>供应商</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.supplierIds`" class="mb-0px!" >
<SupplierSelect v-model="row.supplierIds" class="!w-265px" clearable @update:newValue="handleSelectedUser($index, $event)"/>
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center">
<template #header><span class="hl-table_header">*</span>预估总价</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.estimatedPrices`" class="mb-0px!" >
<el-input-number v-model="row.estimatedPrices" type="number" :precision="2" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>预计到货日期</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.arriveTimes`" class="mb-0px!" >
<el-date-picker class="!w-265px" v-model="row.arriveTimes" type="date" value-format="x" placeholder="预计到货日期" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header>技术要求</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.descriptions`" class="mb-0px!" >
<el-input class="!w-265px" v-model="row.descriptions" placeholder="技术要求" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center">
<template #header>理论重量(吨)</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.theWeight`" class="mb-0px!" >
<el-input-number v-model="row.theWeight" type="number" :precision="3" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="责任人" align="center" prop="duEmpName" min-width="120" />
<el-table-column label="状态" align="center" prop="mplanStatus" min-width="120" >
<template #default="scope">
{{
getIntDictOptions(DICT_TYPE.MATERIAL_PLAN_BOOM_MPLAN_STATUS).find(
(dict) => dict.value === scope.row.mplanStatus
)?.label || '未知状态'
}}
</template>
</el-table-column>
<el-table-column label="打回原因" align="center" prop="rejRemark" min-width="120" />
<el-table-column label="采购单号" align="center" prop="purchaseNo" min-width="120" />
</el-table>
<!-- 分页 -->
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-form>
</el-card>
</el-col>
</el-row>
</el-card>
</el-card>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import download from '@/utils/download'
import { useCommonStateWithOut } from '@/store/modules/common'
import {inject, ref} from "vue";
import * as MaterialPlanApi from "@/api/heli/materialplan";
import * as MaterialPlanBoomApi from "@/api/heli/materialplanboom";
import * as PartPurchaseOrderApi from "@/api/heli/partpurchaseorder";
import {ElTable} from "element-plus";
import {useUserStore} from "@/store/modules/user";
import SupplierSelect from "@/views/heli/hlvuestyle/supplierSelect.vue";
import {setFlagsFromString} from "node:v8";
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const userStore = useUserStore()
const username = userStore.getUser.nickname
const reload: any = inject('reload')
const commonStore = useCommonStateWithOut()
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const router = useRouter()
const multipleTable = ref<InstanceType<typeof ElTable>>()
const multipleSelection = ref([])
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
planCode: undefined,
projectCode: undefined,
projectSubCode: undefined,
customerName: undefined,
projectName: undefined,
projectSubName: undefined,
version: undefined,
bomStatus: undefined,
remark: undefined,
mplanStatus: 0,
createTime: [],
duEmpName:username,
materialName:undefined,
matName:undefined,
projectMaterialPlanNo:undefined,
matType:1
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
list.value=[]
const data = await MaterialPlanApi.getPartPurchasePages(queryParams)
list.value = data.list
list.value.forEach(item=> {
if(item.isFoams == 'Y'){
item.isFoams = true
}else{
item.isFoams = false
}
if (item.flag==1){
item.isFoams = true
item.isFoam = 'Y'
}else {
item.isFoams = false
item.isFoam = 'N'
}
})
total.value = data.total
} finally {
loading.value = false
}
}
/** 导出按钮操作 */
const handleExportDetail = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
// 发起导出
exportLoading.value = true
const data = await MaterialPlanApi.exportPart(queryParams)
download.excel(data, '零件物料需求计划.xlsx')
} catch {
} finally {
exportLoading.value = false
}
}
const handleOutsourcingChange= async (row: any) => {
if(row.isFoams == false){
row.isFoam = 'N'
}else{
row.isFoam = 'Y'
}
}
const handleSelectionChange = (val) => {
// multipleTable.value.clearSelection()
multipleTable.value=val
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
// //接收供应商传递的数据
// const handleSelectedSupplier = (newValue: any) => {
// formData.value.supplierId = newValue?.id
// }
const handleSelectedUser = (currentIndex, newValue: any) => {
list.value[currentIndex].supplierIds = newValue?.id
}
const singleSubmissions=()=>{
submitForm();
}
const submitForm = async () => {
try {
console.log("开始提交"); // 调试点1确认函数是否触发
const list = multipleTable.value|| []; // 安全获取数据
console.log(list);
// 1. 检查空数据
if (!list || list.length==null) {
message.error("提交明细不能为空,请确认");
return;
}
let i;
for (i = 0; i < list.length; i++) {
if (list[i].purchaseAmounts === null || list[i].purchaseAmounts === 0) {
message.error("采购数量为0或空");
break;
}
if (list[i].isFoam==true||list[i].isFoam=='Y'){
if (list[i].foamPrice === null || list[i].foamPrice === 0) {
message.error("泡沫费用为0或空");
break;
}
}
if (list[i].supplierIds === null) {
message.error("供应商为空");
break;
}
if (list[i].arriveTimes === null) {
message.error("预计到货日期为空");
break;
}
if (list[i].estimatedPrices === null) {
message.error("预估总价为空");
break;
}
}
if (i < list.length){
return;
}
// 2. 检查项目一致性
const firstProjectName = list[0].projectName;
if (list.some(item => item.projectName !== firstProjectName)) {
message.error("不同项目不能同时生成采购单");
return;
}
//3. 检查生成采购订单状态
const checkMaterialPlans = async () => {
for (const item of list) {
const checkParams = await MaterialPlanBoomApi.getMaterialPlanBoom(item.id);
if (checkParams.projectPurchaseOrderMakeId !== null) {
message.warning("存在零件清单已生成采购订单,请刷新界面!");
return false; // 提前终止检查
}
}
return true; // 所有检查通过
};
// 调用方法
const allValid = await checkMaterialPlans();
if (!allValid) {
// 继续后续操作
return;
}
// 4. 添加加载状态Element Plus 兼容处理)
formLoading.value = true;
console.log(list)
// 5. 提交数据(添加超时处理)
const res = await Promise.race([
PartPurchaseOrderApi.createPurchaseOrderMakeAndDetail(list),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("请求超时")), 30000)
)
]);
message.success("提交成功");
getList(); // 确保刷新完成
emit('success');
} catch (error) {
console.error("提交失败:", error);
// message.error(`操作失败: ${error.message || "未知错误"}`);
} finally {
formLoading.value = false;
}
}
const withdraw = async () => {
if (queryParams.projectMaterialPlanNo==null){
message.error("物料需求单号为空,不允许撤回")
return
}
await MaterialPlanApi.withdraw(queryParams.projectMaterialPlanNo)
message.success("撤回成功")
// 发送操作成功的事件
getList()
emit('success')
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>
<style>
/* 占位样式 */
</style>