Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2026-07-03 15:04:52 +08:00
22 changed files with 3319 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
package com.klp.pt.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.pt.domain.vo.PtProductSurfaceSpecVo;
import com.klp.pt.domain.bo.PtProductSurfaceSpecBo;
import com.klp.pt.service.IPtProductSurfaceSpecService;
import com.klp.common.core.page.TableDataInfo;
/**
* 产品面质量明细
*
* @author klp
* @date 2026-07-02
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/pt/productSurfaceSpec")
public class PtProductSurfaceSpecController extends BaseController {
private final IPtProductSurfaceSpecService iPtProductSurfaceSpecService;
/**
* 查询产品面质量明细列表
*/
@GetMapping("/list")
public TableDataInfo<PtProductSurfaceSpecVo> list(PtProductSurfaceSpecBo bo, PageQuery pageQuery) {
return iPtProductSurfaceSpecService.queryPageList(bo, pageQuery);
}
/**
* 导出产品面质量明细列表
*/
@Log(title = "产品面质量明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(PtProductSurfaceSpecBo bo, HttpServletResponse response) {
List<PtProductSurfaceSpecVo> list = iPtProductSurfaceSpecService.queryList(bo);
ExcelUtil.exportExcel(list, "产品面质量明细", PtProductSurfaceSpecVo.class, response);
}
/**
* 获取产品面质量明细详细信息
*
* @param surfaceId 主键
*/
@GetMapping("/{surfaceId}")
public R<PtProductSurfaceSpecVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long surfaceId) {
return R.ok(iPtProductSurfaceSpecService.queryById(surfaceId));
}
/**
* 新增产品面质量明细
*/
@Log(title = "产品面质量明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody PtProductSurfaceSpecBo bo) {
return toAjax(iPtProductSurfaceSpecService.insertByBo(bo));
}
/**
* 修改产品面质量明细
*/
@Log(title = "产品面质量明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PtProductSurfaceSpecBo bo) {
return toAjax(iPtProductSurfaceSpecService.updateByBo(bo));
}
/**
* 删除产品面质量明细
*
* @param surfaceIds 主键串
*/
@Log(title = "产品面质量明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{surfaceIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] surfaceIds) {
return toAjax(iPtProductSurfaceSpecService.deleteWithValidByIds(Arrays.asList(surfaceIds), true));
}
}

View File

@@ -0,0 +1,100 @@
package com.klp.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.domain.vo.PtProductToleranceVo;
import com.klp.domain.bo.PtProductToleranceBo;
import com.klp.service.IPtProductToleranceService;
import com.klp.common.core.page.TableDataInfo;
/**
* 产品尺寸公差明细
*
* @author klp
* @date 2026-07-02
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/klp/productTolerance")
public class PtProductToleranceController extends BaseController {
private final IPtProductToleranceService iPtProductToleranceService;
/**
* 查询产品尺寸公差明细列表
*/
@GetMapping("/list")
public TableDataInfo<PtProductToleranceVo> list(PtProductToleranceBo bo, PageQuery pageQuery) {
return iPtProductToleranceService.queryPageList(bo, pageQuery);
}
/**
* 导出产品尺寸公差明细列表
*/
@Log(title = "产品尺寸公差明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(PtProductToleranceBo bo, HttpServletResponse response) {
List<PtProductToleranceVo> list = iPtProductToleranceService.queryList(bo);
ExcelUtil.exportExcel(list, "产品尺寸公差明细", PtProductToleranceVo.class, response);
}
/**
* 获取产品尺寸公差明细详细信息
*
* @param toleranceId 主键
*/
@GetMapping("/{toleranceId}")
public R<PtProductToleranceVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long toleranceId) {
return R.ok(iPtProductToleranceService.queryById(toleranceId));
}
/**
* 新增产品尺寸公差明细
*/
@Log(title = "产品尺寸公差明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody PtProductToleranceBo bo) {
return toAjax(iPtProductToleranceService.insertByBo(bo));
}
/**
* 修改产品尺寸公差明细
*/
@Log(title = "产品尺寸公差明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PtProductToleranceBo bo) {
return toAjax(iPtProductToleranceService.updateByBo(bo));
}
/**
* 删除产品尺寸公差明细
*
* @param toleranceIds 主键串
*/
@Log(title = "产品尺寸公差明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{toleranceIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] toleranceIds) {
return toAjax(iPtProductToleranceService.deleteWithValidByIds(Arrays.asList(toleranceIds), true));
}
}

View File

@@ -0,0 +1,70 @@
package com.klp.pt.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* 产品面质量明细对象 pt_product_surface_spec
*
* @author klp
* @date 2026-07-02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("pt_product_surface_spec")
public class PtProductSurfaceSpec extends BaseEntity {
private static final long serialVersionUID=1L;
/**
*
*/
@TableId(value = "surface_id")
private Long surfaceId;
/**
* 关联产品标准ID
*/
private Long standardId;
/**
* FB/FC/FD
*/
private String surfaceQualityGrade;
/**
*
*/
private BigDecimal roughnessRaMin;
/**
*
*/
private BigDecimal roughnessRaMax;
/**
* 干/轻油/重油
*/
private String oilingType;
/**
*
*/
private BigDecimal oilingWeightMin;
/**
*
*/
private BigDecimal oilingWeightMax;
/**
* 允许/禁止缺陷
*/
private String defectDesc;
/**
*
*/
private String remark;
/**
*
*/
@TableLogic
private Long delFlag;
}

View File

@@ -0,0 +1,86 @@
package com.klp.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* 产品尺寸公差明细对象 pt_product_tolerance
*
* @author klp
* @date 2026-07-02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("pt_product_tolerance")
public class PtProductTolerance extends BaseEntity {
private static final long serialVersionUID=1L;
/**
*
*/
@TableId(value = "tolerance_id")
private Long toleranceId;
/**
* 关联产品标准ID
*/
private Long standardId;
/**
* THICKNESS/WIDTH/FLATNESS
*/
private String toleranceType;
/**
* 普通/精密
*/
private String toleranceGrade;
/**
*
*/
private BigDecimal applicableThickMin;
/**
*
*/
private BigDecimal applicableThickMax;
/**
*
*/
private BigDecimal applicableWidthMin;
/**
*
*/
private BigDecimal applicableWidthMax;
/**
* 上偏差
*/
private BigDecimal toleranceValuePlus;
/**
* 下偏差
*/
private BigDecimal toleranceValueMinus;
/**
*
*/
private String toleranceUnit;
/**
*
*/
private String measurementStandard;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
*
*/
@TableLogic
private Long delFlag;
}

