fix(budget): 新增预算相关接口
This commit is contained in:
@@ -29,6 +29,8 @@ public enum HttpErrorResponseEnum implements NcHttpErrorResponseInterface {
|
||||
|
||||
PRICE_PUBLISH_YEAR_MONTH_NEEDED("缺少年份或月份", 1201, HttpStatus.SC_NOT_FOUND),
|
||||
PRICE_PUBLISH_NOT_FOUND("未找到对应数据", 1202, HttpStatus.SC_NOT_FOUND),
|
||||
|
||||
BUDGET_NOT_FOUND("未找到对应数据", 1301, HttpStatus.SC_NOT_FOUND),
|
||||
;
|
||||
|
||||
private String message;
|
||||
|
142
src/main/java/mjkf/xinke/main/controller/BudgetController.java
Normal file
142
src/main/java/mjkf/xinke/main/controller/BudgetController.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package mjkf.xinke.main.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
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.auth.core.util.StpLoginUserUtil;
|
||||
import mjkf.xinke.main.common.http.FuHttpResponse;
|
||||
import mjkf.xinke.main.constant.HttpErrorResponseEnum;
|
||||
import mjkf.xinke.main.model.db.Budget;
|
||||
import mjkf.xinke.main.model.db.BudgetItem;
|
||||
import mjkf.xinke.main.model.db.PricePublish;
|
||||
import mjkf.xinke.main.model.vo.BudgetCreateRequest;
|
||||
import mjkf.xinke.main.model.vo.BudgetDetail;
|
||||
import mjkf.xinke.main.service.BudgetItemService;
|
||||
import mjkf.xinke.main.service.BudgetService;
|
||||
import mjkf.xinke.main.service.PricePublishService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 预算 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author han0
|
||||
* @since 2023-12-14
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/budget")
|
||||
public class BudgetController {
|
||||
|
||||
@Resource
|
||||
BudgetService budgetService;
|
||||
|
||||
@Resource
|
||||
BudgetItemService budgetItemService;
|
||||
|
||||
@Resource
|
||||
PricePublishService pricePublishService;
|
||||
|
||||
@ApiOperation("新增预算")
|
||||
@PostMapping("/")
|
||||
@Transactional
|
||||
public HttpResponse create (
|
||||
@ApiParam("参数") @RequestBody BudgetCreateRequest params
|
||||
) throws Exception {
|
||||
params.check();
|
||||
var user = StpLoginUserUtil.getLoginUser();
|
||||
|
||||
// 查询各月份材料价格
|
||||
LambdaQueryWrapper<PricePublish> query = pricePublishService.getQuery(params);
|
||||
// 转换查询结果为键值对 材料id,月份 => 价格
|
||||
var priceMap = pricePublishService.getPriceMapEntryByMaterialIdAndMonth(query);
|
||||
// 各月份求和
|
||||
var totalMap = new HashMap<String, Integer>();
|
||||
var budgetItemList = new ArrayList<BudgetItem>();
|
||||
for (var item: params.getItems()) {
|
||||
var meta = new ArrayList<Map<String, Object>>();
|
||||
for (var month: params.getMonths()) {
|
||||
var key = item.getName() + month.toString();
|
||||
var price = priceMap.getOrDefault(key, 0);
|
||||
meta.add(Map.of(
|
||||
"month", month,
|
||||
"total", price * item.getQuantity(),
|
||||
"price", price
|
||||
)
|
||||
);
|
||||
var total = totalMap.getOrDefault(month.toString(), 0);
|
||||
totalMap.put(month.toString(), total + price * item.getQuantity());
|
||||
// 遍历月份 获取各材料各月份总数
|
||||
}
|
||||
var budgetItem = new BudgetItem(item, meta);
|
||||
budgetItemList.add(budgetItem);
|
||||
}
|
||||
// 入库
|
||||
var budget = new Budget(params, user, totalMap);
|
||||
budgetService.save(budget);
|
||||
for (var budgetItem: budgetItemList) {
|
||||
budgetItem.setBudgetId(budget.getId());
|
||||
budgetItemService.save(budgetItem);
|
||||
}
|
||||
|
||||
return FuHttpResponse.Builder().dataResponse(budgetItemList).build();
|
||||
}
|
||||
|
||||
@ApiOperation("查询预算")
|
||||
@GetMapping("/")
|
||||
public HttpResponse list (
|
||||
@ApiParam("每页数量") @RequestParam(name = "limit", defaultValue = "10") Integer limit,
|
||||
@ApiParam("页码") @RequestParam(name = "page", defaultValue = "1") Integer page,
|
||||
@ApiParam(value = "名称") @RequestParam(value="name") String name
|
||||
) throws Exception {
|
||||
var query = new LambdaQueryWrapper<Budget>();
|
||||
if (!ObjectUtils.isEmpty(name)) {
|
||||
query.like(Budget::getName, name);
|
||||
}
|
||||
var result = budgetService.page(new Page<>(page, limit), query);
|
||||
return FuHttpResponse.Builder().dataResponse(result).build();
|
||||
}
|
||||
|
||||
@ApiOperation("删除预算")
|
||||
@DeleteMapping("/")
|
||||
public HttpResponse delete (
|
||||
@ApiParam(value = "id列表:1,2,3") @RequestParam(value="ids") String ids
|
||||
) throws Exception {
|
||||
var idList = Arrays.asList(ids.split(","));
|
||||
var query = new LambdaQueryWrapper<Budget>();
|
||||
query.in(Budget::getId, idList);
|
||||
budgetService.remove(query);
|
||||
return FuHttpResponse.Builder().dataResponse().build();
|
||||
}
|
||||
|
||||
@ApiOperation("预算详情")
|
||||
@GetMapping("/{id}")
|
||||
public HttpResponse detail (
|
||||
@ApiParam(value = "id") @PathVariable("id") Integer id
|
||||
) throws Exception {
|
||||
var budget = budgetService.getById(id);
|
||||
if (budget == null) {
|
||||
throw new NcHttpException(HttpErrorResponseEnum.BUDGET_NOT_FOUND);
|
||||
}
|
||||
|
||||
var query = new LambdaQueryWrapper<BudgetItem>();
|
||||
query.eq(BudgetItem::getBudgetId, id);
|
||||
var list = budgetItemService.list(query);
|
||||
|
||||
var result = new BudgetDetail(budget, list);
|
||||
return FuHttpResponse.Builder().dataResponse(result).build();
|
||||
}
|
||||
|
||||
// todo 在价格发布创建时补全材料id
|
||||
}
|
16
src/main/java/mjkf/xinke/main/dao/BudgetItemMapper.java
Normal file
16
src/main/java/mjkf/xinke/main/dao/BudgetItemMapper.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package mjkf.xinke.main.dao;
|
||||
|
||||
import mjkf.xinke.main.model.db.BudgetItem;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author han0
|
||||
* @since 2023-12-19
|
||||
*/
|
||||
public interface BudgetItemMapper extends BaseMapper<BudgetItem> {
|
||||
|
||||
}
|
16
src/main/java/mjkf/xinke/main/dao/BudgetMapper.java
Normal file
16
src/main/java/mjkf/xinke/main/dao/BudgetMapper.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package mjkf.xinke.main.dao;
|
||||
|
||||
import mjkf.xinke.main.model.db.Budget;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author han0
|
||||
* @since 2023-12-19
|
||||
*/
|
||||
public interface BudgetMapper extends BaseMapper<Budget> {
|
||||
|
||||
}
|
93
src/main/java/mjkf/xinke/main/model/db/Budget.java
Normal file
93
src/main/java/mjkf/xinke/main/model/db/Budget.java
Normal file
@@ -0,0 +1,93 @@
|
||||
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.time.LocalDate;
|
||||
import java.util.*;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
|
||||
import mjkf.xinke.main.common.serializer.FastjsonArrayHandler;
|
||||
import mjkf.xinke.main.model.vo.BudgetCreateRequest;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author han0
|
||||
* @since 2023-12-19
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName(value="BUDGET", autoResultMap=true)
|
||||
@ApiModel(value = "Budget对象", description = "")
|
||||
public class Budget extends Model<Budget> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "ID", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
@TableField("`NAME`")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("总数")
|
||||
@TableField("AMOUNT")
|
||||
private Integer amount;
|
||||
|
||||
@ApiModelProperty("最小值")
|
||||
@TableField("MIN_AMOUNT")
|
||||
@JsonProperty(value = "min_amount")
|
||||
private Integer minAmount;
|
||||
|
||||
@ApiModelProperty("最大值")
|
||||
@TableField("MAX_AMOUNT")
|
||||
@JsonProperty(value = "max_amount")
|
||||
private Integer maxAmount;
|
||||
|
||||
@ApiModelProperty("日期")
|
||||
@TableField("`DATE`")
|
||||
private LocalDate date;
|
||||
|
||||
@ApiModelProperty("年份")
|
||||
@TableField("`YEAR`")
|
||||
private Integer year;
|
||||
|
||||
@ApiModelProperty("月份")
|
||||
@TableField(value="`MONTHS`", typeHandler = FastjsonArrayHandler.class)
|
||||
private List months;
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Budget() {}
|
||||
|
||||
public Budget(BudgetCreateRequest params, SaBaseLoginUser user, HashMap<String, Integer> totalMap) {
|
||||
this.name = params.getName();
|
||||
this.amount = params.getItems().stream().mapToInt(item -> item.getTotalPrice()).sum();
|
||||
|
||||
List<Map.Entry<String,Integer>> list = new ArrayList(totalMap.entrySet());
|
||||
Collections.sort(list, (o1, o2) -> (o1.getValue() - o2.getValue()));
|
||||
|
||||
this.minAmount = list.get(0).getValue();
|
||||
this.maxAmount = list.get(list.size() -1).getValue();
|
||||
// list.get(0).getKey();
|
||||
// list.get(list.size() -1 ).getKey();
|
||||
this.date = LocalDate.now();
|
||||
this.year = params.getYear();
|
||||
this.months = params.getMonths();
|
||||
}
|
||||
|
||||
}
|
84
src/main/java/mjkf/xinke/main/model/db/BudgetItem.java
Normal file
84
src/main/java/mjkf/xinke/main/model/db/BudgetItem.java
Normal file
@@ -0,0 +1,84 @@
|
||||
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.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.main.common.serializer.FastjsonArrayHandler;
|
||||
import mjkf.xinke.main.model.vo.BudgetCreateRequest;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author han0
|
||||
* @since 2023-12-19
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName(value="BUDGET_ITEM", autoResultMap=true)
|
||||
@ApiModel(value = "BudgetItem对象", description = "")
|
||||
public class BudgetItem extends Model<BudgetItem> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "ID", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("预算id")
|
||||
@TableField("BUDGET_ID")
|
||||
@JsonProperty(value = "budget_id")
|
||||
private Integer budgetId;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
@TableField("`NAME`")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("总数")
|
||||
@TableField("QUANTITY")
|
||||
private Integer quantity;
|
||||
|
||||
@ApiModelProperty("数据")
|
||||
@TableField(value="`META`", typeHandler = FastjsonArrayHandler.class)
|
||||
private List<Map<String, Object>> meta;
|
||||
|
||||
@ApiModelProperty("单位")
|
||||
@TableField("UNIT")
|
||||
private String unit;
|
||||
|
||||
@ApiModelProperty("单价")
|
||||
@TableField("UNIT_PRICE")
|
||||
private Integer unitPrice;
|
||||
|
||||
@ApiModelProperty("总价")
|
||||
@TableField("TOTAL_PRICE")
|
||||
private Integer totalPrice;
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public BudgetItem() {}
|
||||
|
||||
public BudgetItem(BudgetCreateRequest.BudgetMaterial item, ArrayList<Map<String, Object>> meta) {
|
||||
this.meta = meta;
|
||||
this.name = item.getName();
|
||||
this.quantity = item.getTotalPrice();
|
||||
this.unit = item.getUnit();
|
||||
this.unitPrice = item.getUnitPrice();
|
||||
this.totalPrice = item.getTotalPrice();
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package mjkf.xinke.main.model.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class BudgetCreateRequest {
|
||||
|
||||
@ApiModelProperty("项目名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("年份")
|
||||
private Integer year;
|
||||
|
||||
@ApiModelProperty("月份")
|
||||
private List<Integer> months;
|
||||
|
||||
@ApiModelProperty("材料")
|
||||
private List<BudgetMaterial> items;
|
||||
|
||||
public void check() throws Exception{
|
||||
}
|
||||
|
||||
@Data
|
||||
static public class BudgetMaterial implements Serializable {
|
||||
@ApiModelProperty("材料id")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("材料名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("单位")
|
||||
private String unit;
|
||||
|
||||
@ApiModelProperty("单价")
|
||||
@JsonProperty(value = "unit_price")
|
||||
private Integer unitPrice;
|
||||
|
||||
@ApiModelProperty("数量")
|
||||
private Integer quantity;
|
||||
|
||||
@ApiModelProperty("总价")
|
||||
@JsonProperty(value = "total_price")
|
||||
private Integer totalPrice;
|
||||
}
|
||||
}
|
48
src/main/java/mjkf/xinke/main/model/vo/BudgetDetail.java
Normal file
48
src/main/java/mjkf/xinke/main/model/vo/BudgetDetail.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package mjkf.xinke.main.model.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import mjkf.xinke.main.model.db.Budget;
|
||||
import mjkf.xinke.main.model.db.BudgetItem;
|
||||
import mjkf.xinke.main.model.db.LocalMaterial;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class BudgetDetail{
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer amount;
|
||||
|
||||
@JsonProperty(value = "min_amount")
|
||||
private Integer minAmount;
|
||||
|
||||
@JsonProperty(value = "max_amount")
|
||||
private Integer maxAmount;
|
||||
|
||||
private LocalDate date;
|
||||
|
||||
private Integer year;
|
||||
|
||||
private List months;
|
||||
|
||||
private List<BudgetItem> list;
|
||||
|
||||
public BudgetDetail() {}
|
||||
|
||||
public BudgetDetail(Budget data, List<BudgetItem> list) {
|
||||
this.id = data.getId();
|
||||
this.name = data.getName();
|
||||
this.amount = data.getAmount();
|
||||
this.minAmount = data.getMinAmount();
|
||||
this.maxAmount = data.getMaxAmount();
|
||||
this.date = data.getDate();
|
||||
this.year = data.getYear();
|
||||
this.months = data.getMonths();
|
||||
this.list = list;
|
||||
}
|
||||
}
|
12
src/main/java/mjkf/xinke/main/service/BudgetItemService.java
Normal file
12
src/main/java/mjkf/xinke/main/service/BudgetItemService.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package mjkf.xinke.main.service;
|
||||
|
||||
import mjkf.xinke.main.model.db.BudgetItem;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BudgetItemService extends ServiceImpl<BaseMapper<BudgetItem>, BudgetItem> {
|
||||
|
||||
}
|
||||
|
12
src/main/java/mjkf/xinke/main/service/BudgetService.java
Normal file
12
src/main/java/mjkf/xinke/main/service/BudgetService.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package mjkf.xinke.main.service;
|
||||
|
||||
import mjkf.xinke.main.model.db.Budget;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BudgetService extends ServiceImpl<BaseMapper<Budget>, Budget> {
|
||||
|
||||
}
|
||||
|
@@ -4,8 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import mjkf.xinke.main.model.db.PricePublish;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import mjkf.xinke.main.model.vo.BudgetCreateRequest;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class PricePublishService extends ServiceImpl<BaseMapper<PricePublish>, PricePublish> {
|
||||
|
||||
@@ -28,5 +33,24 @@ public class PricePublishService extends ServiceImpl<BaseMapper<PricePublish>, P
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapper getQuery(BudgetCreateRequest params) {
|
||||
var query = new LambdaQueryWrapper<PricePublish>();
|
||||
query.eq(PricePublish::getYear, params.getYear());
|
||||
query.in(PricePublish::getMonth, params.getMonths());
|
||||
query.in(PricePublish::getName, params.getItems().stream().map(item -> item.getName()).collect(Collectors.toList()));
|
||||
// query.in(PricePublish::getMaterialId, params.getItems().stream().map(item -> item.getId()).collect(Collectors.toList()));
|
||||
return query;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getPriceMapEntryByMaterialIdAndMonth(LambdaQueryWrapper<PricePublish> query) {
|
||||
var result = new HashMap<String, Integer>();
|
||||
var items = this.list(query);
|
||||
for (PricePublish item: items) {
|
||||
var key = item.getName() + item.getMonth().toString();
|
||||
result.put(key, item.getPrice().intValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user