feat(proorder): 新增生产订单管理功能

This commit is contained in:
zxy 2026-04-24 09:18:14 +08:00
parent 9067214b06
commit 67772cc8e6
15 changed files with 856 additions and 16 deletions

View File

@ -1,9 +1,9 @@
package jnpf.service; package jnpf.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.model.orderdetail.OrderDetailEntity;
import jnpf.model.order.OrderItemWithOrderPagination; import jnpf.model.order.OrderItemWithOrderPagination;
import jnpf.model.order.OrderItemWithOrderVO; import jnpf.model.order.OrderItemWithOrderVO;
import jnpf.model.orderdetail.OrderDetailEntity;
import jnpf.model.orderdetail.OrderDetailForm; import jnpf.model.orderdetail.OrderDetailForm;
import jnpf.model.orderdetail.OrderDetailPagination; import jnpf.model.orderdetail.OrderDetailPagination;
@ -33,7 +33,9 @@ public interface OrderDetailService extends IService<OrderDetailEntity> {
* @param saleOrdId 销售订单ID * @param saleOrdId 销售订单ID
* @return 订单明细列表 * @return 订单明细列表
*/ */
List<OrderDetailEntity> getListByOrderId(Long saleOrdId); List<OrderDetailEntity> getListBySaleOrderId(Long saleOrdId);
List<OrderDetailEntity> getListByOrderId(Long orderId);
List<OrderItemWithOrderVO> getOrderItemWithOrder(OrderItemWithOrderPagination pagination); List<OrderItemWithOrderVO> getOrderItemWithOrder(OrderItemWithOrderPagination pagination);

View File

@ -30,4 +30,6 @@ public interface ProOrderLineService extends IService<ProOrderLineEntity> {
* @return 产线订单列表 * @return 产线订单列表
*/ */
List<ProOrderLineEntity> getListByProNo(String proNo); List<ProOrderLineEntity> getListByProNo(String proNo);
boolean removeByProId(Integer id);
} }

View File

@ -38,4 +38,5 @@ public interface ProOrderService extends IService<ProOrderEntity> {
String generateCheck(ExampleOrderForm proOrderForm); String generateCheck(ExampleOrderForm proOrderForm);
String removeInfo(ProOrderEntity proOrderEntity);
} }

View File

@ -3,6 +3,8 @@ package jnpf.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.model.order.ProSoRelationEntity; import jnpf.model.order.ProSoRelationEntity;
import java.util.List;
/** /**
* 生产订单对应销售订单 Service * 生产订单对应销售订单 Service
* *
@ -13,4 +15,5 @@ import jnpf.model.order.ProSoRelationEntity;
*/ */
public interface ProSoRelationService extends IService<ProSoRelationEntity> { public interface ProSoRelationService extends IService<ProSoRelationEntity> {
List<ProSoRelationEntity> getListByProId(Integer id);
} }

View File

@ -31,13 +31,21 @@ public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, Order
} }
@Override @Override
public List<OrderDetailEntity> getListByOrderId(Long saleOrdId) { public List<OrderDetailEntity> getListBySaleOrderId(Long saleOrdId) {
QueryWrapper<OrderDetailEntity> query = new QueryWrapper<>(); QueryWrapper<OrderDetailEntity> query = new QueryWrapper<>();
query.lambda().eq(OrderDetailEntity::getSaleOrdId, saleOrdId); query.lambda().eq(OrderDetailEntity::getSaleOrdId, saleOrdId);
query.lambda().orderByDesc(OrderDetailEntity::getCreatorTime); query.lambda().orderByDesc(OrderDetailEntity::getCreatorTime);
return this.list(query); return this.list(query);
} }
@Override
public List<OrderDetailEntity> getListByOrderId(Long orderId) {
QueryWrapper<OrderDetailEntity> query = new QueryWrapper<>();
query.lambda().eq(OrderDetailEntity::getId, orderId);
query.lambda().orderByDesc(OrderDetailEntity::getCreatorTime);
return this.list(query);
}
@Override @Override
public List<OrderItemWithOrderVO> getOrderItemWithOrder(OrderItemWithOrderPagination pagination) { public List<OrderItemWithOrderVO> getOrderItemWithOrder(OrderItemWithOrderPagination pagination) {
Page<OrderItemWithOrderVO> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize()); Page<OrderItemWithOrderVO> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());

