7 changed files with 242 additions and 0 deletions
-
31src/main/java/com/xujie/modules/supplier/controller/PartPriceAnalysisController.java
-
24src/main/java/com/xujie/modules/supplier/data/PartPriceAnalysisQueryVo.java
-
41src/main/java/com/xujie/modules/supplier/data/PartPriceAnalysisVo.java
-
14src/main/java/com/xujie/modules/supplier/mapper/PartPriceAnalysisMapper.java
-
11src/main/java/com/xujie/modules/supplier/service/IPartPriceAnalysisService.java
-
81src/main/java/com/xujie/modules/supplier/service/impl/PartPriceAnalysisServiceImpl.java
-
40src/main/resources/mapper/supplier/PartPriceAnalysisMapper.xml
@ -0,0 +1,31 @@ |
|||||
|
package com.xujie.modules.supplier.controller; |
||||
|
|
||||
|
import com.xujie.common.utils.R; |
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisQueryVo; |
||||
|
import com.xujie.modules.supplier.service.IPartPriceAnalysisService; |
||||
|
import io.swagger.annotations.Api; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
@Api(tags = "物料价格分析") |
||||
|
@RestController |
||||
|
@RequestMapping("/supplier/partPriceAnalysis") |
||||
|
public class PartPriceAnalysisController { |
||||
|
|
||||
|
@Autowired |
||||
|
private IPartPriceAnalysisService partPriceAnalysisService; |
||||
|
|
||||
|
@PostMapping("/list") |
||||
|
@ApiOperation("查询已接受报价记录") |
||||
|
public R list(@RequestBody PartPriceAnalysisQueryVo query) { |
||||
|
try { |
||||
|
return R.ok().put("list", partPriceAnalysisService.list(query)); |
||||
|
} catch (Exception e) { |
||||
|
return R.error(e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
package com.xujie.modules.supplier.data; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* 物料价格分析查询条件 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class PartPriceAnalysisQueryVo { |
||||
|
|
||||
|
private String site; |
||||
|
|
||||
|
/** 开始时间(必填) */ |
||||
|
private String startDate; |
||||
|
|
||||
|
/** 结束时间(可选) */ |
||||
|
private String endDate; |
||||
|
|
||||
|
/** 物料编码(必填) */ |
||||
|
private String partNo; |
||||
|
|
||||
|
/** 供应商编码(可选,填写则按物料+供应商过滤) */ |
||||
|
private String supplierId; |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
package com.xujie.modules.supplier.data; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import lombok.Data; |
||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 物料价格分析结果 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class PartPriceAnalysisVo { |
||||
|
|
||||
|
private String partNo; |
||||
|
|
||||
|
private String partDesc; |
||||
|
|
||||
|
private BigDecimal price; |
||||
|
|
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
||||
|
private Date createdDate; |
||||
|
|
||||
|
private String supplierId; |
||||
|
|
||||
|
private String supplierName; |
||||
|
|
||||
|
/** 一级分类名称 */ |
||||
|
private String categoryName; |
||||
|
|
||||
|
/** 二级分类名称 */ |
||||
|
private String categoryLevel2Name; |
||||
|
|
||||
|
/** 三级分类名称 */ |
||||
|
private String categoryLevel3Name; |
||||
|
|
||||
|
/** 相对上一次报价涨跌幅,如 +5%、-5% */ |
||||
|
private String priceChangeRate; |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
package com.xujie.modules.supplier.mapper; |
||||
|
|
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisQueryVo; |
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisVo; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Mapper |
||||
|
public interface PartPriceAnalysisMapper { |
||||
|
|
||||
|
List<PartPriceAnalysisVo> listAcceptedQuotes(@Param("query") PartPriceAnalysisQueryVo query); |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
package com.xujie.modules.supplier.service; |
||||
|
|
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisQueryVo; |
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisVo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface IPartPriceAnalysisService { |
||||
|
|
||||
|
List<PartPriceAnalysisVo> list(PartPriceAnalysisQueryVo query); |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
package com.xujie.modules.supplier.service.impl; |
||||
|
|
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisQueryVo; |
||||
|
import com.xujie.modules.supplier.data.PartPriceAnalysisVo; |
||||
|
import com.xujie.modules.supplier.mapper.PartPriceAnalysisMapper; |
||||
|
import com.xujie.modules.supplier.service.IPartPriceAnalysisService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.math.RoundingMode; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Service |
||||
|
public class PartPriceAnalysisServiceImpl implements IPartPriceAnalysisService { |
||||
|
|
||||
|
@Autowired |
||||
|
private PartPriceAnalysisMapper partPriceAnalysisMapper; |
||||
|
|
||||
|
@Override |
||||
|
public List<PartPriceAnalysisVo> list(PartPriceAnalysisQueryVo query) { |
||||
|
if (query == null) { |
||||
|
throw new RuntimeException("查询参数不能为空"); |
||||
|
} |
||||
|
if (!StringUtils.hasText(query.getStartDate())) { |
||||
|
throw new RuntimeException("开始时间不能为空"); |
||||
|
} |
||||
|
if (!StringUtils.hasText(query.getPartNo())) { |
||||
|
throw new RuntimeException("物料编码不能为空"); |
||||
|
} |
||||
|
if (!StringUtils.hasText(query.getSite())) { |
||||
|
throw new RuntimeException("工厂不能为空"); |
||||
|
} |
||||
|
|
||||
|
query.setSite(query.getSite().trim()); |
||||
|
query.setPartNo(query.getPartNo().trim()); |
||||
|
if (StringUtils.hasText(query.getSupplierId())) { |
||||
|
query.setSupplierId(query.getSupplierId().trim()); |
||||
|
} |
||||
|
|
||||
|
List<PartPriceAnalysisVo> list = partPriceAnalysisMapper.listAcceptedQuotes(query); |
||||
|
fillPriceChangeRate(list); |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 列表按报价时间倒序(最新在上),与下一条(时间上更早的一次报价)比较涨跌幅 |
||||
|
*/ |
||||
|
private void fillPriceChangeRate(List<PartPriceAnalysisVo> list) { |
||||
|
if (list == null || list.isEmpty()) { |
||||
|
return; |
||||
|
} |
||||
|
for (int i = 0; i < list.size(); i++) { |
||||
|
PartPriceAnalysisVo current = list.get(i); |
||||
|
if (i >= list.size() - 1) { |
||||
|
current.setPriceChangeRate(null); |
||||
|
continue; |
||||
|
} |
||||
|
PartPriceAnalysisVo previous = list.get(i + 1); |
||||
|
current.setPriceChangeRate(calcPriceChangeRate(current.getPrice(), previous.getPrice())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private String calcPriceChangeRate(BigDecimal currentPrice, BigDecimal previousPrice) { |
||||
|
if (currentPrice == null || previousPrice == null || previousPrice.compareTo(BigDecimal.ZERO) == 0) { |
||||
|
return null; |
||||
|
} |
||||
|
BigDecimal changePercent = currentPrice.subtract(previousPrice) |
||||
|
.multiply(BigDecimal.valueOf(100)) |
||||
|
.divide(previousPrice, 2, RoundingMode.HALF_UP); |
||||
|
if (changePercent.compareTo(BigDecimal.ZERO) == 0) { |
||||
|
return "0%"; |
||||
|
} |
||||
|
String value = changePercent.stripTrailingZeros().toPlainString(); |
||||
|
if (changePercent.compareTo(BigDecimal.ZERO) > 0) { |
||||
|
return "+" + value + "%"; |
||||
|
} |
||||
|
return value + "%"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
<?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.xujie.modules.supplier.mapper.PartPriceAnalysisMapper"> |
||||
|
|
||||
|
<select id="listAcceptedQuotes" resultType="com.xujie.modules.supplier.data.PartPriceAnalysisVo"> |
||||
|
SELECT |
||||
|
A.part_no AS partNo, |
||||
|
A.part_desc AS partDesc, |
||||
|
A.price AS price, |
||||
|
A.created_date AS createdDate, |
||||
|
B.supplier_id AS supplierId, |
||||
|
B.supplier_name AS supplierName, |
||||
|
pf1.family_name AS categoryName, |
||||
|
pf2.family_name AS categoryLevel2Name, |
||||
|
pf3.family_name AS categoryLevel3Name |
||||
|
FROM PurQuotationReplyHist A |
||||
|
INNER JOIN PurQuotationHeader B |
||||
|
ON A.order_no = B.order_no AND A.site = B.site |
||||
|
LEFT JOIN part P |
||||
|
ON A.site = P.site AND A.part_no = P.part_no |
||||
|
LEFT JOIN part_family pf1 |
||||
|
ON P.site = pf1.site AND P.category = pf1.family_id |
||||
|
LEFT JOIN part_family pf2 |
||||
|
ON P.site = pf2.site AND P.category_level2 = pf2.family_id |
||||
|
LEFT JOIN part_family pf3 |
||||
|
ON P.site = pf3.site AND P.category_level3 = pf3.family_id |
||||
|
WHERE A.site = #{query.site} |
||||
|
AND A.status IN ('已接受', '已接收') |
||||
|
AND A.part_no = #{query.partNo} |
||||
|
AND A.created_date >= CAST(#{query.startDate} AS DATETIME) |
||||
|
<if test="query.endDate != null and query.endDate != ''"> |
||||
|
AND A.created_date < DATEADD(day, 1, CAST(#{query.endDate} AS DATE)) |
||||
|
</if> |
||||
|
<if test="query.supplierId != null and query.supplierId != ''"> |
||||
|
AND B.supplier_id = #{query.supplierId} |
||||
|
</if> |
||||
|
ORDER BY A.created_date DESC, A.seq_no DESC, A.order_no, A.item_no |
||||
|
</select> |
||||
|
|
||||
|
</mapper> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue