施工产值导出,大图
This commit is contained in:
@ -25,7 +25,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
public class DashScopeChat {
|
||||
|
||||
@Resource
|
||||
private SimpleChat simpleChat;
|
||||
private DashScopeSimpleChat dashScopeSimpleChat;
|
||||
|
||||
@Resource
|
||||
private IAIChatMemoryService chatMemoryService;
|
||||
@ -66,10 +66,8 @@ public class DashScopeChat {
|
||||
.collectList()
|
||||
.flatMapMany(tokens -> {
|
||||
String aiResponse = String.join("", tokens);
|
||||
if (isFirst) {
|
||||
// 异步生成标题
|
||||
generateChatTitleAsync(chatId, message, aiResponse, userId);
|
||||
}
|
||||
// 返回完整的流结果
|
||||
return Flux.fromIterable(tokens);
|
||||
});
|
||||
@ -100,7 +98,7 @@ public class DashScopeChat {
|
||||
用户:%s
|
||||
AI:%s
|
||||
""", userMessage, aiResponse);
|
||||
String title = simpleChat.doChat(prompt);
|
||||
String title = dashScopeSimpleChat.doChat(prompt);
|
||||
log.info("用户:{} 生成标题成功:{} -> {}", userId, chatId, title);
|
||||
// 保存对话数据
|
||||
AIChatMemory memory = new AIChatMemory();
|
||||
|
||||
@ -9,11 +9,11 @@ import org.springframework.stereotype.Component;
|
||||
* @date 2025-11-04 15:26
|
||||
*/
|
||||
@Component
|
||||
public class SimpleChat {
|
||||
public class DashScopeSimpleChat {
|
||||
|
||||
private final ChatClient dashScopeChatClient;
|
||||
|
||||
public SimpleChat(ChatClient.Builder chatClientBuilder) {
|
||||
public DashScopeSimpleChat(ChatClient.Builder chatClientBuilder) {
|
||||
this.dashScopeChatClient = chatClientBuilder
|
||||
// 设置 ChatClient 中 ChatModel 的 Options 参数
|
||||
.defaultOptions(
|
||||
@ -41,7 +41,6 @@ import org.dromara.patch.service.IPdMasterService;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.system.domain.SysMenu;
|
||||
import org.dromara.system.domain.vo.RouterVo;
|
||||
import org.dromara.system.mapper.SysRoleMapper;
|
||||
import org.dromara.system.service.impl.SysMenuServiceImpl;
|
||||
import org.dromara.system.service.impl.SysUserServiceImpl;
|
||||
import org.dromara.warm.flow.core.FlowEngine;
|
||||
@ -97,7 +96,6 @@ public class PersonalHomeController extends BaseController {
|
||||
@Resource
|
||||
private IBusProjectService projectService;
|
||||
|
||||
private final SysRoleMapper roleMapper;
|
||||
private final SysMenuServiceImpl sysMenuService;
|
||||
|
||||
// region AI 模块
|
||||
|
||||
@ -18,7 +18,7 @@ import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueBo;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueFacilityReq;
|
||||
import org.dromara.out.domain.vo.OutConstructionAllValueVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueVo;
|
||||
import org.dromara.out.service.IOutConstructionValueService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -59,6 +59,16 @@ public class OutConstructionValueController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "施工产值", OutConstructionValueVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出施工产值范围列表
|
||||
*/
|
||||
@SaCheckPermission("out:constructionValue:export")
|
||||
@Log(title = "施工产值", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/exportByProject")
|
||||
public void exportByProject(OutConstructionValueBo bo, HttpServletResponse response) {
|
||||
outConstructionValueService.exportExcel(bo, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取施工产值详细信息
|
||||
*
|
||||
|
||||
@ -23,8 +23,8 @@ import org.dromara.out.domain.OutConstructionValue;
|
||||
import org.dromara.out.domain.OutConstructionValueRange;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueRangeBo;
|
||||
import org.dromara.out.domain.vo.OutConstructionAllValueRangeVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueRangeVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeVo;
|
||||
import org.dromara.out.service.IOutConstructionValueRangeService;
|
||||
import org.dromara.out.service.IOutConstructionValueService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@ -114,6 +114,16 @@ public class OutConstructionValueRangeController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出施工产值范围列表
|
||||
*/
|
||||
@SaCheckPermission("out:constructionValueRange:export")
|
||||
@Log(title = "施工产值范围", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/exportByProject")
|
||||
public void exportByProject(OutConstructionValueRangeBo bo, HttpServletResponse response) {
|
||||
outConstructionValueRangeService.exportExcel(bo, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取施工产值范围详细信息
|
||||
*
|
||||
|
||||
@ -0,0 +1,119 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvalue;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 15:46
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueCategoryVo {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 范围ID
|
||||
*/
|
||||
private Long rangeId;
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 方阵id
|
||||
*/
|
||||
private Long matrixId;
|
||||
|
||||
/**
|
||||
* 分项工程id
|
||||
*/
|
||||
private Long progressCategoryId;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计划详情id
|
||||
*/
|
||||
private Long detailId;
|
||||
|
||||
/**
|
||||
* 人工填报数量
|
||||
*/
|
||||
private Integer artificialNum;
|
||||
|
||||
/**
|
||||
* 无人机识别数量
|
||||
*/
|
||||
private Integer uavNum;
|
||||
|
||||
/**
|
||||
* 确认数量
|
||||
*/
|
||||
private Integer confirmNum;
|
||||
|
||||
/**
|
||||
* 计划数量
|
||||
*/
|
||||
private Integer planNum;
|
||||
|
||||
/**
|
||||
* 対乙产值
|
||||
*/
|
||||
private BigDecimal outValue;
|
||||
|
||||
/**
|
||||
* 上报日期
|
||||
*/
|
||||
private LocalDate reportDate;
|
||||
|
||||
/**
|
||||
* 计划日期
|
||||
*/
|
||||
private LocalDate planDate;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 方阵名称
|
||||
*/
|
||||
private String matrixName;
|
||||
|
||||
/**
|
||||
* 类别名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 计量单位
|
||||
*/
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 祖级列表
|
||||
*/
|
||||
private String ancestors;
|
||||
|
||||
/**
|
||||
* 关联结构(1子项目 2方阵 3项目)
|
||||
*/
|
||||
private String relevancyStructure;
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvalue;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 10:09
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueMatrixVo {
|
||||
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@ExcelProperty(value = "项目")
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 子项目名
|
||||
*/
|
||||
@ExcelProperty(value = "子项")
|
||||
private String subProjectName;
|
||||
|
||||
/**
|
||||
* 方阵名称
|
||||
*/
|
||||
@ExcelProperty(value = "方阵")
|
||||
private String matrixName;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
@ExcelProperty(value = "分部分项")
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private BigDecimal number;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对甲)")
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对乙)")
|
||||
private BigDecimal outValue;
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvalue;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 10:08
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueProjectVo {
|
||||
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@ExcelProperty(value = "项目")
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
@ExcelProperty(value = "分部分项")
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private BigDecimal number;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对甲)")
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对乙)")
|
||||
private BigDecimal outValue;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvalue;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 10:08
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueSubProjectVo {
|
||||
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@ExcelProperty(value = "项目")
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 子项目名
|
||||
*/
|
||||
@ExcelProperty(value = "子项")
|
||||
private String subProjectName;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
@ExcelProperty(value = "分部分项")
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private BigDecimal number;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对甲)")
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对乙)")
|
||||
private BigDecimal outValue;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.out.domain.vo;
|
||||
package org.dromara.out.domain.vo.outconstructionvalue;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
@ -0,0 +1,71 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvaluerange;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 11:31
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueRangeMatrixVo {
|
||||
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@ExcelProperty(value = "项目")
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 子项目名
|
||||
*/
|
||||
@ExcelProperty(value = "子项")
|
||||
private String subProjectName;
|
||||
|
||||
/**
|
||||
* 方阵名称
|
||||
*/
|
||||
@ExcelProperty(value = "方阵")
|
||||
private String matrixName;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
@ExcelProperty(value = "分部分项")
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private BigDecimal number;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对甲)")
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对乙)")
|
||||
private BigDecimal outValue;
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvaluerange;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 11:30
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueRangeProjectVo {
|
||||
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@ExcelProperty(value = "项目")
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
@ExcelProperty(value = "分部分项")
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private BigDecimal number;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对甲)")
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对乙)")
|
||||
private BigDecimal outValue;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.dromara.out.domain.vo.outconstructionvaluerange;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-12-01 11:30
|
||||
*/
|
||||
@Data
|
||||
public class OutConstructionValueRangeSubProjectVo {
|
||||
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@ExcelProperty(value = "项目")
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 子项目名
|
||||
*/
|
||||
@ExcelProperty(value = "子项")
|
||||
private String subProjectName;
|
||||
|
||||
/**
|
||||
* 分项工程名称
|
||||
*/
|
||||
@ExcelProperty(value = "分部分项")
|
||||
private String progressCategoryName;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private BigDecimal number;
|
||||
|
||||
/**
|
||||
* 对甲产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对甲)")
|
||||
private BigDecimal ownerValue;
|
||||
|
||||
/**
|
||||
* 产值
|
||||
*/
|
||||
@ExcelProperty(value = "金额(对乙)")
|
||||
private BigDecimal outValue;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.out.domain.vo;
|
||||
package org.dromara.out.domain.vo.outconstructionvaluerange;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
import org.dromara.out.domain.OutConstructionValueRange;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueVo;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@ -3,7 +3,7 @@ package org.dromara.out.mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.dromara.out.domain.OutConstructionValue;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.out.mapper;
|
||||
|
||||
import org.dromara.out.domain.OutConstructionValueRange;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueRangeVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
package org.dromara.out.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.out.domain.OutConstructionValueRange;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueRangeBo;
|
||||
import org.dromara.out.domain.vo.OutConstructionAllValueRangeVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueRangeVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -77,4 +78,12 @@ public interface IOutConstructionValueRangeService extends IService<OutConstruct
|
||||
* @return 所有施工范围产值
|
||||
*/
|
||||
OutConstructionAllValueRangeVo getAllValue(OutConstructionValueRangeBo bo);
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param response 响应
|
||||
*/
|
||||
void exportExcel(OutConstructionValueRangeBo bo, HttpServletResponse response);
|
||||
}
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
package org.dromara.out.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.out.domain.OutConstructionValue;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueBo;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueFacilityReq;
|
||||
import org.dromara.out.domain.vo.OutConstructionAllValueVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueCategoryVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueVo;
|
||||
import org.dromara.progress.domain.PgsProgressCategory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
@ -110,4 +113,23 @@ public interface IOutConstructionValueService extends IService<OutConstructionVa
|
||||
* @param list 列表
|
||||
*/
|
||||
void supplementaryData(List<OutConstructionValueVo> list);
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param response 响应
|
||||
*/
|
||||
void exportExcel(OutConstructionValueBo bo, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 构建导出需要的数据
|
||||
*
|
||||
* @param valueList 施工产值列表
|
||||
* @param valueCategoryList 进度类别列表
|
||||
* @param topList 顶层进度类别列表
|
||||
*/
|
||||
void buildExportData(List<OutConstructionValue> valueList,
|
||||
List<OutConstructionValueCategoryVo> valueCategoryList,
|
||||
List<PgsProgressCategory> topList);
|
||||
}
|
||||
|
||||
@ -2,19 +2,27 @@ package org.dromara.out.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
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 jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||
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.core.utils.file.FileUtils;
|
||||
import org.dromara.common.excel.convert.ExcelBigNumberConvert;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.out.domain.OutConstructionValue;
|
||||
@ -22,24 +30,36 @@ import org.dromara.out.domain.OutConstructionValueRange;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueBo;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueRangeBo;
|
||||
import org.dromara.out.domain.vo.OutConstructionAllValueRangeVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueRangeVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.OutConstructionValueCategoryVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeMatrixVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeProjectVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeSubProjectVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvaluerange.OutConstructionValueRangeVo;
|
||||
import org.dromara.out.mapper.OutConstructionValueRangeMapper;
|
||||
import org.dromara.out.service.IOutConstructionValueRangeService;
|
||||
import org.dromara.out.service.IOutConstructionValueService;
|
||||
import org.dromara.progress.domain.PgsProgressCategory;
|
||||
import org.dromara.progress.domain.PgsProgressPlanDetail;
|
||||
import org.dromara.progress.service.IPgsProgressCategoryService;
|
||||
import org.dromara.progress.service.IPgsProgressPlanDetailService;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 施工产值范围Service业务层处理
|
||||
@ -61,6 +81,9 @@ public class OutConstructionValueRangeServiceImpl extends ServiceImpl<OutConstru
|
||||
@Resource
|
||||
private IPgsProgressPlanDetailService progressPlanDetailService;
|
||||
|
||||
@Resource
|
||||
private IBusProjectService projectService;
|
||||
|
||||
/**
|
||||
* 获取指定日期所在的周数(根据中国周规则)
|
||||
*
|
||||
@ -126,7 +149,16 @@ public class OutConstructionValueRangeServiceImpl extends ServiceImpl<OutConstru
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<OutConstructionValueRange> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByDesc(OutConstructionValueRange::getId);
|
||||
lqw.eq(bo.getProjectId() != null, OutConstructionValueRange::getProjectId, bo.getProjectId());
|
||||
if (bo.getProjectId() != null) {
|
||||
// 获取当前项目的子项目
|
||||
List<BusProject> projects = projectService.lambdaQuery()
|
||||
.eq(BusProject::getPId, bo.getProjectId())
|
||||
.select(BusProject::getId)
|
||||
.list();
|
||||
List<Long> list = new ArrayList<>(projects.stream().map(BusProject::getId).toList());
|
||||
list.add(bo.getProjectId());
|
||||
lqw.in(OutConstructionValueRange::getProjectId, list);
|
||||
}
|
||||
// 日期范围过滤
|
||||
if (bo.getStartDate() != null) {
|
||||
// 获取本周的星期一
|
||||
@ -219,6 +251,354 @@ public class OutConstructionValueRangeServiceImpl extends ServiceImpl<OutConstru
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param response 响应
|
||||
*/
|
||||
@Override
|
||||
public void exportExcel(OutConstructionValueRangeBo bo, HttpServletResponse response) {
|
||||
Long projectId = bo.getProjectId();
|
||||
if (projectId == null) {
|
||||
throw new ServiceException("请选择项目");
|
||||
}
|
||||
BusProject project = projectService.getById(projectId);
|
||||
if (project == null) {
|
||||
throw new ServiceException("项目不存在");
|
||||
}
|
||||
// 获取子项目
|
||||
List<BusProject> projectList = projectService.lambdaQuery()
|
||||
.eq(BusProject::getPId, projectId)
|
||||
.list();
|
||||
projectList.add(project);
|
||||
Map<Long, String> projectNameMap = projectList.stream()
|
||||
.collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName));
|
||||
LambdaQueryWrapper<OutConstructionValueRange> lqw = buildQueryWrapper(bo);
|
||||
List<OutConstructionValueRange> list = this.list(lqw);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
throw new ServiceException("无数据导出");
|
||||
}
|
||||
// 根据周产值查询具体产值
|
||||
Set<Long> rangeIds = list.stream().map(OutConstructionValueRange::getId).collect(Collectors.toSet());
|
||||
List<OutConstructionValue> valueList = constructionValueService.lambdaQuery()
|
||||
.in(OutConstructionValue::getRangeId, rangeIds)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(valueList)) {
|
||||
throw new ServiceException("无数据导出");
|
||||
}
|
||||
List<OutConstructionValueCategoryVo> valueCategoryList = new ArrayList<>();
|
||||
List<PgsProgressCategory> topList = new ArrayList<>();
|
||||
constructionValueService.buildExportData(valueList, valueCategoryList, topList);
|
||||
// 汇总数据
|
||||
List<OutConstructionValueRangeProjectVo> projectVoList = new ArrayList<>();
|
||||
List<OutConstructionValueRangeSubProjectVo> subProjectVoList = new ArrayList<>();
|
||||
List<OutConstructionValueRangeMatrixVo> matrixVoList = new ArrayList<>();
|
||||
// 合计
|
||||
BigDecimal totalNumber = BigDecimal.ZERO;
|
||||
BigDecimal totalOwnerValue = BigDecimal.ZERO;
|
||||
BigDecimal totalOutValue = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal subTotalNumber = BigDecimal.ZERO;
|
||||
BigDecimal subTotalOwnerValue = BigDecimal.ZERO;
|
||||
BigDecimal subTotalOutValue = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal matrixTotalNumber = BigDecimal.ZERO;
|
||||
BigDecimal matrixTotalOwnerValue = BigDecimal.ZERO;
|
||||
BigDecimal matrixTotalOutValue = BigDecimal.ZERO;
|
||||
// 根据名称+结构分类
|
||||
Map<String, List<PgsProgressCategory>> topNameMap =
|
||||
topList.stream().collect(Collectors.groupingBy(item -> item.getName() + "_" + item.getRelevancyStructure()));
|
||||
for (Map.Entry<String, List<PgsProgressCategory>> entry : topNameMap.entrySet()) {
|
||||
String[] keys = entry.getKey().split("_");
|
||||
String name = keys[0];
|
||||
String structure = keys[1];
|
||||
List<PgsProgressCategory> topNodes = entry.getValue();
|
||||
List<Long> topIds = topNodes.stream().map(PgsProgressCategory::getId).toList();
|
||||
// 找出全部子孙节点
|
||||
List<OutConstructionValueCategoryVo> children = findChildren(valueCategoryList, topIds);
|
||||
// 子类按名称分组
|
||||
Map<String, List<OutConstructionValueCategoryVo>> childrenMap =
|
||||
children.stream().collect(Collectors.groupingBy(OutConstructionValueCategoryVo::getName));
|
||||
for (Map.Entry<String, List<OutConstructionValueCategoryVo>> childrenEntry : childrenMap.entrySet()) {
|
||||
String childName = childrenEntry.getKey();
|
||||
List<OutConstructionValueCategoryVo> childrenEntryValue = childrenEntry.getValue();
|
||||
// ======= 构建项目级数据 =======
|
||||
Summary summary = calculateSummary(childrenEntryValue);
|
||||
OutConstructionValueRangeProjectVo projectVo =
|
||||
buildProjectVo(project, name, childName, childrenEntryValue, summary);
|
||||
projectVoList.add(projectVo);
|
||||
totalNumber = totalNumber.add(summary.number);
|
||||
totalOwnerValue = totalOwnerValue.add(summary.ownerValue);
|
||||
totalOutValue = totalOutValue.add(summary.outValue);
|
||||
// ======= 构建子项目级数据 =======
|
||||
if (structure.equals("1") || structure.equals("2")) {
|
||||
Map<Long, List<OutConstructionValueCategoryVo>> subMap =
|
||||
childrenEntryValue.stream().collect(Collectors.groupingBy(OutConstructionValueCategoryVo::getProjectId));
|
||||
for (Map.Entry<Long, List<OutConstructionValueCategoryVo>> subEntry : subMap.entrySet()) {
|
||||
Summary subSummary = calculateSummary(subEntry.getValue());
|
||||
OutConstructionValueRangeSubProjectVo subVo =
|
||||
buildSubProjectVo(project, name, childName, subEntry, projectNameMap, subSummary);
|
||||
subProjectVoList.add(subVo);
|
||||
subTotalNumber = subTotalNumber.add(subSummary.number);
|
||||
subTotalOwnerValue = subTotalOwnerValue.add(subSummary.ownerValue);
|
||||
subTotalOutValue = subTotalOutValue.add(subSummary.outValue);
|
||||
}
|
||||
}
|
||||
// ======= 构建方阵级数据 =======
|
||||
if (structure.equals("2")) {
|
||||
Map<String, List<OutConstructionValueCategoryVo>> matrixMap =
|
||||
childrenEntryValue.stream().collect(Collectors.groupingBy(OutConstructionValueCategoryVo::getMatrixName));
|
||||
for (Map.Entry<String, List<OutConstructionValueCategoryVo>> matrixEntry : matrixMap.entrySet()) {
|
||||
Summary matrixSummary = calculateSummary(matrixEntry.getValue());
|
||||
OutConstructionValueRangeMatrixVo matrixVo =
|
||||
buildMatrixVo(project, name, childName, matrixEntry, projectNameMap, matrixSummary);
|
||||
matrixVoList.add(matrixVo);
|
||||
matrixTotalNumber = matrixTotalNumber.add(matrixSummary.number);
|
||||
matrixTotalOwnerValue = matrixTotalOwnerValue.add(matrixSummary.ownerValue);
|
||||
matrixTotalOutValue = matrixTotalOutValue.add(matrixSummary.outValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 排序
|
||||
projectVoList.sort(Comparator.comparing(OutConstructionValueRangeProjectVo::getProgressCategoryName));
|
||||
subProjectVoList.sort(Comparator.comparing(OutConstructionValueRangeSubProjectVo::getSubProjectName)
|
||||
.thenComparing(OutConstructionValueRangeSubProjectVo::getProgressCategoryName));
|
||||
matrixVoList.sort(Comparator.comparing(OutConstructionValueRangeMatrixVo::getSubProjectName)
|
||||
.thenComparing(OutConstructionValueRangeMatrixVo::getMatrixName)
|
||||
.thenComparing(OutConstructionValueRangeMatrixVo::getProgressCategoryName));
|
||||
// 填充合计
|
||||
OutConstructionValueRangeProjectVo rangeProjectVo = new OutConstructionValueRangeProjectVo();
|
||||
rangeProjectVo.setProjectName("合计");
|
||||
rangeProjectVo.setNumber(totalNumber);
|
||||
rangeProjectVo.setOwnerValue(totalOwnerValue);
|
||||
rangeProjectVo.setOutValue(totalOutValue);
|
||||
projectVoList.add(rangeProjectVo);
|
||||
OutConstructionValueRangeSubProjectVo rangeSubProjectVo = new OutConstructionValueRangeSubProjectVo();
|
||||
rangeSubProjectVo.setProjectName("合计");
|
||||
rangeSubProjectVo.setNumber(subTotalNumber);
|
||||
rangeSubProjectVo.setOwnerValue(subTotalOwnerValue);
|
||||
rangeSubProjectVo.setOutValue(subTotalOutValue);
|
||||
subProjectVoList.add(rangeSubProjectVo);
|
||||
OutConstructionValueRangeMatrixVo rangeMatrixVo = new OutConstructionValueRangeMatrixVo();
|
||||
rangeMatrixVo.setProjectName("合计");
|
||||
rangeMatrixVo.setNumber(matrixTotalNumber);
|
||||
rangeMatrixVo.setOwnerValue(matrixTotalOwnerValue);
|
||||
rangeMatrixVo.setOutValue(matrixTotalOutValue);
|
||||
matrixVoList.add(rangeMatrixVo);
|
||||
// 构建导出数据
|
||||
buildExportExcel(project.getProjectName(), response, projectVoList, subProjectVoList, matrixVoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找子级
|
||||
*
|
||||
* @param all 所有数据
|
||||
* @param topIds 顶级ID
|
||||
* @return 子级
|
||||
*/
|
||||
private List<OutConstructionValueCategoryVo> findChildren(
|
||||
List<OutConstructionValueCategoryVo> all,
|
||||
List<Long> topIds) {
|
||||
return all.stream()
|
||||
.filter(item -> {
|
||||
String ancestors = item.getAncestors();
|
||||
if (ancestors == null) return false;
|
||||
return topIds.stream().anyMatch(topId ->
|
||||
ancestors.contains("," + topId + ",") ||
|
||||
ancestors.startsWith(topId + ",") ||
|
||||
ancestors.endsWith("," + topId) ||
|
||||
ancestors.equals(String.valueOf(topId))
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总静态类
|
||||
*/
|
||||
static class Summary {
|
||||
BigDecimal number;
|
||||
BigDecimal ownerValue;
|
||||
BigDecimal outValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算汇总
|
||||
*
|
||||
* @param list 数据
|
||||
* @return 汇总
|
||||
*/
|
||||
private Summary calculateSummary(List<OutConstructionValueCategoryVo> list) {
|
||||
Summary s = new Summary();
|
||||
s.number = BigDecimal.ZERO;
|
||||
s.ownerValue = BigDecimal.ZERO;
|
||||
s.outValue = BigDecimal.ZERO;
|
||||
for (OutConstructionValueCategoryVo c : list) {
|
||||
int num = (c.getConfirmNum() == null || c.getConfirmNum() == 0)
|
||||
? c.getArtificialNum() + c.getUavNum()
|
||||
: c.getConfirmNum();
|
||||
|
||||
s.number = s.number.add(BigDecimal.valueOf(num));
|
||||
s.ownerValue = s.ownerValue.add(c.getOwnerValue());
|
||||
s.outValue = s.outValue.add(c.getOutValue());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第一个非空的值
|
||||
*
|
||||
* @param list 数据
|
||||
* @param getter 获取器
|
||||
* @return 值
|
||||
*/
|
||||
private <T> T getFirstNonNull(List<OutConstructionValueCategoryVo> list,
|
||||
Function<OutConstructionValueCategoryVo, T> getter) {
|
||||
return list.stream()
|
||||
.map(getter)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建项目VO
|
||||
*
|
||||
* @param project 项目
|
||||
* @param name 名称
|
||||
* @param childName 子名称
|
||||
* @param list 数据
|
||||
* @param summary 合计
|
||||
* @return 项目VO
|
||||
*/
|
||||
private OutConstructionValueRangeProjectVo buildProjectVo(
|
||||
BusProject project,
|
||||
String name,
|
||||
String childName,
|
||||
List<OutConstructionValueCategoryVo> list,
|
||||
Summary summary) {
|
||||
OutConstructionValueRangeProjectVo vo = new OutConstructionValueRangeProjectVo();
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setProgressCategoryName(name + "/" + childName);
|
||||
vo.setUnit(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnit));
|
||||
vo.setUnitType(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnitType));
|
||||
vo.setNumber(summary.number);
|
||||
vo.setOwnerValue(summary.ownerValue);
|
||||
vo.setOutValue(summary.outValue);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建子项VO
|
||||
*
|
||||
* @param project 项目
|
||||
* @param name 名称
|
||||
* @param childName 子名称
|
||||
* @param entry 数据
|
||||
* @param summary 合计
|
||||
* @return 子项VO
|
||||
*/
|
||||
private OutConstructionValueRangeSubProjectVo buildSubProjectVo(
|
||||
BusProject project,
|
||||
String name,
|
||||
String childName,
|
||||
Map.Entry<Long, List<OutConstructionValueCategoryVo>> entry,
|
||||
Map<Long, String> projectNameMap,
|
||||
Summary summary) {
|
||||
OutConstructionValueRangeSubProjectVo vo = new OutConstructionValueRangeSubProjectVo();
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setSubProjectName(projectNameMap.get(entry.getKey()));
|
||||
vo.setProgressCategoryName(name + "/" + childName);
|
||||
vo.setUnit(getFirstNonNull(entry.getValue(), OutConstructionValueCategoryVo::getUnit));
|
||||
vo.setUnitType(getFirstNonNull(entry.getValue(), OutConstructionValueCategoryVo::getUnitType));
|
||||
vo.setNumber(summary.number);
|
||||
vo.setOwnerValue(summary.ownerValue);
|
||||
vo.setOutValue(summary.outValue);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建方阵VO
|
||||
*
|
||||
* @param project 项目
|
||||
* @param name 名称
|
||||
* @param childName 子名称
|
||||
* @param entry 数据
|
||||
* @param projectNameMap 项目名称
|
||||
* @param summary 合计
|
||||
* @return 方阵VO
|
||||
*/
|
||||
private OutConstructionValueRangeMatrixVo buildMatrixVo(
|
||||
BusProject project,
|
||||
String name,
|
||||
String childName,
|
||||
Map.Entry<String, List<OutConstructionValueCategoryVo>> entry,
|
||||
Map<Long, String> projectNameMap,
|
||||
Summary summary) {
|
||||
List<OutConstructionValueCategoryVo> list = entry.getValue();
|
||||
OutConstructionValueRangeMatrixVo vo = new OutConstructionValueRangeMatrixVo();
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setMatrixName(entry.getKey());
|
||||
vo.setProgressCategoryName(name + "/" + childName);
|
||||
Long pid = list.stream()
|
||||
.map(OutConstructionValueCategoryVo::getProjectId)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst().orElse(project.getId());
|
||||
vo.setSubProjectName(projectNameMap.getOrDefault(pid, project.getProjectName()));
|
||||
vo.setUnit(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnit));
|
||||
vo.setUnitType(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnitType));
|
||||
vo.setNumber(summary.number);
|
||||
vo.setOwnerValue(summary.ownerValue);
|
||||
vo.setOutValue(summary.outValue);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建导出Excel
|
||||
*
|
||||
* @param projectName 项目名称
|
||||
* @param response 响应
|
||||
* @param projectVoList 项目VO
|
||||
* @param subProjectVoList 子项VO
|
||||
* @param matrixVoList 方阵VO
|
||||
*/
|
||||
private void buildExportExcel(String projectName, HttpServletResponse response,
|
||||
List<OutConstructionValueRangeProjectVo> projectVoList,
|
||||
List<OutConstructionValueRangeSubProjectVo> subProjectVoList,
|
||||
List<OutConstructionValueRangeMatrixVo> matrixVoList) {
|
||||
String fileName = projectName + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "-" + "施工产值.xlsx";
|
||||
FileUtils.setAttachmentResponseHeader(response, fileName);
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
|
||||
// 构建 ExcelWriter
|
||||
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
||||
.autoCloseStream(false)
|
||||
// 自动适配
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
// 大数值自动转换 防止失真
|
||||
.registerConverter(new ExcelBigNumberConvert())
|
||||
.build()) {
|
||||
// === Sheet1 ===
|
||||
WriteSheet sheet1 = EasyExcel.writerSheet(0, "按项目汇总")
|
||||
.head(OutConstructionValueRangeProjectVo.class)
|
||||
.build();
|
||||
excelWriter.write(projectVoList, sheet1);
|
||||
// === Sheet2 ===
|
||||
WriteSheet sheet2 = EasyExcel.writerSheet(1, "按子项汇总")
|
||||
.head(OutConstructionValueRangeSubProjectVo.class)
|
||||
.build();
|
||||
excelWriter.write(subProjectVoList, sheet2);
|
||||
// === Sheet3 ===
|
||||
WriteSheet sheet3 = EasyExcel.writerSheet(2, "按方阵汇总")
|
||||
.head(OutConstructionValueRangeMatrixVo.class)
|
||||
.build();
|
||||
excelWriter.write(matrixVoList, sheet3);
|
||||
} catch (IOException e) {
|
||||
log.error("施工产值Excel导出失败", e);
|
||||
throw new ServiceException("导出Excel失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
|
||||
* 正常使用只需#processEvent.flowCode=='leave1'
|
||||
|
||||
@ -1,16 +1,23 @@
|
||||
package org.dromara.out.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
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 jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.core.utils.file.FileUtils;
|
||||
import org.dromara.common.excel.convert.ExcelBigNumberConvert;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.facility.domain.FacMatrix;
|
||||
@ -20,7 +27,7 @@ import org.dromara.out.domain.OutConstructionValueRange;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueBo;
|
||||
import org.dromara.out.domain.bo.OutConstructionValueFacilityReq;
|
||||
import org.dromara.out.domain.vo.OutConstructionAllValueVo;
|
||||
import org.dromara.out.domain.vo.OutConstructionValueVo;
|
||||
import org.dromara.out.domain.vo.outconstructionvalue.*;
|
||||
import org.dromara.out.mapper.OutConstructionValueMapper;
|
||||
import org.dromara.out.service.IOutConstructionValueRangeService;
|
||||
import org.dromara.out.service.IOutConstructionValueService;
|
||||
@ -35,11 +42,17 @@ import org.dromara.progress.service.IPgsProgressPlanDetailService;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.domain.vo.project.BusProjectVo;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 施工产值Service业务层处理
|
||||
@ -65,6 +78,8 @@ public class OutConstructionValueServiceImpl extends ServiceImpl<OutConstruction
|
||||
|
||||
private final IOutConstructionValueRangeService constructionValueRangeService;
|
||||
|
||||
private final IPgsProgressCategoryService progressCategoryService;
|
||||
|
||||
/**
|
||||
* 查询施工产值
|
||||
*
|
||||
@ -357,6 +372,402 @@ public class OutConstructionValueServiceImpl extends ServiceImpl<OutConstruction
|
||||
list.sort(Comparator.comparing(OutConstructionValueVo::getProgressCategoryName, Comparator.nullsLast(String::compareTo)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param response 响应
|
||||
*/
|
||||
@Override
|
||||
public void exportExcel(OutConstructionValueBo bo, HttpServletResponse response) {
|
||||
Long projectId = bo.getProjectId();
|
||||
if (projectId == null) {
|
||||
throw new ServiceException("请选择项目");
|
||||
}
|
||||
BusProject project = projectService.getById(projectId);
|
||||
if (project == null) {
|
||||
throw new ServiceException("项目不存在");
|
||||
}
|
||||
// 获取子项目
|
||||
List<BusProject> projectList = projectService.lambdaQuery()
|
||||
.eq(BusProject::getPId, projectId)
|
||||
.list();
|
||||
projectList.add(project);
|
||||
Map<Long, String> projectNameMap = projectList.stream()
|
||||
.collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName));
|
||||
LambdaQueryWrapper<OutConstructionValue> lqw = buildQueryWrapper(bo);
|
||||
List<OutConstructionValue> valueList = this.list(lqw);
|
||||
if (CollUtil.isEmpty(valueList)) {
|
||||
throw new ServiceException("无数据导出");
|
||||
}
|
||||
List<OutConstructionValueCategoryVo> valueCategoryList = new ArrayList<>();
|
||||
List<PgsProgressCategory> topList = new ArrayList<>();
|
||||
this.buildExportData(valueList, valueCategoryList, topList);
|
||||
// 汇总数据
|
||||
List<OutConstructionValueProjectVo> projectVoList = new ArrayList<>();
|
||||
List<OutConstructionValueSubProjectVo> subProjectVoList = new ArrayList<>();
|
||||
List<OutConstructionValueMatrixVo> matrixVoList = new ArrayList<>();
|
||||
// 合计
|
||||
BigDecimal totalNumber = BigDecimal.ZERO;
|
||||
BigDecimal totalOwnerValue = BigDecimal.ZERO;
|
||||
BigDecimal totalOutValue = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal subTotalNumber = BigDecimal.ZERO;
|
||||
BigDecimal subTotalOwnerValue = BigDecimal.ZERO;
|
||||
BigDecimal subTotalOutValue = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal matrixTotalNumber = BigDecimal.ZERO;
|
||||
BigDecimal matrixTotalOwnerValue = BigDecimal.ZERO;
|
||||
BigDecimal matrixTotalOutValue = BigDecimal.ZERO;
|
||||
// 根据名称+结构分类
|
||||
Map<String, List<PgsProgressCategory>> topNameMap =
|
||||
topList.stream().collect(Collectors.groupingBy(item -> item.getName() + "_" + item.getRelevancyStructure()));
|
||||
for (Map.Entry<String, List<PgsProgressCategory>> entry : topNameMap.entrySet()) {
|
||||
String[] keys = entry.getKey().split("_");
|
||||
String name = keys[0];
|
||||
String structure = keys[1];
|
||||
List<PgsProgressCategory> topNodes = entry.getValue();
|
||||
List<Long> topIds = topNodes.stream().map(PgsProgressCategory::getId).toList();
|
||||
// 找出全部子孙节点
|
||||
List<OutConstructionValueCategoryVo> children = findChildren(valueCategoryList, topIds);
|
||||
// 子类按名称分组
|
||||
Map<String, List<OutConstructionValueCategoryVo>> childrenMap =
|
||||
children.stream().collect(Collectors.groupingBy(OutConstructionValueCategoryVo::getName));
|
||||
for (Map.Entry<String, List<OutConstructionValueCategoryVo>> childrenEntry : childrenMap.entrySet()) {
|
||||
String childName = childrenEntry.getKey();
|
||||
List<OutConstructionValueCategoryVo> childrenEntryValue = childrenEntry.getValue();
|
||||
// ======= 构建项目级数据 =======
|
||||
Summary summary = calculateSummary(childrenEntryValue);
|
||||
OutConstructionValueProjectVo projectVo =
|
||||
buildProjectVo(project, name, childName, childrenEntryValue, summary);
|
||||
projectVoList.add(projectVo);
|
||||
totalNumber = totalNumber.add(summary.number);
|
||||
totalOwnerValue = totalOwnerValue.add(summary.ownerValue);
|
||||
totalOutValue = totalOutValue.add(summary.outValue);
|
||||
// ======= 构建子项目级数据 =======
|
||||
if (structure.equals("1") || structure.equals("2")) {
|
||||
Map<Long, List<OutConstructionValueCategoryVo>> subMap =
|
||||
childrenEntryValue.stream().collect(Collectors.groupingBy(OutConstructionValueCategoryVo::getProjectId));
|
||||
for (Map.Entry<Long, List<OutConstructionValueCategoryVo>> subEntry : subMap.entrySet()) {
|
||||
Summary subSummary = calculateSummary(subEntry.getValue());
|
||||
OutConstructionValueSubProjectVo subVo =
|
||||
buildSubProjectVo(project, name, childName, subEntry, projectNameMap, subSummary);
|
||||
subProjectVoList.add(subVo);
|
||||
subTotalNumber = subTotalNumber.add(subSummary.number);
|
||||
subTotalOwnerValue = subTotalOwnerValue.add(subSummary.ownerValue);
|
||||
subTotalOutValue = subTotalOutValue.add(subSummary.outValue);
|
||||
}
|
||||
}
|
||||
// ======= 构建方阵级数据 =======
|
||||
if (structure.equals("2")) {
|
||||
Map<String, List<OutConstructionValueCategoryVo>> matrixMap =
|
||||
childrenEntryValue.stream().collect(Collectors.groupingBy(OutConstructionValueCategoryVo::getMatrixName));
|
||||
for (Map.Entry<String, List<OutConstructionValueCategoryVo>> matrixEntry : matrixMap.entrySet()) {
|
||||
Summary matrixSummary = calculateSummary(matrixEntry.getValue());
|
||||
OutConstructionValueMatrixVo matrixVo =
|
||||
buildMatrixVo(project, name, childName, matrixEntry, projectNameMap, matrixSummary);
|
||||
matrixVoList.add(matrixVo);
|
||||
matrixTotalNumber = matrixTotalNumber.add(matrixSummary.number);
|
||||
matrixTotalOwnerValue = matrixTotalOwnerValue.add(matrixSummary.ownerValue);
|
||||
matrixTotalOutValue = matrixTotalOutValue.add(matrixSummary.outValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 排序
|
||||
projectVoList.sort(Comparator.comparing(OutConstructionValueProjectVo::getProgressCategoryName));
|
||||
subProjectVoList.sort(Comparator.comparing(OutConstructionValueSubProjectVo::getSubProjectName)
|
||||
.thenComparing(OutConstructionValueSubProjectVo::getProgressCategoryName));
|
||||
matrixVoList.sort(Comparator.comparing(OutConstructionValueMatrixVo::getSubProjectName)
|
||||
.thenComparing(OutConstructionValueMatrixVo::getMatrixName)
|
||||
.thenComparing(OutConstructionValueMatrixVo::getProgressCategoryName));
|
||||
// 填充合计
|
||||
OutConstructionValueProjectVo rangeProjectVo = new OutConstructionValueProjectVo();
|
||||
rangeProjectVo.setProjectName("合计");
|
||||
rangeProjectVo.setNumber(totalNumber);
|
||||
rangeProjectVo.setOwnerValue(totalOwnerValue);
|
||||
rangeProjectVo.setOutValue(totalOutValue);
|
||||
projectVoList.add(rangeProjectVo);
|
||||
OutConstructionValueSubProjectVo rangeSubProjectVo = new OutConstructionValueSubProjectVo();
|
||||
rangeSubProjectVo.setProjectName("合计");
|
||||
rangeSubProjectVo.setNumber(subTotalNumber);
|
||||
rangeSubProjectVo.setOwnerValue(subTotalOwnerValue);
|
||||
rangeSubProjectVo.setOutValue(subTotalOutValue);
|
||||
subProjectVoList.add(rangeSubProjectVo);
|
||||
OutConstructionValueMatrixVo rangeMatrixVo = new OutConstructionValueMatrixVo();
|
||||
rangeMatrixVo.setProjectName("合计");
|
||||
rangeMatrixVo.setNumber(matrixTotalNumber);
|
||||
rangeMatrixVo.setOwnerValue(matrixTotalOwnerValue);
|
||||
rangeMatrixVo.setOutValue(matrixTotalOutValue);
|
||||
matrixVoList.add(rangeMatrixVo);
|
||||
// 构建导出数据
|
||||
buildExportExcel(project.getProjectName(), response, projectVoList, subProjectVoList, matrixVoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建导出需要的数据
|
||||
*
|
||||
* @param valueList 施工产值列表
|
||||
* @param valueCategoryList 进度类别列表
|
||||
* @param topList 顶层进度类别列表
|
||||
*/
|
||||
@Override
|
||||
public void buildExportData(List<OutConstructionValue> valueList,
|
||||
List<OutConstructionValueCategoryVo> valueCategoryList,
|
||||
List<PgsProgressCategory> topList) {
|
||||
// 获取对应进度类别
|
||||
Set<Long> progressCategoryIds = valueList.stream()
|
||||
.map(OutConstructionValue::getProgressCategoryId)
|
||||
.collect(Collectors.toSet());
|
||||
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
|
||||
.in(PgsProgressCategory::getId, progressCategoryIds)
|
||||
.list();
|
||||
valueCategoryList.addAll(
|
||||
valueList.stream().map(value -> {
|
||||
OutConstructionValueCategoryVo vo = new OutConstructionValueCategoryVo();
|
||||
BeanUtils.copyProperties(value, vo);
|
||||
PgsProgressCategory category = progressCategoryList.stream()
|
||||
.filter(p -> p.getId().equals(value.getProgressCategoryId()))
|
||||
.findFirst().orElse(null);
|
||||
if (category != null) {
|
||||
vo.setProjectId(category.getProjectId());
|
||||
vo.setMatrixName(category.getMatrixName());
|
||||
vo.setName(category.getName());
|
||||
vo.setUnitType(category.getUnitType());
|
||||
vo.setUnit(category.getUnit());
|
||||
vo.setAncestors(category.getAncestors());
|
||||
vo.setRelevancyStructure(category.getRelevancyStructure());
|
||||
}
|
||||
return vo;
|
||||
}).toList()
|
||||
);
|
||||
// 顶级进度类别
|
||||
Set<Long> topProgressCategoryIds = progressCategoryList.stream()
|
||||
.map(p -> {
|
||||
String ancestors = p.getAncestors();
|
||||
if (StringUtils.isNotBlank(ancestors)) {
|
||||
String[] split = ancestors.split(",");
|
||||
return split.length > 1 ? split[1] : null;
|
||||
}
|
||||
return null;
|
||||
}).filter(Objects::nonNull)
|
||||
.map(Long::parseLong)
|
||||
.collect(Collectors.toSet());
|
||||
List<PgsProgressCategory> tops = progressCategoryService.listByIds(topProgressCategoryIds)
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(PgsProgressCategory::getSort))
|
||||
.toList();
|
||||
topList.addAll(tops);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找子级
|
||||
*
|
||||
* @param all 所有数据
|
||||
* @param topIds 顶级ID
|
||||
* @return 子级
|
||||
*/
|
||||
private List<OutConstructionValueCategoryVo> findChildren(
|
||||
List<OutConstructionValueCategoryVo> all,
|
||||
List<Long> topIds) {
|
||||
return all.stream()
|
||||
.filter(item -> {
|
||||
String ancestors = item.getAncestors();
|
||||
if (ancestors == null) return false;
|
||||
return topIds.stream().anyMatch(topId ->
|
||||
ancestors.contains("," + topId + ",") ||
|
||||
ancestors.startsWith(topId + ",") ||
|
||||
ancestors.endsWith("," + topId) ||
|
||||
ancestors.equals(String.valueOf(topId))
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总静态类
|
||||
*/
|
||||
static class Summary {
|
||||
BigDecimal number;
|
||||
BigDecimal ownerValue;
|
||||
BigDecimal outValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算汇总
|
||||
*
|
||||
* @param list 数据
|
||||
* @return 汇总
|
||||
*/
|
||||
private Summary calculateSummary(List<OutConstructionValueCategoryVo> list) {
|
||||
Summary s = new Summary();
|
||||
s.number = BigDecimal.ZERO;
|
||||
s.ownerValue = BigDecimal.ZERO;
|
||||
s.outValue = BigDecimal.ZERO;
|
||||
for (OutConstructionValueCategoryVo c : list) {
|
||||
int num = (c.getConfirmNum() == null || c.getConfirmNum() == 0)
|
||||
? c.getArtificialNum() + c.getUavNum()
|
||||
: c.getConfirmNum();
|
||||
|
||||
s.number = s.number.add(BigDecimal.valueOf(num));
|
||||
s.ownerValue = s.ownerValue.add(c.getOwnerValue());
|
||||
s.outValue = s.outValue.add(c.getOutValue());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第一个非空的值
|
||||
*
|
||||
* @param list 数据
|
||||
* @param getter 获取器
|
||||
* @return 值
|
||||
*/
|
||||
private <T> T getFirstNonNull(List<OutConstructionValueCategoryVo> list,
|
||||
Function<OutConstructionValueCategoryVo, T> getter) {
|
||||
return list.stream()
|
||||
.map(getter)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建项目VO
|
||||
*
|
||||
* @param project 项目
|
||||
* @param name 名称
|
||||
* @param childName 子名称
|
||||
* @param list 数据
|
||||
* @param summary 合计
|
||||
* @return 项目VO
|
||||
*/
|
||||
private OutConstructionValueProjectVo buildProjectVo(
|
||||
BusProject project,
|
||||
String name,
|
||||
String childName,
|
||||
List<OutConstructionValueCategoryVo> list,
|
||||
Summary summary) {
|
||||
OutConstructionValueProjectVo vo = new OutConstructionValueProjectVo();
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setProgressCategoryName(name + "/" + childName);
|
||||
vo.setUnit(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnit));
|
||||
vo.setUnitType(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnitType));
|
||||
vo.setNumber(summary.number);
|
||||
vo.setOwnerValue(summary.ownerValue);
|
||||
vo.setOutValue(summary.outValue);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建子项VO
|
||||
*
|
||||
* @param project 项目
|
||||
* @param name 名称
|
||||
* @param childName 子名称
|
||||
* @param entry 数据
|
||||
* @param summary 合计
|
||||
* @return 子项VO
|
||||
*/
|
||||
private OutConstructionValueSubProjectVo buildSubProjectVo(
|
||||
BusProject project,
|
||||
String name,
|
||||
String childName,
|
||||
Map.Entry<Long, List<OutConstructionValueCategoryVo>> entry,
|
||||
Map<Long, String> projectNameMap,
|
||||
Summary summary) {
|
||||
OutConstructionValueSubProjectVo vo = new OutConstructionValueSubProjectVo();
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setSubProjectName(projectNameMap.get(entry.getKey()));
|
||||
vo.setProgressCategoryName(name + "/" + childName);
|
||||
vo.setUnit(getFirstNonNull(entry.getValue(), OutConstructionValueCategoryVo::getUnit));
|
||||
vo.setUnitType(getFirstNonNull(entry.getValue(), OutConstructionValueCategoryVo::getUnitType));
|
||||
vo.setNumber(summary.number);
|
||||
vo.setOwnerValue(summary.ownerValue);
|
||||
vo.setOutValue(summary.outValue);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建方阵VO
|
||||
*
|
||||
* @param project 项目
|
||||
* @param name 名称
|
||||
* @param childName 子名称
|
||||
* @param entry 数据
|
||||
* @param projectNameMap 项目名称
|
||||
* @param summary 合计
|
||||
* @return 方阵VO
|
||||
*/
|
||||
private OutConstructionValueMatrixVo buildMatrixVo(
|
||||
BusProject project,
|
||||
String name,
|
||||
String childName,
|
||||
Map.Entry<String, List<OutConstructionValueCategoryVo>> entry,
|
||||
Map<Long, String> projectNameMap,
|
||||
Summary summary) {
|
||||
List<OutConstructionValueCategoryVo> list = entry.getValue();
|
||||
OutConstructionValueMatrixVo vo = new OutConstructionValueMatrixVo();
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setMatrixName(entry.getKey());
|
||||
vo.setProgressCategoryName(name + "/" + childName);
|
||||
Long pid = list.stream()
|
||||
.map(OutConstructionValueCategoryVo::getProjectId)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst().orElse(project.getId());
|
||||
vo.setSubProjectName(projectNameMap.getOrDefault(pid, project.getProjectName()));
|
||||
vo.setUnit(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnit));
|
||||
vo.setUnitType(getFirstNonNull(list, OutConstructionValueCategoryVo::getUnitType));
|
||||
vo.setNumber(summary.number);
|
||||
vo.setOwnerValue(summary.ownerValue);
|
||||
vo.setOutValue(summary.outValue);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建导出Excel
|
||||
*
|
||||
* @param projectName 项目名称
|
||||
* @param response 响应
|
||||
* @param projectVoList 项目VO
|
||||
* @param subProjectVoList 子项VO
|
||||
* @param matrixVoList 方阵VO
|
||||
*/
|
||||
private void buildExportExcel(String projectName, HttpServletResponse response,
|
||||
List<OutConstructionValueProjectVo> projectVoList,
|
||||
List<OutConstructionValueSubProjectVo> subProjectVoList,
|
||||
List<OutConstructionValueMatrixVo> matrixVoList) {
|
||||
String fileName = projectName + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "-" + "施工产值.xlsx";
|
||||
FileUtils.setAttachmentResponseHeader(response, fileName);
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
|
||||
// 构建 ExcelWriter
|
||||
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
||||
.autoCloseStream(false)
|
||||
// 自动适配
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
// 大数值自动转换 防止失真
|
||||
.registerConverter(new ExcelBigNumberConvert())
|
||||
.build()) {
|
||||
// === Sheet1 ===
|
||||
WriteSheet sheet1 = EasyExcel.writerSheet(0, "按项目汇总")
|
||||
.head(OutConstructionValueProjectVo.class)
|
||||
.build();
|
||||
excelWriter.write(projectVoList, sheet1);
|
||||
// === Sheet2 ===
|
||||
WriteSheet sheet2 = EasyExcel.writerSheet(1, "按子项汇总")
|
||||
.head(OutConstructionValueSubProjectVo.class)
|
||||
.build();
|
||||
excelWriter.write(subProjectVoList, sheet2);
|
||||
// === Sheet3 ===
|
||||
WriteSheet sheet3 = EasyExcel.writerSheet(2, "按方阵汇总")
|
||||
.head(OutConstructionValueMatrixVo.class)
|
||||
.build();
|
||||
excelWriter.write(matrixVoList, sheet3);
|
||||
} catch (IOException e) {
|
||||
log.error("施工产值Excel导出失败", e);
|
||||
throw new ServiceException("导出Excel失败");
|
||||
}
|
||||
}
|
||||
|
||||
public void getName(OutConstructionValueVo vo) {
|
||||
//查询分部工程以及分项工程
|
||||
PgsProgressCategoryVo pgsProgressCategoryVo = pgsProgressCategoryService.queryById(vo.getProgressCategoryId());
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
package org.dromara.progress.domain.dto.progresscategory;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-11-28 14:24
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PgsProgressCategoryImportTemp {
|
||||
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 方阵id
|
||||
*/
|
||||
private Long matrixId;
|
||||
|
||||
/**
|
||||
* 方阵名称
|
||||
*/
|
||||
private String matrixName;
|
||||
|
||||
/**
|
||||
* 类别名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 计量方式(0无 1数量 2百分比)
|
||||
*/
|
||||
private String unitType;
|
||||
|
||||
/**
|
||||
* 总数量
|
||||
*/
|
||||
private BigDecimal total;
|
||||
|
||||
/**
|
||||
* 已完成数量
|
||||
*/
|
||||
private BigDecimal completed;
|
||||
|
||||
/**
|
||||
* 计划总数量
|
||||
*/
|
||||
private BigDecimal planTotal;
|
||||
|
||||
/**
|
||||
* 完成状态(0未开始 1进行中 2已完成)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 工作类型
|
||||
*/
|
||||
private String workType;
|
||||
|
||||
/**
|
||||
* 新增完成数量
|
||||
*/
|
||||
private BigDecimal newComplete;
|
||||
}
|
||||
@ -2850,6 +2850,9 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
log.info("导入数据:{}", voList);
|
||||
// 获取当前的所有旧数据
|
||||
List<Long> ids = voList.stream().map(PgsProgressCategoryEnterTemplateVo::getId).toList();
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
throw new ServiceException("数据错误,无法从当前表格中获取到有效数据");
|
||||
}
|
||||
List<PgsProgressCategory> categoryList = this.listByIds(ids);
|
||||
if (CollUtil.isEmpty(categoryList)) {
|
||||
throw new ServiceException("数据错误,当前项目无此数据");
|
||||
@ -2862,18 +2865,22 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
.list();
|
||||
projects.add(project);
|
||||
List<Long> allProjectIds = projects.stream().map(BusProject::getId).toList();
|
||||
List<PgsProgressCategoryImportTemp> tempList = new ArrayList<>();
|
||||
List<PgsProgressCategory> list = voList.stream().map(vo -> {
|
||||
PgsProgressCategory update = new PgsProgressCategory();
|
||||
PgsProgressCategoryImportTemp temp = new PgsProgressCategoryImportTemp();
|
||||
Long id = vo.getId();
|
||||
update.setId(id);
|
||||
temp.setId(id);
|
||||
if (progressCategoryMap.containsKey(id)) {
|
||||
PgsProgressCategory old = progressCategoryMap.get(id);
|
||||
// 如果不是当前项目,或当前项目的子项目,则返回 null
|
||||
if (!allProjectIds.contains(old.getProjectId())) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal oldCompleted = old.getCompleted();
|
||||
// 当已完成数据等于总数,返回 null
|
||||
if (old.getCompleted().compareTo(old.getTotal()) >= 0) {
|
||||
if (old.getTotal().compareTo(BigDecimal.ZERO) == 0 || oldCompleted.compareTo(old.getTotal()) >= 0) {
|
||||
return null;
|
||||
}
|
||||
// 如果完成数量小于等于0,则返回 null
|
||||
@ -2882,9 +2889,17 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
return null;
|
||||
}
|
||||
// 计算完成数量
|
||||
BigDecimal add = old.getCompleted().add(completionCount);
|
||||
BigDecimal add = oldCompleted.add(completionCount);
|
||||
// 确保完成数量小于等于总数
|
||||
BigDecimal minVal = add.min(old.getTotal());
|
||||
// 记录本次新增的数量
|
||||
BigDecimal newCompleted = minVal.subtract(oldCompleted);
|
||||
temp.setNewComplete(newCompleted);
|
||||
// 如果完成数量等于总数量,设置为完成状态
|
||||
if (minVal.compareTo(old.getTotal()) == 0) {
|
||||
update.setStatus(PgsFinishStatusEnum.FINISH.getValue());
|
||||
}
|
||||
tempList.add(temp);
|
||||
update.setCompleted(minVal);
|
||||
} else {
|
||||
log.warn("未匹配的值 => id:{},name:{}", id, vo.getName());
|
||||
@ -2895,7 +2910,6 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
throw new ServiceException("没有需要更新的数据");
|
||||
}
|
||||
|
||||
boolean b = this.updateBatchById(list);
|
||||
if (!b) {
|
||||
throw new ServiceException("更新失败");
|
||||
@ -2906,6 +2920,9 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
|
||||
List<PgsProgressPlanDetail> detailList = progressPlanDetailService.lambdaQuery()
|
||||
.in(PgsProgressPlanDetail::getProgressCategoryId, updateList)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(detailList)) {
|
||||
// 详情为空,直接创建新详情数据
|
||||
}
|
||||
return "导入成功,共更新" + list.size() + "条数据";
|
||||
}
|
||||
|
||||
|
||||
@ -1146,12 +1146,12 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
String file = req.getFile();
|
||||
String tif = req.getTif();
|
||||
if (StringUtils.isNotBlank(file)) {
|
||||
fileUrl = droneBigImageProperties.getUrl() + file;
|
||||
fileUrl = file;
|
||||
} else {
|
||||
fileUrl = req.getFileUrl();
|
||||
}
|
||||
if (StringUtils.isNotBlank(tif)) {
|
||||
tifUrl = droneBigImageProperties.getUrl() + tif;
|
||||
tifUrl = tif;
|
||||
} else {
|
||||
tifUrl = req.getTifUrl();
|
||||
}
|
||||
@ -1225,6 +1225,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
recognizeVo = recognizerManager.recognize(fileUrl);
|
||||
} catch (Exception e) {
|
||||
log.error("识别失败:{}", e.getMessage());
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
if (recognizeVo == null) {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
@ -1288,7 +1289,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
log.error("将识别数据同步到图片上失败", e);
|
||||
throw new ServiceException("将识别数据同步到图片上失败", HttpStatus.ERROR);
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
String recognizerStr = JSONUtil.toJsonStr(recognizerVoList);
|
||||
// 更新数据和状态
|
||||
|
||||
@ -96,12 +96,12 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
@Override
|
||||
public TableDataInfo<XzdBxBxsqVo> queryPageList(XzdBxBxsqBo bo, PageQuery pageQuery) {
|
||||
//暂时定为只能看见自己的报销
|
||||
if (bo.getBxr() == null && !LoginHelper.isSuperAdmin()) {
|
||||
/* if (bo.getBxr() == null && !LoginHelper.isSuperAdmin()) {
|
||||
bo.setBxr(LoginHelper.getUserId());
|
||||
}
|
||||
}*/
|
||||
|
||||
LambdaQueryWrapper<XzdBxBxsq> lqw = buildQueryWrapper(bo);
|
||||
Page<XzdBxBxsqVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
Page<XzdBxBxsqVo> result = baseMapper.selectPage(pageQuery.build(), lqw);
|
||||
setValue(result.getRecords());
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
if (!"0".equals(flowTaskBo.getProjectId())) {
|
||||
List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectList(new LambdaQueryWrapper<FlowDefinition>()
|
||||
.select(FlowDefinition::getId)
|
||||
.like(FlowDefinition::getFlowCode, flowTaskBo.getProjectId()));
|
||||
.like(StringUtils.isNotBlank(flowTaskBo.getProjectId()), FlowDefinition::getFlowCode, flowTaskBo.getProjectId()));
|
||||
if (flowDefinitions != null && !flowDefinitions.isEmpty()) {
|
||||
flowDefinitions.forEach(flowDefinition -> {
|
||||
definitionIds.add(flowDefinition.getId());
|
||||
@ -356,6 +356,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
private Page<FlowTaskVo> getFlowTaskDefinitionIdsVoPage(PageQuery pageQuery, List<Long> definitionIds, QueryWrapper<FlowTaskBo> queryWrapper) {
|
||||
Page<FlowTaskVo> page = flwTaskMapper.getListRunTaskDefinitionIds(pageQuery.build(), definitionIds, queryWrapper);
|
||||
List<FlowTaskVo> records = page.getRecords();
|
||||
|
||||
Reference in New Issue
Block a user