View File

@ -35,8 +35,15 @@ public class ProOrderLineServiceImpl extends ServiceImpl<ProOrderLineMapper, Pro
QueryWrapper<ProOrderLineEntity> query = new QueryWrapper<>(); QueryWrapper<ProOrderLineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderLineEntity::getProNo, proNo); query.lambda().eq(ProOrderLineEntity::getProNo, proNo);
query.lambda().and(wrapper -> wrapper.isNull(ProOrderLineEntity::getDeleteMark) query.lambda().and(wrapper -> wrapper.isNull(ProOrderLineEntity::getDeleteMark)
.or().eq(ProOrderLineEntity::getDeleteMark, 1)); .or().eq(ProOrderLineEntity::getDeleteMark, 0));
query.lambda().orderByAsc(ProOrderLineEntity::getLineCd); query.lambda().orderByAsc(ProOrderLineEntity::getLineCd);
return this.list(query); return this.list(query);
} }
@Override
public boolean removeByProId(Integer id) {
QueryWrapper<ProOrderLineEntity> query = new QueryWrapper<>();
query.lambda().eq(ProOrderLineEntity::getProId, id);
return this.remove(query);
}
} }

View File

@ -3,10 +3,9 @@ package jnpf.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.model.order.ExampleOrderEntity;
import jnpf.model.orderdetail.OrderDetailEntity;
import jnpf.mapper.ProOrderMapper; import jnpf.mapper.ProOrderMapper;
import jnpf.model.order.*; import jnpf.model.order.*;
import jnpf.model.orderdetail.OrderDetailEntity;
import jnpf.model.orderdetail.OrderDetailForm; import jnpf.model.orderdetail.OrderDetailForm;
import jnpf.service.*; import jnpf.service.*;
import jnpf.util.GeneraterSwapUtil; import jnpf.util.GeneraterSwapUtil;
@ -99,10 +98,22 @@ public class ProOrderServiceImpl extends ServiceImpl<ProOrderMapper, ProOrderEnt
@Override @Override
public ProOrderVO getInfoById(Integer id) { public ProOrderVO getInfoById(Integer id) {
ProOrderEntity entity = this.getById(id); ProOrderEntity entity = this.getById(id);
if (entity != null) { // 查询订单明细
return JsonUtil.getJsonToBean(entity, ProOrderVO.class); List<ProOrderLineEntity> lineEntities = proOrderLineService.getListByProId(id);
} ProOrderVO proOrderVO = JsonUtil.getJsonToBean(entity, ProOrderVO.class);
return null; proOrderVO.setLineList(lineEntities);
List<ProSoRelationEntity> soRelationEntities = proSoRelationService.getListByProId(id);
// for (ProSoRelationEntity soRelationEntity : soRelationEntities) {
// 根据销售订单ID查询销售订单信息
// ExampleOrderEntity orderEntity = orderService.getById(soRelationEntity.getSaleOrdId());
// List<OrderDetailEntity> detailEntityList = orderDetailService.getListBySaleOrderId(soRelationEntity.getSaleOrdId());
// 统计转生成数量 produce_qty 累加
// BigDecimal produceQty = detailEntityList.stream().map(OrderDetailEntity::getProduceQty).reduce(BigDecimal.ZERO, BigDecimal::add);
// soRelationEntity.setChangProQty(produceQty);
// }
proOrderVO.setOrderList(soRelationEntities);
return proOrderVO;
} }
@Override @Override
@ -175,7 +186,7 @@ public class ProOrderServiceImpl extends ServiceImpl<ProOrderMapper, ProOrderEnt
orderDetailService.updateById(detailEntity); orderDetailService.updateById(detailEntity);
} }
// 查询所有订单明细如果全部转生产则更新订单状态为已转生产 // 查询所有订单明细如果全部转生产则更新订单状态为已转生产
List<OrderDetailEntity> detailEntities = orderDetailService.getListByOrderId(detailEntity.getSaleOrdId()); List<OrderDetailEntity> detailEntities = orderDetailService.getListBySaleOrderId(detailEntity.getSaleOrdId());
boolean allProduce = detailEntities.stream().allMatch(item -> "2".equals(item.getOrdItemStatus())); boolean allProduce = detailEntities.stream().allMatch(item -> "2".equals(item.getOrdItemStatus()));
if (allProduce) { if (allProduce) {
orderEntity.setProStatus("2"); orderEntity.setProStatus("2");
@ -223,4 +234,37 @@ public class ProOrderServiceImpl extends ServiceImpl<ProOrderMapper, ProOrderEnt
} }
return null; return null;
} }
@Override
@Transactional(rollbackFor = Exception.class)
public String removeInfo(ProOrderEntity proOrderEntity) {
this.baseMapper.deleteById(proOrderEntity);
// 要回滚数据把计划数量还原到订单明细中
List<ProSoRelationEntity> soRelationEntityList = proSoRelationService.getListByProId(proOrderEntity.getId());
for (ProSoRelationEntity proSoRelationEntity : soRelationEntityList) {
OrderDetailEntity detailEntity = orderDetailService.getById(proSoRelationEntity.getProItemId());
detailEntity.setProduceQty(detailEntity.getProduceQty().add(proSoRelationEntity.getChangProQty()));
if (detailEntity.getProduceQty().compareTo(BigDecimal.ZERO) == 0) {
detailEntity.setOrdItemStatus("0");
} else {
detailEntity.setOrdItemStatus("1");
}
orderDetailService.updateById(detailEntity);
proSoRelationService.removeById(proSoRelationEntity);
List<OrderDetailEntity> saleOrderDetailList = orderDetailService.getListBySaleOrderId(proSoRelationEntity.getSaleOrdId());
for (OrderDetailEntity orderDetailEntity : saleOrderDetailList) {
if ("0".equals(orderDetailEntity.getOrdItemStatus())) {
ExampleOrderEntity orderEntity = orderService.getById(orderDetailEntity.getSaleOrdId());
orderEntity.setProStatus("0");
orderService.updateById(orderEntity);
}
}
}
// 产线数据直接删除
boolean b = proOrderLineService.removeByProId(proOrderEntity.getId());
if (!b) {
return "删除产线数据失败";
}
return null;
}
} }

