羊只销售BUg修复

This commit is contained in:
ll
2026-03-06 11:11:35 +08:00
parent 0fc748bbfd
commit e9e5e88a73
6 changed files with 195 additions and 41 deletions

View File

@@ -134,15 +134,30 @@ public class SxSheepSaleController extends BaseController {
}
/**
* 【新增】搜索耳号(模糊查询)
* 【修改】搜索耳号(模糊查询,支持羊舍过滤
*/
@GetMapping("/searchEarNumbers")
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
public AjaxResult searchEarNumbers(
@RequestParam(value = "query", required = false) String query,
@RequestParam(value = "sheepfoldId", required = false) Long sheepfoldId) {
try {
List<String> earNumbers = sxSheepSaleService.searchEarNumbers(query);
List<String> earNumbers = sxSheepSaleService.searchEarNumbers(query, sheepfoldId);
return success(earNumbers);
} catch (Exception e) {
return error("搜索耳号失败:" + e.getMessage());
}
}
/**
* 【新增】专门用于顶部查询条件:搜索列表中已销售的羊只耳号
*/
@GetMapping("/searchSoldEarNumbers")
public AjaxResult searchSoldEarNumbers(@RequestParam(value = "query", required = false) String query) {
try {
List<String> earNumbers = sxSheepSaleService.searchSoldEarNumbers(query);
return success(earNumbers);
} catch (Exception e) {
return error("搜索已销售耳号失败:" + e.getMessage());
}
}
}

View File

@@ -192,6 +192,15 @@ public class SxSheepSale extends BaseEntity {
/** 【新增】非数据库字段:用于前端展示和选择羊舍后传递多个耳号 */
private List<String> bsManageTagsList;
/** 【新增】非数据库字段用于导出指定的记录ID集合 */
private List<Long> exportIds;
/** * 【修复】在子类中重新声明 remark 字段,并打上 @Excel 注解
* 解决 @Excel 不能作用于方法的问题,使得导出时能成功抓取备注列
*/
@Excel(name = "备注")
private String remark;
public void setId(Long id) {
this.id = id;
}
@@ -552,6 +561,27 @@ public class SxSheepSale extends BaseEntity {
this.customerArea = customerArea;
}
public List<Long> getExportIds() {
return exportIds;
}
public void setExportIds(List<Long> exportIds) {
this.exportIds = exportIds;
}
/**
* 【修复】重写 get/set 方法,指向子类自身的 remark 字段
*/
@Override
public String getRemark() {
return remark;
}
@Override
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -600,6 +630,8 @@ public class SxSheepSale extends BaseEntity {
.append("createdByName", getCreatedByName())
.append("sheepfoldName", getSheepfoldName())
.append("currentWeight", getCurrentWeight())
.append("exportIds", getExportIds())
.append("bsManageTagsList", getBsManageTagsList())
.toString();
}
}

View File

@@ -74,10 +74,16 @@ public interface SxSheepSaleMapper {
public List<String> selectSheepTagsBySheepfoldId(Long sheepfoldId);
/**
* 【新增】模糊查询羊只耳号列表(用于前端搜索补全
* 【修改】模糊查询羊只耳号列表(支持传入羊舍ID过滤
* @param query 查询关键字
* @param sheepfoldId 羊舍ID可为空
* @return 耳号列表
*/
public List<String> searchEarNumbers(@Param("query") String query);
public List<String> searchEarNumbers(@Param("query") String query, @Param("sheepfoldId") Long sheepfoldId);
/**
* 【新增】查询已销售的原始耳号数据(含逗号分隔的字符串)
*/
public List<String> selectSoldEarNumbers(@Param("query") String query);
}

View File

@@ -70,10 +70,16 @@ public interface ISxSheepSaleService {
*/
public List<String> selectSheepTagsBySheepfoldId(Long sheepfoldId);
/**
* 【新增】模糊查询羊只耳号列表
* 【修改】模糊查询羊只耳号列表
*/
public List<String> searchEarNumbers(String query, Long sheepfoldId);
/**
* 【新增】查询已销售的单独耳号列表(拆分逗号并去重)
* @param query 查询关键字
* @return 耳号列表
*/
public List<String> searchEarNumbers(String query);
public List<String> searchSoldEarNumbers(String query);
}

View File

