羊只销售BUg修复
This commit is contained in:
@@ -134,15 +134,30 @@ public class SxSheepSaleController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【新增】搜索耳号(模糊查询)
|
* 【修改】搜索耳号(模糊查询,支持羊舍过滤)
|
||||||
*/
|
*/
|
||||||
@GetMapping("/searchEarNumbers")
|
@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 {
|
try {
|
||||||
List<String> earNumbers = sxSheepSaleService.searchEarNumbers(query);
|
List<String> earNumbers = sxSheepSaleService.searchEarNumbers(query, sheepfoldId);
|
||||||
return success(earNumbers);
|
return success(earNumbers);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return error("搜索耳号失败:" + e.getMessage());
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -192,6 +192,15 @@ public class SxSheepSale extends BaseEntity {
|
|||||||
/** 【新增】非数据库字段:用于前端展示和选择羊舍后传递多个耳号 */
|
/** 【新增】非数据库字段:用于前端展示和选择羊舍后传递多个耳号 */
|
||||||
private List<String> bsManageTagsList;
|
private List<String> bsManageTagsList;
|
||||||
|
|
||||||
|
/** 【新增】非数据库字段:用于导出指定的记录ID集合 */
|
||||||
|
private List<Long> exportIds;
|
||||||
|
|
||||||
|
/** * 【修复】在子类中重新声明 remark 字段,并打上 @Excel 注解
|
||||||
|
* 解决 @Excel 不能作用于方法的问题,使得导出时能成功抓取备注列
|
||||||
|
*/
|
||||||
|
@Excel(name = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
public void setId(Long id) {
|
public void setId(Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
@@ -552,6 +561,27 @@ public class SxSheepSale extends BaseEntity {
|
|||||||
this.customerArea = customerArea;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
@@ -600,6 +630,8 @@ public class SxSheepSale extends BaseEntity {
|
|||||||
.append("createdByName", getCreatedByName())
|
.append("createdByName", getCreatedByName())
|
||||||
.append("sheepfoldName", getSheepfoldName())
|
.append("sheepfoldName", getSheepfoldName())
|
||||||
.append("currentWeight", getCurrentWeight())
|
.append("currentWeight", getCurrentWeight())
|
||||||
|
.append("exportIds", getExportIds())
|
||||||
|
.append("bsManageTagsList", getBsManageTagsList())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,10 +74,16 @@ public interface SxSheepSaleMapper {
|
|||||||
public List<String> selectSheepTagsBySheepfoldId(Long sheepfoldId);
|
public List<String> selectSheepTagsBySheepfoldId(Long sheepfoldId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【新增】模糊查询羊只耳号列表(用于前端搜索补全)
|
* 【修改】模糊查询羊只耳号列表(支持传入羊舍ID过滤)
|
||||||
* @param query 查询关键字
|
* @param query 查询关键字
|
||||||
|
* @param sheepfoldId 羊舍ID(可为空)
|
||||||
* @return 耳号列表
|
* @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);
|
||||||
}
|
}
|
||||||
@@ -70,10 +70,16 @@ public interface ISxSheepSaleService {
|
|||||||
*/
|
*/
|
||||||
public List<String> selectSheepTagsBySheepfoldId(Long sheepfoldId);
|
public List<String> selectSheepTagsBySheepfoldId(Long sheepfoldId);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【新增】模糊查询羊只耳号列表
|
* 【修改】模糊查询羊只耳号列表
|
||||||
|
*/
|
||||||
|
public List<String> searchEarNumbers(String query, Long sheepfoldId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【新增】查询已销售的单独耳号列表(拆分逗号并去重)
|
||||||
* @param query 查询关键字
|
* @param query 查询关键字
|
||||||
* @return 耳号列表
|
* @return 耳号列表
|
||||||
*/
|
*/
|
||||||
public List<String> searchEarNumbers(String query);
|
public List<String> searchSoldEarNumbers(String query);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package com.zhyc.module.sale.service.impl;
|
package com.zhyc.module.sale.service.impl;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.mapper.SxSheepSaleMapper;
|
||||||
import com.zhyc.module.sale.domain.SxSheepSale;
|
import com.zhyc.module.sale.domain.SxSheepSale;
|
||||||
import com.zhyc.module.sale.service.ISxSheepSaleService;
|
import com.zhyc.module.sale.service.ISxSheepSaleService;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 羊只销售记录Service业务层处理
|
* 羊只销售记录Service业务层处理
|
||||||
@@ -47,53 +53,93 @@ public class SxSheepSaleServiceImpl implements ISxSheepSaleService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增羊只销售记录
|
* 新增羊只销售记录(支持多选耳号自动拆分为单条记录)
|
||||||
*
|
|
||||||
* @param sxSheepSale 羊只销售记录
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class) // 增加事务注解,确保批量插入要么全成功,要么全失败
|
||||||
public int insertSxSheepSale(SxSheepSale sxSheepSale) {
|
public int insertSxSheepSale(SxSheepSale sxSheepSale) {
|
||||||
// 1. 业务验证 (必填项校验、级联校验)
|
// 1. 业务验证 (必填项校验、级联校验)
|
||||||
validateSalesFields(sxSheepSale);
|
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);
|
calculateSalesFields(sxSheepSale);
|
||||||
|
|
||||||
// 3. 设置默认事件类型
|
int rows = 0;
|
||||||
if (sxSheepSale.getEventType() == null) {
|
|
||||||
sxSheepSale.setEventType("销售");
|
// 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 设置默认事件类型
|
||||||
|
if (singleRecord.getEventType() == null) {
|
||||||
|
singleRecord.setEventType("销售");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 插入数据库
|
||||||
|
rows += sxSheepSaleMapper.insertSxSheepSale(singleRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 处理耳号列表(多个耳号用逗号分隔)
|
return rows;
|
||||||
if (sxSheepSale.getBsManageTagsList() != null && !sxSheepSale.getBsManageTagsList().isEmpty()) {
|
|
||||||
sxSheepSale.setBsManageTags(String.join(",", sxSheepSale.getBsManageTagsList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 调用Mapper插入数据
|
|
||||||
return sxSheepSaleMapper.insertSxSheepSale(sxSheepSale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改羊只销售记录
|
* 修改羊只销售记录
|
||||||
*
|
|
||||||
* @param sxSheepSale 羊只销售记录
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int updateSxSheepSale(SxSheepSale sxSheepSale) {
|
public int updateSxSheepSale(SxSheepSale sxSheepSale) {
|
||||||
// 1. 业务验证
|
// 1. 业务验证
|
||||||
validateSalesFields(sxSheepSale);
|
validateSalesFields(sxSheepSale);
|
||||||
|
|
||||||
// 2. 自动计算逻辑
|
// 2. 限制修改时只能是单只羊
|
||||||
calculateSalesFields(sxSheepSale);
|
if (sxSheepSale.getBsManageTagsList() != null && sxSheepSale.getBsManageTagsList().size() > 1) {
|
||||||
|
throw new RuntimeException("修改单条记录时只能保留一个耳号。如需销售更多羊只,请使用新增功能!");
|
||||||
// 3. 处理耳号列表(多个耳号用逗号分隔)
|
|
||||||
if (sxSheepSale.getBsManageTagsList() != null && !sxSheepSale.getBsManageTagsList().isEmpty()) {
|
|
||||||
sxSheepSale.setBsManageTags(String.join(",", sxSheepSale.getBsManageTagsList()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
return sxSheepSaleMapper.updateSxSheepSale(sxSheepSale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,10 +182,9 @@ public class SxSheepSaleServiceImpl implements ISxSheepSaleService {
|
|||||||
* 【新增】实现模糊查询耳号
|
* 【新增】实现模糊查询耳号
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<String> searchEarNumbers(String query) {
|
public List<String> searchEarNumbers(String query, Long sheepfoldId) {
|
||||||
return sxSheepSaleMapper.searchEarNumbers(query);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -76,12 +76,20 @@
|
|||||||
LEFT JOIN sys_user u_create ON s.created_by = u_create.user_id
|
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
|
LEFT JOIN da_sheepfold sf ON s.sheepfold_id = sf.id
|
||||||
<where>
|
<where>
|
||||||
<if test="bsManageTagsList != null and bsManageTagsList.size() > 0">
|
<if test="exportIds != null and exportIds.size() > 0">
|
||||||
AND s.bs_manage_tags IN
|
AND s.id IN
|
||||||
<foreach collection="bsManageTagsList" item="tag" open="(" separator="," close=")">
|
<foreach collection="exportIds" item="exportId" open="(" separator="," close=")">
|
||||||
#{tag}
|
#{exportId}
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</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 != ''">
|
<if test="(bsManageTagsList == null or bsManageTagsList.size() == 0) and bsManageTags != null and bsManageTags != ''">
|
||||||
AND s.bs_manage_tags LIKE CONCAT('%', #{bsManageTags}, '%')
|
AND s.bs_manage_tags LIKE CONCAT('%', #{bsManageTags}, '%')
|
||||||
</if>
|
</if>
|
||||||
@@ -166,9 +174,26 @@
|
|||||||
<select id="searchEarNumbers" resultType="java.lang.String">
|
<select id="searchEarNumbers" resultType="java.lang.String">
|
||||||
SELECT DISTINCT bs_manage_tags
|
SELECT DISTINCT bs_manage_tags
|
||||||
FROM sheep_file
|
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
|
ORDER BY bs_manage_tags
|
||||||
LIMIT 50
|
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>
|
</select>
|
||||||
|
|
||||||
<insert id="insertSxSheepSale" parameterType="SxSheepSale" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertSxSheepSale" parameterType="SxSheepSale" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
|||||||
Reference in New Issue
Block a user