View File

@ -1,11 +1,14 @@
package jnpf.service.impl; package jnpf.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.mapper.ProSoRelationMapper; import jnpf.mapper.ProSoRelationMapper;
import jnpf.model.order.ProSoRelationEntity; import jnpf.model.order.ProSoRelationEntity;
import jnpf.service.ProSoRelationService; import jnpf.service.ProSoRelationService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* 生产订单对应销售订单 ServiceImpl * 生产订单对应销售订单 ServiceImpl
* *
@ -17,4 +20,11 @@ import org.springframework.stereotype.Service;
@Service @Service
public class ProSoRelationServiceImpl extends ServiceImpl<ProSoRelationMapper, ProSoRelationEntity> implements ProSoRelationService { public class ProSoRelationServiceImpl extends ServiceImpl<ProSoRelationMapper, ProSoRelationEntity> implements ProSoRelationService {
@Override
public List<ProSoRelationEntity> getListByProId(Integer id) {
LambdaQueryWrapper<ProSoRelationEntity> query = new LambdaQueryWrapper<>();
query.eq(ProSoRelationEntity::getProId, id);
query.eq(ProSoRelationEntity::getDeleteMark, 0);
return baseMapper.selectList(query);
}
} }

View File

@ -219,7 +219,7 @@ public class ExampleOrderController {
} }
Map<String, Object> ExampleOrderMap=JsonUtil.entityToMap(entity); Map<String, Object> ExampleOrderMap=JsonUtil.entityToMap(entity);
ExampleOrderMap.put("id", ExampleOrderMap.get("id")); ExampleOrderMap.put("id", ExampleOrderMap.get("id"));
List<OrderDetailEntity> orderDetailList = orderDetailService.getListByOrderId(entity.getId()); List<OrderDetailEntity> orderDetailList = orderDetailService.getListBySaleOrderId(entity.getId());
for (OrderDetailEntity orderDetailEntity : orderDetailList) { for (OrderDetailEntity orderDetailEntity : orderDetailList) {
orderDetailEntity.setUnitName("1".equals(orderDetailEntity.getUnit())?"kg":"T"); orderDetailEntity.setUnitName("1".equals(orderDetailEntity.getUnit())?"kg":"T");
} }