@@ -1,6 +1,9 @@
package com.zhyc.module.sale.service.impl;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.springframework.beans.factory.annotation.Autowired;
@@ -9,6 +12,9 @@ import com.zhyc.common.annotation.DataScope;
import com.zhyc.module.sale.mapper.SxSheepSaleMapper;
import com.zhyc.module.sale.domain.SxSheepSale;
import com.zhyc.module.sale.service.ISxSheepSaleService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.BeanUtils;
import java.util.Arrays;
/**
* 羊只销售记录Service业务层处理
@@ -47,53 +53,93 @@ public class SxSheepSaleServiceImpl implements ISxSheepSaleService {
}
/**
* 新增羊只销售记录
*
* @param sxSheepSale 羊只销售记录
* @return 结果
* 新增羊只销售记录(支持多选耳号自动拆分为单条记录)
*/
@Override
@Transactional(rollbackFor = Exception.class) // 增加事务注解,确保批量插入要么全成功,要么全失败
public int insertSxSheepSale(SxSheepSale sxSheepSale) {
// 1. 业务验证 (必填项校验、级联校验)
validateSalesFields(sxSheepSale);
// 2. 自动计算逻辑 (价格、体重)
// 2. 获取标签列表
List<String> tags = sxSheepSale.getBsManageTagsList();
if (tags == null || tags.isEmpty()) {
if (sxSheepSale.getBsManageTags() != null && !sxSheepSale.getBsManageTags().isEmpty()) {
tags = Arrays.asList(sxSheepSale.getBsManageTags().split(","));
} else {
throw new RuntimeException("耳号不能为空!");
}
}
// 3. 先计算出这批羊的总价、均价、均重(基于前端传来的总数量和总重量)
// 这里的 calculateSalesFields 会自动根据 tags 的数量算出 avgWeight 和 avgPricePerSheep
calculateSalesFields(sxSheepSale);
// 3. 设置默认事件类型
if (sxSheepSale.getEventType() == null) {
sxSheepSale.setEventType("销售");
int rows = 0;
// 4. 遍历每个耳号,拆分为独立的记录进行保存
for (String tag : tags) {
SxSheepSale singleRecord = new SxSheepSale();
// 复制前端传来的公共基础属性(如日期、客户信息、销售人员等)
BeanUtils.copyProperties(sxSheepSale, singleRecord);
// 防御性清空主键,防止 MyBatis 主键回填导致重复主键冲突
singleRecord.setId(null);
// 覆盖为单个耳号
singleRecord.setBsManageTags(tag);
// 清空列表,避免后续影响
singleRecord.setBsManageTagsList(null);
// 5. 调整单条记录的价格和重量字段,使其符合“单只羊”的逻辑
if ("按个体".equals(singleRecord.getPricingMethod())) {
// 按个体卖:单只羊的总价就是单价
singleRecord.setTotalPrice(singleRecord.getUnitPrice());
singleRecord.setAvgPricePerSheep(singleRecord.getUnitPrice());
singleRecord.setTotalWeight(null);
singleRecord.setAvgWeight(null);
} else if ("按体重".equals(singleRecord.getPricingMethod())) {
// 按体重卖:单只羊的重量设为这批羊的平均重量,单只羊的价格设为平均价格
singleRecord.setTotalWeight(sxSheepSale.getAvgWeight());
singleRecord.setAvgWeight(sxSheepSale.getAvgWeight());
singleRecord.setTotalPrice(sxSheepSale.getAvgPricePerSheep());
singleRecord.setAvgPricePerSheep(sxSheepSale.getAvgPricePerSheep());
}
// 4. 处理耳号列表(多个耳号用逗号分隔)
if (sxSheepSale.getBsManageTagsList() != null && !sxSheepSale.getBsManageTagsList().isEmpty()) {
sxSheepSale.setBsManageTags(String.join(",", sxSheepSale.getBsManageTagsList()));
// 6. 设置默认事件类型
if (singleRecord.getEventType() == null) {
singleRecord.setEventType("销售");
}
// 5. 调用Mapper插入数据
return sxSheepSaleMapper.insertSxSheepSale(sxSheepSale);
// 7. 插入数据
rows += sxSheepSaleMapper.insertSxSheepSale(singleRecord);
}
return rows;
}
/**
* 修改羊只销售记录
*
* @param sxSheepSale 羊只销售记录
* @return 结果
*/
@Override
public int updateSxSheepSale(SxSheepSale sxSheepSale) {
// 1. 业务验证
validateSalesFields(sxSheepSale);
// 2. 自动计算逻辑
calculateSalesFields(sxSheepSale);
// 3. 处理耳号列表(多个耳号用逗号分隔)
if (sxSheepSale.getBsManageTagsList() != null && !sxSheepSale.getBsManageTagsList().isEmpty()) {
sxSheepSale.setBsManageTags(String.join(",", sxSheepSale.getBsManageTagsList()));
// 2. 限制修改时只能是单只羊
if (sxSheepSale.getBsManageTagsList() != null && sxSheepSale.getBsManageTagsList().size() > 1) {
throw new RuntimeException("修改单条记录时只能保留一个耳号。如需销售更多羊只,请使用新增功能!");
}
// 4. 调用Mapper更新数据
// 3. 自动计算逻辑此时只会按1只羊进行准确计算
calculateSalesFields(sxSheepSale);
// 4. 处理耳号列表,确保保存的是单个字符串
if (sxSheepSale.getBsManageTagsList() != null && !sxSheepSale.getBsManageTagsList().isEmpty()) {
sxSheepSale.setBsManageTags(sxSheepSale.getBsManageTagsList().get(0));
}
// 5. 调用Mapper更新数据
return sxSheepSaleMapper.updateSxSheepSale(sxSheepSale);
}
@@ -136,10 +182,9 @@ public class SxSheepSaleServiceImpl implements ISxSheepSaleService {
* 【新增】实现模糊查询耳号
*/
@Override
public List<String> searchEarNumbers(String query) {
return sxSheepSaleMapper.searchEarNumbers(query);
public List<String> searchEarNumbers(String query, Long sheepfoldId) {
return sxSheepSaleMapper.searchEarNumbers(query, sheepfoldId);
}
/**
* 自动计算总价、平均体重、平均单只价格
*/
@@ -226,4 +271,29 @@ public class SxSheepSaleServiceImpl implements ISxSheepSaleService {
}
}
}
/**
* 【新增】实现查询已销售的耳号,并处理逗号分隔的问题
*/
@Override
public List<String> searchSoldEarNumbers(String query) {
// 获取包含关键字的原始字符串(可能包含逗号)
List<String> rawTags = sxSheepSaleMapper.selectSoldEarNumbers(query);
Set<String> uniqueTags = new HashSet<>();
for (String raw : rawTags) {
if (raw != null && !raw.isEmpty()) {
String[] tags = raw.split(",");
for (String tag : tags) {
// 再次进行精准包含判断(过滤掉连带查出的其他无辜耳号)
if (query == null || query.isEmpty() || tag.contains(query)) {
uniqueTags.add(tag);
}
}
}
}
// 转为列表按字母排序提升体验限制返回最多50条
return uniqueTags.stream().sorted().limit(50).collect(Collectors.toList());
}
}

View File

@@ -76,12 +76,20 @@
LEFT JOIN sys_user u_create ON s.created_by = u_create.user_id
LEFT JOIN da_sheepfold sf ON s.sheepfold_id = sf.id
<where>
<if test="bsManageTagsList != null and bsManageTagsList.size() > 0">
AND s.bs_manage_tags IN
<foreach collection="bsManageTagsList" item="tag" open="(" separator="," close=")">
#{tag}
<if test="exportIds != null and exportIds.size() > 0">
AND s.id IN
<foreach collection="exportIds" item="exportId" open="(" separator="," close=")">
#{exportId}
</foreach>
</if>
<if test="bsManageTagsList != null and bsManageTagsList.size() > 0">
AND (
<foreach collection="bsManageTagsList" item="tag" separator=" OR ">
FIND_IN_SET(#{tag}, s.bs_manage_tags)
</foreach>
)
</if>
<if test="(bsManageTagsList == null or bsManageTagsList.size() == 0) and bsManageTags != null and bsManageTags != ''">
AND s.bs_manage_tags LIKE CONCAT('%', #{bsManageTags}, '%')
</if>
@@ -166,11 +174,28 @@
<select id="searchEarNumbers" resultType="java.lang.String">
SELECT DISTINCT bs_manage_tags
FROM sheep_file
WHERE bs_manage_tags LIKE CONCAT(#{query}, '%')
<where>
<if test="query != null and query != ''">
AND bs_manage_tags LIKE CONCAT('%', #{query}, '%')
</if>
<if test="sheepfoldId != null">
AND sheepfold_id = #{sheepfoldId}
</if>
</where>
ORDER BY bs_manage_tags
LIMIT 50
</select>
<select id="selectSoldEarNumbers" resultType="java.lang.String">
SELECT DISTINCT bs_manage_tags
FROM sx_sheep_sale
<where>
<if test="query != null and query != ''">
bs_manage_tags LIKE CONCAT('%', #{query}, '%')
</if>
</where>
</select>
<insert id="insertSxSheepSale" parameterType="SxSheepSale" useGeneratedKeys="true" keyProperty="id">
insert into sx_sheep_sale
<trim prefix="(" suffix=")" suffixOverrides=",">