diff --git a/src/main/java/mjkf/xinke/main/constant/HttpErrorResponseEnum.java b/src/main/java/mjkf/xinke/main/constant/HttpErrorResponseEnum.java index 759c823..17dda6e 100644 --- a/src/main/java/mjkf/xinke/main/constant/HttpErrorResponseEnum.java +++ b/src/main/java/mjkf/xinke/main/constant/HttpErrorResponseEnum.java @@ -16,13 +16,16 @@ public enum HttpErrorResponseEnum implements NcHttpErrorResponseInterface { FORBIDDEN("没权限访问,请退出重新登录!", 403, HttpStatus.SC_FORBIDDEN), NOT_FOUND("找不到指定资源", 404, HttpStatus.SC_NOT_FOUND), // - MATERIAL_NOT_FOUND("找不到指定材料", 404, HttpStatus.SC_NOT_FOUND), - MATERIAL_CANNOT_DELETE_BUILTIN("内建材料不允许删除", 400, HttpStatus.SC_NOT_FOUND), - MATERIAL_ID_REPEAT("材料 id 重复", 400, HttpStatus.SC_NOT_FOUND), - MATERIAL_ID_INVALID("材料 id 无效", 400, HttpStatus.SC_NOT_FOUND), - MATERIAL_PARENT_ID_INVALID("材料 parent_id 无效", 400, HttpStatus.SC_NOT_FOUND), - MATERIAL_TASK_NOT_FOUND("找不到指定材料采集任务", 400, HttpStatus.SC_NOT_FOUND), - MATERIAL_RESULT_NOT_FOUND("找不到指定材料采集结果", 400, HttpStatus.SC_NOT_FOUND), + MATERIAL_NOT_FOUND("找不到指定材料", 1001, HttpStatus.SC_NOT_FOUND), + MATERIAL_CANNOT_DELETE_BUILTIN("内建材料不允许删除", 1002, HttpStatus.SC_NOT_FOUND), + MATERIAL_ID_REPEAT("材料 id 重复", 1003, HttpStatus.SC_NOT_FOUND), + MATERIAL_ID_INVALID("材料 id 无效", 1004, HttpStatus.SC_NOT_FOUND), + MATERIAL_PARENT_ID_INVALID("材料 parent_id 无效", 1005, HttpStatus.SC_NOT_FOUND), + MATERIAL_TASK_NOT_FOUND("找不到指定材料采集任务", 1006, HttpStatus.SC_NOT_FOUND), + MATERIAL_RESULT_NOT_FOUND("找不到指定材料采集结果", 1007, HttpStatus.SC_NOT_FOUND), + + PRICE_RESULT_YEAR_MONTH_NEEDED("缺少年份或月份", 1101, HttpStatus.SC_NOT_FOUND), + PRICE_RESULT_NOT_FOUND("未找到对应数据", 1102, HttpStatus.SC_NOT_FOUND), ; private String message; diff --git a/src/main/java/mjkf/xinke/main/controller/PriceResultController.java b/src/main/java/mjkf/xinke/main/controller/PriceResultController.java new file mode 100644 index 0000000..0e1001f --- /dev/null +++ b/src/main/java/mjkf/xinke/main/controller/PriceResultController.java @@ -0,0 +1,104 @@ +package mjkf.xinke.main.controller; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.jgy.xxs.core.http.exp.NcHttpException; +import com.jgy.xxs.core.http.resp.HttpResponse; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import mjkf.xinke.main.common.http.FuHttpResponse; +import mjkf.xinke.main.constant.HttpErrorResponseEnum; +import mjkf.xinke.main.model.db.PriceResult; +import mjkf.xinke.main.model.vo.PriceResultEditRequest; +import mjkf.xinke.main.model.vo.PriceResultExport; +import mjkf.xinke.main.service.PriceResultService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 趋势表数据 前端控制器 + *

+ * + * @author han0 + * @since 2023-11-09 + */ +@RestController +@RequestMapping("/price-result") +public class PriceResultController { + @Resource + PriceResultService priceResultService; + + @ApiOperation("获取趋势表数据列表") + @GetMapping("/") + public HttpResponse list( + @ApiParam("年份") @RequestParam("year") Integer year, + @ApiParam("月份") @RequestParam(value = "month") Integer month, + @ApiParam("材料编号") @RequestParam(value = "material_id", required = false) String materialId, + @ApiParam("名称") @RequestParam(value = "name", required = false) String name + ) throws Exception { + if (year == null || month == null) { + throw new NcHttpException(HttpErrorResponseEnum.PRICE_RESULT_YEAR_MONTH_NEEDED); + } + var query = priceResultService.getQuery(year, month, materialId, name); + var result = priceResultService.list(query); + + return FuHttpResponse.Builder().dataResponse(result).build(); + } + + @ApiOperation("导出趋势表数据列表") + @GetMapping("/export") + public HttpResponse export( + @ApiParam("年份") @RequestParam("year") Integer year, + @ApiParam("月份") @RequestParam(value = "month") Integer month, + @ApiParam("材料编号") @RequestParam(value = "material_id", required = false) String materialId, + @ApiParam("名称") @RequestParam(value = "name", required = false) String name, + HttpServletResponse response + ) throws Exception { + if (year == null || month == null) { + throw new NcHttpException(HttpErrorResponseEnum.PRICE_RESULT_YEAR_MONTH_NEEDED); + } + var query = priceResultService.getQuery(year, month, materialId, name); + List result = priceResultService.list(query); + var exportData = result.stream().map(item -> new PriceResultExport(item)).collect(Collectors.toList()); + EasyExcel.write(response.getOutputStream()) + .head(PriceResultExport.class) + .excelType(ExcelTypeEnum.XLSX) + .sheet(0) + .doWrite(exportData); + return FuHttpResponse.Builder().dataResponse(result).build(); + } + + @ApiOperation("编辑趋势表数据") + @PutMapping("/{id}") + public HttpResponse edit( + @PathVariable String id, + @ApiParam("参数") @RequestBody PriceResultEditRequest params + ) throws Exception { + var result = priceResultService.getById(id); + if (result == null) { + throw new NcHttpException(HttpErrorResponseEnum.PRICE_RESULT_NOT_FOUND); + } + result.update(params); + priceResultService.updateById(result); + + return FuHttpResponse.Builder().dataResponse(result).build(); + } + + @ApiOperation("获取趋势表数据趋势") + @GetMapping("/{id}/trend") + public HttpResponse getTrend(@PathVariable String id) throws Exception { + var data = priceResultService.getById(id); + if (data == null) { + throw new NcHttpException(HttpErrorResponseEnum.PRICE_RESULT_NOT_FOUND); + } + var query = priceResultService.getQueryByName(data.getName()); + var result = priceResultService.list(query); + + return FuHttpResponse.Builder().dataResponse(result).build(); + } +} diff --git a/src/main/java/mjkf/xinke/main/dao/PriceResultMapper.java b/src/main/java/mjkf/xinke/main/dao/PriceResultMapper.java new file mode 100644 index 0000000..979a30b --- /dev/null +++ b/src/main/java/mjkf/xinke/main/dao/PriceResultMapper.java @@ -0,0 +1,16 @@ +package mjkf.xinke.main.dao; + +import mjkf.xinke.main.model.db.PriceResult; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 计算结果 Mapper 接口 + *

+ * + * @author han0 + * @since 2023-11-10 + */ +public interface PriceResultMapper extends BaseMapper { + +} diff --git a/src/main/java/mjkf/xinke/main/model/db/PriceResult.java b/src/main/java/mjkf/xinke/main/model/db/PriceResult.java new file mode 100644 index 0000000..6b3a201 --- /dev/null +++ b/src/main/java/mjkf/xinke/main/model/db/PriceResult.java @@ -0,0 +1,166 @@ +package mjkf.xinke.main.model.db; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import mjkf.xinke.main.model.vo.PriceResultEditRequest; + +/** + *

+ * 计算结果 + *

+ * + * @author han0 + * @since 2023-11-10 + */ +@Getter +@Setter +@TableName("PRICE_RESULT") +@ApiModel(value = "PriceResult对象", description = "计算结果") +public class PriceResult extends Model { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("最后更新人id") + @TableField("UPDATE_USER_ID") + private String updateUserId; + + @ApiModelProperty("最后更新人名称") + @TableField("UPDATE_USER_NAME") + private String updateUserName; + + @ApiModelProperty("最后更新时间") + @TableField("UPDATE_TIME") + private LocalDateTime updateTime; + + @ApiModelProperty("创建人id") + @TableField("CREATE_USER_ID") + private String createUserId; + + @ApiModelProperty("创建人名称") + @TableField("CREATE_USER_NAME") + private String createUserName; + + @ApiModelProperty("创建时间") + @TableField("CREATE_TIME") + private LocalDateTime createTime; + + @ApiModelProperty("删除人id") + @TableField("DELETE_USER_ID") + private String deleteUserId; + + @ApiModelProperty("删除人名称") + @TableField("DELETE_USER_NAME") + private String deleteUserName; + + @ApiModelProperty("删除时间") + @TableField("DELETE_TIME") + private LocalDateTime deleteTime; + + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("编号") + @TableField("MATERIAL_ID") + private String materialId; + + @ApiModelProperty("材料名称") + @TableField("`NAME`") + private String name; + + @ApiModelProperty("统计年份") + @TableField("`YEAR`") + private Integer year; + + @ApiModelProperty("统计月份") + @TableField("`MONTH`") + private Integer month; + + @ApiModelProperty("福州交通局价格") + @TableField("PRICE_FTB") + private Integer priceFtb; + + @ApiModelProperty("福州交通局浮动") + @TableField("FLUCTUATING_FTB") + private Integer fluctuatingFtb; + + @ApiModelProperty("三明钢铁价格") + @TableField("PRICE_SS") + private Integer priceSs; + + @ApiModelProperty("三明钢铁浮动") + @TableField("FLUCTUATING_SS") + private Integer fluctuatingSs; + + @ApiModelProperty("福州公路局价格") + @TableField("PRICE_FHB") + private Integer priceFhb; + + @ApiModelProperty("福州公路局浮动") + @TableField("FLUCTUATING_FHB") + private Integer fluctuatingFhb; + + @ApiModelProperty("网络价格") + @TableField("PRICE_NETWORK") + private Integer priceNetwork; + + @ApiModelProperty("网络浮动") + @TableField("FLUCTUATING_NETWORK") + private Integer fluctuatingNetwork; + + @ApiModelProperty("调查价格") + @TableField("PRICE_SURVEY") + private Integer priceSurvey; + + @ApiModelProperty("调查浮动") + @TableField("FLUCTUATING_SURVEY") + private Integer fluctuatingSurvey; + + @ApiModelProperty("上月发布价格") + @TableField("PRICE_LAST_MONTH") + private Integer priceLastMonth; + + @ApiModelProperty("计算价格") + @TableField("PRICE_CALCULATE") + private Integer priceCalculate; + + @ApiModelProperty("推荐价格") + @TableField("PRICE_RECOMMEND") + private Integer priceRecommend; + + @ApiModelProperty("推荐浮动") + @TableField("FLUCTUATING_RECOMMEND") + private Integer fluctuatingRecommend; + + @Override + public Serializable pkVal() { + return this.id; + } + + public PriceResult update(PriceResultEditRequest item) { + this.setPriceFtb(item.getPriceFtb()); + this.setFluctuatingFtb(item.getFluctuatingFtb()); + this.setPriceSs(item.getPriceSs()); + this.setFluctuatingSs(item.getFluctuatingSs()); + this.setPriceFhb(item.getPriceFhb()); + this.setFluctuatingFhb(item.getFluctuatingFhb()); + this.setPriceNetwork(item.getPriceNetwork()); + this.setFluctuatingNetwork(item.getFluctuatingNetwork()); + this.setPriceSurvey(item.getPriceSurvey()); + this.setFluctuatingSurvey(item.getFluctuatingSurvey()); + this.setPriceLastMonth(item.getPriceLastMonth()); + this.setPriceCalculate(item.getPriceCalculate()); + this.setPriceRecommend(item.getPriceRecommend()); + this.setFluctuatingRecommend(item.getFluctuatingRecommend()); + return this; + } +} diff --git a/src/main/java/mjkf/xinke/main/model/vo/PriceResultEditRequest.java b/src/main/java/mjkf/xinke/main/model/vo/PriceResultEditRequest.java new file mode 100644 index 0000000..cd5dca9 --- /dev/null +++ b/src/main/java/mjkf/xinke/main/model/vo/PriceResultEditRequest.java @@ -0,0 +1,47 @@ +package mjkf.xinke.main.model.vo; + +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; + + +@Getter +@Setter +public class PriceResultEditRequest { +// private String materialId; + +// private String name; + +// private Integer year; + +// private Integer month; + + private Integer priceFtb; + + private Integer fluctuatingFtb; + + private Integer priceSs; + + private Integer fluctuatingSs; + + private Integer priceFhb; + + private Integer fluctuatingFhb; + + private Integer priceNetwork; + + private Integer fluctuatingNetwork; + + private Integer priceSurvey; + + private Integer fluctuatingSurvey; + + private Integer priceLastMonth; + + private Integer priceCalculate; + + private Integer priceRecommend; + + private Integer fluctuatingRecommend; +} diff --git a/src/main/java/mjkf/xinke/main/model/vo/PriceResultExport.java b/src/main/java/mjkf/xinke/main/model/vo/PriceResultExport.java new file mode 100644 index 0000000..ccf0547 --- /dev/null +++ b/src/main/java/mjkf/xinke/main/model/vo/PriceResultExport.java @@ -0,0 +1,98 @@ +package mjkf.xinke.main.model.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModel; +import lombok.Getter; +import lombok.Setter; +import mjkf.xinke.main.model.db.PriceResult; + + +/** + *

+ * 计算结果 + *

+ * + * @author han0 + * @since 2023-11-10 + */ +@Getter +@Setter +@ApiModel(value = "PriceResultExport对象", description = "计算结果") +public class PriceResultExport { + @ExcelProperty({"材料编号"}) + private String materialId; + + @ExcelProperty({"材料名称"}) + private String name; + + @ExcelProperty({"统计年份"}) + private Integer year; + + @ExcelProperty({"统计月份"}) + private Integer month; + + @ExcelProperty({"福州交通局", "价格"}) + private String priceFtb; + + @ExcelProperty({"福州交通局", "浮动"}) + private String fluctuatingFtb; + + @ExcelProperty({"三明钢铁", "价格"}) + private String priceSs; + + @ExcelProperty({"三明钢铁", "浮动"}) + private String fluctuatingSs; + + @ExcelProperty({"福州公路局", "价格"}) + private String priceFhb; + + @ExcelProperty({"福州公路局", "浮动"}) + private String fluctuatingFhb; + + @ExcelProperty({"网络价格", "价格"}) + private String priceNetwork; + + @ExcelProperty({"网络价格", "浮动"}) + private String fluctuatingNetwork; + + @ExcelProperty({"调查价格", "价格"}) + private String priceSurvey; + + @ExcelProperty({"调查价格", "浮动"}) + private String fluctuatingSurvey; + + @ExcelProperty({"上月发布价格"}) + private String priceLastMonth; + + @ExcelProperty({"计算价格"}) + private String priceCalculate; + + @ExcelProperty({"推荐价", "价格"}) + private String priceRecommend; + + @ExcelProperty({"推荐价", "浮动"}) + private String fluctuatingRecommend; + + public PriceResultExport() {} + + public PriceResultExport(PriceResult data) { + this.setMaterialId(data.getMaterialId()); + this.setName(data.getName()); + this.setYear(data.getYear()); + this.setMonth(data.getMonth()); + this.setPriceFtb(data.getPriceFtb().toString()); + this.setFluctuatingFtb(data.getFluctuatingFtb().toString()); + this.setPriceSs(data.getPriceSs().toString()); + this.setFluctuatingSs(data.getFluctuatingSs().toString()); + this.setPriceFhb(data.getPriceFhb().toString()); + this.setFluctuatingFhb(data.getFluctuatingFhb().toString()); + this.setPriceNetwork(data.getPriceNetwork().toString()); + this.setFluctuatingNetwork(data.getFluctuatingNetwork().toString()); + this.setPriceSurvey(data.getPriceSurvey().toString()); + this.setFluctuatingSurvey(data.getFluctuatingSurvey().toString()); + this.setPriceLastMonth(data.getPriceLastMonth().toString()); + this.setPriceCalculate(data.getPriceCalculate().toString()); + this.setPriceRecommend(data.getPriceRecommend().toString()); + this.setFluctuatingRecommend(data.getFluctuatingRecommend().toString()); + } +} diff --git a/src/main/java/mjkf/xinke/main/service/ApiService.java b/src/main/java/mjkf/xinke/main/service/ApiService.java index 03ca844..5a935ac 100644 --- a/src/main/java/mjkf/xinke/main/service/ApiService.java +++ b/src/main/java/mjkf/xinke/main/service/ApiService.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; +@Deprecated public interface ApiService { Integer timeout = 60; diff --git a/src/main/java/mjkf/xinke/main/service/OilService.java b/src/main/java/mjkf/xinke/main/service/OilService.java index 1fa06c2..b2e30c9 100644 --- a/src/main/java/mjkf/xinke/main/service/OilService.java +++ b/src/main/java/mjkf/xinke/main/service/OilService.java @@ -22,7 +22,8 @@ public class OilService extends DataService, Oil> { var data = (Oil) obj; LambdaQueryWrapper query = new LambdaQueryWrapper<>(); query.eq(Oil::getName, data.getName()); - query.between(Oil::getDate, LocalDate.of(year, month, 1), LocalDate.of(year, month + 1, 1)); + var date = LocalDate.of(year, month, 1); + query.between(Oil::getDate, date, date.minusMonths(1)); return query; } @@ -34,16 +35,12 @@ public class OilService extends DataService, Oil> { ); } if (year != null) { - query.between(Oil::getDate, - LocalDate.of(year, 1, 1), - LocalDate.of(year + 1, 1, 1) - ); + var date = LocalDate.of(year, month, 1); + query.between(Oil::getDate, date, date.plusYears(1)); } if (month != null) { - query.between(Oil::getDate, - LocalDate.of(year, month, 1), - LocalDate.of(year, month + 1, 1) - ); + var date = LocalDate.of(year, month, 1); + query.between(Oil::getDate, date, date.plusMonths(1)); } if (name != null) { query.like(Oil::getName, name); diff --git a/src/main/java/mjkf/xinke/main/service/PriceResultService.java b/src/main/java/mjkf/xinke/main/service/PriceResultService.java new file mode 100644 index 0000000..98d5f5c --- /dev/null +++ b/src/main/java/mjkf/xinke/main/service/PriceResultService.java @@ -0,0 +1,33 @@ +package mjkf.xinke.main.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import mjkf.xinke.main.model.db.PriceResult; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + + +@Service +public class PriceResultService extends ServiceImpl, PriceResult> { + public LambdaQueryWrapper getQuery(Integer year, Integer month, String materialId, String name) { + var query = new LambdaQueryWrapper(); + if (year != null) { + query = query.eq(PriceResult::getYear, year); + } + if (month != null) { + query = query.eq(PriceResult::getMonth, month); + } + if (materialId != null) { + query.eq(PriceResult::getMaterialId, materialId); + } + if (name != null) { + query.like(PriceResult::getName, name); + } + return query; + } + + public LambdaQueryWrapper getQueryByName(String name) { + return this.getQuery(null, null, null, name); + } +} +