View File

@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* 生产订单 控制类 * 生产订单 控制类
@ -140,11 +141,14 @@ public class ProOrderController {
@Operation(summary = "删除生产订单") @Operation(summary = "删除生产订单")
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
public ActionResult<String> delete(@PathVariable("id") Integer id) { public ActionResult<String> delete(@PathVariable("id") Integer id) {
ProOrderEntity byId = proOrderService.getById(id); ProOrderEntity proOrderEntity = proOrderService.getById(id);
if (ObjectUtil.isNotEmpty(byId)) { if (ObjectUtil.isNotEmpty(proOrderEntity)) {
proOrderService.removeById(id); if (!Objects.equals(proOrderEntity.getPlanStatus(), "0")) {
return ActionResult.fail("该订单产品已下发,不允许删除!");
}
proOrderService.removeInfo(proOrderEntity);
return ActionResult.success("删除成功"); return ActionResult.success("删除成功");
} }
return ActionResult.success("数据不存在,请刷新界面!"); return ActionResult.fail("该订单产品信息不存在,请刷新数据");
} }
} }

View File

@ -6,6 +6,7 @@ import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* 生产订单 VO * 生产订单 VO
@ -102,4 +103,8 @@ public class ProOrderVO implements Serializable {
@Schema(description = "入库数量") @Schema(description = "入库数量")
private BigDecimal storeInQty; private BigDecimal storeInQty;
private List<ProOrderLineEntity> lineList;
private List<ProSoRelationEntity> orderList;
} }

View File

@ -0,0 +1,63 @@
import request from '@/utils/request'
export function getProOrderList(data) {
return request({
url: '/api/example/proOrder/getList',
method: 'post',
data
})
}
export function getProOrderInfo(id) {
return request({
url: `/api/example/proOrder/${id}`,
method: 'get'
})
}
export function createProOrder(data) {
return request({
url: '/api/example/proOrder',
method: 'post',
data
})
}
export function updateProOrder(id, data) {
return request({
url: `/api/example/proOrder/${id}`,
method: 'put',
data
})
}
export function deleteProOrder(id) {
return request({
url: `/api/example/proOrder/delete/${id}`,
method: 'delete'
})
}
export function generateProOrder(data) {
return request({
url: '/api/example/proOrder/generate',
method: 'post',
data
})
}
export function generateProOrderCheck(data) {
return request({
url: '/api/example/proOrder/generateCheck',
method: 'post',
data
})
}
export function closeProOrder(data) {
return request({
url: '/api/example/proOrder/close',
method: 'post',
data
})
}

View File

