部分dto、vo

This commit is contained in:
2025-12-05 11:05:27 +08:00
parent 9a3547b70b
commit 917e9a517a
42 changed files with 2803 additions and 67 deletions

View File

@@ -1,7 +0,0 @@
package org.xyzh;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

View File

@@ -0,0 +1,5 @@
package org.xyzh.api.bidding;
public interface BiddingService {
}

View File

@@ -0,0 +1,56 @@
package org.xyzh.api.bidding.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 投标文件DTO
* 用于创建和更新投标文件
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "投标文件DTO")
public class BidResponseDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "响应文件ID更新时需要")
private String responseId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "响应类型technical-技术标/commercial-商务标/comprehensive-综合标")
private String responseType;
@Schema(description = "文档名称")
private String docName;
@Schema(description = "文档大纲")
private String outline;
@Schema(description = "文档内容")
private String content;
@Schema(description = "生成方式ai-AI生成/template-模板生成/manual-人工编写")
private String generationMethod;
@Schema(description = "使用的模板ID")
private String templateId;
@Schema(description = "使用的AI模型")
private String aiModel;
@Schema(description = "生成状态draft-草稿/reviewing-审核中/approved-已批准/rejected-已拒绝/submitted-已提交")
private String generationStatus;
@Schema(description = "版本号")
private String version;
@Schema(description = "父版本ID")
private String parentVersionId;
@Schema(description = "审核意见")
private String reviewComments;
}

View File

@@ -0,0 +1,47 @@
package org.xyzh.api.bidding.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 招标文档DTO
* 用于创建和更新招标文档
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标文档DTO")
public class BiddingDocumentDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "文档ID更新时需要")
private String docId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "文档类型tender-招标文件/technical-技术标/commercial-商务标/clarification-澄清文件/other-其他")
private String docType;
@Schema(description = "文档名称")
private String docName;
@Schema(description = "关联文件ID")
private String fileId;
@Schema(description = "文件路径")
private String filePath;
@Schema(description = "文件大小")
private Long fileSize;
@Schema(description = "MIME类型")
private String mimeType;
@Schema(description = "版本号")
private String version;
@Schema(description = "语言")
private String language;
}

View File