View File

@@ -68,11 +68,13 @@ public class PtProductStandardBo extends BaseEntity {
/**
* 生效日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date effectiveDate;
/**
* 失效日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date expireDate;
/**

View File

@@ -0,0 +1,72 @@
package com.klp.pt.domain.bo;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.math.BigDecimal;
/**
* 产品面质量明细业务对象 pt_product_surface_spec
*
* @author klp
* @date 2026-07-02
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PtProductSurfaceSpecBo extends BaseEntity {
/**
*
*/
private Long surfaceId;
/**
* 关联产品标准ID
*/
private Long standardId;
/**
* FB/FC/FD
*/
private String surfaceQualityGrade;
/**
*
*/
private BigDecimal roughnessRaMin;
/**
*
*/
private BigDecimal roughnessRaMax;
/**
* 干/轻油/重油
*/
private String oilingType;
/**
*
*/
private BigDecimal oilingWeightMin;
/**
*
*/
private BigDecimal oilingWeightMax;
/**
* 允许/禁止缺陷
*/
private String defectDesc;
/**
*
*/
private String remark;
}

View File

@@ -0,0 +1,93 @@
package com.klp.domain.bo;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.math.BigDecimal;
/**
* 产品尺寸公差明细业务对象 pt_product_tolerance
*
* @author klp
* @date 2026-07-02
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PtProductToleranceBo extends BaseEntity {
/**
*
*/
private Long toleranceId;
/**
* 关联产品标准ID
*/
private Long standardId;
/**
* THICKNESS/WIDTH/FLATNESS
*/
private String toleranceType;
/**
* 普通/精密
*/
private String toleranceGrade;
/**
*
*/
private BigDecimal applicableThickMin;
/**
*
*/
private BigDecimal applicableThickMax;
/**
*
*/
private BigDecimal applicableWidthMin;
/**
*
*/
private BigDecimal applicableWidthMax;
/**
* 上偏差
*/
private BigDecimal toleranceValuePlus;
/**
* 下偏差
*/
private BigDecimal toleranceValueMinus;
/**
*
*/
private String toleranceUnit;
/**
*
*/
private String measurementStandard;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

View File

@@ -0,0 +1,84 @@
package com.klp.pt.domain.vo;
import java.math.BigDecimal;
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;
/**
* 产品面质量明细视图对象 pt_product_surface_spec
*
* @author klp
* @date 2026-07-02
*/
@Data
@ExcelIgnoreUnannotated
public class PtProductSurfaceSpecVo {
private static final long serialVersionUID = 1L;
/**
*
*/
@ExcelProperty(value = "")
private Long surfaceId;
/**
* 关联产品标准ID
*/
@ExcelProperty(value = "关联产品标准ID")
private Long standardId;
/**
* FB/FC/FD
*/
@ExcelProperty(value = "FB/FC/FD")
private String surfaceQualityGrade;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal roughnessRaMin;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal roughnessRaMax;
/**
* 干/轻油/重油
*/
@ExcelProperty(value = "干/轻油/重油")
private String oilingType;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal oilingWeightMin;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal oilingWeightMax;
/**
* 允许/禁止缺陷
*/
@ExcelProperty(value = "允许/禁止缺陷")
private String defectDesc;
/**
*
*/
@ExcelProperty(value = "")
private String remark;
}

View File

@@ -0,0 +1,108 @@
package com.klp.domain.vo;
import java.math.BigDecimal;
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;
/**
* 产品尺寸公差明细视图对象 pt_product_tolerance
*
* @author klp
* @date 2026-07-02
*/
@Data
@ExcelIgnoreUnannotated
public class PtProductToleranceVo {
private static final long serialVersionUID = 1L;
/**
*
*/
@ExcelProperty(value = "")
private Long toleranceId;
/**
* 关联产品标准ID
*/
@ExcelProperty(value = "关联产品标准ID")
private Long standardId;
/**
* THICKNESS/WIDTH/FLATNESS
*/
@ExcelProperty(value = "THICKNESS/WIDTH/FLATNESS")
private String toleranceType;
/**
* 普通/精密
*/
@ExcelProperty(value = "普通/精密")
private String toleranceGrade;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal applicableThickMin;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal applicableThickMax;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal applicableWidthMin;
/**
*
*/
@ExcelProperty(value = "")
private BigDecimal applicableWidthMax;
/**
* 上偏差
*/
@ExcelProperty(value = "上偏差")
private BigDecimal toleranceValuePlus;
/**
* 下偏差
*/
@ExcelProperty(value = "下偏差")
private BigDecimal toleranceValueMinus;
/**
*
*/
@ExcelProperty(value = "")
private String toleranceUnit;
/**
*
*/
@ExcelProperty(value = "")
private String measurementStandard;
/**
*
*/
@ExcelProperty(value = "")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "")
private String remark;
}

View File

@@ -0,0 +1,15 @@
package com.klp.pt.mapper;
import com.klp.pt.domain.PtProductSurfaceSpec;
import com.klp.pt.domain.vo.PtProductSurfaceSpecVo;
import com.klp.common.core.mapper.BaseMapperPlus;
/**
* 产品面质量明细Mapper接口
*
* @author klp
* @date 2026-07-02
*/
public interface PtProductSurfaceSpecMapper extends BaseMapperPlus<PtProductSurfaceSpecMapper, PtProductSurfaceSpec, PtProductSurfaceSpecVo> {
}

View File

@@ -0,0 +1,15 @@
package com.klp.mapper;
import com.klp.domain.PtProductTolerance;
import com.klp.domain.vo.PtProductToleranceVo;
import com.klp.common.core.mapper.BaseMapperPlus;
/**
* 产品尺寸公差明细Mapper接口
*
* @author klp
* @date 2026-07-02
*/
public interface PtProductToleranceMapper extends BaseMapperPlus<PtProductToleranceMapper, PtProductTolerance, PtProductToleranceVo> {
}

View File