@ -0,0 +1,207 @@
<template>
<el-dialog
title="生产订单详情"
:visible.sync="dialogVisible"
width="1200px"
:close-on-click-modal="false"
@close="handleClose"
>
<el-form :model="dataForm" size="small" label-width="120px" label-position="right" v-loading="loading">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="生产订单号">
<el-input :value="dataForm.proNo" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="生成日期">
<el-input :value="formatDate(dataForm.proDate)" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="订单状态">
<el-input :value="getPlanStatusLabel(dataForm.planStatus)" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="产品编码">
<el-input :value="dataForm.materialCode" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品名称">
<el-input :value="dataForm.materialName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="规格型号">
<el-input :value="dataForm.spec" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="单位">
<el-input :value="dataForm.unit" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划数量">
<el-input :value="dataForm.planQty" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="完成数量">
<el-input :value="dataForm.completeQty" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="入库数量">
<el-input :value="dataForm.storeInQty" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划开始日期">
<el-input :value="formatDate(dataForm.planBgDate)" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划完成日期">
<el-input :value="formatDate(dataForm.planEndDate)" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="编制人">
<el-input :value="dataForm.planEmpName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="是否所有产线">
<el-input :value="dataForm.isAllLine == '0' ? '是' : '否'" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="备注">
<el-input :value="dataForm.remark" type="textarea" :rows="2" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<div v-if="dataForm.lineList && dataForm.lineList.length > 0" style="margin-top: 20px;">
<div style="font-weight: bold; margin-bottom: 10px;">产线信息</div>
<el-table :data="dataForm.lineList" border size="small">
<el-table-column type="index" label="序号" width="60" align="center"/>
<el-table-column prop="lineCd" label="产线编码" align="center"/>
<el-table-column prop="lineName" label="产线名称" align="center"/>
<el-table-column prop="planQty" label="计划数量" align="center"/>
<el-table-column prop="completeQty" label="完成数量" align="center"/>
<el-table-column prop="proBgDate" label="开始日期" align="center" :formatter="formatDateColumn"/>
<el-table-column prop="proEndDate" label="结束日期" align="center" :formatter="formatDateColumn"/>
</el-table>
</div>
<div v-if="dataForm.soRelationList && dataForm.soRelationList.length > 0" style="margin-top: 20px;">
<div style="font-weight: bold; margin-bottom: 10px;">关联销售订单</div>
<el-table :data="dataForm.soRelationList" border size="small">
<el-table-column type="index" label="序号" width="60" align="center"/>
<el-table-column prop="saleOrdNo" label="销售订单号" align="center"/>
<el-table-column prop="custName" label="客户名称" align="center"/>
<el-table-column prop="materialCode" label="产品编码" align="center"/>
<el-table-column prop="materialName" label="产品名称" align="center"/>
<el-table-column prop="changProQty" label="转产数量" align="center"/>
</el-table>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose"> </el-button>
</div>
</el-dialog>
</template>
<script>
import {getProOrderInfo} from "./api";
export default {
name: "ProOrderDetail",
data() {
return {
dialogVisible: false,
loading: false,
dataForm: {
id: null,
proNo: '',
proDate: null,
materialCode: '',
materialName: '',
spec: '',
unit: '',
planQty: null,
completeQty: null,
storeInQty: null,
planBgDate: null,
planEndDate: null,
planEmpName: '',
isAllLine: '',
planStatus: '',
remark: '',
lineList: [],
soRelationList: []
}
}
},
methods: {
init(id) {
this.dialogVisible = true
this.loading = true
getProOrderInfo(id).then((res) => {
this.dataForm = res.data || {}
this.loading = false
}).catch(() => {
this.loading = false
this.dialogVisible = false
})
},
formatDate(timestamp) {
if (!timestamp) return ''
const date = new Date(timestamp)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
},
formatDateColumn(row, column, cellValue) {
if (!cellValue) return ''
return this.formatDate(cellValue)
},
getPlanStatusLabel(value) {
const statusMap = {
'0': '未下发',
'1': '已下发',
'2': '执行中',
'3': '已完成',
'4': '暂停',
'5': '关闭'
}
return statusMap[value] || value
},
handleClose() {
this.dialogVisible = false
this.$emit('close')
}
}
}
</script>

View File

@ -0,0 +1,85 @@
<template>
<el-dialog
title="生成生产订单"
:visible.sync="dialogVisible"
width="900px"
:close-on-click-modal="false"
@close="handleClose"
>
<div style="margin-bottom: 15px;">
<el-alert
title="请从销售订单列表中选择需要生成生产订单的明细"
type="info"
:closable="false">
</el-alert>
</div>
<el-table
:data="selectedOrders"
border
max-height="400">
<el-table-column prop="saleOrdNo" label="销售订单号" align="center" min-width="120"/>
<el-table-column prop="materialCode" label="产品编码" align="center" min-width="120"/>
<el-table-column prop="materialName" label="产品名称" align="center" min-width="150"/>
<el-table-column prop="spec" label="规格型号" align="center" min-width="120"/>
<el-table-column prop="unit" label="单位" align="center" min-width="80"/>
<el-table-column prop="qty" label="数量" align="center" min-width="100"/>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button type="text" class="JNPF-table-delBtn" @click="removeItem(scope.$index)">移除</el-button>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleSubmit" :loading="btnLoading"> </el-button>
<el-button @click="handleClose"> </el-button>
</div>
</el-dialog>
</template>
<script>
import {generateProOrderCheck} from './api'
export default {
data() {
return {
dialogVisible: false,
btnLoading: false,
selectedOrders: []
}
},
methods: {
init() {
this.dialogVisible = true
this.selectedOrders = []
},
removeItem(index) {
this.selectedOrders.splice(index, 1)
},
handleSubmit() {
if (this.selectedOrders.length === 0) {
this.$message.warning('请先选择要生成生产订单的数据')
return
}
this.btnLoading = true
const data = {
orderItemList: this.selectedOrders
}
generateProOrderCheck(data).then(() => {
this.$message.success('生成成功')
this.dialogVisible = false
this.btnLoading = false
this.$emit('refresh')
}).catch(() => {
this.btnLoading = false
})
},
handleClose() {
this.dialogVisible = false
}
}
}
</script>

