refactor(module/frozen-sale | mapper/Stock): 仓库状态同步 | 修复业务逻辑错误

增删改查操作时将动态同步仓库中的Item状态
移除了数量计算 (业务无关)
修改了仓储模块的部分 SQL (适配状态同步)
This commit is contained in:
2025-12-27 16:11:58 +08:00
parent 65b3b7c694
commit 5e54877119
7 changed files with 202 additions and 66 deletions

View File

@@ -1,9 +1,14 @@
package com.zhyc.module.frozen.controller; package com.zhyc.module.frozen.controller;
import java.util.List; import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.zhyc.module.frozen.domain.DdFe;
import com.zhyc.module.frozen.domain.DdFs;
import com.zhyc.module.frozen.service.IDdFeService;
import com.zhyc.module.frozen.service.IDdFsService;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
@@ -23,24 +28,29 @@ import com.zhyc.common.core.page.TableDataInfo;
/** /**
* 销售主单Controller * 销售主单Controller
* *
* @author HashMap * @author HashMap
* @date 2025-12-01 * @date 2025-12-01
*/ */
@RestController @RestController
@RequestMapping("/sale/sale") @RequestMapping("/sale/sale")
public class DdSaleController extends BaseController public class DdSaleController extends BaseController {
{ private final IDdSaleService ddSaleService;
@Autowired private final IDdFeService ddFeService;
private IDdSaleService ddSaleService; private final IDdFsService ddFsService;
public DdSaleController(IDdSaleService ddSaleService, IDdFeService ddFeService, IDdFsService ddFsService) {
this.ddSaleService = ddSaleService;
this.ddFeService = ddFeService;
this.ddFsService = ddFsService;
}
/** /**
* 查询销售主单列表 * 查询销售主单列表
*/ */
@PreAuthorize("@ss.hasPermi('sale:sale:list')") @PreAuthorize("@ss.hasPermi('sale:sale:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(DdSale ddSale) public TableDataInfo list(DdSale ddSale) {
{
startPage(); startPage();
List<DdSale> list = ddSaleService.selectDdSaleList(ddSale); List<DdSale> list = ddSaleService.selectDdSaleList(ddSale);
return getDataTable(list); return getDataTable(list);
@@ -52,10 +62,9 @@ public class DdSaleController extends BaseController
@PreAuthorize("@ss.hasPermi('sale:sale:export')") @PreAuthorize("@ss.hasPermi('sale:sale:export')")
@Log(title = "销售主单", businessType = BusinessType.EXPORT) @Log(title = "销售主单", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, DdSale ddSale) public void export(HttpServletResponse response, DdSale ddSale) {
{
List<DdSale> list = ddSaleService.selectDdSaleList(ddSale); List<DdSale> list = ddSaleService.selectDdSaleList(ddSale);
ExcelUtil<DdSale> util = new ExcelUtil<DdSale>(DdSale.class); ExcelUtil<DdSale> util = new ExcelUtil<>(DdSale.class);
util.exportExcel(response, list, "销售主单数据"); util.exportExcel(response, list, "销售主单数据");
} }
@@ -64,8 +73,7 @@ public class DdSaleController extends BaseController
*/ */
@PreAuthorize("@ss.hasPermi('sale:sale:query')") @PreAuthorize("@ss.hasPermi('sale:sale:query')")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) public AjaxResult getInfo(@PathVariable("id") Long id) {
{
return success(ddSaleService.selectDdSaleById(id)); return success(ddSaleService.selectDdSaleById(id));
} }
@@ -75,8 +83,7 @@ public class DdSaleController extends BaseController
@PreAuthorize("@ss.hasPermi('sale:sale:add')") @PreAuthorize("@ss.hasPermi('sale:sale:add')")
@Log(title = "销售主单", businessType = BusinessType.INSERT) @Log(title = "销售主单", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@RequestBody DdSale ddSale) public AjaxResult add(@RequestBody DdSale ddSale) {
{
return toAjax(ddSaleService.insertDdSale(ddSale)); return toAjax(ddSaleService.insertDdSale(ddSale));
} }
@@ -86,8 +93,7 @@ public class DdSaleController extends BaseController
@PreAuthorize("@ss.hasPermi('sale:sale:edit')") @PreAuthorize("@ss.hasPermi('sale:sale:edit')")
@Log(title = "销售主单", businessType = BusinessType.UPDATE) @Log(title = "销售主单", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@RequestBody DdSale ddSale) public AjaxResult edit(@RequestBody DdSale ddSale) {
{
return toAjax(ddSaleService.updateDdSale(ddSale)); return toAjax(ddSaleService.updateDdSale(ddSale));
} }
@@ -96,9 +102,39 @@ public class DdSaleController extends BaseController
*/ */
@PreAuthorize("@ss.hasPermi('sale:sale:remove')") @PreAuthorize("@ss.hasPermi('sale:sale:remove')")
@Log(title = "销售主单", businessType = BusinessType.DELETE) @Log(title = "销售主单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) public AjaxResult remove(@PathVariable Long[] ids) {
{
return toAjax(ddSaleService.deleteDdSaleByIds(ids)); return toAjax(ddSaleService.deleteDdSaleByIds(ids));
} }
@GetMapping("/codeDict")
public AjaxResult getSaleItemCodeDict() {
DdFe fe = new DdFe();
fe.setStatus("正常");
DdFs fs = new DdFs();
fs.setStat("正常");
List<DdFe> ddFeList = Optional
.ofNullable(ddFeService.selectDdFeList(fe))
.orElse(Collections.emptyList());
List<DdFs> ddFsList = Optional
.ofNullable(ddFsService.selectDdFsList(fs))
.orElse(Collections.emptyList());
// 提取 code 字段
List<String> feCodeList = ddFeList.stream()
.map(DdFe::getCode)
.collect(Collectors.toList());
List<String> fsCodeList = ddFsList.stream()
.map(DdFs::getCode)
.collect(Collectors.toList());
Map<String, List<String>> saleItemCodeDict = new HashMap<>(2);
saleItemCodeDict.put("embryo", feCodeList);
saleItemCodeDict.put("semen", fsCodeList);
return AjaxResult.success(saleItemCodeDict);
}
} }

View File

@@ -3,6 +3,7 @@ package com.zhyc.module.frozen.mapper;
import java.util.List; import java.util.List;
import com.zhyc.module.frozen.domain.DdSale; import com.zhyc.module.frozen.domain.DdSale;
import com.zhyc.module.frozen.domain.DdSaleItem; import com.zhyc.module.frozen.domain.DdSaleItem;
import org.apache.ibatis.annotations.Mapper;
/** /**
* 销售主单Mapper接口 * 销售主单Mapper接口
@@ -10,6 +11,7 @@ import com.zhyc.module.frozen.domain.DdSaleItem;
* @author HashMap * @author HashMap
* @date 2025-12-01 * @date 2025-12-01
*/ */
@Mapper
public interface DdSaleMapper public interface DdSaleMapper
{ {
/** /**

View File

@@ -7,7 +7,6 @@ import java.util.Map;
import com.zhyc.common.exception.ServiceException; import com.zhyc.common.exception.ServiceException;
import com.zhyc.common.utils.DateUtils; import com.zhyc.common.utils.DateUtils;
import com.zhyc.common.utils.StringUtils; import com.zhyc.common.utils.StringUtils;
import com.zhyc.module.produce.breed.domain.ScEmbryoFlush;
import com.zhyc.module.produce.breed.mapper.ScEmbryoFlushMapper; import com.zhyc.module.produce.breed.mapper.ScEmbryoFlushMapper;
import com.zhyc.module.produce.breed.service.IScEmbryoFlushService; import com.zhyc.module.produce.breed.service.IScEmbryoFlushService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -15,17 +14,16 @@ import org.springframework.stereotype.Service;
import com.zhyc.module.frozen.mapper.DdFeMapper; import com.zhyc.module.frozen.mapper.DdFeMapper;
import com.zhyc.module.frozen.domain.DdFe; import com.zhyc.module.frozen.domain.DdFe;
import com.zhyc.module.frozen.service.IDdFeService; import com.zhyc.module.frozen.service.IDdFeService;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/** /**
* 冻胚库存Service业务层处理 * 冻胚库存Service业务层处理
* *
* @author ruoyi * @author ruoyi
* @date 2025-11-29 * @date 2025-11-29
*/ */
@Service @Service
public class DdFeServiceImpl implements IDdFeService public class DdFeServiceImpl implements IDdFeService
{ {
@Autowired @Autowired
private DdFeMapper ddFeMapper; private DdFeMapper ddFeMapper;
@@ -35,7 +33,7 @@ public class DdFeServiceImpl implements IDdFeService
private IScEmbryoFlushService scEmbryoFlushService; private IScEmbryoFlushService scEmbryoFlushService;
/** /**
* 查询冻胚库存 * 查询冻胚库存
* *
* @param id 冻胚库存主键 * @param id 冻胚库存主键
* @return 冻胚库存 * @return 冻胚库存
*/ */
@@ -47,7 +45,7 @@ public class DdFeServiceImpl implements IDdFeService
/** /**
* 查询冻胚库存列表 * 查询冻胚库存列表
* *
* @param ddFe 冻胚库存 * @param ddFe 冻胚库存
* @return 冻胚库存 * @return 冻胚库存
*/ */
@@ -59,7 +57,7 @@ public class DdFeServiceImpl implements IDdFeService
/** /**
* 新增冻胚库存 * 新增冻胚库存
* *
* @param ddFe 冻胚库存 * @param ddFe 冻胚库存
* @return 结果 * @return 结果
*/ */
@@ -75,7 +73,7 @@ public class DdFeServiceImpl implements IDdFeService
/** /**
* 修改冻胚库存 * 修改冻胚库存
* *
* @param ddFe 冻胚库存 * @param ddFe 冻胚库存
* @return 结果 * @return 结果
*/ */
@@ -87,7 +85,7 @@ public class DdFeServiceImpl implements IDdFeService
/** /**
* 批量删除冻胚库存 * 批量删除冻胚库存
* *
* @param ids 需要删除的冻胚库存主键 * @param ids 需要删除的冻胚库存主键
* @return 结果 * @return 结果
*/ */
@@ -99,7 +97,7 @@ public class DdFeServiceImpl implements IDdFeService
/** /**
* 删除冻胚库存信息 * 删除冻胚库存信息
* *
* @param id 冻胚库存主键 * @param id 冻胚库存主键
* @return 结果 * @return 结果
*/ */

View File

@@ -8,6 +8,7 @@ import com.zhyc.module.base.domain.BasSheep;
import com.zhyc.module.base.domain.BasSheepVariety; import com.zhyc.module.base.domain.BasSheepVariety;
import com.zhyc.module.base.mapper.BasSheepMapper; import com.zhyc.module.base.mapper.BasSheepMapper;
import com.zhyc.module.base.mapper.BasSheepVarietyMapper; import com.zhyc.module.base.mapper.BasSheepVarietyMapper;
import com.zhyc.module.frozen.domain.DdFe;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.zhyc.module.frozen.mapper.DdFsMapper; import com.zhyc.module.frozen.mapper.DdFsMapper;
@@ -15,6 +16,7 @@ import com.zhyc.module.frozen.domain.DdFs;
import com.zhyc.module.frozen.service.IDdFsService; import com.zhyc.module.frozen.service.IDdFsService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 冻精库存Service业务层处理 * 冻精库存Service业务层处理

View File

@@ -1,10 +1,19 @@
package com.zhyc.module.frozen.service.impl; package com.zhyc.module.frozen.service.impl;
import java.util.HashSet;
import java.util.List; import java.util.List;
import com.zhyc.common.utils.DateUtils; import com.zhyc.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired; import com.zhyc.module.frozen.domain.DdFe;
import com.zhyc.module.frozen.domain.DdFs;
import com.zhyc.module.frozen.service.IDdFeService;
import com.zhyc.module.frozen.service.IDdFsService;
import lombok.val;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set;
import com.zhyc.common.utils.StringUtils; import com.zhyc.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.zhyc.module.frozen.domain.DdSaleItem; import com.zhyc.module.frozen.domain.DdSaleItem;
@@ -14,120 +23,208 @@ import com.zhyc.module.frozen.service.IDdSaleService;
/** /**
* 销售主单Service业务层处理 * 销售主单Service业务层处理
* *
* @author HashMap * @author HashMap
* @date 2025-12-01 * @date 2025-12-01
*/ */
@Service @Service
public class DdSaleServiceImpl implements IDdSaleService public class DdSaleServiceImpl implements IDdSaleService {
{ private final DdSaleMapper ddSaleMapper;
@Autowired
private DdSaleMapper ddSaleMapper; private final IDdFeService ddFeService;
private final IDdFsService ddFsService;
public DdSaleServiceImpl(DdSaleMapper ddSaleMapper, IDdFeService ddFeService, IDdFsService ddFsService) {
this.ddSaleMapper = ddSaleMapper;
this.ddFeService = ddFeService;
this.ddFsService = ddFsService;
}
/** /**
* 查询销售主单 * 查询销售主单
* *
* @param id 销售主单主键 * @param id 销售主单主键
* @return 销售主单 * @return 销售主单
*/ */
@Override @Override
public DdSale selectDdSaleById(Long id) public DdSale selectDdSaleById(Long id) {
{
return ddSaleMapper.selectDdSaleById(id); return ddSaleMapper.selectDdSaleById(id);
} }
/** /**
* 查询销售主单列表 * 查询销售主单列表
* *
* @param ddSale 销售主单 * @param ddSale 销售主单
* @return 销售主单 * @return 销售主单
*/ */
@Override @Override
public List<DdSale> selectDdSaleList(DdSale ddSale) public List<DdSale> selectDdSaleList(DdSale ddSale) {
{
return ddSaleMapper.selectDdSaleList(ddSale); return ddSaleMapper.selectDdSaleList(ddSale);
} }
/** /**
* 新增销售主单 * 新增销售主单
* *
* @param ddSale 销售主单 * @param ddSale 销售主单
* @return 结果 * @return 结果
*/ */
@Transactional @Transactional
@Override @Override
public int insertDdSale(DdSale ddSale) public int insertDdSale(DdSale ddSale) {
{
ddSale.setCreateTime(DateUtils.getNowDate()); ddSale.setCreateTime(DateUtils.getNowDate());
int rows = ddSaleMapper.insertDdSale(ddSale); int rows = ddSaleMapper.insertDdSale(ddSale);
List<DdSaleItem> ddSaleItemList = ddSale.getDdSaleItemList();
// 同步后写入
ddSale.setDdSaleItemList(syncMateData(ddSaleItemList));
updateStock(ddSaleItemList, -1);
insertDdSaleItem(ddSale); insertDdSaleItem(ddSale);
return rows; return rows;
} }
/** /**
* 修改销售主单 * 修改销售主单
* * 若依主子表更新逻辑为先删除所有子项,再填充更新项
* 必须先批量恢复库存再执行插入操作完成更新
*
* @param ddSale 销售主单 * @param ddSale 销售主单
* @return 结果 * @return 结果
*/ */
@Transactional @Transactional
@Override @Override
public int updateDdSale(DdSale ddSale) public int updateDdSale(DdSale ddSale) {
{ DdSale originalData = selectDdSaleById(ddSale.getId());
List<DdSaleItem> originalDataSaleItemList = originalData.getDdSaleItemList();
// 恢复库存
updateStock(originalDataSaleItemList, 1);
ddSaleMapper.deleteDdSaleItemBySaleId(ddSale.getId()); ddSaleMapper.deleteDdSaleItemBySaleId(ddSale.getId());
// 更新元信息
ddSale.setDdSaleItemList(syncMateData(ddSale.getDdSaleItemList()));
insertDdSaleItem(ddSale); insertDdSaleItem(ddSale);
return ddSaleMapper.updateDdSale(ddSale); return ddSaleMapper.updateDdSale(ddSale);
} }
/** /**
* 批量删除销售主单 * 批量删除销售主单
* *
* @param ids 需要删除的销售主单主键 * @param ids 需要删除的销售主单主键
* @return 结果 * @return 结果
*/ */
@Transactional @Transactional
@Override @Override
public int deleteDdSaleByIds(Long[] ids) public int deleteDdSaleByIds(Long[] ids) {
{ // 删除前同步数据
for (Long id : ids) {
DdSale ddSale = selectDdSaleById(id);
updateStock(ddSale.getDdSaleItemList(), 1);
}
ddSaleMapper.deleteDdSaleItemBySaleIds(ids); ddSaleMapper.deleteDdSaleItemBySaleIds(ids);
return ddSaleMapper.deleteDdSaleByIds(ids); return ddSaleMapper.deleteDdSaleByIds(ids);
} }
/** /**
* 删除销售主单信息 * 删除销售主单信息
* *
* @param id 销售主单主键 * @param id 销售主单主键
* @return 结果 * @return 结果
*/ */
@Transactional @Transactional
@Override @Override
public int deleteDdSaleById(Long id) public int deleteDdSaleById(Long id) {
{ DdSale ddSale = selectDdSaleById(id);
if (ddSale != null) {
// 删除前更新库存
updateStock(ddSale.getDdSaleItemList(), 1);
}
ddSaleMapper.deleteDdSaleItemBySaleId(id); ddSaleMapper.deleteDdSaleItemBySaleId(id);
return ddSaleMapper.deleteDdSaleById(id); return ddSaleMapper.deleteDdSaleById(id);
} }
/** /**
* 新增销售明细信息 * 新增销售明细信息
* *
* @param ddSale 销售主单对象 * @param ddSale 销售主单对象
*/ */
public void insertDdSaleItem(DdSale ddSale) public void insertDdSaleItem(DdSale ddSale) {
{
List<DdSaleItem> ddSaleItemList = ddSale.getDdSaleItemList(); List<DdSaleItem> ddSaleItemList = ddSale.getDdSaleItemList();
Long id = ddSale.getId(); Long id = ddSale.getId();
if (StringUtils.isNotNull(ddSaleItemList)) // Set 检查重复项
{ Set<String> replaceVal = new HashSet<>();
if (StringUtils.isNotNull(ddSaleItemList)) {
List<DdSaleItem> list = new ArrayList<DdSaleItem>(); List<DdSaleItem> list = new ArrayList<DdSaleItem>();
for (DdSaleItem ddSaleItem : ddSaleItemList) // 插入前更新库存
{ updateStock(ddSaleItemList, -1);
for (DdSaleItem ddSaleItem : ddSaleItemList) {
ddSaleItem.setSaleId(id); ddSaleItem.setSaleId(id);
list.add(ddSaleItem); list.add(ddSaleItem);
if (!replaceVal.contains(ddSaleItem.getItemCode())) {
replaceVal.add(ddSaleItem.getItemCode());
} else {
throw new RuntimeException("存在重复项");
}
} }
if (list.size() > 0) if (!list.isEmpty()) {
{
ddSaleMapper.batchDdSaleItem(list); ddSaleMapper.batchDdSaleItem(list);
} }
} }
} }
/**
*
* @param ddSaleItemList 销售子项列表
* @param type 更新类型 1 入库 -1 出库
*/
public void updateStock(List<DdSaleItem> ddSaleItemList, long type) {
if (ddSaleItemList == null || type != 1 && type != -1) {
throw new RuntimeException("错误数据");
}
String status = type == 1 ? "正常" : "销售";
for (DdSaleItem ddSaleItem : ddSaleItemList) {
if (ddSaleItem.getItemType().equals("embryo")) {
DdFe fe = new DdFe();
fe.setCode(ddSaleItem.getItemCode());
fe.setId(ddFeService.selectDdFeList(fe).get(0).getId());
fe.setStatus(status);
ddFeService.updateDdFe(fe);
}
if (ddSaleItem.getItemType().equals("semen")) {
DdFs fs = new DdFs();
fs.setCode(ddSaleItem.getItemCode());
fs.setId(ddFsService.selectDdFsList(fs).get(0).getId());
fs.setStat(status);
ddFsService.updateDdFs(fs);
}
}
}
public List<DdSaleItem> syncMateData(List<DdSaleItem> ddSaleItemList) {
for (DdSaleItem saleItem : ddSaleItemList) {
if (saleItem.getItemType().equals("embryo")) {
DdFe query = new DdFe();
query.setCode(saleItem.getItemCode());
DdFe result = ddFeService.selectDdFeList(query).get(0);
if (result == null || result.getStatus().equals("1")) {
throw new RuntimeException("不存在的项");
}
// 同步销售项信息
saleItem.setQty(result.getQty());
saleItem.setBucketId(result.getBucketId());
saleItem.setTankId(result.getTankId());
saleItem.setRackId(result.getRackId());
} else if (saleItem.getItemType().equals("semen")) {
DdFs query = new DdFs();
query.setCode(saleItem.getItemCode());
DdFs result = ddFsService.selectDdFsList(query).get(0);
if (result == null || result.getStat().equals("1")) {
throw new RuntimeException("不存在的项");
}
// 同步销售项信息
saleItem.setQty(result.getQty());
saleItem.setBucketId(result.getBucketId());
saleItem.setTankId(result.getTankId());
saleItem.setRackId(result.getRackId());
}
}
return ddSaleItemList;
}
} }

View File

@@ -33,6 +33,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectDdFsVo"/> <include refid="selectDdFsVo"/>
<where> <where>
<if test="code != null and code != ''"> and code like concat('%', #{code}, '%')</if> <if test="code != null and code != ''"> and code like concat('%', #{code}, '%')</if>
<if test="stat != null and stat != ''">and stat = #{stat}</if>
<if test="tech != null and tech != ''"> and tech like concat('%', #{tech}, '%')</if> <if test="tech != null and tech != ''"> and tech like concat('%', #{tech}, '%')</if>
<if test="params.beginFreezeDt != null and params.endFreezeDt != null"> <if test="params.beginFreezeDt != null and params.endFreezeDt != null">
and freeze_dt between #{params.beginFreezeDt} and #{params.endFreezeDt} and freeze_dt between #{params.beginFreezeDt} and #{params.endFreezeDt}

View File

@@ -138,7 +138,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete> </delete>
<delete id="deleteDdSaleItemBySaleId" parameterType="Long"> <delete id="deleteDdSaleItemBySaleId" parameterType="Long">
delete from dd_sl_item where sale_id = #{saleId} delete from dd_sl_item where sale_id = #{id}
</delete> </delete>
<insert id="batchDdSaleItem"> <insert id="batchDdSaleItem">