@@ -0,0 +1,50 @@
package com.klp.pt.service;
import com.klp.pt.domain.PtProductSurfaceSpec;
import com.klp.pt.domain.vo.PtProductSurfaceSpecVo;
import com.klp.pt.domain.bo.PtProductSurfaceSpecBo;
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-07-02
*/
public interface IPtProductSurfaceSpecService {
/**
* 查询产品面质量明细
*/
PtProductSurfaceSpecVo queryById(Long surfaceId);
/**
* 查询产品面质量明细列表
*/
TableDataInfo<PtProductSurfaceSpecVo> queryPageList(PtProductSurfaceSpecBo bo, PageQuery pageQuery);
/**
* 查询产品面质量明细列表
*/
List<PtProductSurfaceSpecVo> queryList(PtProductSurfaceSpecBo bo);
/**
* 新增产品面质量明细
*/
Boolean insertByBo(PtProductSurfaceSpecBo bo);
/**
* 修改产品面质量明细
*/
Boolean updateByBo(PtProductSurfaceSpecBo bo);
/**
* 校验并批量删除产品面质量明细信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,49 @@
package com.klp.service;
import com.klp.domain.PtProductTolerance;
import com.klp.domain.vo.PtProductToleranceVo;
import com.klp.domain.bo.PtProductToleranceBo;
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-07-02
*/
public interface IPtProductToleranceService {
/**
* 查询产品尺寸公差明细
*/
PtProductToleranceVo queryById(Long toleranceId);
/**
* 查询产品尺寸公差明细列表
*/
TableDataInfo<PtProductToleranceVo> queryPageList(PtProductToleranceBo bo, PageQuery pageQuery);
/**
* 查询产品尺寸公差明细列表
*/
List<PtProductToleranceVo> queryList(PtProductToleranceBo bo);
/**
* 新增产品尺寸公差明细
*/
Boolean insertByBo(PtProductToleranceBo bo);
/**
* 修改产品尺寸公差明细
*/
Boolean updateByBo(PtProductToleranceBo bo);
/**
* 校验并批量删除产品尺寸公差明细信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,116 @@
package com.klp.pt.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.pt.domain.bo.PtProductSurfaceSpecBo;
import com.klp.pt.domain.vo.PtProductSurfaceSpecVo;
import com.klp.pt.domain.PtProductSurfaceSpec;
import com.klp.pt.mapper.PtProductSurfaceSpecMapper;
import com.klp.pt.service.IPtProductSurfaceSpecService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 产品面质量明细Service业务层处理
*
* @author klp
* @date 2026-07-02
*/
@RequiredArgsConstructor
@Service
public class PtProductSurfaceSpecServiceImpl implements IPtProductSurfaceSpecService {
private final PtProductSurfaceSpecMapper baseMapper;
/**
* 查询产品面质量明细
*/
@Override
public PtProductSurfaceSpecVo queryById(Long surfaceId){
return baseMapper.selectVoById(surfaceId);
}
/**
* 查询产品面质量明细列表
*/
@Override
public TableDataInfo<PtProductSurfaceSpecVo> queryPageList(PtProductSurfaceSpecBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<PtProductSurfaceSpec> lqw = buildQueryWrapper(bo);
Page<PtProductSurfaceSpecVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询产品面质量明细列表
*/
@Override
public List<PtProductSurfaceSpecVo> queryList(PtProductSurfaceSpecBo bo) {
LambdaQueryWrapper<PtProductSurfaceSpec> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<PtProductSurfaceSpec> buildQueryWrapper(PtProductSurfaceSpecBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<PtProductSurfaceSpec> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getStandardId() != null, PtProductSurfaceSpec::getStandardId, bo.getStandardId());
lqw.eq(StringUtils.isNotBlank(bo.getSurfaceQualityGrade()), PtProductSurfaceSpec::getSurfaceQualityGrade, bo.getSurfaceQualityGrade());
lqw.eq(bo.getRoughnessRaMin() != null, PtProductSurfaceSpec::getRoughnessRaMin, bo.getRoughnessRaMin());
lqw.eq(bo.getRoughnessRaMax() != null, PtProductSurfaceSpec::getRoughnessRaMax, bo.getRoughnessRaMax());
lqw.eq(StringUtils.isNotBlank(bo.getOilingType()), PtProductSurfaceSpec::getOilingType, bo.getOilingType());
lqw.eq(bo.getOilingWeightMin() != null, PtProductSurfaceSpec::getOilingWeightMin, bo.getOilingWeightMin());
lqw.eq(bo.getOilingWeightMax() != null, PtProductSurfaceSpec::getOilingWeightMax, bo.getOilingWeightMax());
lqw.eq(StringUtils.isNotBlank(bo.getDefectDesc()), PtProductSurfaceSpec::getDefectDesc, bo.getDefectDesc());
return lqw;
}
/**
* 新增产品面质量明细
*/
@Override
public Boolean insertByBo(PtProductSurfaceSpecBo bo) {
PtProductSurfaceSpec add = BeanUtil.toBean(bo, PtProductSurfaceSpec.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setSurfaceId(add.getSurfaceId());
}
return flag;
}
/**
* 修改产品面质量明细
*/
@Override
public Boolean updateByBo(PtProductSurfaceSpecBo bo) {
PtProductSurfaceSpec update = BeanUtil.toBean(bo, PtProductSurfaceSpec.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(PtProductSurfaceSpec entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除产品面质量明细
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,121 @@
package com.klp.pt.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.domain.bo.PtProductToleranceBo;
import com.klp.domain.vo.PtProductToleranceVo;
import com.klp.domain.PtProductTolerance;
import com.klp.mapper.PtProductToleranceMapper;
import com.klp.service.IPtProductToleranceService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 产品尺寸公差明细Service业务层处理
*
* @author klp
* @date 2026-07-02
*/
@RequiredArgsConstructor
@Service
public class PtProductToleranceServiceImpl implements IPtProductToleranceService {
private final PtProductToleranceMapper baseMapper;
/**
* 查询产品尺寸公差明细
*/
@Override
public PtProductToleranceVo queryById(Long toleranceId){
return baseMapper.selectVoById(toleranceId);
}
/**
* 查询产品尺寸公差明细列表
*/
@Override
public TableDataInfo<PtProductToleranceVo> queryPageList(PtProductToleranceBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<PtProductTolerance> lqw = buildQueryWrapper(bo);
Page<PtProductToleranceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询产品尺寸公差明细列表
*/
@Override
public List<PtProductToleranceVo> queryList(PtProductToleranceBo bo) {
LambdaQueryWrapper<PtProductTolerance> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<PtProductTolerance> buildQueryWrapper(PtProductToleranceBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<PtProductTolerance> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getStandardId() != null, PtProductTolerance::getStandardId, bo.getStandardId());
lqw.eq(StringUtils.isNotBlank(bo.getToleranceType()), PtProductTolerance::getToleranceType, bo.getToleranceType());
lqw.eq(StringUtils.isNotBlank(bo.getToleranceGrade()), PtProductTolerance::getToleranceGrade, bo.getToleranceGrade());
lqw.eq(bo.getApplicableThickMin() != null, PtProductTolerance::getApplicableThickMin, bo.getApplicableThickMin());
lqw.eq(bo.getApplicableThickMax() != null, PtProductTolerance::getApplicableThickMax, bo.getApplicableThickMax());
lqw.eq(bo.getApplicableWidthMin() != null, PtProductTolerance::getApplicableWidthMin, bo.getApplicableWidthMin());
lqw.eq(bo.getApplicableWidthMax() != null, PtProductTolerance::getApplicableWidthMax, bo.getApplicableWidthMax());
lqw.eq(bo.getToleranceValuePlus() != null, PtProductTolerance::getToleranceValuePlus, bo.getToleranceValuePlus());
lqw.eq(bo.getToleranceValueMinus() != null, PtProductTolerance::getToleranceValueMinus, bo.getToleranceValueMinus());
lqw.eq(StringUtils.isNotBlank(bo.getToleranceUnit()), PtProductTolerance::getToleranceUnit, bo.getToleranceUnit());
lqw.eq(StringUtils.isNotBlank(bo.getMeasurementStandard()), PtProductTolerance::getMeasurementStandard, bo.getMeasurementStandard());
lqw.eq(bo.getSortOrder() != null, PtProductTolerance::getSortOrder, bo.getSortOrder());
return lqw;
}
/**
* 新增产品尺寸公差明细
*/
@Override
public Boolean insertByBo(PtProductToleranceBo bo) {
PtProductTolerance add = BeanUtil.toBean(bo, PtProductTolerance.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setToleranceId(add.getToleranceId());
}
return flag;
}
/**
* 修改产品尺寸公差明细
*/
@Override
public Boolean updateByBo(PtProductToleranceBo bo) {
PtProductTolerance update = BeanUtil.toBean(bo, PtProductTolerance.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(PtProductTolerance entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除产品尺寸公差明细
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,26 @@
<?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.pt.mapper.PtProductSurfaceSpecMapper">
<resultMap type="com.klp.pt.domain.PtProductSurfaceSpec" id="PtProductSurfaceSpecResult">
<result property="surfaceId" column="surface_id"/>
<result property="standardId" column="standard_id"/>
<result property="surfaceQualityGrade" column="surface_quality_grade"/>
<result property="roughnessRaMin" column="roughness_ra_min"/>
<result property="roughnessRaMax" column="roughness_ra_max"/>
<result property="oilingType" column="oiling_type"/>
<result property="oilingWeightMin" column="oiling_weight_min"/>
<result property="oilingWeightMax" column="oiling_weight_max"/>
<result property="defectDesc" column="defect_desc"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,30 @@
<?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.mapper.PtProductToleranceMapper">
<resultMap type="com.klp.domain.PtProductTolerance" id="PtProductToleranceResult">
<result property="toleranceId" column="tolerance_id"/>
<result property="standardId" column="standard_id"/>
<result property="toleranceType" column="tolerance_type"/>
<result property="toleranceGrade" column="tolerance_grade"/>
<result property="applicableThickMin" column="applicable_thick_min"/>
<result property="applicableThickMax" column="applicable_thick_max"/>
<result property="applicableWidthMin" column="applicable_width_min"/>
<result property="applicableWidthMax" column="applicable_width_max"/>
<result property="toleranceValuePlus" column="tolerance_value_plus"/>
<result property="toleranceValueMinus" column="tolerance_value_minus"/>
<result property="toleranceUnit" column="tolerance_unit"/>
<result property="measurementStandard" column="measurement_standard"/>
<result property="sortOrder" column="sort_order"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,35 @@
import request from '@/utils/request'
// ==================== 工艺主表 ====================
export function listProcesse(query) {
return request({ url: '/pt/processe/list', method: 'get', params: query })
}
export function getProcesse(processId) {
return request({ url: '/pt/processe/' + processId, method: 'get' })
}
export function addProcesse(data) {
return request({ url: '/pt/processe', method: 'post', data })
}
export function updateProcesse(data) {
return request({ url: '/pt/processe', method: 'put', data })
}
export function delProcesse(processIds) {
return request({ url: '/pt/processe/' + processIds, method: 'delete' })
}
// ==================== 工序参数明细 ====================
export function listProcessStepParam(query) {
return request({ url: '/pt/processStepParam/list', method: 'get', params: query })
}
export function getProcessStepParam(paramId) {
return request({ url: '/pt/processStepParam/' + paramId, method: 'get' })
}
export function addProcessStepParam(data) {
return request({ url: '/pt/processStepParam', method: 'post', data })
}
export function updateProcessStepParam(data) {
return request({ url: '/pt/processStepParam', method: 'put', data })
}
export function delProcessStepParam(paramIds) {
return request({ url: '/pt/processStepParam/' + paramIds, method: 'delete' })
}

View File

@@ -0,0 +1,154 @@
import request from '@/utils/request'
// ==================== 产品标准主表 ====================
export function listProductStandard(query) {
return request({ url: '/pt/productStandard/list', method: 'get', params: query })
}
export function getProductStandard(standardId) {
return request({ url: '/pt/productStandard/' + standardId, method: 'get' })
}
export function addProductStandard(data) {
return request({ url: '/pt/productStandard', method: 'post', data })
}
export function updateProductStandard(data) {
return request({ url: '/pt/productStandard', method: 'put', data })
}
export function delProductStandard(standardIds) {
return request({ url: '/pt/productStandard/' + standardIds, method: 'delete' })
}
// ==================== 产品用途 ====================
export function listProductApplication(query) {
return request({ url: '/pt/productApplication/list', method: 'get', params: query })
}
export function getProductApplication(applicationId) {
return request({ url: '/pt/productApplication/' + applicationId, method: 'get' })
}
export function addProductApplication(data) {
return request({ url: '/pt/productApplication', method: 'post', data })
}
export function updateProductApplication(data) {
return request({ url: '/pt/productApplication', method: 'put', data })
}
export function delProductApplication(applicationIds) {
return request({ url: '/pt/productApplication/' + applicationIds, method: 'delete' })
}
// ==================== 化学成分 ====================
export function listProductChemicalComposition(query) {
return request({ url: '/pt/productChemicalComposition/list', method: 'get', params: query })
}
export function getProductChemicalComposition(compositionId) {
return request({ url: '/pt/productChemicalComposition/' + compositionId, method: 'get' })
}
export function addProductChemicalComposition(data) {
return request({ url: '/pt/productChemicalComposition', method: 'post', data })
}
export function updateProductChemicalComposition(data) {
return request({ url: '/pt/productChemicalComposition', method: 'put', data })
}
export function delProductChemicalComposition(compositionIds) {
return request({ url: '/pt/productChemicalComposition/' + compositionIds, method: 'delete' })
}
// ==================== 镀层规格 ====================
export function listProductCoatingSpec(query) {
return request({ url: '/pt/productCoatingSpec/list', method: 'get', params: query })
}
export function getProductCoatingSpec(coatingId) {
return request({ url: '/pt/productCoatingSpec/' + coatingId, method: 'get' })
}
export function addProductCoatingSpec(data) {
return request({ url: '/pt/productCoatingSpec', method: 'post', data })
}
export function updateProductCoatingSpec(data) {
return request({ url: '/pt/productCoatingSpec', method: 'put', data })
}
export function delProductCoatingSpec(coatingIds) {
return request({ url: '/pt/productCoatingSpec/' + coatingIds, method: 'delete' })
}
// ==================== 尺寸规格 ====================
export function listProductDimension(query) {
return request({ url: '/pt/productDimension/list', method: 'get', params: query })
}
export function getProductDimension(dimensionId) {
return request({ url: '/pt/productDimension/' + dimensionId, method: 'get' })
}
export function addProductDimension(data) {
return request({ url: '/pt/productDimension', method: 'post', data })
}
export function updateProductDimension(data) {
return request({ url: '/pt/productDimension', method: 'put', data })
}
export function delProductDimension(dimensionIds) {
return request({ url: '/pt/productDimension/' + dimensionIds, method: 'delete' })
}
// ==================== 物理性能 ====================
export function listProductPhysicalProperty(query) {
return request({ url: '/pt/productPhysicalProperty/list', method: 'get', params: query })
}
export function getProductPhysicalProperty(propertyId) {
return request({ url: '/pt/productPhysicalProperty/' + propertyId, method: 'get' })
}
export function addProductPhysicalProperty(data) {
return request({ url: '/pt/productPhysicalProperty', method: 'post', data })
}
export function updateProductPhysicalProperty(data) {
return request({ url: '/pt/productPhysicalProperty', method: 'put', data })
}
export function delProductPhysicalProperty(propertyIds) {
return request({ url: '/pt/productPhysicalProperty/' + propertyIds, method: 'delete' })
}
// ==================== 参考标准 ====================
export function listProductRefStandard(query) {
return request({ url: '/pt/productRefStandard/list', method: 'get', params: query })
}
export function getProductRefStandard(refId) {
return request({ url: '/pt/productRefStandard/' + refId, method: 'get' })
}
export function addProductRefStandard(data) {
return request({ url: '/pt/productRefStandard', method: 'post', data })
}
export function updateProductRefStandard(data) {
return request({ url: '/pt/productRefStandard', method: 'put', data })
}
export function delProductRefStandard(refIds) {
return request({ url: '/pt/productRefStandard/' + refIds, method: 'delete' })
}
// ==================== 尺寸公差 ====================
export function listProductTolerance(query) {
return request({ url: '/klp/productTolerance/list', method: 'get', params: query })
}
export function getProductTolerance(toleranceId) {
return request({ url: '/klp/productTolerance/' + toleranceId, method: 'get' })
}
export function addProductTolerance(data) {
return request({ url: '/klp/productTolerance', method: 'post', data })
}
export function updateProductTolerance(data) {
return request({ url: '/klp/productTolerance', method: 'put', data })
}
export function delProductTolerance(toleranceIds) {
return request({ url: '/klp/productTolerance/' + toleranceIds, method: 'delete' })
}
// ==================== 表面质量 ====================
export function listProductSurfaceSpec(query) {
return request({ url: '/pt/productSurfaceSpec/list', method: 'get', params: query })
}
export function getProductSurfaceSpec(surfaceId) {
return request({ url: '/pt/productSurfaceSpec/' + surfaceId, method: 'get' })
}
export function addProductSurfaceSpec(data) {
return request({ url: '/pt/productSurfaceSpec', method: 'post', data })
}
export function updateProductSurfaceSpec(data) {
return request({ url: '/pt/productSurfaceSpec', method: 'put', data })
}
export function delProductSurfaceSpec(surfaceIds) {
return request({ url: '/pt/productSurfaceSpec/' + surfaceIds, method: 'delete' })
}

View File

@@ -0,0 +1,675 @@
<template>
<div class="pt-process-page">
<DragResizePanel :initialSize="300" :minSize="240" :maxSize="550">
<!-- ==================== 左侧面板工艺列表 ==================== -->
<template #panelA>
<div class="left-panel">
<div class="left-topbar">
<el-input
v-model="processSearch"
placeholder="搜索工艺名称..."
clearable
size="small"
prefix-icon="el-icon-search"
class="left-search-input"
@keyup.enter.native="handleProcessSearch"
/>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="handleProcessAdd">新增</el-button>
<el-button size="mini" :icon="filterExpanded ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" @click="filterExpanded = !filterExpanded">
{{ filterExpanded ? '收起' : '筛选' }}
</el-button>
</div>
<div class="left-filter" v-show="filterExpanded">
<el-form :model="processFilters" size="small" label-width="56px">
<el-form-item label="状态">
<el-select v-model="processFilters.status" placeholder="全部" clearable style="width:100%">
<el-option label="启用" :value="1" />
<el-option label="停用" :value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="handleProcessSearch">搜索</el-button>
<el-button size="mini" @click="resetProcessFilters">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="left-list" v-loading="processLoading">
<div
v-for="item in processList"
:key="item.processId"
:class="['process-item', { active: selectedProcess && selectedProcess.processId === item.processId }]"
@click="selectProcess(item)"
>
<div class="process-item-header">
<div class="process-item-name">{{ item.processName }}</div>
<div class="process-item-actions" @click.stop>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleProcessUpdate(item)" />
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleProcessDelete(item)" />
</div>
</div>
<div class="process-item-meta">
<span class="process-item-code">{{ item.processCode }}</span>
<span :class="['process-item-status', item.status === 1 ? 'on' : 'off']">
{{ item.status === 1 ? '启用' : '停用' }}
</span>
</div>
</div>
<el-empty v-if="!processLoading && processList.length === 0" description="暂无工艺路线" :image-size="50" />
</div>
<pagination
v-show="processTotal > 0"
:total="processTotal"
:page.sync="processQueryParams.pageNum"
:limit.sync="processQueryParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
:pager-count="3"
small
@pagination="getProcessList"
/>
</div>
</template>
<!-- ==================== 右侧面板工序参数 ==================== -->
<template #panelB>
<div class="right-panel">
<div v-if="!selectedProcess" class="empty-hint">
<el-empty description="请从左侧列表选择一个工艺路线,查看和编辑其工序参数" :image-size="100" />
</div>
<template v-else>
<div class="selected-process-info">
<div class="process-info-left">
<span class="process-info-name">{{ selectedProcess.processName }}</span>
<span class="process-info-code">{{ selectedProcess.processCode }}</span>
</div>
<div class="process-info-right">
<span v-if="selectedProcess.targetYield" class="process-info-tag">成材率 {{ selectedProcess.targetYield }}%</span>
<span v-if="selectedProcess.standardCapacity" class="process-info-tag">产能 {{ selectedProcess.standardCapacity }}t/h</span>
<span :class="['process-info-status', selectedProcess.status === 1 ? 'on' : 'off']">
{{ selectedProcess.status === 1 ? '启用' : '停用' }}
</span>
</div>
</div>
<div class="tab-toolbar">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增参数</el-button>
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete()">删除</el-button>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
</div>
<el-table
v-loading="loading"
:data="dataList"
size="small"
border
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="45" align="center" />
<el-table-column v-for="col in stepColumns" :key="col.prop" v-bind="col">
<template slot-scope="scope">
<template v-if="editingId != null && editingId === scope.row.paramId">
<el-input v-if="col.editType === 'input'" v-model="editForm[col.prop]" size="small" />
<el-input-number v-else-if="col.editType === 'number'" v-model="editForm[col.prop]" size="small" :controls="false" style="width:100%" />
<el-select v-else-if="col.editType === 'select'" v-model="editForm[col.prop]" size="small" style="width:100%">
<el-option v-for="opt in col.options" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
<span v-else>{{ scope.row[col.prop] }}</span>
</template>
<span v-else>
{{ col.formatter ? col.formatter(scope.row, col, scope.row[col.prop]) : scope.row[col.prop] }}
</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="140" class-name="small-padding fixed-width">
<template slot-scope="scope">
<template v-if="editingId != null && editingId === scope.row.paramId">
<el-button size="mini" type="text" style="color:#67c23a" @click="saveEdit(scope.row)">保存</el-button>
<el-button size="mini" type="text" @click="cancelEdit()">取消</el-button>
</template>
<template v-else>
<el-button size="mini" type="text" icon="el-icon-edit" @click="startEdit(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</template>
</div>
</template>
</DragResizePanel>
<!-- ==================== 参数新增弹窗 ==================== -->
<el-dialog title="新增工序参数" :visible.sync="open" width="650px" append-to-body :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="addRules" label-width="100px" size="small">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="工序顺序" prop="stepOrder">
<el-input-number v-model="form.stepOrder" :min="1" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工序名称" prop="stepName">
<el-select v-model="form.stepName" placeholder="请选择" clearable style="width:100%">
<el-option label="酸洗" value="酸洗" />
<el-option label="冷轧" value="冷轧" />
<el-option label="退火" value="退火" />
<el-option label="镀锌" value="镀锌" />
<el-option label="平整" value="平整" />
<el-option label="拉矫" value="拉矫" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="参数编码" prop="paramCode">
<el-input v-model="form.paramCode" placeholder="TEMP/SPEED/TENSION" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="参数名称" prop="paramNameZh">
<el-input v-model="form.paramNameZh" placeholder="请输入中文名" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="参数分类" prop="paramCategory">
<el-select v-model="form.paramCategory" placeholder="请选择" clearable style="width:100%">
<el-option label="温度" value="温度" />
<el-option label="速度" value="速度" />
<el-option label="压力" value="压力" />
<el-option label="电流" value="电流" />
<el-option label="张力" value="张力" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="℃/m/min/MPa/A" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="最小值" prop="minValue">
<el-input-number v-model="form.minValue" :controls="false" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="最大值" prop="maxValue">
<el-input-number v-model="form.maxValue" :controls="false" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标值" prop="targetValue">
<el-input-number v-model="form.targetValue" :controls="false" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报警下限" prop="alarmMin">
<el-input-number v-model="form.alarmMin" :controls="false" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报警上限" prop="alarmMax">
<el-input-number v-model="form.alarmMax" :controls="false" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否CCP" prop="isCritical">
<el-select v-model="form.isCritical" clearable style="width:100%">
<el-option label="是" :value="1" />
<el-option label="否" :value="0" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="排序" prop="sortOrder">
<el-input-number v-model="form.sortOrder" :controls="false" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="2" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="small" @click="submitForm"> </el-button>
<el-button size="small" @click="cancelAdd"> </el-button>
</div>
</el-dialog>
<!-- ==================== 工艺新增/编辑弹窗 ==================== -->
<el-dialog :title="processDialogTitle" :visible.sync="processDialogOpen" width="550px" append-to-body :close-on-click-modal="false">
<el-form ref="processForm" :model="processForm" :rules="processRules" label-width="80px" size="small">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="工艺代号" prop="processCode">
<el-input v-model="processForm.processCode" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工艺名称" prop="processName">
<el-input v-model="processForm.processName" placeholder="请输入工艺名称" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="适配产品">
<el-input v-model="processForm.adaptProductType" placeholder="逗号分隔,如 CRC,GI" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="status">
<el-select v-model="processForm.status" style="width:100%">
<el-option label="启用" :value="1" />
<el-option label="停用" :value="0" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="目标成材率">
<el-input-number v-model="processForm.targetYield" :controls="false" style="width:100%">
<template slot="suffix">%</template>
</el-input-number>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标准产能">
<el-input-number v-model="processForm.standardCapacity" :controls="false" style="width:100%">
<template slot="suffix">t/h</template>
</el-input-number>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="工艺流程">
<el-input v-model="processForm.flowOverview" type="textarea" :rows="3" placeholder="描述整体工艺流程" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注">
<el-input v-model="processForm.remark" type="textarea" :rows="2" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="small" @click="submitProcessForm" :loading="processSubmitting"> </el-button>
<el-button size="small" @click="cancelProcessDialog"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import DragResizePanel from '@/components/DragResizePanel/index.vue'
import {
listProcesse, getProcesse, addProcesse, updateProcesse, delProcesse,
listProcessStepParam, getProcessStepParam, addProcessStepParam, updateProcessStepParam, delProcessStepParam
} from '@/api/pt/process'
const boolFormatter = (row, col, val) => (val === 1 || val === '1') ? '是' : '否'
const STEP_COLUMNS = [
{ prop: 'stepOrder', label: '工序顺序', width: 80, editType: 'number' },
{ prop: 'stepName', label: '工序名称', width: 90, editType: 'select',
options: [{ label: '酸洗', value: '酸洗' }, { label: '冷轧', value: '冷轧' }, { label: '退火', value: '退火' }, { label: '镀锌', value: '镀锌' }, { label: '平整', value: '平整' }, { label: '拉矫', value: '拉矫' }] },
{ prop: 'paramCode', label: '参数编码', width: 100, editType: 'input' },
{ prop: 'paramNameZh', label: '参数名称', minWidth: 100, editType: 'input' },
{ prop: 'paramCategory', label: '分类', width: 70, editType: 'select',
options: [{ label: '温度', value: '温度' }, { label: '速度', value: '速度' }, { label: '压力', value: '压力' }, { label: '电流', value: '电流' }, { label: '张力', value: '张力' }] },
{ prop: 'minValue', label: '最小值', width: 80, editType: 'number' },
{ prop: 'maxValue', label: '最大值', width: 80, editType: 'number' },
{ prop: 'targetValue', label: '目标值', width: 80, editType: 'number' },
{ prop: 'unit', label: '单位', width: 60, editType: 'input' },
{ prop: 'isCritical', label: 'CCP', width: 55, editType: 'select', formatter: boolFormatter,
options: [{ label: '是', value: 1 }, { label: '否', value: 0 }] },
{ prop: 'alarmMin', label: '报警下限', width: 80, editType: 'number' },
{ prop: 'alarmMax', label: '报警上限', width: 80, editType: 'number' },
{ prop: 'sortOrder', label: '排序', width: 55, editType: 'number' }
]
export default {
name: 'PtProcesse',
components: { DragResizePanel },
data() {
return {
// ===== 工艺列表 =====
processLoading: false,
processList: [],
processTotal: 0,
processQueryParams: { pageNum: 1, pageSize: 20 },
processSearch: '',
filterExpanded: false,
processFilters: { status: null },
selectedProcess: null,
// ===== 工艺弹窗 =====
processDialogOpen: false,
processDialogTitle: '',
processForm: {},
processSubmitting: false,
processRules: {
processName: [{ required: true, message: '请输入工艺名称', trigger: 'blur' }]
},
// ===== 工序参数表格 =====
loading: false,
dataList: [],
total: 0,
queryParams: { pageNum: 1, pageSize: 20 },
showSearch: true,
ids: [],
multiple: true,
stepColumns: STEP_COLUMNS,
// ===== 行内编辑 =====
editingId: null,
editForm: {},
editFormOriginal: null,
// ===== 新增弹窗 =====
open: false,
form: {},
addRules: {
stepOrder: [{ required: true, message: '请输入工序顺序', trigger: 'blur' }],
stepName: [{ required: true, message: '请选择工序名称', trigger: 'change' }]
}
}
},
created() {
this.getProcessList()
},
methods: {
// ==================== 工艺 CRUD ====================
getProcessList() {
this.processLoading = true
const params = { ...this.processQueryParams }
if (this.processSearch) params.processName = this.processSearch
if (this.processFilters.status != null && this.processFilters.status !== '') {
params.status = this.processFilters.status
}
listProcesse(params).then(res => {
this.processList = res.rows || []
this.processTotal = res.total || 0
this.processLoading = false
}).catch(() => { this.processLoading = false })
},
handleProcessSearch() {
this.processQueryParams.pageNum = 1
this.getProcessList()
},
resetProcessFilters() {
this.processFilters = { status: null }
this.processSearch = ''
this.processQueryParams.pageNum = 1
this.getProcessList()
},
selectProcess(item) {
this.cancelEdit()
this.selectedProcess = item
this.resetQueryParams()
this.getList()
},
handleProcessAdd() {
const now = new Date()
const code = 'PRC-' +
now.getFullYear() + String(now.getMonth() + 1).padStart(2, '0') +
String(now.getDate()).padStart(2, '0') + '-' +
String(now.getHours()).padStart(2, '0') +
String(now.getMinutes()).padStart(2, '0') +
String(now.getSeconds()).padStart(2, '0')
this.processForm = {
processId: undefined, processCode: code, processName: '',
adaptProductType: '', status: 1, targetYield: undefined,
standardCapacity: undefined, flowOverview: '', remark: ''
}
this.processDialogTitle = '新增工艺路线'
this.processDialogOpen = true
this.processSubmitting = false
this.$nextTick(() => { if (this.$refs['processForm']) this.$refs['processForm'].clearValidate() })
},
handleProcessUpdate(item) {
const row = item || this.selectedProcess
if (!row) return
getProcesse(row.processId).then(res => {
const d = res.data || {}
this.processForm = {
processId: d.processId, processCode: d.processCode || '',
processName: d.processName || '', adaptProductType: d.adaptProductType || '',
status: d.status != null ? d.status : 1,
targetYield: d.targetYield, standardCapacity: d.standardCapacity,
flowOverview: d.flowOverview || '', remark: d.remark || ''
}
this.processDialogTitle = '修改工艺路线'
this.processDialogOpen = true
this.processSubmitting = false
this.$nextTick(() => { if (this.$refs['processForm']) this.$refs['processForm'].clearValidate() })
})
},
handleProcessDelete(item) {
const row = item || this.selectedProcess
if (!row) return
this.$modal.confirm('确认删除工艺「' + row.processName + '」?').then(() => {
return delProcesse(row.processId)
}).then(() => {
this.$modal.msgSuccess('删除成功')
if (this.selectedProcess && this.selectedProcess.processId === row.processId) {
this.selectedProcess = null; this.dataList = []; this.total = 0
}
this.getProcessList()
}).catch(() => {})
},
submitProcessForm() {
this.$refs['processForm'].validate(valid => {
if (!valid) return
this.processSubmitting = true
const d = this.processForm
const act = d.processId ? updateProcesse(d) : addProcesse(d)
act.then(() => {
this.$modal.msgSuccess(d.processId ? '修改成功' : '新增成功')
this.processDialogOpen = false
this.processSubmitting = false
this.getProcessList()
if (d.processId && this.selectedProcess && this.selectedProcess.processId === d.processId) {
getProcesse(d.processId).then(res => { this.selectedProcess = res.data })
}
}).catch(() => { this.processSubmitting = false })
})
},
cancelProcessDialog() {
this.processDialogOpen = false
},
// ==================== 工序参数 CRUD ====================
resetQueryParams() {
this.queryParams = { pageNum: 1, pageSize: 20, processId: this.selectedProcess ? this.selectedProcess.processId : undefined }
this.ids = []
this.multiple = true
},
getList() {
if (!this.selectedProcess) return
this.loading = true
const params = { ...this.queryParams, processId: this.selectedProcess.processId }
listProcessStepParam(params).then(res => {
this.dataList = res.rows || []
this.total = res.total || 0
this.loading = false
}).catch(() => { this.loading = false })
},
handleSelectionChange(sel) {
this.ids = sel.map(i => i.paramId)
this.multiple = !sel.length
},
handleAdd() {
this.cancelEdit()
this.form = { processId: this.selectedProcess.processId }
this.open = true
this.$nextTick(() => { if (this.$refs['form']) this.$refs['form'].clearValidate() })
},
cancelAdd() { this.open = false },
submitForm() {
this.$refs['form'].validate(valid => {
if (!valid) return
addProcessStepParam(this.form).then(() => {
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
})
})
},
handleDelete(row) {
const ids = row ? row.paramId : this.ids.join(',')
if (!ids) { this.$modal.msgWarning('请选择要删除的记录'); return }
this.$modal.confirm('确认删除?').then(() => delProcessStepParam(ids)).then(() => {
this.getList(); this.$modal.msgSuccess('删除成功')
}).catch(() => {})
},
// ==================== 行内编辑 ====================
startEdit(row) {
const form = {}
this.stepColumns.forEach(c => { form[c.prop] = row[c.prop] })
form.paramId = row.paramId
form.processId = row.processId
this.editForm = form
this.editFormOriginal = JSON.parse(JSON.stringify(row))
this.editingId = row.paramId
},
cancelEdit() {
this.editingId = null
this.editForm = {}
this.editFormOriginal = null
},
saveEdit(row) {
const data = { ...this.editForm }
const idx = this.dataList.findIndex(r => r.paramId === row.paramId)
if (idx >= 0) this.dataList.splice(idx, 1, { ...this.dataList[idx], ...data })
this.editingId = null
this.editForm = {}
const original = this.editFormOriginal
this.editFormOriginal = null
updateProcessStepParam(data).then(() => {
this.$modal.msgSuccess('保存成功')
}).catch(() => {
if (idx >= 0 && original) this.dataList.splice(idx, 1, original)
this.$modal.msgError('保存失败,已还原')
})
}
}
}
</script>
<style lang="scss" scoped>
.pt-process-page {
height: calc(100vh - 84px);
::v-deep .left-panel .pagination-container {
padding: 4px 8px;
.el-pagination {
flex-wrap: wrap; justify-content: center;
.el-pagination__total { font-size: 11px; }
.el-pagination__sizes { margin: 0 2px; }
}
}
}
// ===== 左侧面板 =====
.left-panel {
height: 100%; display: flex; flex-direction: column;
background: #fff; border-right: 1px solid #e8e8e8;
.left-topbar {
display: flex; align-items: center; gap: 6px;
padding: 8px 10px; border-bottom: 1px solid #ebeef5;
.left-search-input { flex: 1; }
}
.left-filter {
padding: 8px 10px; border-bottom: 1px solid #ebeef5; background: #fafafa;
::v-deep .el-form-item { margin-bottom: 6px; }
::v-deep .el-form-item__label { font-size: 11px; }
}
.left-list {
flex: 1; overflow-y: auto;
.process-item {
padding: 10px 12px; cursor: pointer;
border-bottom: 1px solid #f0f2f5; transition: all 0.15s;
&:hover { background: #f5f7fa; .process-item-actions { opacity: 1; } }
&.active {
background: #ecf5ff; border-left: 3px solid #409EFF; padding-left: 9px;
.process-item-name { color: #409EFF; }
}
&:last-child { border-bottom: none; }
}
.process-item-header {
display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px;
}
.process-item-name {
font-size: 13px; font-weight: 600; color: #303133;
flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.4;
}
.process-item-actions {
opacity: 0; flex-shrink: 0; transition: opacity 0.15s;
.el-button + .el-button { margin-left: 0; }
}
.process-item-meta { display: flex; align-items: center; gap: 6px; }
.process-item-code {
font-size: 11px; color: #909399; font-family: 'SF Mono', 'Menlo', monospace;
background: #f5f7fa; padding: 1px 6px; border-radius: 3px;
}
.process-item-status {
font-size: 10px; padding: 1px 6px; border-radius: 3px;
&.on { color: #67c23a; background: #f0f9eb; }
&.off { color: #909399; background: #f4f4f5; }
}
}
}
// ===== 右侧面板 =====
.right-panel {
height: 100%; display: flex; flex-direction: column;
background: #fff; padding: 0 12px 12px; overflow: auto;
}
.selected-process-info {
display: flex; align-items: center; justify-content: space-between;
margin: 10px 0 8px; padding: 10px 14px; background: #fff;
border: 1px solid #e4e7ed; border-left: 4px solid #409EFF;
border-radius: 0 6px 6px 0; box-shadow: 0 1px 3px rgba(0,0,0,0.04);
flex-shrink: 0; gap: 12px;
.process-info-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.process-info-name { font-size: 15px; font-weight: 700; color: #303133; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.process-info-code {
font-size: 11px; font-family: 'SF Mono', 'Menlo', monospace; color: #909399;
background: #f5f7fa; border: 1px solid #e4e7ed; padding: 2px 8px; border-radius: 4px; white-space: nowrap; flex-shrink: 0;
}
.process-info-right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.process-info-tag {
font-size: 11px; padding: 2px 8px; border-radius: 4px; line-height: 18px;
color: #409EFF; background: #ecf5ff; border: 1px solid #d9ecff;
}
.process-info-status {
font-size: 11px; padding: 2px 8px; border-radius: 4px; white-space: nowrap; line-height: 18px;
&.on { color: #67c23a; background: #f0f9eb; border: 1px solid #e1f3d8; }
&.off { color: #909399; background: #f4f4f5; border: 1px solid #e9e9eb; }
}
}
.empty-hint { display: flex; justify-content: center; align-items: center; flex: 1; }
.tab-toolbar {
display: flex; align-items: center; gap: 8px;
padding: 6px 0; flex-shrink: 0;
.right-toolbar { margin-left: auto; }
}
</style>

View File

File diff suppressed because it is too large Load Diff