View File

@ -0,0 +1,399 @@
<template>
<div class="JNPF-common-layout pro-order-data">
<div class="JNPF-common-layout-center">
<el-row class="JNPF-common-search-box" :gutter="16">
<el-form @submit.native.prevent>
<el-col :span="6">
<el-form-item label="订单日期">
<el-date-picker
v-model="query.proDateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="产品名称">
<el-input v-model="query.materialName" placeholder="请输入产品名称" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="规格型号">
<el-input v-model="query.spec" placeholder="请输入规格型号" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="订单状态">
<JnpfSelect v-model="query.planStatus" placeholder="请选择订单状态" clearable :options="planStatusOptions"
:props="planStatusProps">
</JnpfSelect>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="btn">
<el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
<el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
<el-button type="primary" @click="completeHandle()" width="90px">订单完成</el-button>
<el-button type="primary" @click="closeHandle()" width="90px">订单关闭</el-button>
</el-form-item>
</el-col>
</el-form>
</el-row>
<div class="JNPF-common-layout-main" style="flex: 1; overflow: visible;">
<!-- <div class="JNPF-common-head">
<div>
<el-button type="primary" icon="icon-ym icon-ym-btn-add" @click="generateHandle()">生成生产订单</el-button>
</div>
<div class="JNPF-common-head-right"></div>
</div> -->
<div style="overflow-x: auto; min-height: 400px;">
<JNPF-table
v-loading="listLoading"
:data="list"
:hasNO="false"
border
ref="table"
:row-key="row => row.id"
@selection-change="handleSelectionChange"
:index="false"
@row-click="handleRowClick"
:highlight-current-row="true">
<el-table-column type="index" label="序号" align="center" width="60" fixed="left"/>
<el-table-column type="selection" align="center" :reserve-selection="true" fixed="left"/>
<el-table-column prop="proNo" label="生产订单号" align="center" min-width="140" fixed="left"/>
<el-table-column prop="materialName" label="产品名称" align="center" min-width="150"/>
<el-table-column prop="spec" label="规格型号" align="center" min-width="120"/>
<el-table-column prop="unit" label="单位" align="center" min-width="80">
<template slot-scope="scope">
{{ scope.row.unit == '1' ? 'kg' : scope.row.unit == '2' ? 'T' : scope.row.unit }}
</template>
</el-table-column>
<el-table-column prop="planQty" label="订单数量" align="center" min-width="100">
<template slot-scope="scope">
{{ scope.row.planQty || 0 }}
</template>
</el-table-column>
<el-table-column prop="completeQty" label="完成数量" align="center" min-width="100">
<template slot-scope="scope">
{{ scope.row.completeQty || 0 }}
</template>
</el-table-column>
<el-table-column prop="storeInQty" label="入库数量" align="center" min-width="100">
<template slot-scope="scope">
{{ scope.row.storeInQty || 0 }}
</template>
</el-table-column>
<el-table-column prop="planBgDate" label="计划开始日期" align="center" min-width="110" :formatter="jnpf.tableDateFormat1"/>
<el-table-column prop="planEndDate" label="计划完成日期" align="center" min-width="110" :formatter="jnpf.tableDateFormat1"/>
<el-table-column prop="processFlow" label="工艺流程" align="center" min-width="100"/>
<el-table-column prop="planEmpName" label="编制人员" align="center" min-width="100"/>
<el-table-column prop="planStatus" label="订单状态" align="center" min-width="100" fixed="right">
<template slot-scope="scope">
<el-tag :type="getPlanStatusType(scope.row.planStatus)" size="small">
{{ getPlanStatusLabel(scope.row.planStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="180">
<template slot-scope="scope">
<el-button type="text" @click="detailHandle(scope.row)">详情</el-button>
<el-button type="text" @click="deleteHandle(scope.row)">删除</el-button>
<!-- <el-button type="text" @click="closeHandle(scope.row)" v-if="canClose(scope.row)">关闭</el-button> -->
</template>
</el-table-column>
</JNPF-table>
</div>
<pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize"
@pagination="initData"/>
<div style="margin-top: 20px;">
<el-row :gutter="20">
<el-col :span="12">
<div style="border: 1px solid #ebeef5; border-radius: 4px; padding: 10px;">
<div style="margin-bottom: 10px; font-weight: bold;">关联销售订单</div>
<JNPF-table
:data="orderList"
border>
<el-table-column prop="saleOrdNo" label="销售订单编号" align="center" min-width="120"/>
<el-table-column prop="custName" label="客户名称" align="center" min-width="120"/>
<el-table-column prop="materialName" label="产品名称" align="center" min-width="120"/>
<el-table-column prop="spec" label="规格型号" align="center" min-width="100"/>
<el-table-column prop="changProQty" label="转生产数量" align="center" min-width="100">
<template slot-scope="scope">
{{ scope.row.changProQty || 0 }}
</template>
</el-table-column>
</JNPF-table>
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ebeef5; border-radius: 4px; padding: 10px;">
<div style="margin-bottom: 10px; font-weight: bold;">产线订单信息</div>
<JNPF-table
:data="lineList"
border>
<el-table-column prop="lineCd" label="产线编码" align="center" min-width="100"/>
<!-- <el-table-column prop="lineName" label="产线名称" align="center" min-width="120"/> -->
<el-table-column prop="proBgDate" label="开工时间" align="center" min-width="110" :formatter="jnpf.tableDateFormat1"/>
<el-table-column prop="proEndDate" label="完工时间" align="center" min-width="110" :formatter="jnpf.tableDateFormat1"/>
<el-table-column prop="planQty" label="计划数量" align="center" min-width="100"/>
<el-table-column prop="completeQty" label="完成数量" align="center" min-width="100">
<template slot-scope="scope">
{{ scope.row.completeQty || 0 }}
</template>
</el-table-column>
<el-table-column prop="planStatus" label="计划状态" align="center" min-width="100">
<template slot-scope="scope">
<el-tag :type="getPlanStatusType(scope.row.planStatus)" size="small">
{{ getPlanStatusLabel(scope.row.planStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="180">
<template slot-scope="scope">
<el-button type="text" @click="detailHandle(scope.row)">详情</el-button>
</template>
</el-table-column>
</JNPF-table>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
<GenerateForm v-if="generateVisible" ref="GenerateForm" @refresh="refresh"/>
<Detail v-if="detailVisible" ref="Detail" @close="detailVisible = false"/>
</div>
</template>
<script>
import {getProOrderList, deleteProOrder, getProOrderInfo} from "./api";
import GenerateForm from "./generateForm";
import Detail from "./detail";
import jnpf from "@/utils/jnpf";
export default {
name: "proorder",
components: {
GenerateForm,
Detail
},
data() {
return {
query: {
proNo: undefined,
materialCode: undefined,
materialName: undefined,
planStatus: undefined,
planBgDateRange: undefined,
planEndDateRange: undefined
},
list: [],
listLoading: false,
total: 0,
hasSelected: false,
selectedRowId: null,
listQuery: {
currentPage: 1,
pageSize: 20,
sort: "",
sidx: ""
},
generateVisible: false,
detailVisible: false,
planStatusOptions: [
{ fullName: "未下发", id: "0" },
{ fullName: "已下发", id: "1" },
{ fullName: "执行中", id: "2" },
{ fullName: "已完成", id: "3" },
{ fullName: "暂停", id: "4" },
{ fullName: "关闭", id: "5" }
],
planStatusProps: { label: "fullName", value: "id" },
//
orderList: [],
// 线
lineList: []
};
},
computed: {
jnpf() {
return jnpf;
}
},
created() {
this.initDefaultDate();
this.initData();
},
methods: {
initDefaultDate() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const day = now.getDate();
const firstDayStr = `${year}-${String(month + 1).padStart(2, '0')}-01`;
const lastDayStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
this.query.proDateRange = [firstDayStr, lastDayStr];
},
handleSelectionChange(val) {
this.hasSelected = val.length > 0;
},
handleRowClick(row) {
this.selectedRowId = row.id;
this.loadDetailData(row.id);
},
initData() {
this.listLoading = true;
let _query = {
...this.listQuery,
...this.query,
dataType: 0
};
if (this.query.planBgDateRange && this.query.planBgDateRange.length === 2) {
_query.planBgDateStart = this.query.planBgDateRange[0];
_query.planBgDateEnd = this.query.planBgDateRange[1];
}
if (this.query.planEndDateRange && this.query.planEndDateRange.length === 2) {
_query.planEndDateStart = this.query.planEndDateRange[0];
_query.planEndDateEnd = this.query.planEndDateRange[1];
}
Object.keys(_query).forEach(key => {
if (_query[key] === undefined || _query[key] === null || _query[key] === '') {
if (key !== 'dataType') {
delete _query[key];
}
}
});
getProOrderList(_query).then((res) => {
this.list = res.data.list || [];
this.total = res.data.pagination.total;
this.listLoading = false;
//
if (this.list.length > 0) {
this.selectedRowId = this.list[0].id;
this.loadDetailData(this.list[0].id);
} else {
this.selectedRowId = null;
this.orderList = [];
this.lineList = [];
}
}).catch(() => {
this.listLoading = false;
});
},
loadDetailData(proOrderId) {
// 线
getProOrderInfo(proOrderId).then((res) => {
const data = res.data || {};
this.orderList = data.orderList || [];
this.lineList = data.lineList || [];
}).catch(() => {
this.orderList = [];
this.lineList = [];
});
},
search() {
this.listQuery.currentPage = 1;
this.initData();
},
reset() {
this.query = {
proNo: undefined,
materialCode: undefined,
materialName: undefined,
planStatus: undefined,
planBgDateRange: undefined,
planEndDateRange: undefined
};
this.initDefaultDate();
this.search();
},
generateHandle() {
this.generateVisible = true;
this.$nextTick(() => {
this.$refs.GenerateForm.init();
});
},
detailHandle(row) {
this.detailVisible = true;
this.$nextTick(() => {
this.$refs.Detail.init(row.id);
});
},
closeHandle(row) {
this.$confirm('此操作将关闭该生产订单, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//
this.$message.success('关闭成功');
this.initData();
}).catch(() => {
});
},
deleteHandle(row) {
this.$confirm('此操作将永久删除该生产订单, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteProOrder(row.id).then(() => {
this.$message.success('删除成功');
this.initData();
}).catch((err) => {
const msg = err?.response?.data?.message || err?.message || '删除失败';
this.$message.error(msg);
});
}).catch(() => {
});
},
refresh() {
this.initData();
},
lineDetailHandle(row) {
this.detailVisible = true;
this.$nextTick(() => {
this.$refs.Detail.init(row.proId || row.id);
});
},
getPlanStatusLabel(value) {
const statusMap = {
'0': '未下发',
'1': '已下发',
'2': '执行中',
'3': '已完成',
'4': '暂停',
'5': '关闭'
};
return statusMap[value] || value;
},
getPlanStatusType(value) {
const typeMap = {
'0': 'info',
'1': '',
'2': 'primary',
'3': 'success',
'4': 'warning',
'5': 'danger'
};
return typeMap[value] || '';
},
canClose(row) {
return row.planStatus !== '3' && row.planStatus !== '5';
}
}
};
</script>
<style scoped>
</style>