@@ -0,0 +1,93 @@
package org.xyzh.api.bidding.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 招标项目DTO
* 用于创建和更新招标项目
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标项目DTO")
public class BiddingProjectDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "项目ID更新时需要")
private String projectId;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "项目类型public-公开招标/invitation-邀请招标/competitive_negotiation-竞争性谈判")
private String projectType;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "来源平台")
private String sourcePlatform;
@Schema(description = "来源URL")
private String sourceUrl;
@Schema(description = "发布日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date publishDate;
@Schema(description = "投标截止日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date deadline;
@Schema(description = "开标日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date openingDate;
@Schema(description = "预算金额")
private BigDecimal budgetAmount;
@Schema(description = "货币单位")
private String currency;
@Schema(description = "项目状态")
private String projectStatus;
@Schema(description = "中标状态")
private String winningStatus;
@Schema(description = "中标金额")
private BigDecimal winningAmount;
@Schema(description = "客户名称")
private String clientName;
@Schema(description = "客户联系方式")
private String clientContact;
@Schema(description = "联系人")
private String contactPerson;
@Schema(description = "项目地点")
private String projectLocation;
@Schema(description = "项目描述")
private String description;
@Schema(description = "关键词")
private List<String> keywords;
@Schema(description = "负责人")
private String responsibleUser;
@Schema(description = "团队成员")
private List<String> teamMembers;
}

View File

@@ -0,0 +1,67 @@
package org.xyzh.api.bidding.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.fasterxml.jackson.databind.JsonNode;
import java.math.BigDecimal;
/**
* 招标要素DTO
* 用于创建和更新招标要素
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标要素DTO")
public class BiddingRequirementDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "要素ID更新时需要")
private String reqId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "来源文档ID")
private String docId;
@Schema(description = "要素类别commercial-商务要素/technical-技术参数/veto-否决项/qualification-资质要求/delivery-交付要求/payment-付款条件/scoring-评分标准")
private String reqCategory;
@Schema(description = "要素名称")
private String reqName;
@Schema(description = "要素内容")
private String reqContent;
@Schema(description = "要素值")
private String reqValue;
@Schema(description = "是否必填", defaultValue = "false")
private Boolean isMandatory;
@Schema(description = "是否为否决项", defaultValue = "false")
private Boolean isVeto;
@Schema(description = "优先级")
private Integer priority;
@Schema(description = "提取方式ai-AI提取/manual-人工录入")
private String extractionMethod;
@Schema(description = "置信度分数")
private BigDecimal confidenceScore;
@Schema(description = "来源位置")
private JsonNode sourceLocation;
@Schema(description = "合规状态compliant-符合/non_compliant-不符合/pending-待确认")
private String complianceStatus;
@Schema(description = "响应内容")
private String responseContent;
@Schema(description = "备注")
private String notes;
}

View File

@@ -0,0 +1,66 @@
package org.xyzh.api.bidding.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import java.util.Date;
import java.util.List;
/**
* 项目流程节点DTO
* 用于创建和更新流程节点
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "项目流程节点DTO")
public class ProcessNodeDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "流程节点ID更新时需要")
private String processId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "节点名称")
private String nodeName;
@Schema(description = "节点类型collection-文件收集/analysis-需求分析/preparation-文件准备/review-内部审核/submission-投标提交/opening-开标/result-结果通知")
private String nodeType;
@Schema(description = "节点顺序")
private Integer nodeOrder;
@Schema(description = "节点状态pending-待处理/in_progress-进行中/completed-已完成/skipped-已跳过")
private String nodeStatus;
@Schema(description = "计划开始时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date plannedStartTime;
@Schema(description = "计划结束时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date plannedEndTime;
@Schema(description = "实际开始时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date actualStartTime;
@Schema(description = "实际结束时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date actualEndTime;
@Schema(description = "负责人")
private String responsibleUser;
@Schema(description = "参与人员")
private List<String> participants;
@Schema(description = "节点备注")
private String notes;
@Schema(description = "附件ID数组")
private List<String> attachments;
}

View File

@@ -0,0 +1,97 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import java.util.Date;
/**
* 投标文件VO
* 用于前端展示投标文件信息
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "投标文件VO")
public class BidResponseVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "响应文件ID")
private String responseId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "响应类型")
private String responseType;
@Schema(description = "响应类型名称(中文)")
private String responseTypeName;
@Schema(description = "文档名称")
private String docName;
@Schema(description = "文档大纲")
private String outline;
@Schema(description = "文档内容")
private String content;
@Schema(description = "内容字数")
private Integer contentWordCount;
@Schema(description = "生成方式")
private String generationMethod;
@Schema(description = "生成方式名称")
private String generationMethodName;
@Schema(description = "使用的模板ID")
private String templateId;
@Schema(description = "使用的模板名称")
private String templateName;
@Schema(description = "使用的AI模型")
private String aiModel;
@Schema(description = "生成状态")
private String generationStatus;
@Schema(description = "生成状态名称")
private String generationStatusName;
@Schema(description = "生成状态颜色标签")
private String statusColor;
@Schema(description = "关联文件ID")
private String fileId;
@Schema(description = "文件路径")
private String filePath;
@Schema(description = "文件下载URL")
private String fileUrl;
@Schema(description = "版本号")
private String version;
@Schema(description = "父版本ID")
private String parentVersionId;
@Schema(description = "是否有历史版本", defaultValue = "false")
private Boolean hasHistory;
@Schema(description = "审核意见")
private String reviewComments;
@Schema(description = "创建者姓名")
private String creatorName;
@Schema(description = "更新者姓名")
private String updaterName;
}

View File

@@ -0,0 +1,90 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.Date;
/**
* 招标文档VO
* 用于前端展示招标文档信息
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标文档VO")
public class BiddingDocumentVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "文档ID")
private String docId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "文档类型")
private String docType;
@Schema(description = "文档类型名称(中文)")
private String docTypeName;
@Schema(description = "文档名称")
private String docName;
@Schema(description = "关联文件ID")
private String fileId;
@Schema(description = "文件路径")
private String filePath;
@Schema(description = "文件下载URL")
private String fileUrl;
@Schema(description = "文件大小")
private Long fileSize;
@Schema(description = "文件大小格式化显示")
private String fileSizeFormatted;
@Schema(description = "MIME类型")
private String mimeType;
@Schema(description = "文件类型图标")
private String fileIcon;
@Schema(description = "版本号")
private String version;
@Schema(description = "语言")
private String language;
@Schema(description = "页数")
private Integer pageCount;
@Schema(description = "解析状态")
private String parseStatus;
@Schema(description = "解析状态名称")
private String parseStatusName;
@Schema(description = "解析结果")
private JsonNode parseResult;
@Schema(description = "提取的结构化数据")
private JsonNode extractionData;
@Schema(description = "AI分析结果")
private String aiAnalysis;
@Schema(description = "上传日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date uploadDate;
@Schema(description = "创建者姓名")
private String creatorName;
}

View File

@@ -0,0 +1,135 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 招标项目VO
* 用于前端展示招标项目详细信息
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标项目VO")
public class BiddingProjectVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "项目ID")
private String projectId;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "项目类型")
private String projectType;
@Schema(description = "项目类型名称(中文)")
private String projectTypeName;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "来源平台")
private String sourcePlatform;
@Schema(description = "来源URL")
private String sourceUrl;
@Schema(description = "发布日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date publishDate;
@Schema(description = "投标截止日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date deadline;
@Schema(description = "开标日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date openingDate;
@Schema(description = "距离截止日期剩余天数")
private Long daysUntilDeadline;
@Schema(description = "预算金额")
private BigDecimal budgetAmount;
@Schema(description = "货币单位")
private String currency;
@Schema(description = "预算金额格式化显示")
private String budgetAmountFormatted;
@Schema(description = "项目状态")
private String projectStatus;
@Schema(description = "项目状态名称(中文)")
private String projectStatusName;
@Schema(description = "中标状态")
private String winningStatus;
@Schema(description = "中标状态名称(中文)")
private String winningStatusName;
@Schema(description = "中标金额")
private BigDecimal winningAmount;
@Schema(description = "中标金额格式化显示")
private String winningAmountFormatted;
@Schema(description = "客户名称")
private String clientName;
@Schema(description = "客户联系方式")
private String clientContact;
@Schema(description = "联系人")
private String contactPerson;
@Schema(description = "项目地点")
private String projectLocation;
@Schema(description = "项目描述")
private String description;
@Schema(description = "关键词")
private List<String> keywords;
@Schema(description = "负责人ID")
private String responsibleUser;
@Schema(description = "负责人姓名")
private String responsibleUserName;
@Schema(description = "团队成员")
private List<String> teamMembers;
@Schema(description = "团队成员姓名列表")
private List<String> teamMemberNames;
@Schema(description = "部门名称")
private String deptName;
@Schema(description = "文档数量")
private Integer documentCount;
@Schema(description = "要素数量")
private Integer requirementCount;
@Schema(description = "否决项数量")
private Integer vetoCount;
@Schema(description = "投标文件数量")
private Integer responseCount;
@Schema(description = "完成进度(百分比)")
private Integer progressPercentage;
}

View File

@@ -0,0 +1,102 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.databind.JsonNode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 招标要素VO
* 用于前端展示招标要素信息
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标要素VO")
public class BiddingRequirementVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "要素ID")
private String reqId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "来源文档ID")
private String docId;
@Schema(description = "来源文档名称")
private String docName;
@Schema(description = "要素类别")
private String reqCategory;
@Schema(description = "要素类别名称(中文)")
private String reqCategoryName;
@Schema(description = "要素名称")
private String reqName;
@Schema(description = "要素内容")
private String reqContent;
@Schema(description = "要素值")
private String reqValue;
@Schema(description = "是否必填", defaultValue = "false")
private Boolean isMandatory;
@Schema(description = "是否为否决项", defaultValue = "false")
private Boolean isVeto;
@Schema(description = "优先级")
private Integer priority;
@Schema(description = "优先级标签(高/中/低)")
private String priorityLabel;
@Schema(description = "提取方式")
private String extractionMethod;
@Schema(description = "提取方式名称")
private String extractionMethodName;
@Schema(description = "置信度分数")
private BigDecimal confidenceScore;
@Schema(description = "置信度百分比")
private Integer confidencePercentage;
@Schema(description = "来源位置")
private JsonNode sourceLocation;
@Schema(description = "来源位置描述")
private String sourceLocationDesc;
@Schema(description = "合规状态")
private String complianceStatus;
@Schema(description = "合规状态名称")
private String complianceStatusName;
@Schema(description = "合规状态标签颜色")
private String complianceStatusColor;
@Schema(description = "响应内容")
private String responseContent;
@Schema(description = "是否已响应", defaultValue = "false")
private Boolean hasResponse;
@Schema(description = "备注")
private String notes;
@Schema(description = "创建者姓名")
private String creatorName;
}

View File

@@ -0,0 +1,102 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import java.util.Date;
import java.util.List;
/**
* 项目流程节点VO
* 用于前端展示流程节点信息
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "项目流程节点VO")
public class ProcessNodeVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "流程节点ID")
private String processId;
@Schema(description = "所属项目ID")
private String projectId;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "节点名称")
private String nodeName;
@Schema(description = "节点类型")
private String nodeType;
@Schema(description = "节点类型名称")
private String nodeTypeName;
@Schema(description = "节点顺序")
private Integer nodeOrder;
@Schema(description = "节点状态")
private String nodeStatus;
@Schema(description = "节点状态名称")
private String nodeStatusName;
@Schema(description = "节点状态颜色")
private String statusColor;
@Schema(description = "节点图标")
private String nodeIcon;
@Schema(description = "计划开始时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date plannedStartTime;
@Schema(description = "计划结束时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date plannedEndTime;
@Schema(description = "实际开始时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date actualStartTime;
@Schema(description = "实际结束时间", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date actualEndTime;
@Schema(description = "计划耗时(天)")
private Integer plannedDuration;
@Schema(description = "实际耗时(天)")
private Integer actualDuration;
@Schema(description = "是否延期", defaultValue = "false")
private Boolean isDelayed;
@Schema(description = "延期天数")
private Integer delayedDays;
@Schema(description = "负责人ID")
private String responsibleUser;
@Schema(description = "负责人姓名")
private String responsibleUserName;
@Schema(description = "参与人员ID列表")
private List<String> participants;
@Schema(description = "参与人员姓名列表")
private List<String> participantNames;
@Schema(description = "节点备注")
private String notes;
@Schema(description = "附件ID数组")
private List<String> attachments;
@Schema(description = "附件数量")
private Integer attachmentCount;
}

View File

@@ -0,0 +1,70 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.fastjson2.annotation.JSONField;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 招标项目列表VO简化版
* 用于前端列表展示
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "招标项目列表VO")
public class ProjectListVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "项目ID")
private String projectId;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "项目类型")
private String projectType;
@Schema(description = "项目类型名称")
private String projectTypeName;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "投标截止日期", format = "date-time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date deadline;
@Schema(description = "距离截止日期剩余天数")
private Long daysUntilDeadline;
@Schema(description = "是否即将截止(<3天", defaultValue = "false")
private Boolean isUrgent;
@Schema(description = "预算金额格式化显示")
private String budgetAmountFormatted;
@Schema(description = "项目状态")
private String projectStatus;
@Schema(description = "项目状态名称")
private String projectStatusName;
@Schema(description = "中标状态")
private String winningStatus;
@Schema(description = "客户名称")
private String clientName;
@Schema(description = "负责人姓名")
private String responsibleUserName;
@Schema(description = "完成进度(百分比)")
private Integer progressPercentage;
}

View File

@@ -0,0 +1,67 @@
package org.xyzh.api.bidding.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.util.Map;
/**
* 项目统计VO
* 用于前端展示项目统计数据
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "项目统计VO")
public class ProjectStatisticsVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "总项目数")
private Long totalProjects;
@Schema(description = "进行中的项目数")
private Long ongoingProjects;
@Schema(description = "已提交的项目数")
private Long submittedProjects;
@Schema(description = "已中标的项目数")
private Long wonProjects;
@Schema(description = "未中标的项目数")
private Long lostProjects;
@Schema(description = "中标率(百分比)")
private BigDecimal winRate;
@Schema(description = "即将截止的项目数(<3天")
private Long urgentProjects;
@Schema(description = "总预算金额")
private BigDecimal totalBudget;
@Schema(description = "总中标金额")
private BigDecimal totalWinningAmount;
@Schema(description = "按状态分组统计")
private Map<String, Long> projectsByStatus;
@Schema(description = "按类型分组统计")
private Map<String, Long> projectsByType;
@Schema(description = "按行业分组统计")
private Map<String, Long> projectsByIndustry;
@Schema(description = "按月份分组统计最近12个月")
private Map<String, Long> projectsByMonth;
@Schema(description = "按负责人分组统计")
private Map<String, Long> projectsByUser;
@Schema(description = "平均项目周期(天)")
private Integer avgProjectCycle;
@Schema(description = "最近7天新增项目数")
private Long recentNewProjects;
}