投标管理模块

This commit is contained in:
2025-08-21 00:55:47 +08:00
parent 27dd36749b
commit f031c7ba4c
22 changed files with 518 additions and 119 deletions

View File

@ -1,26 +1,24 @@
package org.dromara.bidding.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.bidding.domain.bo.BusBiddingLimitListBo;
import org.dromara.bidding.domain.vo.BusBiddingLimitListVo;
import org.dromara.bidding.service.IBusBiddingLimitListService;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.bidding.domain.vo.BusBiddingLimitListVo;
import org.dromara.bidding.domain.bo.BusBiddingLimitListBo;
import org.dromara.bidding.service.IBusBiddingLimitListService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 成本-投标
@ -39,10 +37,37 @@ public class BusBiddingLimitListController extends BaseController {
/**
* 查询成本-投标列表
*/
@SaCheckPermission("bidding:biddingLimitList:list")
@GetMapping("/list")
public TableDataInfo<BusBiddingLimitListVo> list(BusBiddingLimitListBo bo, PageQuery pageQuery) {
return busBiddingLimitListService.queryPageList(bo, pageQuery);
// @SaCheckPermission("bidding:biddingLimitList:list")
// @GetMapping("/list")
// public TableDataInfo<BusBiddingLimitListVo> list(BusBiddingLimitListBo bo, PageQuery pageQuery) {
// return busBiddingLimitListService.queryPageList(bo, pageQuery);
// }
/**
* 查询成本-投标列表
*/
@SaCheckPermission("bidding:biddingLimitList:getTree")
@GetMapping("/getTree")
public R<List<BusBiddingLimitListVo>> getTree(BusBiddingLimitListBo bo) {
return R.ok(busBiddingLimitListService.getTree(bo));
}
/**
* 获取所有版本号
*/
@SaCheckPermission("bidding:biddingLimitList:obtainAllVersionNumbers")
@GetMapping("/obtainAllVersionNumbers")
public R<List<String>> obtainAllVersionNumbers(BusBiddingLimitListBo bo) {
return R.ok(busBiddingLimitListService.obtainAllVersionNumbers(bo));
}
/**
* 获取指定版本的sheet
*/
@SaCheckPermission("bidding:biddingLimitList:sheetList")
@GetMapping("/sheetList")
public R<List<String>> sheetList(BusBiddingLimitListBo bo) {
return R.ok(busBiddingLimitListService.sheetList(bo));
}
/**
@ -56,6 +81,17 @@ public class BusBiddingLimitListController extends BaseController {
ExcelUtil.exportExcel(list, "成本-投标", BusBiddingLimitListVo.class, response);
}
/**
* 导入成本-投标excel
*/
@SaCheckPermission("bidding:biddingLimitList:importExcelFile")
@Log(title = "成本-投标", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/importExcelFile")
public R<Void> importExcelFile(Long projectId, @RequestParam("file") MultipartFile file) {
return toAjax(busBiddingLimitListService.importExcelFile(projectId, file));
}
/**
* 获取成本-投标详细信息
*
@ -64,20 +100,20 @@ public class BusBiddingLimitListController extends BaseController {
@SaCheckPermission("bidding:biddingLimitList:query")
@GetMapping("/{id}")
public R<BusBiddingLimitListVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
@PathVariable Long id) {
return R.ok(busBiddingLimitListService.queryById(id));
}
/**
* 新增成本-投标
*/
@SaCheckPermission("bidding:biddingLimitList:add")
@Log(title = "成本-投标", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BusBiddingLimitListBo bo) {
return toAjax(busBiddingLimitListService.insertByBo(bo));
}
// @SaCheckPermission("bidding:biddingLimitList:add")
// @Log(title = "成本-投标", businessType = BusinessType.INSERT)
// @RepeatSubmit()
// @PostMapping()
// public R<Void> add(@Validated(AddGroup.class) @RequestBody BusBiddingLimitListBo bo) {
// return toAjax(busBiddingLimitListService.insertByBo(bo));
// }
/**
* 修改成本-投标
@ -95,11 +131,11 @@ public class BusBiddingLimitListController extends BaseController {
*
* @param ids 主键串
*/
@SaCheckPermission("bidding:biddingLimitList:remove")
@Log(title = "成本-投标", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(busBiddingLimitListService.deleteWithValidByIds(List.of(ids), true));
}
// @SaCheckPermission("bidding:biddingLimitList:remove")
// @Log(title = "成本-投标", businessType = BusinessType.DELETE)
// @DeleteMapping("/{ids}")
// public R<Void> remove(@NotEmpty(message = "主键不能为空")
// @PathVariable Long[] ids) {
// return toAjax(busBiddingLimitListService.deleteWithValidByIds(List.of(ids), true));
// }
}

View File

@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
@ -41,8 +43,17 @@ public class BusBiddingUserController extends BaseController {
*/
@SaCheckPermission("bidding:biddingUser:list")
@GetMapping("/list")
public TableDataInfo<BusBiddingUserVo> list(BusBiddingUserBo bo, PageQuery pageQuery) {
return busBiddingUserService.queryPageList(bo, pageQuery);
public R<BusBiddingUserVo> list(BusBiddingUserBo bo) {
return R.ok(busBiddingUserService.getPersonnel(bo));
}
/**
* 查询招投标人员列表
*/
@SaCheckPermission("bidding:biddingUser:getUser")
@GetMapping("/getUser")
public R<List<SysUser>> getUser() {
return R.ok(busBiddingUserService.getUser());
}
/**
@ -75,7 +86,7 @@ public class BusBiddingUserController extends BaseController {
@Log(title = "招投标人员", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BusBiddingUserBo bo) {
public R<Void> add(@RequestBody BusBiddingUserBo bo) {
return toAjax(busBiddingUserService.insertByBo(bo));
}

View File

@ -6,6 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.math.BigDecimal;
/**
* 成本-投标对象 bus_bidding_limit_list
@ -75,12 +76,12 @@ public class BusBiddingLimitList extends BaseEntity {
/**
* 数量
*/
private Long quantity;
private BigDecimal quantity;
/**
* 单价
*/
private Long unitPrice;
private BigDecimal unitPrice;
/**
* 备注

View File

@ -4,6 +4,9 @@ import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
@ -47,12 +50,12 @@ public class BusListOfWinningBids extends BaseEntity {
/**
* 中标价(原币)
*/
private Long winningBidOriginal;
private BigDecimal winningBidOriginal;
/**
* 汇率
*/
private Long exchangeRate;
private BigDecimal exchangeRate;
/**
* 币种
@ -67,17 +70,17 @@ public class BusListOfWinningBids extends BaseEntity {
/**
* 中标价
*/
private Long winningBid;
private BigDecimal winningBid;
/**
* 中标日期
*/
private Date bidWinningDate;
private LocalDate bidWinningDate;
/**
* 投标保证金
*/
private Long bidDeposit;
private BigDecimal bidDeposit;
/**
* 是否退还
@ -92,7 +95,7 @@ public class BusListOfWinningBids extends BaseEntity {
/**
* 总造价
*/
private Long totalCost;
private BigDecimal totalCost;
/**
* 立项申请人
@ -107,7 +110,7 @@ public class BusListOfWinningBids extends BaseEntity {
/**
* 立项申请日期
*/
private Date projectApplicantTime;
private LocalDate projectApplicantTime;
/**
* 流程状态

View File

@ -9,6 +9,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
/**
* 成本-投标业务对象 bus_bidding_limit_list
*
@ -76,12 +78,12 @@ public class BusBiddingLimitListBo extends BaseEntity {
/**
* 数量
*/
private Long quantity;
private BigDecimal quantity;
/**
* 单价
*/
private Long unitPrice;
private BigDecimal unitPrice;
/**
* 备注

View File

@ -8,6 +8,9 @@ import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
@ -47,12 +50,12 @@ public class BusListOfWinningBidsBo extends BaseEntity {
/**
* 中标价(原币)
*/
private Long winningBidOriginal;
private BigDecimal winningBidOriginal;
/**
* 汇率
*/
private Long exchangeRate;
private BigDecimal exchangeRate;
/**
* 币种
@ -67,17 +70,17 @@ public class BusListOfWinningBidsBo extends BaseEntity {
/**
* 中标价
*/
private Long winningBid;
private BigDecimal winningBid;
/**
* 中标日期
*/
private Date bidWinningDate;
private LocalDate bidWinningDate;
/**
* 投标保证金
*/
private Long bidDeposit;
private BigDecimal bidDeposit;
/**
* 是否退还
@ -92,7 +95,7 @@ public class BusListOfWinningBidsBo extends BaseEntity {
/**
* 总造价
*/
private Long totalCost;
private BigDecimal totalCost;
/**
* 立项申请人
@ -107,7 +110,7 @@ public class BusListOfWinningBidsBo extends BaseEntity {
/**
* 立项申请日期
*/
private Date projectApplicantTime;
private LocalDate projectApplicantTime;
/**
* 流程状态

View File

@ -7,11 +7,14 @@ import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
@ -92,13 +95,18 @@ public class BusBiddingLimitListVo implements Serializable {
* 数量
*/
@ExcelProperty(value = "数量")
private Long quantity;
private BigDecimal quantity;
/**
* 单价
*/
@ExcelProperty(value = "单价")
private Long unitPrice;
private BigDecimal unitPrice;
/**
* 总价
*/
private BigDecimal price;
/**
* 备注
@ -107,4 +115,9 @@ public class BusBiddingLimitListVo implements Serializable {
private String remark;
/**
* 子节点
*/
private List<BusBiddingLimitListVo> children = new ArrayList<>();
}

View File

@ -1,5 +1,7 @@
package org.dromara.bidding.domain.vo;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.bidding.domain.BusListOfWinningBids;
@ -57,15 +59,14 @@ public class BusListOfWinningBidsVo implements Serializable {
/**
* 中标价(原币)
*/
@ExcelProperty(value = "中标价", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "原=币")
private Long winningBidOriginal;
@ExcelProperty(value = "中标价(原币)", converter = ExcelDictConvert.class)
private BigDecimal winningBidOriginal;
/**
* 汇率
*/
@ExcelProperty(value = "汇率")
private Long exchangeRate;
private BigDecimal exchangeRate;
/**
* 币种
@ -83,19 +84,19 @@ public class BusListOfWinningBidsVo implements Serializable {
* 中标价
*/
@ExcelProperty(value = "中标价")
private Long winningBid;
private BigDecimal winningBid;
/**
* 中标日期
*/
@ExcelProperty(value = "中标日期")
private Date bidWinningDate;
private LocalDate bidWinningDate;
/**
* 投标保证金
*/
@ExcelProperty(value = "投标保证金")
private Long bidDeposit;
private BigDecimal bidDeposit;
/**
* 是否退还
@ -114,7 +115,7 @@ public class BusListOfWinningBidsVo implements Serializable {
* 总造价
*/
@ExcelProperty(value = "总造价")
private Long totalCost;
private BigDecimal totalCost;
/**
* 立项申请人
@ -132,7 +133,7 @@ public class BusListOfWinningBidsVo implements Serializable {
* 立项申请日期
*/
@ExcelProperty(value = "立项申请日期")
private Date projectApplicantTime;
private LocalDate projectApplicantTime;
/**
* 流程状态

View File

@ -7,6 +7,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
import java.util.List;
@ -67,4 +69,17 @@ public interface IBusBiddingLimitListService extends IService<BusBiddingLimitLis
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 查询成本-投标表返树形结构数据
* @param bo
* @return
*/
List<BusBiddingLimitListVo> getTree(BusBiddingLimitListBo bo);
Boolean importExcelFile(Long projectId, MultipartFile file);
List<String> obtainAllVersionNumbers(BusBiddingLimitListBo bo);
List<String> sheetList(BusBiddingLimitListBo bo);
}

View File

@ -7,6 +7,9 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import java.util.Collection;
import java.util.List;
@ -67,4 +70,12 @@ public interface IBusBiddingUserService extends IService<BusBiddingUser>{
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 获取部门下用户
* @return
*/
List<SysUser> getUser();
BusBiddingUserVo getPersonnel(BusBiddingUserBo bo);
}

View File

@ -1,24 +1,32 @@
package org.dromara.bidding.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.dromara.bidding.domain.BusBiddingLimitList;
import org.dromara.bidding.domain.bo.BusBiddingLimitListBo;
import org.dromara.bidding.domain.vo.BusBiddingLimitListVo;
import org.dromara.bidding.domain.BusBiddingLimitList;
import org.dromara.bidding.mapper.BusBiddingLimitListMapper;
import org.dromara.bidding.service.IBusBiddingLimitListService;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.utils.excel.ExcelDynamicReader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
* 成本-投标Service业务层处理
@ -26,12 +34,11 @@ import java.util.Collection;
* @author Lion Li
* @date 2025-08-20
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitListMapper, BusBiddingLimitList> implements IBusBiddingLimitListService {
private final BusBiddingLimitListMapper baseMapper;
/**
* 查询成本-投标
*
@ -39,7 +46,7 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
* @return 成本-投标
*/
@Override
public BusBiddingLimitListVo queryById(Long id){
public BusBiddingLimitListVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
@ -120,7 +127,7 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BusBiddingLimitList entity){
private void validEntityBeforeSave(BusBiddingLimitList entity) {
//TODO 做一些数据校验,如唯一约束
}
@ -133,9 +140,119 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public List<BusBiddingLimitListVo> getTree(BusBiddingLimitListBo bo) {
//获取所有数据
List<BusBiddingLimitListVo> listVoList = queryList(bo);
//过滤数量和单价为空的数据并计算总价
listVoList.stream().filter(vo -> vo.getUnitPrice() != null && vo.getUnitPrice().compareTo(BigDecimal.ZERO) != 0)
.filter(vo -> vo.getQuantity() != null && vo.getQuantity().compareTo(BigDecimal.ZERO) != 0)
.forEach(item -> {
item.setPrice(item.getUnitPrice().multiply(item.getQuantity()).setScale(2, RoundingMode.HALF_UP));
});
//构建父子映射
Map<String, List<BusBiddingLimitListVo>> parentMap = listVoList.stream()
.collect(Collectors.groupingBy(BusBiddingLimitListVo::getPid));
//递归组装树形结构
List<BusBiddingLimitListVo> treeList = buildTree("0", parentMap);
return treeList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean importExcelFile(Long projectId, MultipartFile file) {
// 跳过1行表头读取0到6列共7列映射到ExcelData实体类
List<BusBiddingLimitListBo> dataList = null;
try {
dataList = ExcelDynamicReader.readExcel(
file, // 上传的文件
1, // 跳过1行表头
0, // 从第0列开始
12, // 到第12列结束
BusBiddingLimitListBo.class // 目标实体类
);
} catch (Exception e) {
throw new RuntimeException("文件错误" + e.getMessage());
}
List<BusBiddingLimitList> busBillofquantities = new ArrayList<>();
List<BusBiddingLimitListBo> stream = dataList.stream()
.filter(Objects::nonNull) // 过滤掉 null 对象
.filter(data -> data.getUnitPrice() != null && data.getUnitPrice().compareTo(BigDecimal.ZERO) != 0)
.filter(data -> data.getQuantity() != null && data.getQuantity().compareTo(BigDecimal.ZERO) != 0)
.toList();
if (CollUtil.isEmpty(stream)) {
throw new ServiceException("表格中无有效数据", HttpStatus.BAD_REQUEST);
}
stream.forEach(item -> {
BusBiddingLimitList limitList = new BusBiddingLimitList();
limitList.setId(item.getId());
limitList.setProjectId(item.getProjectId());
limitList.setUnitPrice(item.getUnitPrice());
busBillofquantities.add(limitList);
});
log.info(busBillofquantities.toString());
return this.updateBatchById(busBillofquantities);
}
@Override
public List<String> obtainAllVersionNumbers(BusBiddingLimitListBo bo) {
List<BusBiddingLimitList> busBiddingLimitLists = baseMapper.selectList(new LambdaQueryWrapper<BusBiddingLimitList>()
.select(BusBiddingLimitList::getVersions)
.eq(bo.getProjectId() != null, BusBiddingLimitList::getProjectId, bo.getProjectId())
.orderByDesc(BusBiddingLimitList::getCreateTime)
.groupBy(BusBiddingLimitList::getVersions));
return busBiddingLimitLists.stream()
.filter(Objects::nonNull)
.map(BusBiddingLimitList::getVersions)
.collect(Collectors.toList());
}
@Override
public List<String> sheetList(BusBiddingLimitListBo bo) {
List<BusBiddingLimitList> busBiddingLimitLists = baseMapper.selectList(new LambdaQueryWrapper<BusBiddingLimitList>()
.select(BusBiddingLimitList::getSheet)
.eq(bo.getProjectId() != null, BusBiddingLimitList::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getVersions()), BusBiddingLimitList::getVersions, bo.getVersions())
.orderByAsc(BusBiddingLimitList::getSheet)
.groupBy(BusBiddingLimitList::getSheet));
return busBiddingLimitLists.stream()
.filter(Objects::nonNull)
.map(BusBiddingLimitList::getSheet)
.collect(Collectors.toList());
}
/**
* 递归构建树形结构
*
* @param parentId 父节点ID顶级节点为0
* @param parentMap 父子映射表key=pidvalue=子节点列表)
* @return 组装好的子树列表
*/
private List<BusBiddingLimitListVo> buildTree(String parentId, Map<String, List<BusBiddingLimitListVo>> parentMap) {
// 获取当前父节点的所有直接子节点
List<BusBiddingLimitListVo> children = parentMap.getOrDefault(parentId, Collections.emptyList());
if (children.isEmpty()) {
return Collections.emptyList();
}
// 为每个子节点递归设置其下一级子节点
for (BusBiddingLimitListVo child : children) {
// 递归查询当前子节点的子节点,设置为它的子树
List<BusBiddingLimitListVo> subChildren = buildTree(child.getSid(), parentMap);
// 注意需要在Vo中添加子节点列表字段用于存储子树
child.setChildren(subChildren);
}
return children;
}
}

View File

@ -1,6 +1,7 @@
package org.dromara.bidding.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.checkerframework.checker.units.qual.A;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@ -9,6 +10,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.dromara.bidding.domain.bo.BusBiddingUserBo;
import org.dromara.bidding.domain.vo.BusBiddingUserVo;
@ -31,6 +36,8 @@ import java.util.Collection;
public class BusBiddingUserServiceImpl extends ServiceImpl<BusBiddingUserMapper, BusBiddingUser> implements IBusBiddingUserService {
private final BusBiddingUserMapper baseMapper;
@Autowired
private ISysUserService sysUserService;
/**
* 查询招投标人员
@ -87,6 +94,13 @@ public class BusBiddingUserServiceImpl extends ServiceImpl<BusBiddingUserMapper,
*/
@Override
public Boolean insertByBo(BusBiddingUserBo bo) {
if (bo.getId() != null) {
return updateByBo(bo);
}
return add(bo);
}
private boolean add(BusBiddingUserBo bo) {
BusBiddingUser add = MapstructUtils.convert(bo, BusBiddingUser.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
@ -130,4 +144,14 @@ public class BusBiddingUserServiceImpl extends ServiceImpl<BusBiddingUserMapper,
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public List<SysUser> getUser() {
return sysUserService.findThis();
}
@Override
public BusBiddingUserVo getPersonnel(BusBiddingUserBo bo) {
return baseMapper.selectVoOne(new LambdaQueryWrapper<BusBiddingUser>().eq(BusBiddingUser::getProjectId, bo.getProjectId()));
}
}

View File

@ -90,7 +90,7 @@ public class BusBillofquantitiesLimitListController extends BaseController {
/**
* 导入excel
*/
@SaCheckPermission("design:billofquantitiesLimitList:importExcelFile")
@SaCheckPermission("tender:billofquantitiesLimitList:importExcelFile")
@Log(title = "导入excel", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/importExcelFile")

View File

@ -8,6 +8,7 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo;
import org.dromara.tender.domain.TenderPlanFile;
import org.dromara.tender.service.impl.TenderPlanFileServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
@ -58,6 +59,18 @@ public class BusSegmentedIndicatorPlanningController extends BaseController {
return busSegmentedIndicatorPlanningService.queryPageList(bo, pageQuery);
}
@SaCheckPermission("tender:segmentedIndicatorPlanning:getMore")
@GetMapping("/getMore")
public R<List<BusBillofquantitiesLimitListVo>> getMore(BusSegmentedIndicatorPlanningBo bo) {
// if (bo.getProjectId() == null) {
// throw new ServiceException("项目id不能为空");
// }
if (bo.getId() == null) {
throw new ServiceException("id不能为空");
}
return R.ok(busSegmentedIndicatorPlanningService.getMore(bo));
}
/**
* 导出分标策划列表
*/

View File

@ -35,7 +35,7 @@ public class BusSegmentedIndicatorPlanningBo extends BaseEntity {
* 项目Id
*/
// @NotNull(message = "项目Id不能为空", groups = { AddGroup.class, EditGroup.class })
// private Long projectId;
private Long projectId;
/**

View File

@ -1,9 +1,12 @@
package org.dromara.tender.mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.tender.domain.BusBillofquantitiesLimitList;
import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
/**
* 限价一览Mapper接口
*
@ -12,4 +15,6 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
*/
public interface BusBillofquantitiesLimitListMapper extends BaseMapperPlus<BusBillofquantitiesLimitList, BusBillofquantitiesLimitListVo> {
List<BusBillofquantitiesLimitListVo> selectListBySids(@Param("sids") List<String> sids);
}

View File

@ -94,4 +94,6 @@ public interface IBusBillofquantitiesLimitListService extends IService<BusBillof
* @return
*/
Boolean importExcelFile(Long id, MultipartFile file) throws Exception;
List<BusBillofquantitiesLimitListVo> getListByIds(List<Long> ids);
}

View File

@ -1,5 +1,6 @@
package org.dromara.tender.service;
import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo;
import org.dromara.tender.domain.vo.BusSegmentedIndicatorPlanningVo;
import org.dromara.tender.domain.bo.BusSegmentedIndicatorPlanningBo;
import org.dromara.tender.domain.BusSegmentedIndicatorPlanning;
@ -69,4 +70,6 @@ public interface IBusSegmentedIndicatorPlanningService extends IService<BusSegme
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<BusBillofquantitiesLimitListVo> getMore(BusSegmentedIndicatorPlanningBo bo);
}

View File

@ -79,7 +79,7 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill
private LambdaQueryWrapper<BusBillofquantitiesLimitList> buildQueryWrapper(BusBillofquantitiesLimitListBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BusBillofquantitiesLimitList> lqw = Wrappers.lambdaQuery();
lqw.orderByDesc(BusBillofquantitiesLimitList::getId);
// lqw.orderByDesc(BusBillofquantitiesLimitList::getId);
lqw.eq(bo.getProjectId() != null, BusBillofquantitiesLimitList::getProjectId, bo.getProjectId());
lqw.eq(StringUtils.isNotBlank(bo.getVersions()), BusBillofquantitiesLimitList::getVersions, bo.getVersions());
lqw.eq(StringUtils.isNotBlank(bo.getSheet()), BusBillofquantitiesLimitList::getSheet, bo.getSheet());
@ -90,8 +90,7 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill
lqw.eq(StringUtils.isNotBlank(bo.getSpecification()), BusBillofquantitiesLimitList::getSpecification, bo.getSpecification());
lqw.eq(StringUtils.isNotBlank(bo.getUnit()), BusBillofquantitiesLimitList::getUnit, bo.getUnit());
lqw.eq(bo.getQuantity() != null, BusBillofquantitiesLimitList::getQuantity, bo.getQuantity());
// lqw.eq(bo.getUnitPrice() != null, BusBillofquantitiesLimitList::getUnitPrice, bo.getUnitPrice());
// lqw.eq(bo.getPrice() != null, BusBillofquantitiesLimitList::getPrice, bo.getPrice());
lqw.orderByAsc(BusBillofquantitiesLimitList::getSid);
return lqw;
}
@ -120,9 +119,6 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill
*/
@Override
public Boolean updateByBo(BusBillofquantitiesLimitListBo bo) {
// if (bo.getUnitPrice() != null && bo.getQuantity() != null) {
// bo.setPrice(bo.getUnitPrice().multiply(bo.getQuantity()).setScale(2, RoundingMode.HALF_UP));
// }
BusBillofquantitiesLimitList update = MapstructUtils.convert(bo, BusBillofquantitiesLimitList.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
@ -154,6 +150,7 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill
public List<BusBillofquantitiesLimitListVo> getTree(BusBillofquantitiesLimitListBo bo) {
//获取所有数据
List<BusBillofquantitiesLimitListVo> listVoList = queryList(bo);
//过滤数量和单价为空的数据并计算总价
listVoList.stream().filter(vo -> vo.getUnitPrice() !=null && vo.getUnitPrice().compareTo(BigDecimal.ZERO) != 0)
.filter(vo ->vo.getQuantity() !=null && vo.getQuantity().compareTo(BigDecimal.ZERO) != 0)
.forEach(item -> {
@ -211,32 +208,31 @@ public class BusBillofquantitiesLimitListServiceImpl extends ServiceImpl<BusBill
List<BusBillofquantitiesLimitList> busBillofquantities = new ArrayList<BusBillofquantitiesLimitList>();
dataList.stream()
.filter(Objects::nonNull) // 过滤掉 null 对象
.filter(data-> data.getUnitPrice() !=null && data.getUnitPrice().compareTo(BigDecimal.ZERO) != 0)
.filter(data ->data.getQuantity() !=null && data.getQuantity().compareTo(BigDecimal.ZERO) != 0)
.filter(data-> data.getUnitPrice() !=null && data.getUnitPrice().compareTo(BigDecimal.ZERO) != 0)//过滤单价为空的数据
.filter(data ->data.getQuantity() !=null && data.getQuantity().compareTo(BigDecimal.ZERO) != 0)//过滤数量为空的数据
.forEach(item -> {
BusBillofquantitiesLimitList limitList = new BusBillofquantitiesLimitList();
limitList.setId(item.getId());
limitList.setProjectId(item.getProjectId());
limitList.setProjectId(id);
limitList.setUnitPrice(item.getUnitPrice());
busBillofquantities.add(limitList);
});
// //1、获取到解析数据
// ExcelReader.ExcelData excelData = ExcelReader.readExcelFromMultipartFile(file);
// // 2. 解析所有工作表转换为带父子关系的ExcelMaterial列表 解析所有Sheet数据按规则生成sid和pid
// List<BusBillofquantitiesLimitList> allMaterials = new ArrayList<>();
// for (ExcelReader.SheetData sheetData : excelData.getSheetDataList()) {
//// String sheetName = sheetData.getSheetName();
// List<List<String>> rowDataList = sheetData.getData();
//
// //获取字段为id和单价
// List<BusBillofquantitiesLimitList> limitListArrayList = new ArrayList<>();
//
// }
return baseMapper.updateBatchById(busBillofquantities);
}
@Override
public List<BusBillofquantitiesLimitListVo> getListByIds(List<Long> ids) {
List<BusBillofquantitiesLimitList> limitListList = baseMapper.selectBatchIds(ids);
List<String> sids = new ArrayList<>();
limitListList.forEach(item -> {
sids.add(item.getSid());
});
List<BusBillofquantitiesLimitListVo> listVoList = baseMapper.selectListBySids(sids);
return listVoList;
}
/**
* 递归构建树形结构
* @param parentId 父节点ID顶级节点为0

View File

@ -10,6 +10,13 @@ import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.tender.domain.BusBillofquantitiesLimitList;
import org.dromara.tender.domain.BusIndicatorPlanningLimitList;
import org.dromara.tender.domain.BusSegmentedIndicatorPlanning;
import org.dromara.tender.domain.bo.BusIndicatorPlanningLimitListBo;
@ -22,13 +29,17 @@ import org.dromara.tender.service.IBusBillofquantitiesLimitListService;
import org.dromara.tender.service.IBusSegmentedIndicatorPlanningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.dromara.tender.domain.bo.BusSegmentedIndicatorPlanningBo;
import org.dromara.tender.domain.vo.BusSegmentedIndicatorPlanningVo;
import org.dromara.tender.domain.BusSegmentedIndicatorPlanning;
import org.dromara.tender.mapper.BusSegmentedIndicatorPlanningMapper;
import org.dromara.tender.service.IBusSegmentedIndicatorPlanningService;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
* 分标策划Service业务层处理
@ -53,7 +64,7 @@ public class BusSegmentedIndicatorPlanningServiceImpl extends ServiceImpl<BusSeg
* @return 分标策划
*/
@Override
public BusSegmentedIndicatorPlanningVo queryById(Long id) {
public BusSegmentedIndicatorPlanningVo queryById(Long id){
return baseMapper.selectVoById(id);
}
@ -111,6 +122,7 @@ public class BusSegmentedIndicatorPlanningServiceImpl extends ServiceImpl<BusSeg
if (flag) {
bo.setId(add.getId());
if (bo.getLimitListBos() != null && !bo.getLimitListBos().isEmpty()) {
//生成分标策划-限价一览对象集合
List<BusIndicatorPlanningLimitList> planningLimitListList = new ArrayList<>();
for (BusIndicatorPlanningLimitListBo limitListBo : bo.getLimitListBos()) {
BusIndicatorPlanningLimitList busIndicatorPlanningLimitList = new BusIndicatorPlanningLimitList();
@ -121,11 +133,13 @@ public class BusSegmentedIndicatorPlanningServiceImpl extends ServiceImpl<BusSeg
if (busBillofquantitiesLimitListVo == null) {
throw new ServiceException("限价一览数据不存在");
}
if (busBillofquantitiesLimitListVo.getQuantity().compareTo(limitListBo.getNum().add(count)) < 0) {
throw new ServiceException(busBillofquantitiesLimitListVo.getName() + "数量超过了总数量");
if (busBillofquantitiesLimitListVo.getQuantity().compareTo(limitListBo.getNum().add(count !=null ? count: BigDecimal.valueOf(0))) < 0) {
throw new ServiceException(busBillofquantitiesLimitListVo.getName()+"数量超过了总数量");
}
busIndicatorPlanningLimitList.setNum(limitListBo.getNum());
planningLimitListList.add(busIndicatorPlanningLimitList);
}
//批量新增
indicatorPlanningLimitListMapper.insertBatch(planningLimitListList);
}
}
@ -200,10 +214,77 @@ public class BusSegmentedIndicatorPlanningServiceImpl extends ServiceImpl<BusSeg
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
//删除子表数据
for (Long id : ids) {
indicatorPlanningLimitListMapper.delete(new LambdaQueryWrapper<BusIndicatorPlanningLimitList>()
.eq(BusIndicatorPlanningLimitList::getSegmentedIndicatorId, id));
}
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public List<BusBillofquantitiesLimitListVo> getMore(BusSegmentedIndicatorPlanningBo bo) {
List<BusIndicatorPlanningLimitList> planningLimitListList = indicatorPlanningLimitListMapper.selectList(new LambdaQueryWrapper<BusIndicatorPlanningLimitList>()
.eq(BusIndicatorPlanningLimitList::getSegmentedIndicatorId, bo.getId()));
List<Long> ids = new ArrayList<>();
for (BusIndicatorPlanningLimitList planningLimitList : planningLimitListList) {
ids.add(planningLimitList.getLimitListId());
}
List<BusBillofquantitiesLimitListVo> billofquantitiesLimitListList = busBillofquantitiesLimitListService.getListByIds(ids);
List<BusBillofquantitiesLimitListVo> list = billofquantitiesLimitListList.stream().distinct().collect(Collectors.toList());
for (BusBillofquantitiesLimitListVo limitList : list) {
for (BusIndicatorPlanningLimitList limitList1 : planningLimitListList) {
if (limitList.getId().equals(limitList1.getLimitListId())){
limitList.setQuantity(limitList1.getNum());
if (limitList.getUnitPrice() != null && limitList.getQuantity() != null) {
limitList.setPrice(limitList.getUnitPrice().multiply(limitList.getQuantity()).setScale(2, RoundingMode.HALF_UP));
}
break;
}
}
}
// List<BusBillofquantitiesLimitListVo> list = new ArrayList<>();
// list1.forEach(item -> {
// list.add(MapstructUtils.convert(item, BusBillofquantitiesLimitListVo.class));
// });
//构建父子映射
Map<String, List<BusBillofquantitiesLimitListVo>> parentMap = list.stream()
.collect(Collectors.groupingBy(BusBillofquantitiesLimitListVo::getPid));
//递归组装树形结构
return buildTree("0", parentMap);
}
/**
* 递归构建树形结构
* @param parentId 父节点ID顶级节点为0
* @param parentMap 父子映射表key=pidvalue=子节点列表)
* @return 组装好的子树列表
*/
private List<BusBillofquantitiesLimitListVo> buildTree(String parentId, Map<String, List<BusBillofquantitiesLimitListVo>> parentMap) {
// 获取当前父节点的所有直接子节点
List<BusBillofquantitiesLimitListVo> children = parentMap.getOrDefault(parentId, Collections.emptyList());
if (children.isEmpty()) {
return Collections.emptyList();
}
// 为每个子节点递归设置其下一级子节点
for (BusBillofquantitiesLimitListVo child : children) {
// 递归查询当前子节点的子节点,设置为它的子树
List<BusBillofquantitiesLimitListVo> subChildren = buildTree(child.getSid(), parentMap);
// 注意需要在Vo中添加子节点列表字段用于存储子树
child.setChildren(subChildren);
}
return children;
}
}

View File

@ -4,4 +4,65 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.tender.mapper.BusBillofquantitiesLimitListMapper">
<resultMap id="BusBillofquantitiesLimitListVOResultMap" type="org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo">
<id column="id" property="id"/>
<result column="project_id" property="projectId"/>
<result column="versions" property="versions"/>
<result column="sheet" property="sheet"/>
<result column="sid" property="sid"/>
<result column="pid" property="pid"/>
<result column="num" property="num"/>
<result column="name" property="name"/>
<result column="specification" property="specification"/>
<result column="unit" property="unit"/>
<result column="quantity" property="quantity"/>
<result column="unit_price" property="unitPrice"/>
<result column="remark" property="remark"/>
</resultMap>
<select id="selectListBySids" resultType="org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo">
with recursive parent as (
select b.id as id,
b.project_id as projectId,
b.versions as versions,
b.sheet as sheet,
b.sid as sid,
b.pid as pid,
b.num as num,
b.name as name,
b.specification as specification,
b.unit as unit,
b.quantity as quantity,
b.unit_price as unitPrice,
b.remark as remark,
0 as level
from bus_billofquantities_limit_list b
where b.sid in
<foreach collection="sids" item="sid" separator="," open="(" close=")">
#{sid}
</foreach>
union all
select p.id as id,
p.project_id as projectId,
p.versions as versions,
p.sheet as sheet,
p.sid as sid,
p.pid as pid,
p.num as num,
p.name as name,
p.specification as specification,
p.unit as unit,
p.quantity as quantity,
p.unit_price as unitPrice,
p.remark as remark, parent.level + 1
from bus_billofquantities_limit_list p
inner join parent on p.sid = parent.pid
)
select *
from parent
ORDER BY level, sid
</select>
</mapper>

View File

@ -5,8 +5,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="org.dromara.tender.mapper.BusIndicatorPlanningLimitListMapper">
<select id="getLimitCoount" resultType="java.math.BigDecimal">
SELECT SUM("num") as num
SELECT CAST(
SUM( num ) AS DECIMAL ( 20, 2 )) as num
from bus_indicator_planning_limit_list
where id = #{limitListId}
where limit_list_id = #{limitListId}
</select>
</mapper>