heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/materialplan/purchasemake.vue
2026-03-05 09:00:48 +08:00

521 lines
17 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="projectCode">
<el-input v-model="queryParams.projectCode" placeholder="请输入项目编号" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<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="customerName">
<el-input v-model="queryParams.customerName" 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="boomName">
<el-input v-model="queryParams.boomName" placeholder="请输入零件名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="采购状态" prop="orderStatus">
<el-select @change="e => clearItem(e)" clearable v-model="queryParams.orderStatus" placeholder="请选择采购状态" class="!w-240px">
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.HELI_PURCHASE_STATUS)" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</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: 20px" @click="opearteForm(0)" type="success" size="large">订单生成</el-button>
<el-button style="margin-left: 20px" @click="opearteForm(1)" type="warning" size="large">采购订单管理</el-button>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-form ref="subFormRef" :model="list" v-loading="formLoading" label-width="0" >
<el-table
:row-key="getRowKeys" ref="multipleTable"
@selection-change="handleSelectionChange" v-loading="loading" :data="list" :show-overflow-tooltip="true" class="hl-table">
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
/>
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="子项目编码" align="center" prop="projectSubCode" min-width="150" />
<el-table-column label="物料编码" align="center" min-width="180" >
<template #header><span class="hl-table_header">*</span>物料编码</template>
<!-- <template #default="scope">-->
<!-- <el-select-->
<!-- v-model="scope.row.boomCode"-->
<!-- placeholder="请输入物料编码或名称"-->
<!-- :remote-method="e => remoteMethod(e,scope.row)"-->
<!-- remote-show-suffix-->
<!-- remote-->
<!-- @click="remoteMethod(scope.row.boomCode,scope.row)"-->
<!-- :disabled="scope.row.orderStatus == 2"-->
<!-- clearable-->
<!-- reserve-keyword-->
<!-- filterable-->
<!-- @change="e => changeSupp(e,scope.row)"-->
<!-- :loading="meterialLoading"-->
<!-- class="!w-150px"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item in scope.row.materialSelectList"-->
<!-- :key="item.code"-->
<!-- :label="item.code"-->
<!-- :value="item"-->
<!-- >-->
<!-- <span style="float: left">{{ item.name }}</span>-->
<!-- <span style="float: right; color: #8492a6; font-size: 13px">{{ item.code }}</span>-->
<!-- </el-option>-->
<!-- </el-select>-->
<!--</template>-->
<template #default="scope">
<el-input v-model="scope.row.matName" disabled>
<template #suffix>
<Icon @click="serachLog(scope.row)" icon="ep:search" color="primary"/>
</template>
</el-input>
</template>
</el-table-column>
<el-table-column label="标准件名称" align="center" prop="boomName" min-width="150" />
<el-table-column label="规格型号" align="center" prop="boomSpec" min-width="150" />
<el-table-column label="需求数量" align="center" prop="boomAmount" min-width="100" />
<el-table-column label="采购数量" align="center" prop="purchaseAmount" min-width="180" />
<el-table-column label="需求完成时间" align="center" prop="requireTime" :formatter="dateFormatter2" min-width="180" />
<el-table-column label="计划到货日期" align="center" prop="arriveTime" :formatter="dateFormatter2" min-width="180" />
<el-table-column label="供应商" align="center" prop="supplierName" min-width="180" >
<template #default="scope">
<el-select
v-model="scope.row.supplierId"
size="large"
disabled
filterable
style="width: 165 px"
>
<el-option
v-for="item in supplierList"
:key="item.id"
:label="item.brief"
:value="item.id"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="价格" align="center" prop="estimatedPrice" min-width="120" />
<el-table-column label="状态" align="center" prop="orderStatus" min-width="80" >
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_PURCHASE_STATUS" :value="scope.row.orderStatus" />
</template>
</el-table-column>
<el-table-column label="采购单号" align="center" prop="purchaseNo" min-width="180" />
</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>
<div class="hl-footer text-center">
</div>
</el-card>
<matLog ref="matLogRef" @success="getMat" />
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import download from '@/utils/download'
import * as purchaseOrderMakeDetailApi from '@/api/heli/purchaseordermakedetail'
import { useCommonStateWithOut } from '@/store/modules/common'
import * as matApi from '@/api/heli/material'
import { useUserStore } from '@/store/modules/user'
import matLog from './storageLogs.vue'
import * as supplierApi from '@/api/heli/supplier'
import {inject, ref} from "vue";
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const userStore = useUserStore()
const username = userStore.getUser.nickname
defineOptions({ name: 'purchasemake' })
const reload: any = inject('reload')
const commonStore = useCommonStateWithOut()
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const router = useRouter()
import {
dateFormatter,
formatDate, dateFormatter2
} from "@/utils/formatTime";
const meterialLoading = ref(false)
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
planCode: undefined,
projectCode: undefined,
customerName: undefined,
boomName:undefined,
projectName: undefined,
projectSubName: undefined,
version: undefined,
bomStatus: undefined,
remark: undefined,
orderStatus: 1,
createTime: [],
ownerName:username,
materialName:undefined,
projectMaterialPlanNo:undefined
})
const queryParams1 = reactive({
pageNo: 1,
pageSize: 999,
status:1,
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const matLogRef = ref()
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
multipleTable.value.clearSelection();
const data = await purchaseOrderMakeDetailApi.page(queryParams)
list.value = data.list
for (const row of list.value ) {
// 如果boomCode不为空则调用remoteMethod进行查询
if (row.boomCode) {
await remoteMethod(row.boomCode, row);
}
}
total.value = data.total
} finally {
loading.value = false
}
}
const ids = ref([])
const multipleTable=ref()
const getRowKeys=(row)=>{
return row.id;
}
const materialSelectList = ref([])
const queryMaterialParams = {
pageNo: 1,
pageSize: 99,
inventoryCodes: undefined,
inventoryName: undefined,
}
const remoteMethod = async (query, row) => {
meterialLoading.value = true;
try {
if (query) {
// 更新查询参数
queryMaterialParams.inventoryName = query;
// 调用API获取物料列表
const data = await matApi.getMaterialPage(queryMaterialParams);
// 更新当前行的物料选择列表
row.materialSelectList = data.list;
} else {
// 如果没有查询条件,则清空物料选择列表
queryMaterialParams.inventoryName = undefined;
const data = await matApi.getMaterialPage(queryMaterialParams);
row.materialSelectList = data.list;
}
} catch (error) {
console.error("查询物料失败:", error);
// 发生错误时清空物料选择列表
row.materialSelectList = [];
} finally {
meterialLoading.value = false;
}
};
const getMateriallist = async(row) =>{
const data = await matApi.getMaterialPage(queryMaterialParams)
row.materialSelectList = data.list
}
const serachLog = (row) => {
matLogRef.value.open(row.id)
}
const handleSelectionChange = (selection) => {
ids.value = selection;
}
const clearItem = (e) =>{
multipleTable.value.clearSelection();
}
/** 导出按钮操作 */
const handleExportDetail = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
// 发起导出
exportLoading.value = true
const data = await materialPlanBoomApi.exportMaterialPlanBoom(queryParams)
download.excel(data, '标准件物料需求计划.xlsx')
} catch {
} finally {
exportLoading.value = false
}
}
const getMat = async (rowids,ids,matCodes,name) => {
//formData.value.boomItemDOList = arrBoom
for(var i = 0 ; i < list.value.length ; i ++){
if(list.value[i].id == rowids){
console.log(name)
list.value[i].boomCode = matCodes
list.value[i].materialId = ids
list.value[i].matName = name
console.log(list.value[i].matName)
// await updateRow(2,list.value[i]);
break;
}
}
}
const changeSupp = async(e,row) => {
if(e){
row.materialId = e.id
row.boomCode = e.code
// row.boomName = e.materialName;
// row.boomSpec = e.spec;
// row.boomUnit = e.unit
// await updateRows(row)
}else{
row.materialId = null;
await updateRows(row)
}
}
const updateRows = async(row) =>{
await purchaseOrderMakeDetailApi.updatePurchaseOrderDetail(row);
}
const changeDate = async(e,row) => {
if(e){
await updateRow(5,row)
}
}
// const serachLog = (row) => {
// matLogRef.value.open(row.id,row.matCode)
// }
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
const opearteForm = async(type) =>{
loading.value = true;
if(type == 1){
router.push({ path: '/purchase/purchaseordernomanagement', query: { flush: 1 } })
return;
}
if(ids.value != null && ids.value.length > 0){
if(type == 0){
//送审
var isError = false;
var sets = new Set();
for(var i = 0 ; i<ids.value.length ;i++){
var row = ids.value[i];
if(row.orderStatus == 2){
message.error('已生成采购订单')
loading.value = false
return
}
if(!row.materialId){
message.error('物料编码不能为空')
loading.value = false
return
}
if( !sets.has(row.supplierId) || sets == null ){
sets.add(row.supplierId)
}
}
if(sets != null && sets.size > 1){
message.error('不同供应商,不能生成一个订单,请确认!');
loading.value = false
return
}
var form = {
id:1,
purchaseOrderId:1,
boomDetailId:1,
projectPlanSubId:1,
updateList:ids.value,
buyType:0
}
try {
await purchaseOrderMakeDetailApi.updatePurchaseOrderDetail(form); // 尝试调用 API
message.success("生成成功"); // &#9888; 仅在成功时执行
} catch (error) {
} finally {
loading.value = false; // &#9209; 确保无论如何都关闭加载
await getList(); // &#128260; 无论如何都刷新列表
}
}
}else{
message.error("至少选择一项后进行操作!")
loading.value = false
return ;
}
}
const updateRow = async(type,row) =>{
if(type == 1){
if(row.purchaseAmount != null){
await materialPlanBoomApi.updateMaterialPlanBoom(row)
}
}else if(type == 2){
if(row.matRest != null){
await materialPlanBoomApi.updateMaterialPlanBoom(row)
}
}else if(type == 3){
if(row.estimatedPrice != null){
await materialPlanBoomApi.updateMaterialPlanBoom(row)
}
}else if(type == 4){
if(row.supplierId){
await materialPlanBoomApi.updateMaterialPlanBoom(row)
}
}else if(type == 5){
if(row.arriveTime){
await materialPlanBoomApi.updateMaterialPlanBoom(row)
}
}
}
const supplierList = ref([])
const supplier = async() =>{
var data = await supplierApi.getSupplierPage(queryParams1);
supplierList.value =data.list
//console.log(supplierList/)
}
const handleSelectedUser = (currentIndex, newValue: any) => {
list.value[currentIndex].duEmpId = newValue?.id
}
const submitForm = async () => {
const filteredList = list.value.filter(item => item.duEmpId !== null && item.duEmpId !== undefined);
if (filteredList.length <= 0) {
message.error("提交明细不能为空,请确认");
return;
}
const firstProjectSubId = filteredList[0].projectSubId;
for (let i = 1; i < filteredList.length; i++) {
if (filteredList[i].projectSubId !== firstProjectSubId) {
message.error("标准件明细不属于同一个子项目,请确认");
return;
}
}
for (let i = 0; i < filteredList.length; i++) {
if (filteredList[i].projectMaterialPlanNo!=null){
message.error("零件"+filteredList[i].materialName+"已生成物料需求计划,请确认")
return
}
if (filteredList[i].boomArriveDate==null){
message.error("零件"+filteredList[i].materialName+"要求完成日期为空,请确认")
return
}
if (filteredList[i].duEmpId==null){
message.error("零件"+filteredList[i].materialName+"责任人为空,请确认")
return
}
}
formLoading.value = true
try {
await ProcessBomApi.submitForm(filteredList)
message.success("提交成功")
// 发送操作成功的事件
getList()
emit('success')
} finally {
formLoading.value = false
}
}
const withdraw = async () => {
if (queryParams.projectMaterialPlanNo==null){
message.error("物料需求单号为空,不允许撤回")
return
}
await ProcessBomApi.withdraw(queryParams.projectMaterialPlanNo)
message.success("撤回成功")
// 发送操作成功的事件
getList()
emit('success')
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
// 发起导出
exportLoading.value = true
// const data = await ProcessBomApi.exportProcessBom(queryParams)
// download.excel(data, '工艺bom.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted( async() => {
await supplier()
await getList()
})
</script>
<style>
/* 占位样式 */
</style>