Compare commits
9 Commits
feat/erp-p
...
0.8.X
| Author | SHA1 | Date | |
|---|---|---|---|
| b3dbdaef58 | |||
| d627a72aea | |||
| 16ba2dfa18 | |||
| 289555fd44 | |||
| 1c0b0da99e | |||
| 7e9caf9bb7 | |||
| 86200d189d | |||
| 3277610ff7 | |||
| 143853a87d |
@@ -36,6 +36,9 @@ CREATE TABLE IF NOT EXISTS wms_furnace_plan_coil (
|
||||
plan_coil_id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
plan_id BIGINT NOT NULL COMMENT '计划ID',
|
||||
coil_id BIGINT NOT NULL COMMENT '钢卷ID',
|
||||
logic_warehouse_id BIGINT NULL COMMENT '逻辑库区去向(钢卷退火后目标逻辑库区)',
|
||||
furnace_level TINYINT(1) NULL COMMENT '炉火层级(1=一层,2=二层,3=三层)',
|
||||
contract_id BIGINT NULL COMMENT '合同ID',
|
||||
del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)',
|
||||
create_by VARCHAR(64) NULL,
|
||||
update_by VARCHAR(64) NULL,
|
||||
|
||||
@@ -107,6 +107,12 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
extracted(records);
|
||||
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
private void extracted(List<CrmOrderVo> records) {
|
||||
Set<String> userNames = records.stream()
|
||||
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy()))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
@@ -178,8 +184,6 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
private QueryWrapper<CrmOrder> buildQueryWrapperPlus(CrmOrderBo bo) {
|
||||
@@ -262,7 +266,9 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
|
||||
@Override
|
||||
public List<CrmOrderVo> queryList(CrmOrderBo bo) {
|
||||
QueryWrapper<CrmOrder> lqw = buildQueryWrapperPlus(bo);
|
||||
return baseMapper.selectVoPagePlus(lqw);
|
||||
List<CrmOrderVo> crmOrderVos = baseMapper.selectVoPagePlus(lqw);
|
||||
extracted(crmOrderVos);
|
||||
return crmOrderVos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,5 +19,9 @@
|
||||
<groupId>com.klp</groupId>
|
||||
<artifactId>klp-wms</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.klp</groupId>
|
||||
<artifactId>klp-crm</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.klp.flow.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import com.klp.common.annotation.RepeatSubmit;
|
||||
import com.klp.common.annotation.Log;
|
||||
import com.klp.common.core.controller.BaseController;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.flow.domain.vo.SchDetailCoilRelVo;
|
||||
import com.klp.flow.domain.bo.SchDetailCoilRelBo;
|
||||
import com.klp.flow.service.ISchDetailCoilRelService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/flow/detailCoilRel")
|
||||
public class SchDetailCoilRelController extends BaseController {
|
||||
|
||||
private final ISchDetailCoilRelService iSchDetailCoilRelService;
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<SchDetailCoilRelVo> list(SchDetailCoilRelBo bo, PageQuery pageQuery) {
|
||||
return iSchDetailCoilRelService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出排产明细钢卷关系列表
|
||||
*/
|
||||
@Log(title = "排产明细钢卷关系", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(SchDetailCoilRelBo bo, HttpServletResponse response) {
|
||||
List<SchDetailCoilRelVo> list = iSchDetailCoilRelService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "排产明细钢卷关系", SchDetailCoilRelVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排产明细钢卷关系详细信息
|
||||
*
|
||||
* @param relId 主键
|
||||
*/
|
||||
@GetMapping("/{relId}")
|
||||
public R<SchDetailCoilRelVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long relId) {
|
||||
return R.ok(iSchDetailCoilRelService.queryById(relId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增排产明细钢卷关系
|
||||
*/
|
||||
@Log(title = "排产明细钢卷关系", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody SchDetailCoilRelBo bo) {
|
||||
return toAjax(iSchDetailCoilRelService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改排产明细钢卷关系
|
||||
*/
|
||||
@Log(title = "排产明细钢卷关系", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SchDetailCoilRelBo bo) {
|
||||
return toAjax(iSchDetailCoilRelService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除排产明细钢卷关系
|
||||
*
|
||||
* @param relIds 主键串
|
||||
*/
|
||||
@Log(title = "排产明细钢卷关系", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{relIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] relIds) {
|
||||
return toAjax(iSchDetailCoilRelService.deleteWithValidByIds(Arrays.asList(relIds), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.klp.flow.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系对象 sch_detail_coil_rel
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sch_detail_coil_rel")
|
||||
public class SchDetailCoilRel extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "rel_id")
|
||||
private Long relId;
|
||||
/**
|
||||
* 排产明细ID(关联 sch_prod_schedule_detail.schedule_detail_id)
|
||||
*/
|
||||
private Long scheduleDetailId;
|
||||
/**
|
||||
* 钢卷ID(关联 wms_material_coil.coil_id)
|
||||
*/
|
||||
private Long coilId;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 删除标志(0=正常,1=已删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.klp.flow.domain.bo;
|
||||
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系业务对象 sch_detail_coil_rel
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SchDetailCoilRelBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long relId;
|
||||
|
||||
/**
|
||||
* 排产明细ID(关联 sch_prod_schedule_detail.schedule_detail_id)
|
||||
*/
|
||||
private Long scheduleDetailId;
|
||||
|
||||
/**
|
||||
* 钢卷ID(关联 wms_material_coil.coil_id)
|
||||
*/
|
||||
private Long coilId;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import javax.validation.constraints.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* 排产单主业务对象 sch_prod_schedule
|
||||
@@ -33,6 +34,8 @@ public class SchProdScheduleBo extends BaseEntity {
|
||||
/**
|
||||
* 生产日期(和合同号组成业务关联键)
|
||||
*/
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date prodDate;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.klp.flow.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系视图对象 sch_detail_coil_rel
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class SchDetailCoilRelVo {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long relId;
|
||||
|
||||
/**
|
||||
* 排产明细ID(关联 sch_prod_schedule_detail.schedule_detail_id)
|
||||
*/
|
||||
@ExcelProperty(value = "排产明细ID", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "关=联,s=ch_prod_schedule_detail.schedule_detail_id")
|
||||
private Long scheduleDetailId;
|
||||
|
||||
/**
|
||||
* 钢卷ID(关联 wms_material_coil.coil_id)
|
||||
*/
|
||||
@ExcelProperty(value = "钢卷ID", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "关=联,w=ms_material_coil.coil_id")
|
||||
private Long coilId;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.klp.flow.domain.vo;
|
||||
import java.math.BigDecimal;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
@@ -69,5 +70,10 @@ public class SchProdScheduleDetailVo {
|
||||
@ExcelProperty(value = "单行排产备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 关联的排产单主表信息
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private SchProdScheduleVo schedule;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,14 @@ import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import com.klp.crm.domain.vo.CrmOrderVo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 排产单主视图对象 sch_prod_schedule
|
||||
@@ -186,5 +190,16 @@ public class SchProdScheduleVo {
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 关联的排产明细列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<SchProdScheduleDetailVo> detailList;
|
||||
|
||||
/**
|
||||
* 关联的CRM订单列表(通过合同号 relContractNo 匹配 CrmOrder.contractCode)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<CrmOrderVo> orderList;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.klp.flow.mapper;
|
||||
|
||||
import com.klp.flow.domain.SchDetailCoilRel;
|
||||
import com.klp.flow.domain.vo.SchDetailCoilRelVo;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系Mapper接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
public interface SchDetailCoilRelMapper extends BaseMapperPlus<SchDetailCoilRelMapper, SchDetailCoilRel, SchDetailCoilRelVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.klp.flow.service;
|
||||
|
||||
import com.klp.flow.domain.SchDetailCoilRel;
|
||||
import com.klp.flow.domain.vo.SchDetailCoilRelVo;
|
||||
import com.klp.flow.domain.bo.SchDetailCoilRelBo;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系Service接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
public interface ISchDetailCoilRelService {
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系
|
||||
*/
|
||||
SchDetailCoilRelVo queryById(Long relId);
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系列表
|
||||
*/
|
||||
TableDataInfo<SchDetailCoilRelVo> queryPageList(SchDetailCoilRelBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系列表
|
||||
*/
|
||||
List<SchDetailCoilRelVo> queryList(SchDetailCoilRelBo bo);
|
||||
|
||||
/**
|
||||
* 新增排产明细钢卷关系
|
||||
*/
|
||||
Boolean insertByBo(SchDetailCoilRelBo bo);
|
||||
|
||||
/**
|
||||
* 修改排产明细钢卷关系
|
||||
*/
|
||||
Boolean updateByBo(SchDetailCoilRelBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除排产明细钢卷关系信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.klp.flow.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.klp.flow.domain.bo.SchDetailCoilRelBo;
|
||||
import com.klp.flow.domain.vo.SchDetailCoilRelVo;
|
||||
import com.klp.flow.domain.SchDetailCoilRel;
|
||||
import com.klp.flow.mapper.SchDetailCoilRelMapper;
|
||||
import com.klp.flow.service.ISchDetailCoilRelService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 排产明细钢卷关系Service业务层处理
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-06-25
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SchDetailCoilRelServiceImpl implements ISchDetailCoilRelService {
|
||||
|
||||
private final SchDetailCoilRelMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系
|
||||
*/
|
||||
@Override
|
||||
public SchDetailCoilRelVo queryById(Long relId){
|
||||
return baseMapper.selectVoById(relId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<SchDetailCoilRelVo> queryPageList(SchDetailCoilRelBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<SchDetailCoilRel> lqw = buildQueryWrapper(bo);
|
||||
Page<SchDetailCoilRelVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询排产明细钢卷关系列表
|
||||
*/
|
||||
@Override
|
||||
public List<SchDetailCoilRelVo> queryList(SchDetailCoilRelBo bo) {
|
||||
LambdaQueryWrapper<SchDetailCoilRel> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SchDetailCoilRel> buildQueryWrapper(SchDetailCoilRelBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<SchDetailCoilRel> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getScheduleDetailId() != null, SchDetailCoilRel::getScheduleDetailId, bo.getScheduleDetailId());
|
||||
lqw.eq(bo.getCoilId() != null, SchDetailCoilRel::getCoilId, bo.getCoilId());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增排产明细钢卷关系
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(SchDetailCoilRelBo bo) {
|
||||
SchDetailCoilRel add = BeanUtil.toBean(bo, SchDetailCoilRel.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setRelId(add.getRelId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改排产明细钢卷关系
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(SchDetailCoilRelBo bo) {
|
||||
SchDetailCoilRel update = BeanUtil.toBean(bo, SchDetailCoilRel.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(SchDetailCoilRel entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除排产明细钢卷关系
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,17 @@ import org.springframework.stereotype.Service;
|
||||
import com.klp.flow.domain.bo.SchProdScheduleDetailBo;
|
||||
import com.klp.flow.domain.vo.SchProdScheduleDetailVo;
|
||||
import com.klp.flow.domain.SchProdScheduleDetail;
|
||||
import com.klp.flow.domain.vo.SchProdScheduleVo;
|
||||
import com.klp.flow.mapper.SchProdScheduleDetailMapper;
|
||||
import com.klp.flow.mapper.SchProdScheduleMapper;
|
||||
import com.klp.flow.service.ISchProdScheduleDetailService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 排产单明细Service业务层处理
|
||||
@@ -30,13 +35,18 @@ import java.util.Collection;
|
||||
public class SchProdScheduleDetailServiceImpl implements ISchProdScheduleDetailService {
|
||||
|
||||
private final SchProdScheduleDetailMapper baseMapper;
|
||||
private final SchProdScheduleMapper scheduleMapper;
|
||||
|
||||
/**
|
||||
* 查询排产单明细
|
||||
*/
|
||||
@Override
|
||||
public SchProdScheduleDetailVo queryById(Long scheduleDetailId){
|
||||
return baseMapper.selectVoById(scheduleDetailId);
|
||||
SchProdScheduleDetailVo vo = baseMapper.selectVoById(scheduleDetailId);
|
||||
if (vo != null) {
|
||||
fillSchedule(Collections.singletonList(vo));
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,6 +56,7 @@ public class SchProdScheduleDetailServiceImpl implements ISchProdScheduleDetailS
|
||||
public TableDataInfo<SchProdScheduleDetailVo> queryPageList(SchProdScheduleDetailBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<SchProdScheduleDetail> lqw = buildQueryWrapper(bo);
|
||||
Page<SchProdScheduleDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
fillSchedule(result.getRecords());
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@@ -55,7 +66,32 @@ public class SchProdScheduleDetailServiceImpl implements ISchProdScheduleDetailS
|
||||
@Override
|
||||
public List<SchProdScheduleDetailVo> queryList(SchProdScheduleDetailBo bo) {
|
||||
LambdaQueryWrapper<SchProdScheduleDetail> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
List<SchProdScheduleDetailVo> list = baseMapper.selectVoList(lqw);
|
||||
fillSchedule(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量填充主表信息
|
||||
*/
|
||||
private void fillSchedule(List<SchProdScheduleDetailVo> voList) {
|
||||
if (voList == null || voList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<Long> scheduleIds = voList.stream()
|
||||
.map(SchProdScheduleDetailVo::getScheduleId)
|
||||
.filter(id -> id != null)
|
||||
.collect(Collectors.toSet());
|
||||
if (scheduleIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<SchProdScheduleVo> schedules = scheduleMapper.selectVoBatchIds(scheduleIds);
|
||||
Map<Long, SchProdScheduleVo> scheduleMap = schedules != null
|
||||
? schedules.stream().collect(Collectors.toMap(SchProdScheduleVo::getScheduleId, s -> s, (a, b) -> a))
|
||||
: Collections.emptyMap();
|
||||
for (SchProdScheduleDetailVo vo : voList) {
|
||||
vo.setSchedule(scheduleMap.get(vo.getScheduleId()));
|
||||
}
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SchProdScheduleDetail> buildQueryWrapper(SchProdScheduleDetailBo bo) {
|
||||
|
||||
@@ -12,12 +12,24 @@ import org.springframework.stereotype.Service;
|
||||
import com.klp.flow.domain.bo.SchProdScheduleBo;
|
||||
import com.klp.flow.domain.vo.SchProdScheduleVo;
|
||||
import com.klp.flow.domain.SchProdSchedule;
|
||||
import com.klp.flow.domain.SchProdScheduleDetail;
|
||||
import com.klp.flow.domain.vo.SchProdScheduleDetailVo;
|
||||
import com.klp.flow.mapper.SchProdScheduleMapper;
|
||||
import com.klp.flow.mapper.SchProdScheduleDetailMapper;
|
||||
import com.klp.flow.mapper.SchSaleScheduleRelMapper;
|
||||
import com.klp.flow.domain.SchSaleScheduleRel;
|
||||
import com.klp.flow.service.ISchProdScheduleService;
|
||||
import com.klp.crm.service.ICrmOrderService;
|
||||
import com.klp.crm.domain.bo.CrmOrderBo;
|
||||
import com.klp.crm.domain.vo.CrmOrderVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 排产单主Service业务层处理
|
||||
@@ -30,13 +42,21 @@ import java.util.Collection;
|
||||
public class SchProdScheduleServiceImpl implements ISchProdScheduleService {
|
||||
|
||||
private final SchProdScheduleMapper baseMapper;
|
||||
private final SchProdScheduleDetailMapper detailMapper;
|
||||
private final SchSaleScheduleRelMapper relMapper;
|
||||
private final ICrmOrderService crmOrderService;
|
||||
|
||||
/**
|
||||
* 查询排产单主
|
||||
*/
|
||||
@Override
|
||||
public SchProdScheduleVo queryById(Long scheduleId){
|
||||
return baseMapper.selectVoById(scheduleId);
|
||||
SchProdScheduleVo vo = baseMapper.selectVoById(scheduleId);
|
||||
if (vo != null) {
|
||||
fillDetailList(Collections.singletonList(vo));
|
||||
fillOrderList(Collections.singletonList(vo));
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,6 +66,8 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService {
|
||||
public TableDataInfo<SchProdScheduleVo> queryPageList(SchProdScheduleBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<SchProdSchedule> lqw = buildQueryWrapper(bo);
|
||||
Page<SchProdScheduleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
fillDetailList(result.getRecords());
|
||||
fillOrderList(result.getRecords());
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@@ -55,7 +77,95 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService {
|
||||
@Override
|
||||
public List<SchProdScheduleVo> queryList(SchProdScheduleBo bo) {
|
||||
LambdaQueryWrapper<SchProdSchedule> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
List<SchProdScheduleVo> list = baseMapper.selectVoList(lqw);
|
||||
fillDetailList(list);
|
||||
fillOrderList(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量填充明细列表
|
||||
*/
|
||||
private void fillDetailList(List<SchProdScheduleVo> voList) {
|
||||
if (voList == null || voList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Long> scheduleIds = voList.stream()
|
||||
.map(SchProdScheduleVo::getScheduleId)
|
||||
.filter(id -> id != null)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (scheduleIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
LambdaQueryWrapper<SchProdScheduleDetail> detailQw = Wrappers.lambdaQuery();
|
||||
detailQw.in(SchProdScheduleDetail::getScheduleId, scheduleIds);
|
||||
List<SchProdScheduleDetailVo> allDetails = detailMapper.selectVoList(detailQw);
|
||||
if (allDetails == null || allDetails.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<Long, List<SchProdScheduleDetailVo>> detailMap = allDetails.stream()
|
||||
.collect(Collectors.groupingBy(SchProdScheduleDetailVo::getScheduleId));
|
||||
for (SchProdScheduleVo vo : voList) {
|
||||
vo.setDetailList(detailMap.getOrDefault(vo.getScheduleId(), Collections.emptyList()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量填充CRM订单列表(通过 sch_sale_schedule_rel 关联表)
|
||||
*/
|
||||
private void fillOrderList(List<SchProdScheduleVo> voList) {
|
||||
if (voList == null || voList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 1. 收集所有 scheduleId
|
||||
List<Long> scheduleIds = voList.stream()
|
||||
.map(SchProdScheduleVo::getScheduleId)
|
||||
.filter(id -> id != null)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (scheduleIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 2. 查关联表,获取 scheduleId → orderId 映射
|
||||
LambdaQueryWrapper<SchSaleScheduleRel> relQw = Wrappers.lambdaQuery();
|
||||
relQw.in(SchSaleScheduleRel::getScheduleId, scheduleIds);
|
||||
List<SchSaleScheduleRel> rels = relMapper.selectList(relQw);
|
||||
if (rels == null || rels.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 收集所有 orderId(去重)
|
||||
Set<Long> orderIdSet = rels.stream()
|
||||
.map(SchSaleScheduleRel::getOrderId)
|
||||
.filter(id -> id != null)
|
||||
.collect(Collectors.toSet());
|
||||
// scheduleId → 关联的 orderId 列表
|
||||
Map<Long, List<Long>> scheduleOrderIdsMap = rels.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
SchSaleScheduleRel::getScheduleId,
|
||||
Collectors.mapping(SchSaleScheduleRel::getOrderId, Collectors.toList())
|
||||
));
|
||||
if (orderIdSet.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 3. 批量查 CrmOrder
|
||||
CrmOrderBo orderBo = new CrmOrderBo();
|
||||
orderBo.setOrderIds(new java.util.ArrayList<>(orderIdSet));
|
||||
List<CrmOrderVo> allOrders = crmOrderService.queryList(orderBo);
|
||||
Map<Long, CrmOrderVo> orderMap = allOrders != null
|
||||
? allOrders.stream().collect(Collectors.toMap(CrmOrderVo::getOrderId, o -> o, (a, b) -> a))
|
||||
: Collections.emptyMap();
|
||||
// 4. 回填到 VO
|
||||
for (SchProdScheduleVo vo : voList) {
|
||||
List<Long> orderIds = scheduleOrderIdsMap.get(vo.getScheduleId());
|
||||
if (orderIds != null) {
|
||||
List<CrmOrderVo> orders = orderIds.stream()
|
||||
.map(orderMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
vo.setOrderList(orders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SchProdSchedule> buildQueryWrapper(SchProdScheduleBo bo) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.klp.flow.mapper.SchDetailCoilRelMapper">
|
||||
|
||||
<resultMap type="com.klp.flow.domain.SchDetailCoilRel" id="SchDetailCoilRelResult">
|
||||
<result property="relId" column="rel_id"/>
|
||||
<result property="scheduleDetailId" column="schedule_detail_id"/>
|
||||
<result property="coilId" column="coil_id"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
||||
27
klp-ui/src/api/aps/order.js
Normal file
27
klp-ui/src/api/aps/order.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询 CRM 订单列表(只读)
|
||||
export function listCrmOrder(query) {
|
||||
return request({
|
||||
url: '/crm/order/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 CRM 订单详情
|
||||
export function getCrmOrder(orderId) {
|
||||
return request({
|
||||
url: '/crm/order/' + orderId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 CRM 订单明细列表
|
||||
export function listCrmOrderItem(query) {
|
||||
return request({
|
||||
url: '/crm/orderItem/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
120
klp-ui/src/api/aps/requirement.js
Normal file
120
klp-ui/src/api/aps/requirement.js
Normal file
@@ -0,0 +1,120 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// ====== 产需单(SchProdSchedule)CRUD ======
|
||||
|
||||
// 查询产需单列表
|
||||
export function listRequirement(query) {
|
||||
return request({
|
||||
url: '/flow/prodSchedule/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询产需单详情
|
||||
export function getRequirement(scheduleId) {
|
||||
return request({
|
||||
url: '/flow/prodSchedule/' + scheduleId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增产需单
|
||||
export function addRequirement(data) {
|
||||
return request({
|
||||
url: '/flow/prodSchedule',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改产需单
|
||||
export function updateRequirement(data) {
|
||||
return request({
|
||||
url: '/flow/prodSchedule',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除产需单
|
||||
export function delRequirement(scheduleIds) {
|
||||
return request({
|
||||
url: '/flow/prodSchedule/' + scheduleIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// ====== 产需单明细(SchProdScheduleDetail) ======
|
||||
|
||||
// 查询产需单明细列表
|
||||
export function listRequirementDetail(query) {
|
||||
return request({
|
||||
url: '/flow/prodScheduleDetail/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增产需单明细
|
||||
export function addRequirementDetail(data) {
|
||||
return request({
|
||||
url: '/flow/prodScheduleDetail',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改产需单明细
|
||||
export function updateRequirementDetail(data) {
|
||||
return request({
|
||||
url: '/flow/prodScheduleDetail',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除产需单明细
|
||||
export function delRequirementDetail(detailIds) {
|
||||
return request({
|
||||
url: '/flow/prodScheduleDetail/' + detailIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// ====== 销售订单-产需单关联(SchSaleScheduleRel) ======
|
||||
|
||||
// 查询关联列表
|
||||
export function listRel(query) {
|
||||
return request({
|
||||
url: '/flow/saleScheduleRel/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增关联(绑定订单)
|
||||
export function addRel(data) {
|
||||
return request({
|
||||
url: '/flow/saleScheduleRel',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改关联
|
||||
export function updateRel(data) {
|
||||
return request({
|
||||
url: '/flow/saleScheduleRel',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除关联(解绑订单)
|
||||
export function delRel(relIds) {
|
||||
return request({
|
||||
url: '/flow/saleScheduleRel/' + relIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
35
klp-ui/src/api/aps/schedule.js
Normal file
35
klp-ui/src/api/aps/schedule.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 按日期查询产需单列表
|
||||
export function listScheduleByDate(prodDate) {
|
||||
return request({
|
||||
url: '/flow/prodSchedule/list',
|
||||
method: 'get',
|
||||
params: { prodDate }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询产需单明细(用于排产单聚合)
|
||||
export function listScheduleDetail(scheduleId) {
|
||||
return request({
|
||||
url: '/flow/prodScheduleDetail/list',
|
||||
method: 'get',
|
||||
params: { scheduleId }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 CRM 订单信息(用于下钻)
|
||||
export function getCrmOrderInfo(orderId) {
|
||||
return request({
|
||||
url: '/crm/order/' + orderId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 CRM 订单明细(用于下钻展示)
|
||||
export function getCrmOrderItem(orderDetailId) {
|
||||
return request({
|
||||
url: '/crm/orderItem/' + orderDetailId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -735,7 +735,7 @@ export default {
|
||||
if (!d.detailDate) return
|
||||
if (!map[d.detailDate]) map[d.detailDate] = { detailDate: d.detailDate }
|
||||
const sfx = d.shift && d.shift !== '0' ? '_' + d.shift : ''
|
||||
map[d.detailDate]['q' + d.itemId + sfx] = d.quantity
|
||||
map[d.detailDate]['q' + d.itemId + sfx] = d.quantity != null && d.quantity !== '' ? Number(d.quantity).toFixed(2) : d.quantity
|
||||
})
|
||||
this.gridRows = Object.values(map).sort((a,b) => a.detailDate.localeCompare(b.detailDate))
|
||||
},
|
||||
@@ -780,7 +780,7 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
evalF(f) { const s = f.replace(/[^0-9+\-*/.()\s]/g,''); if(!s) return null; try { const r = new Function('return ('+s+')')(); return isFinite(r)?Math.round(r*10000)/10000:null } catch(e){ return null } },
|
||||
evalF(f) { const s = f.replace(/[^0-9+\-*/.()\s]/g,''); if(!s) return null; try { const r = new Function('return ('+s+')')(); return isFinite(r)?(Math.round(r*100)/100).toFixed(2):null } catch(e){ return null } },
|
||||
sortGrid() { this.gridRows.sort((a,b)=>{if(!a.detailDate)return 1;if(!b.detailDate)return -1;return a.detailDate.localeCompare(b.detailDate)}) },
|
||||
async saveGrid() {
|
||||
const rid = this.activeReport.reportId; if (!rid) return; this.saving = true
|
||||
@@ -860,7 +860,7 @@ export default {
|
||||
try {
|
||||
const val = await handler(col.queryCondition, row, col, this.activeReport, shift)
|
||||
if (val != null) {
|
||||
const round3 = n => Math.round(n * 1000) / 1000
|
||||
const round3 = n => (Math.round(n * 100) / 100).toFixed(2)
|
||||
if (Array.isArray(val)) {
|
||||
this.$set(row, 'q' + col.itemId + '_1', round3(val[0]))
|
||||
this.$set(row, 'q' + col.itemId + '_2', round3(val[1]))
|
||||
@@ -946,7 +946,7 @@ export default {
|
||||
if (!col.queryCondition) return
|
||||
const handler = queryHandlers[col.category] || queryHandlers['default']
|
||||
if (!handler) { this.$modal.msgWarning(`类别 "${col.category}" 未注册查询处理器`); return }
|
||||
const round3 = n => Math.round(n * 1000) / 1000
|
||||
const round3 = n => (Math.round(n * 100) / 100).toFixed(2)
|
||||
const tasks = []
|
||||
for (const row of this.gridRows) {
|
||||
if (!row.detailDate) continue
|
||||
|
||||
@@ -130,7 +130,7 @@ export default {
|
||||
else return row.lineType || '-'
|
||||
}
|
||||
},
|
||||
formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(4)) },
|
||||
formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(2)) },
|
||||
async loadItems() { if (!this.allItems.length) { const r = await listItem({ pageNum:1, pageSize:999 }); this.allItems = r.rows || [] } },
|
||||
async enter(row) { const r = await getProdReport(row.reportId); if (r.data) this.activeReport = r.data; else this.activeReport = row; this.loadGrid() }
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ export default {
|
||||
else return row.lineType || '-'
|
||||
}
|
||||
},
|
||||
formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(4)) },
|
||||
formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(2)) },
|
||||
async loadItems() { if (!this.allItems.length) { const r = await listItem({ pageNum:1, pageSize:999 }); this.allItems = r.rows || [] } },
|
||||
async enter(row) { const r = await getProdReport(row.reportId); if (r.data) this.activeReport = r.data; else this.activeReport = row; this.loadGrid() }
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
@pagination="getList" />
|
||||
|
||||
<el-row :gutter="20" class="mt16">
|
||||
<el-col :span="12">
|
||||
<el-col :span="10">
|
||||
<div class="custom-panel">
|
||||
<div class="panel-header">
|
||||
<span class="panel-title">领料列表</span>
|
||||
@@ -102,7 +102,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="14">
|
||||
<div class="custom-panel">
|
||||
<div class="panel-header">
|
||||
<span class="panel-title">退火计划</span>
|
||||
@@ -136,8 +136,33 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="入场卷号" align="center" prop="enterCoilNo" />
|
||||
<el-table-column label="当前卷号" align="center" prop="coil.currentCoilNo" />
|
||||
|
||||
<el-table-column label="创建时间" align="center" prop="action" width="200">
|
||||
<el-table-column label="合同号" align="center" prop="contractId" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-select
|
||||
v-model="scope.row.contractId"
|
||||
placeholder="搜索"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="(q) => remoteSearchOrders(q)"
|
||||
:loading="orderLoading"
|
||||
clearable
|
||||
size="small"
|
||||
@change="handleContractIdChange(scope.row)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in orderList"
|
||||
:key="item.orderId"
|
||||
:label="`${item.contractCode} - ${item.companyName}`"
|
||||
:value="item.orderId"
|
||||
>
|
||||
<span style="font-weight:bold">{{ item.contractCode }}</span>
|
||||
<span style="color:#8492a6;font-size:13px;margin-left:8px">{{ item.companyName }}</span>
|
||||
<span style="color:#c0c4cc;font-size:12px;float:right">{{ item.salesman }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="action">
|
||||
<template slot-scope="scope">
|
||||
<el-date-picker style="width: 185px" v-model="scope.row.createTime" type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择创建时间" @change="handlePLanCoilChange(scope.row)" />
|
||||
@@ -159,7 +184,7 @@
|
||||
</el-row>
|
||||
|
||||
<el-dialog title="完成退火" :visible.sync="completeOpen" width="800px" append-to-body>
|
||||
<div class="complete-tip">请为每条钢卷分配逻辑库区去向和关联合同,未分配将无法完成。</div>
|
||||
<div class="complete-tip">请确认每条钢卷的逻辑库区去向,所有钢卷须已在明细中绑定合同。</div>
|
||||
<el-table :data="completeCoils" v-loading="completeLoading" height="360px">
|
||||
<el-table-column label="入场钢卷号" prop="enterCoilNo" align="center" />
|
||||
<el-table-column label="钢卷去向" align="center" width="270">
|
||||
@@ -170,11 +195,9 @@
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="关联合同" align="center" width="270">
|
||||
<el-table-column label="合同" align="center" width="140">
|
||||
<template slot-scope="scope">
|
||||
<div style="width: 100%; display: flex; align-items: center;">
|
||||
<ContractSelect v-model="scope.row.contractId" placeholder="请选择合同" />
|
||||
</div>
|
||||
<span>{{ scope.row.contractCode || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -238,6 +261,7 @@
|
||||
import { listAnnealPlan, updateAnnealPlanCoil, getAnnealPlan, addAnnealPlan, updateAnnealPlan, delAnnealPlan, changeAnnealPlanStatus, inFurnace, completeAnnealPlan, listAnnealPlanCoils, bindAnnealPlanCoils, unbindAnnealPlanCoil } from "@/api/wms/annealPlan";
|
||||
import { listAnnealFurnace } from "@/api/wms/annealFurnace";
|
||||
import { listMaterialCoil } from "@/api/wms/coil";
|
||||
import { listOrder } from "@/api/crm/order";
|
||||
import { listCoilContractRel } from '@/api/wms/coilContractRel';
|
||||
import { listWarehouse } from '@/api/wms/warehouse'
|
||||
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
|
||||
@@ -279,6 +303,8 @@ export default {
|
||||
},
|
||||
currentPlan: {},
|
||||
coilList: [],
|
||||
orderList: [],
|
||||
orderLoading: false,
|
||||
materialLoading: false,
|
||||
materialTotal: 0,
|
||||
materialList: [],
|
||||
@@ -303,6 +329,7 @@ export default {
|
||||
floatLayerConfig: {
|
||||
columns: [
|
||||
{ label: '入场钢卷号', prop: 'enterCoilNo' },
|
||||
{ label: '合同号', prop: 'contractId' },
|
||||
{ label: '当前钢卷号', prop: 'coil.currentCoilNo' },
|
||||
{ label: '厂家卷号', prop: 'coil.supplierCoilNo' },
|
||||
{ label: '逻辑库位', prop: 'coil.warehouseName' },
|
||||
@@ -332,6 +359,7 @@ export default {
|
||||
this.loadFurnaces();
|
||||
this.getMaterialCoils();
|
||||
this.loadWarehouses();
|
||||
this.loadOrderList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
@@ -363,6 +391,33 @@ export default {
|
||||
this.loadPlanCoils();
|
||||
});
|
||||
},
|
||||
handleContractIdChange(row) {
|
||||
updateAnnealPlanCoil(row).then(() => {
|
||||
this.$message.success('合同号已更新');
|
||||
});
|
||||
},
|
||||
loadOrderList() {
|
||||
this.orderLoading = true;
|
||||
listOrder({ pageNum: 1, pageSize: 100 }).then(response => {
|
||||
this.orderList = response.rows || [];
|
||||
this.orderLoading = false;
|
||||
}).catch(() => {
|
||||
this.orderLoading = false;
|
||||
});
|
||||
},
|
||||
remoteSearchOrders(query) {
|
||||
if (query) {
|
||||
this.orderLoading = true;
|
||||
listOrder({ pageNum: 1, pageSize: 20, keyword: query }).then(response => {
|
||||
this.orderList = response.rows || [];
|
||||
this.orderLoading = false;
|
||||
}).catch(() => {
|
||||
this.orderLoading = false;
|
||||
});
|
||||
} else {
|
||||
this.loadOrderList();
|
||||
}
|
||||
},
|
||||
getMaterialCoils() {
|
||||
this.materialLoading = true;
|
||||
listMaterialCoil(this.materialQueryParams).then(response => {
|
||||
@@ -397,17 +452,10 @@ export default {
|
||||
...item,
|
||||
coilId: item.coilId,
|
||||
enterCoilNo: item.enterCoilNo,
|
||||
warehouseId: item.logicWarehouseId || null
|
||||
warehouseId: item.logicWarehouseId || null,
|
||||
contractId: item.contractId || null,
|
||||
contractCode: (this.orderList.find(o => o.orderId === item.contractId) || {}).contractCode || null,
|
||||
}));
|
||||
// 查询每个钢卷绑定的合同号作为默认值
|
||||
for (const coil of this.completeCoils) {
|
||||
listCoilContractRel({ coilId: coil.coilId }).then(res => {
|
||||
const rows = res.rows || []
|
||||
if (rows.length > 0 && rows[0].contractId) {
|
||||
this.$set(coil, 'contractId', rows[0].contractId)
|
||||
}
|
||||
})
|
||||
}
|
||||
this.completeLoading = false;
|
||||
}).catch(() => {
|
||||
this.completeLoading = false;
|
||||
@@ -585,9 +633,14 @@ export default {
|
||||
warehouseId: item.warehouseId,
|
||||
contractId: item.contractId,
|
||||
}));
|
||||
const missing = locations.filter(item => !item.warehouseId || !item.contractId);
|
||||
if (missing.length > 0) {
|
||||
this.$message.warning('请先为所有钢卷分配实际库位和关联合同');
|
||||
const missingWarehouse = locations.filter(item => !item.warehouseId);
|
||||
if (missingWarehouse.length > 0) {
|
||||
this.$message.warning('请先为所有钢卷分配实际库位');
|
||||
return;
|
||||
}
|
||||
const missingContract = locations.filter(item => !item.contractId);
|
||||
if (missingContract.length > 0) {
|
||||
this.$message.warning('请先在明细中为所有钢卷绑定合同后再完成退火');
|
||||
return;
|
||||
}
|
||||
this.completeLoading = true;
|
||||
@@ -703,8 +756,7 @@ export default {
|
||||
/* ========== 修复在这里 ========== */
|
||||
.material-grid {
|
||||
display: grid;
|
||||
/* 核心修复:去掉固定 4 列,改用自动填充,实现真正自适应 */
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
min-height: 120px;
|
||||
/* 必须加,让 grid 不受父级弹性压缩影响 */
|
||||
@@ -712,15 +764,6 @@ export default {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 媒体查询只需要控制最小宽度即可,不用写死列数 */
|
||||
@media (max-width: 768px) {
|
||||
.material-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================== */
|
||||
|
||||
.material-card {
|
||||
border: 1px solid #e9ecf2;
|
||||
border-radius: 8px;
|
||||
@@ -806,3 +849,6 @@ export default {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
html { overflow-y: scroll; }
|
||||
</style>
|
||||
|
||||
445
klp-ui/src/views/wms/post/aps/order.vue
Normal file
445
klp-ui/src/views/wms/post/aps/order.vue
Normal file
@@ -0,0 +1,445 @@
|
||||
<template>
|
||||
<div class="app-container" style="height: calc(100vh - 84px); display: flex;">
|
||||
<!-- 左侧订单列表 -->
|
||||
<div class="left-panel" v-loading="orderLoading" style="width: 30%; border-right: 1px solid #e4e7ed; overflow-y: auto;">
|
||||
<!-- 筛选区 -->
|
||||
<div class="filter-section" style="padding: 10px; border-bottom: 1px solid #e4e7ed;">
|
||||
<!-- 第一行:搜索 + 按钮 + 记录数 -->
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
|
||||
<div style="display: flex; align-items: center; gap: 4px; flex-wrap: wrap;">
|
||||
<el-input v-model="queryParams.keyword" placeholder="请输入关键字" clearable
|
||||
@keyup.enter.native="handleSearch" style="width: 160px;" />
|
||||
<el-button class="aps-btn-red" icon="el-icon-search" size="mini" @click="handleSearch">筛选</el-button>
|
||||
<el-button icon="el-icon-sort" size="mini" @click="toggleMoreFilter"
|
||||
:class="showMoreFilter ? 'aps-btn-red' : 'aps-btn-silver'"></el-button>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #909399;">
|
||||
共 <span class="aps-total-count">{{ total }}</span> 条记录
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二行:日期范围 -->
|
||||
<div style="display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 4px;">
|
||||
<div style="display: flex; align-items: center; gap: 4px; font-size: 13px; color: #606266;">
|
||||
<span style="white-space: nowrap;">签订日期:</span>
|
||||
<el-date-picker clearable v-model="queryParams.signDateStart" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="签订开始" style="width: 150px;" @change="handleSearch" />
|
||||
<span>~</span>
|
||||
<el-date-picker clearable v-model="queryParams.signDateEnd" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="签订结束" style="width: 150px;" @change="handleSearch" />
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 4px; font-size: 13px; color: #606266;">
|
||||
<span style="white-space: nowrap;">交货日期:</span>
|
||||
<el-date-picker clearable v-model="queryParams.deliveryDateStart" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="交货开始" style="width: 150px;" @change="handleSearch" />
|
||||
<span>~</span>
|
||||
<el-date-picker clearable v-model="queryParams.deliveryDateEnd" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="交货结束" style="width: 150px;" @change="handleSearch" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第三行:更多筛选条件 -->
|
||||
<div v-show="showMoreFilter" class="more-filter"
|
||||
style="margin-top: 8px; padding-top: 10px; border-top: 1px dashed #e4e7ed;">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="80px">
|
||||
<el-form-item label="订单编号" prop="orderCode">
|
||||
<el-input v-model="queryParams.orderCode" placeholder="请输入订单编号" clearable
|
||||
@keyup.enter.native="handleSearch" />
|
||||
</el-form-item>
|
||||
<el-form-item label="销售员" prop="salesman">
|
||||
<el-select v-model="queryParams.salesman" placeholder="请选择销售员" clearable style="width: 140px;">
|
||||
<el-option v-for="item in dict.type.wip_pack_saleman" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单状态" prop="orderStatus">
|
||||
<el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable style="width: 140px;">
|
||||
<el-option v-for="(value, key) in ORDER_STATUS" :key="value" :label="key" :value="value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="aps-btn-silver" icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 列表区域 -->
|
||||
<div class="custom-list">
|
||||
<div class="list-body">
|
||||
<div
|
||||
v-for="item in orderList"
|
||||
:key="item.orderId"
|
||||
class="list-item"
|
||||
:class="{ 'list-item-active': currentOrder && currentOrder.orderId === item.orderId }"
|
||||
@click="handleOrderClick(item)"
|
||||
>
|
||||
<!-- 第一行:订单编号 + 客户公司 -->
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<div style="font-weight: bold;">{{ item.contractName }}</div>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #606266;">{{ item.companyName }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二行:销售员 + 合同号 -->
|
||||
<div style="font-size: 12px; color: #909399; margin-bottom: 6px;">
|
||||
<span>销售员: {{ item.salesman }}</span>
|
||||
<span style="margin-left: 20px;">合同号: {{ item.contractCode }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 第三行:签订时间 + 交货日期 -->
|
||||
<div style="font-size: 12px; color: #909399; margin-bottom: 6px;">
|
||||
<span>签订时间: {{ item.signTime }}</span>
|
||||
<span style="margin-left: 20px;">交货日期: {{ item.deliveryDate }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 第四行:签订地点 + 状态 -->
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<div style="font-size: 12px; color: #909399;">
|
||||
签订地点: {{ item.signLocation || '-' }}
|
||||
</div>
|
||||
<el-tag
|
||||
:type="statusTagType(item.orderStatus)"
|
||||
size="small"
|
||||
>{{ statusLabel(item.orderStatus) }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="orderList.length === 0 && !orderLoading" style="padding: 40px; text-align: center; color: #909399;">
|
||||
暂无订单数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
style="padding: 10px; margin-bottom: 10px !important;"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 右侧内容区域 -->
|
||||
<div class="right-panel" v-if="currentOrder && currentOrder.orderId" style="flex: 1; display: flex; flex-direction: column;">
|
||||
<div class="detail-panel">
|
||||
<!-- 订单基本信息(含甲乙双方)卡片 -->
|
||||
<div class="detail-card">
|
||||
<div class="detail-card-header">
|
||||
<span>订单基本信息</span>
|
||||
</div>
|
||||
<div class="detail-card-body">
|
||||
<div class="form-grid-2">
|
||||
<div class="form-field"><label>销售员</label><div class="field-value">{{ currentOrder.salesman }}</div></div>
|
||||
<div class="form-field"><label>合同号</label><div class="field-value">{{ currentOrder.contractCode }}</div></div>
|
||||
<div class="form-field"><label>签订时间</label><div class="field-value">{{ currentOrder.signTime }}</div></div>
|
||||
<div class="form-field"><label>交货日期</label><div class="field-value">{{ currentOrder.deliveryDate }}</div></div>
|
||||
<div class="form-field"><label>订单总金额</label><div class="field-value">{{ currentOrder.orderAmount }}</div></div>
|
||||
<div class="form-field"><label>签订地点</label><div class="field-value">{{ currentOrder.signLocation }}</div></div>
|
||||
<div class="form-field" style="grid-column:1/3;"><label>备注</label><div class="field-value">{{ currentOrder.remark }}</div></div>
|
||||
</div>
|
||||
<div class="section-divider"></div>
|
||||
<div class="form-grid-2">
|
||||
<div class="form-field"><label>供方名称(甲方)</label><div class="field-value">{{ currentOrder.supplier }}</div></div>
|
||||
<div class="form-field"><label>供方地址</label><div class="field-value">{{ currentOrder.supplierAddress }}</div></div>
|
||||
<div class="form-field"><label>供方电话</label><div class="field-value">{{ currentOrder.supplierPhone }}</div></div>
|
||||
<div class="form-field"><label>供方开户行</label><div class="field-value">{{ currentOrder.supplierBank }}</div></div>
|
||||
<div class="form-field"><label>供方账号</label><div class="field-value">{{ currentOrder.supplierAccount }}</div></div>
|
||||
<div class="form-field"><label>供方税号</label><div class="field-value">{{ currentOrder.supplierTaxNo }}</div></div>
|
||||
<div class="form-field" style="border-top:1px solid #e8e8e8;padding-top:8px;margin-top:4px;grid-column:1/3;"></div>
|
||||
<div class="form-field"><label>需方名称(乙方)</label><div class="field-value">{{ currentOrder.customer }}</div></div>
|
||||
<div class="form-field"><label>需方地址</label><div class="field-value">{{ currentOrder.customerAddress }}</div></div>
|
||||
<div class="form-field"><label>需方电话</label><div class="field-value">{{ currentOrder.customerPhone }}</div></div>
|
||||
<div class="form-field"><label>需方开户行</label><div class="field-value">{{ currentOrder.customerBank }}</div></div>
|
||||
<div class="form-field"><label>需方账号</label><div class="field-value">{{ currentOrder.customerAccount }}</div></div>
|
||||
<div class="form-field"><label>需方税号</label><div class="field-value">{{ currentOrder.customerTaxNo }}</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 订单明细卡片 -->
|
||||
<div class="detail-card">
|
||||
<div class="detail-card-header">
|
||||
<span>订单明细({{ productList.length }} 条)</span>
|
||||
</div>
|
||||
<div class="detail-card-body" style="padding:0;">
|
||||
<div v-if="productList.length > 0" class="aps-product-table-wrap">
|
||||
<el-table :data="productList" border size="small" class="aps-product-table">
|
||||
<el-table-column label="规格" prop="spec" min-width="120" />
|
||||
<el-table-column label="材质" prop="material" width="100" align="center" />
|
||||
<el-table-column label="数量(吨)" prop="quantity" width="90" align="right" />
|
||||
<el-table-column label="含税单价" prop="taxPrice" width="100" align="right" />
|
||||
<el-table-column label="含税总额" prop="taxTotal" width="100" align="right" />
|
||||
<el-table-column label="无税单价" prop="noTaxPrice" width="100" align="right" />
|
||||
<el-table-column label="无税总额" prop="noTaxTotal" width="100" align="right" />
|
||||
<el-table-column label="税额" prop="taxAmount" width="90" align="right" />
|
||||
<el-table-column label="备注" prop="remark" min-width="120" />
|
||||
</el-table>
|
||||
<div class="aps-product-summary">
|
||||
<span>产品名称:{{ productName }}</span>
|
||||
<span>总数量:{{ totalQuantity }} 吨</span>
|
||||
<span>含税总额:{{ totalTaxTotal }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="暂无产品明细" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else style="flex: 1; display: flex; flex-direction: column;">
|
||||
<el-empty description="选择订单后查看内容" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listCrmOrder } from '@/api/aps/order'
|
||||
import { parseProductContent } from '@/utils/productContent'
|
||||
import { ORDER_STATUS } from '@/views/crm/js/enum'
|
||||
import FileList from '@/components/FileList'
|
||||
|
||||
export default {
|
||||
name: 'ApsOrder',
|
||||
components: { FileList },
|
||||
dicts: ['wip_pack_saleman'],
|
||||
data() {
|
||||
return {
|
||||
ORDER_STATUS,
|
||||
showMoreFilter: false,
|
||||
orderLoading: false,
|
||||
orderList: [],
|
||||
total: 0,
|
||||
currentOrder: null,
|
||||
productList: [],
|
||||
productName: '',
|
||||
totalQuantity: 0,
|
||||
totalTaxTotal: 0,
|
||||
queryParams: {
|
||||
keyword: '',
|
||||
orderCode: '',
|
||||
salesman: '',
|
||||
orderStatus: undefined,
|
||||
signDateStart: undefined,
|
||||
signDateEnd: undefined,
|
||||
deliveryDateStart: undefined,
|
||||
deliveryDateEnd: undefined,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
toggleMoreFilter() {
|
||||
this.showMoreFilter = !this.showMoreFilter
|
||||
},
|
||||
handleSearch() {
|
||||
this.queryParams.pageNum = 1
|
||||
this.getList()
|
||||
},
|
||||
resetQuery() {
|
||||
this.queryParams.orderCode = ''
|
||||
this.queryParams.salesman = ''
|
||||
this.queryParams.orderStatus = undefined
|
||||
this.queryParams.signDateStart = undefined
|
||||
this.queryParams.signDateEnd = undefined
|
||||
this.queryParams.deliveryDateStart = undefined
|
||||
this.queryParams.deliveryDateEnd = undefined
|
||||
this.handleSearch()
|
||||
},
|
||||
getList() {
|
||||
this.orderLoading = true
|
||||
listCrmOrder(this.queryParams).then(res => {
|
||||
this.orderList = res.rows || []
|
||||
this.total = res.total || 0
|
||||
}).catch(() => {
|
||||
this.orderList = []
|
||||
this.total = 0
|
||||
}).finally(() => {
|
||||
this.orderLoading = false
|
||||
})
|
||||
},
|
||||
handleOrderClick(order) {
|
||||
this.currentOrder = order
|
||||
this.parseProductContent(order)
|
||||
},
|
||||
parseProductContent(order) {
|
||||
if (!order || !order.productContent) {
|
||||
this.productList = []
|
||||
this.productName = ''
|
||||
this.totalQuantity = 0
|
||||
this.totalTaxTotal = 0
|
||||
return
|
||||
}
|
||||
const parsed = parseProductContent(order.productContent)
|
||||
this.productList = parsed.products || []
|
||||
this.productName = parsed.productName || ''
|
||||
this.totalQuantity = parsed.totalQuantity || 0
|
||||
this.totalTaxTotal = parsed.totalTaxTotal || 0
|
||||
},
|
||||
statusTagType(status) {
|
||||
const map = { 0: 'info', 1: 'warning', 2: 'primary', 3: 'success', 4: 'success' }
|
||||
return map[status] || 'info'
|
||||
},
|
||||
statusLabel(status) {
|
||||
const labels = { 0: '待生产', 1: '生产中', 2: '部分发货', 3: '已发货', 4: '已签收' }
|
||||
return labels[status] || '未知'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './scss/aps-theme.scss';
|
||||
|
||||
.app-container {
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
height: calc(100vh - 84px);
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
height: calc(100vh - 84px);
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
// ====== 左侧列表(参照 ContractList.vue) ======
|
||||
.custom-list {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
padding: 10px;
|
||||
border-bottom: 2px solid #dddddd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.list-item:hover {
|
||||
background-color: $aps-silver-1;
|
||||
}
|
||||
|
||||
.list-item-active {
|
||||
background-color: $aps-red-1;
|
||||
border-left: 3px solid $aps-red-2;
|
||||
}
|
||||
|
||||
.aps-total-count {
|
||||
color: $aps-red-2;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.aps-btn-red {
|
||||
@include aps-btn-red;
|
||||
}
|
||||
|
||||
.aps-btn-silver {
|
||||
@include aps-btn-silver;
|
||||
}
|
||||
|
||||
// ====== 右侧详情面板(参照 HTML 设计稿) ======
|
||||
.detail-panel {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
background: $aps-bg;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $aps-white;
|
||||
border: 1px solid $aps-border;
|
||||
border-radius: $aps-radius;
|
||||
box-shadow: $aps-shadow-sm;
|
||||
}
|
||||
|
||||
.detail-card-header {
|
||||
background: linear-gradient(to right, $aps-red-2, $aps-red-3);
|
||||
color: white;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.detail-card-body {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.form-grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px 16px;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.form-field label {
|
||||
font-size: 11px;
|
||||
color: $aps-text-muted;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.form-field .field-value {
|
||||
font-size: 13px;
|
||||
color: $aps-text;
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px solid $aps-silver-mid;
|
||||
}
|
||||
|
||||
// ====== 产品明细 ======
|
||||
.aps-detail-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: $aps-silver-5;
|
||||
border-left: 3px solid $aps-red-2;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.aps-product-table-wrap {
|
||||
border: 1px solid $aps-silver-3;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.aps-product-table {
|
||||
width: 100%;
|
||||
|
||||
::v-deep th {
|
||||
background: $aps-silver-1 !important;
|
||||
color: $aps-silver-5 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.aps-product-summary {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
padding: 8px 16px;
|
||||
background: $aps-silver-1;
|
||||
border-top: 1px solid $aps-silver-3;
|
||||
font-size: 13px;
|
||||
color: $aps-silver-5;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
1022
klp-ui/src/views/wms/post/aps/requirement.vue
Normal file
1022
klp-ui/src/views/wms/post/aps/requirement.vue
Normal file
File diff suppressed because it is too large
Load Diff
316
klp-ui/src/views/wms/post/aps/schedule.vue
Normal file
316
klp-ui/src/views/wms/post/aps/schedule.vue
Normal file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<div class="aps-sch-page">
|
||||
<!-- 顶部工具栏 -->
|
||||
<div class="aps-sch-toolbar">
|
||||
<span class="aps-sch-label">生产日期:</span>
|
||||
<el-date-picker
|
||||
v-model="queryDate"
|
||||
type="date"
|
||||
placeholder="选择生产日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
size="small"
|
||||
style="width:160px"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
<el-button size="small" class="aps-btn-red" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
||||
<div class="aps-sch-summary" v-if="summaryText">
|
||||
<span>{{ summaryText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 排产明细卡片 -->
|
||||
<div class="detail-card aps-sch-card">
|
||||
<div class="detail-card-header">
|
||||
<span>排产明细</span>
|
||||
<span v-if="detailList.length > 0" style="font-weight:normal;font-size:12px;opacity:0.8;">
|
||||
共 {{ scheduleList.length }} 个产需单,{{ detailList.length }} 条明细
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-card-body" style="padding:0;" v-loading="schLoading">
|
||||
<el-table
|
||||
v-if="detailList.length > 0"
|
||||
:data="detailList"
|
||||
border
|
||||
size="small"
|
||||
class="aps-table"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column label="排产单号" prop="scheduleNo" min-width="140" fixed="left">
|
||||
<template slot-scope="{ row }">
|
||||
<span class="sch-link-text">{{ row.scheduleNo }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格" prop="spec" min-width="120" />
|
||||
<el-table-column label="材质" prop="material" width="90" align="center" />
|
||||
<el-table-column label="排产吨数" prop="scheduleWeight" width="100" align="right" />
|
||||
<el-table-column label="品名" prop="productType" min-width="100" />
|
||||
<el-table-column label="订货单位" prop="customerName" min-width="140" />
|
||||
<el-table-column label="业务员" prop="businessUser" width="80" align="center" />
|
||||
<el-table-column label="交货期(天)" prop="deliveryCycle" width="90" align="center" />
|
||||
<el-table-column label="备注" prop="remark" min-width="140" />
|
||||
</el-table>
|
||||
<div v-else-if="!schLoading" style="padding:40px;text-align:center;color:#909399;">
|
||||
{{ hasQueried ? '该日期暂无排产数据' : '请选择日期查询排产数据' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 下钻弹窗 -->
|
||||
<el-dialog
|
||||
title="来源订单信息"
|
||||
:visible.sync="drillDialogVisible"
|
||||
width="600px"
|
||||
append-to-body
|
||||
>
|
||||
<div v-if="drillOrder" class="detail-card" style="border:none;box-shadow:none;">
|
||||
<div class="detail-card-body">
|
||||
<div class="form-grid-2">
|
||||
<div class="form-field"><label>订单编号</label><div class="field-value">{{ drillOrder.orderCode }}</div></div>
|
||||
<div class="form-field"><label>销售员</label><div class="field-value">{{ drillOrder.salesman }}</div></div>
|
||||
<div class="form-field"><label>客户公司</label><div class="field-value">{{ drillOrder.companyName }}</div></div>
|
||||
<div class="form-field"><label>联系人</label><div class="field-value">{{ drillOrder.contactPerson }}</div></div>
|
||||
<div class="form-field"><label>联系电话</label><div class="field-value">{{ drillOrder.contactWay }}</div></div>
|
||||
<div class="form-field"><label>交货日期</label><div class="field-value">{{ drillOrder.deliveryDate }}</div></div>
|
||||
<div class="form-field"><label>合同号</label><div class="field-value">{{ drillOrder.contractCode }}</div></div>
|
||||
<div class="form-field" style="grid-column:1/3;"><label>备注</label><div class="field-value">{{ drillOrder.remark }}</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-empty description="未找到订单信息" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listRequirement } from '@/api/aps/requirement'
|
||||
import { getCrmOrderInfo } from '@/api/aps/schedule'
|
||||
|
||||
export default {
|
||||
name: 'ApsSchedule',
|
||||
data() {
|
||||
const today = new Date()
|
||||
const y = today.getFullYear()
|
||||
const m = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(today.getDate()).padStart(2, '0')
|
||||
return {
|
||||
queryDate: `${y}-${m}-${d}`,
|
||||
schLoading: false,
|
||||
hasQueried: false,
|
||||
scheduleList: [],
|
||||
detailList: [],
|
||||
summaryText: '',
|
||||
drillDialogVisible: false,
|
||||
drillOrder: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.handleQuery()
|
||||
},
|
||||
methods: {
|
||||
handleDateChange() {
|
||||
this.handleQuery()
|
||||
},
|
||||
handleQuery() {
|
||||
if (!this.queryDate) {
|
||||
this.$message.warning('请选择生产日期')
|
||||
return
|
||||
}
|
||||
this.schLoading = true
|
||||
this.hasQueried = true
|
||||
this.detailList = []
|
||||
this.scheduleList = []
|
||||
|
||||
// 后端 list 接口已通过 fillDetailList 填充 detailList
|
||||
listRequirement({ prodDate: this.queryDate, pageNum: 1, pageSize: 999 }).then(res => {
|
||||
const list = res.rows || []
|
||||
this.scheduleList = list
|
||||
|
||||
// 扁平化所有 detailList
|
||||
const merged = []
|
||||
list.forEach(sch => {
|
||||
const details = sch.detailList || []
|
||||
details.forEach(d => {
|
||||
merged.push({
|
||||
...d,
|
||||
scheduleNo: sch.scheduleNo,
|
||||
customerName: sch.customerName,
|
||||
businessUser: sch.businessUser,
|
||||
deliveryCycle: sch.deliveryCycle,
|
||||
_scheduleId: sch.scheduleId
|
||||
})
|
||||
})
|
||||
})
|
||||
this.detailList = merged
|
||||
|
||||
const totalWeight = merged.reduce((sum, d) => sum + (parseFloat(d.scheduleWeight) || 0), 0)
|
||||
this.summaryText = `共 ${list.length} 个产需单,${merged.length} 条明细,排产总吨数 ${totalWeight.toFixed(3)} 吨`
|
||||
}).catch(() => {
|
||||
this.detailList = []
|
||||
this.summaryText = ''
|
||||
}).finally(() => {
|
||||
this.schLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
handleRowClick(row) {
|
||||
// 通过 _scheduleId 找到产需单,然后找到关联的订单
|
||||
const sch = this.scheduleList.find(s => s.scheduleId === row._scheduleId)
|
||||
if (!sch || !sch.orderList || sch.orderList.length === 0) {
|
||||
this.$message.warning('未找到关联订单')
|
||||
return
|
||||
}
|
||||
// 取第一个关联订单展示
|
||||
const order = sch.orderList[0]
|
||||
getCrmOrderInfo(order.orderId).then(res => {
|
||||
this.drillOrder = res.data
|
||||
this.drillDialogVisible = true
|
||||
}).catch(() => {
|
||||
this.$message.warning('未找到来源订单')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './scss/aps-theme.scss';
|
||||
|
||||
.aps-sch-page {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
background: $aps-bg;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
// 工具栏
|
||||
.aps-sch-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 16px;
|
||||
background: $aps-white;
|
||||
border: 1px solid $aps-border;
|
||||
border-radius: $aps-radius;
|
||||
box-shadow: $aps-shadow-sm;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.aps-sch-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: $aps-text;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.aps-sch-summary {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
color: $aps-text-muted;
|
||||
background: $aps-silver-1;
|
||||
padding: 4px 12px;
|
||||
border-radius: $aps-radius;
|
||||
border: 1px solid $aps-border;
|
||||
}
|
||||
|
||||
// 排产卡片
|
||||
.aps-sch-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.detail-card-body {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 表格
|
||||
.aps-table {
|
||||
width: 100%;
|
||||
|
||||
::v-deep th {
|
||||
background: $aps-silver-1 !important;
|
||||
color: $aps-text !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
::v-deep .el-table__body tr:hover > td {
|
||||
background-color: $aps-red-1 !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::v-deep td {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.sch-link-text {
|
||||
color: $aps-red-2;
|
||||
font-weight: 500;
|
||||
&:hover {
|
||||
color: $aps-red-3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
// 复用卡片/网格变量
|
||||
.aps-btn-red {
|
||||
@include aps-btn-red;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $aps-white;
|
||||
border: 1px solid $aps-border;
|
||||
border-radius: $aps-radius;
|
||||
box-shadow: $aps-shadow-sm;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail-card-header {
|
||||
background: linear-gradient(to right, $aps-red-2, $aps-red-3);
|
||||
color: white;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.detail-card-body {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.form-grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px 16px;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.form-field label {
|
||||
font-size: 11px;
|
||||
color: $aps-text-muted;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.form-field .field-value {
|
||||
font-size: 13px;
|
||||
color: $aps-text;
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px solid $aps-silver-mid;
|
||||
}
|
||||
</style>
|
||||
143
klp-ui/src/views/wms/post/aps/scss/aps-theme.scss
Normal file
143
klp-ui/src/views/wms/post/aps/scss/aps-theme.scss
Normal file
@@ -0,0 +1,143 @@
|
||||
// ============================================
|
||||
// APS 排产管理模块 — 银灰色 + 红色主题
|
||||
// 每个页面通过 @import 引入并提供 scoped 命名空间
|
||||
// ============================================
|
||||
|
||||
// ——— 颜色变量 ———
|
||||
$aps-silver-1: #f5f5f5; // 最浅银灰(背景)
|
||||
$aps-silver-2: #e8e8e8; // 浅银灰(卡片/列表行)
|
||||
$aps-silver-3: #d9d9d9; // 中银灰(边框)
|
||||
$aps-silver-4: #8c8c8c; // 深银灰(次要文字/图标)
|
||||
$aps-silver-5: #595959; // 最深银灰(主标题/强调文字)
|
||||
|
||||
$aps-red-1: #fff1f0; // 极浅红(背景高亮)
|
||||
$aps-red-2: #ff4d4f; // 标准红(主按钮/标签)
|
||||
$aps-red-3: #cf1322; // 深红(hover/边框强调)
|
||||
$aps-red-4: #f5222d; // 辅助红
|
||||
|
||||
// ——— 混入:列表项 ———
|
||||
@mixin aps-list-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
margin-bottom: 6px;
|
||||
border: 1px solid $aps-silver-3;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
border-color: $aps-red-2;
|
||||
background-color: $aps-red-1;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-left: 3px solid $aps-red-2;
|
||||
border-color: $aps-red-2;
|
||||
background-color: $aps-red-1;
|
||||
box-shadow: 0 0 0 1px rgba($aps-red-2, 0.08) inset;
|
||||
}
|
||||
}
|
||||
|
||||
// ——— 混入:银色卡片 ———
|
||||
@mixin aps-card {
|
||||
background: #fff;
|
||||
border: 1px solid $aps-silver-3;
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
// ——— 混入:银色按钮变体 ———
|
||||
@mixin aps-btn-silver {
|
||||
color: $aps-silver-5;
|
||||
background: $aps-silver-1;
|
||||
border-color: $aps-silver-3;
|
||||
|
||||
&:hover {
|
||||
color: $aps-red-2;
|
||||
border-color: $aps-red-2;
|
||||
background: $aps-red-1;
|
||||
}
|
||||
}
|
||||
|
||||
// ——— 混入:红色按钮变体 ———
|
||||
@mixin aps-btn-red {
|
||||
color: #fff;
|
||||
background: $aps-red-2;
|
||||
border-color: $aps-red-2;
|
||||
|
||||
&:hover {
|
||||
background: $aps-red-3;
|
||||
border-color: $aps-red-3;
|
||||
}
|
||||
}
|
||||
|
||||
// ——— 混入:状态标签 ———
|
||||
@mixin aps-status-tag($bg, $color) {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
background: $bg;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
// ——— 详情卡片通用变量(参照 HTML 设计稿) ———
|
||||
$aps-bg: #f4f5f7;
|
||||
$aps-white: #ffffff;
|
||||
$aps-border: #c8cdd2;
|
||||
$aps-text: #2c3e50;
|
||||
$aps-text-muted: #7f8c8d;
|
||||
$aps-silver-mid: #d5d8dc;
|
||||
$aps-shadow-sm: 0 1px 4px rgba(0,0,0,0.08);
|
||||
$aps-radius: 4px;
|
||||
|
||||
// ——— 混入:详情卡片 ———
|
||||
@mixin aps-detail-card {
|
||||
background: $aps-white;
|
||||
border: 1px solid $aps-border;
|
||||
border-radius: $aps-radius;
|
||||
box-shadow: $aps-shadow-sm;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// ——— 混入:卡片头部渐变 ———
|
||||
@mixin aps-card-header {
|
||||
background: linear-gradient(to right, $aps-red-2, $aps-red-3);
|
||||
color: white;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
// ——— 混入:表单网格(2列) ———
|
||||
@mixin aps-form-grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px 16px;
|
||||
}
|
||||
|
||||
// ——— 混入:表单字段 ———
|
||||
@mixin aps-form-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
|
||||
label {
|
||||
font-size: 11px;
|
||||
color: $aps-text-muted;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
font-size: 13px;
|
||||
color: $aps-text;
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px solid $aps-silver-mid;
|
||||
}
|
||||
}
|
||||
@@ -47,9 +47,9 @@ public class WmsFurnacePlanCoil extends BaseEntity {
|
||||
private Integer furnaceLevel;
|
||||
|
||||
/**
|
||||
* 合同号
|
||||
* 合同ID
|
||||
*/
|
||||
private String contractNo;
|
||||
private Long contractId;
|
||||
|
||||
/**
|
||||
* 删除标志(0=正常,1=已删除)
|
||||
|
||||
@@ -43,9 +43,9 @@ public class WmsFurnacePlanCoilBo extends BaseEntity {
|
||||
private Integer furnaceLevel;
|
||||
|
||||
/**
|
||||
* 合同号
|
||||
* 合同ID
|
||||
*/
|
||||
private String contractNo;
|
||||
private Long contractId;
|
||||
|
||||
/**
|
||||
* 钢卷ID列表(逗号分隔)
|
||||
|
||||
@@ -432,5 +432,11 @@ public class WmsMaterialCoilBo extends BaseEntity {
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean excludeAccepted;
|
||||
|
||||
/**
|
||||
* 是否排除已绑定排产明细的钢卷(true=列表不返回已绑定排产明细的钢卷)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean excludeScheduledDetail;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ public class WmsFurnacePlanCoilVo {
|
||||
@ExcelProperty(value = "炉火层级")
|
||||
private Integer furnaceLevel;
|
||||
|
||||
@ExcelProperty(value = "合同号")
|
||||
private String contractNo;
|
||||
@ExcelProperty(value = "合同ID")
|
||||
private Long contractId;
|
||||
|
||||
@ExcelProperty(value = "入场钢卷号")
|
||||
private String enterCoilNo;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class WmsFurnacePlanCoilServiceImpl implements IWmsFurnacePlanCoilService
|
||||
lqw.eq(bo.getCoilId() != null, WmsFurnacePlanCoil::getCoilId, bo.getCoilId());
|
||||
lqw.eq(bo.getLogicWarehouseId() != null, WmsFurnacePlanCoil::getLogicWarehouseId, bo.getLogicWarehouseId());
|
||||
lqw.eq(bo.getFurnaceLevel() != null, WmsFurnacePlanCoil::getFurnaceLevel, bo.getFurnaceLevel());
|
||||
lqw.eq(bo.getContractNo() != null, WmsFurnacePlanCoil::getContractNo, bo.getContractNo());
|
||||
lqw.eq(bo.getContractId() != null, WmsFurnacePlanCoil::getContractId, bo.getContractId());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,6 +392,11 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
|
||||
if (targetLocation == null) {
|
||||
throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未分配库位");
|
||||
}
|
||||
// 校验合同ID:必须所有钢卷都已绑定合同
|
||||
Long contractId = contractIdMap.get(coil.getCoilId());
|
||||
if (contractId == null) {
|
||||
throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未绑定合同,请先在明细中设置合同");
|
||||
}
|
||||
|
||||
WmsMaterialCoil oldCoil = materialCoilMapper.selectById(coil.getCoilId());
|
||||
if (oldCoil == null) {
|
||||
@@ -414,7 +419,7 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService {
|
||||
updateBo.setStatus(0);
|
||||
updateBo.setExportBy(null);
|
||||
updateBo.setExportTime(null);
|
||||
updateBo.setContractId(contractIdMap.get(coil.getCoilId()));
|
||||
updateBo.setContractId(contractId);
|
||||
|
||||
materialCoilService.updateByBo(updateBo, "annealing");
|
||||
|
||||
|
||||
@@ -1128,6 +1128,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
if (Boolean.TRUE.equals(bo.getExcludeAccepted())) {
|
||||
qw.apply("NOT EXISTS (SELECT 1 FROM ts_accept_coil_rel acr WHERE acr.del_flag = 0 AND acr.coil_id = mc.coil_id)");
|
||||
}
|
||||
// 排除已绑定排产明细的钢卷(防止重复绑定排产单)
|
||||
if (Boolean.TRUE.equals(bo.getExcludeScheduledDetail())) {
|
||||
qw.apply("NOT EXISTS (SELECT 1 FROM sch_prod_schedule_detail_coil sdc WHERE sdc.del_flag = 0 AND sdc.coil_id = mc.coil_id)");
|
||||
}
|
||||
|
||||
// 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN
|
||||
boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType());
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<result property="coilId" column="coil_id"/>
|
||||
<result property="logicWarehouseId" column="logic_warehouse_id"/>
|
||||
<result property="furnaceLevel" column="furnace_level"/>
|
||||
<result property="contractNo" column="contract_no"/>
|
||||
<result property="contractId" column="contract_id"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
|
||||
@@ -3976,6 +3976,7 @@ CREATE TABLE `wms_furnace_plan_coil` (
|
||||
`coil_id` bigint NOT NULL COMMENT '钢卷ID',
|
||||
`logic_warehouse_id` bigint NULL DEFAULT NULL COMMENT '逻辑库区去向(钢卷退火后目标逻辑库区)',
|
||||
`furnace_level` tinyint(1) NULL DEFAULT NULL COMMENT '炉火层级(1=一层,2=二层,3=三层)',
|
||||
`contract_id` bigint NULL DEFAULT NULL COMMENT '合同ID',
|
||||
`del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标记(0正常 1删除)',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
|
||||
Reference in New Issue
Block a user