1.加入ai对话框 模块日报功能

This commit is contained in:
2026-03-25 08:41:07 +08:00
parent 6b22839ca1
commit b7b50046d4
16 changed files with 551 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportPageReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportRespVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportSaveReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.ReportCountByDateVO;
import cn.iocoder.yudao.module.ydoyun.service.aiassistantreport.AiAssistantReportService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - AI 决策助手报告单据")
@RestController
@RequestMapping("/ydoyun/ai-assistant-report")
@RequiredArgsConstructor
@Validated
public class AiAssistantReportController {
private final AiAssistantReportService aiAssistantReportService;
@PostMapping("/save")
@Operation(summary = "保存报告单据")
public CommonResult<Long> saveReport(@Valid @RequestBody AiAssistantReportSaveReqVO saveReqVO) {
return success(aiAssistantReportService.saveReport(saveReqVO));
}
@GetMapping("/my-list")
@Operation(summary = "查询当前人当前模块的历史报告")
public CommonResult<List<AiAssistantReportRespVO>> getMyReportList(
@Parameter(description = "报告人ID", required = true) @RequestParam("reporterId") Long reporterId,
@Parameter(description = "模块编码(可选,为空查所有)") @RequestParam(value = "moduleCode", required = false) String moduleCode) {
return success(aiAssistantReportService.getMyReportList(reporterId, moduleCode));
}
@GetMapping("/my-report-dates")
@Operation(summary = "查询有报告的日期列表(用于日历点状图,不提供补写)")
public CommonResult<List<LocalDate>> getMyReportDates(
@Parameter(description = "报告人ID", required = true) @RequestParam("reporterId") Long reporterId,
@Parameter(description = "模块编码(可选)") @RequestParam(value = "moduleCode", required = false) String moduleCode,
@Parameter(description = "开始日期", required = true) @RequestParam("startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
@Parameter(description = "结束日期", required = true) @RequestParam("endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
return success(aiAssistantReportService.getMyReportDates(reporterId, moduleCode, startDate, endDate));
}
@GetMapping("/list-by-date")
@Operation(summary = "按日期查询报告列表(日历点击查看详情)")
public CommonResult<List<AiAssistantReportRespVO>> getListByDate(
@Parameter(description = "报告人ID", required = true) @RequestParam("reporterId") Long reporterId,
@Parameter(description = "模块编码(可选)") @RequestParam(value = "moduleCode", required = false) String moduleCode,
@Parameter(description = "报告日期", required = true) @RequestParam("reportDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate reportDate) {
return success(aiAssistantReportService.getListByDate(reporterId, moduleCode, reportDate));
}
@GetMapping("/my-page")
@Operation(summary = "分页查询当前人历史报告(按最新记录排序)")
public CommonResult<PageResult<AiAssistantReportRespVO>> getMyReportPage(@Valid AiAssistantReportPageReqVO reqVO) {
return success(aiAssistantReportService.getMyReportPage(reqVO));
}
@GetMapping("/report-count-by-date")
@Operation(summary = "按日期聚合报告提交数量(用于轨迹图)")
public CommonResult<List<ReportCountByDateVO>> getReportCountByDate(
@Parameter(description = "报告人ID", required = true) @RequestParam("reporterId") Long reporterId,
@Parameter(description = "模块编码(可选)") @RequestParam(value = "moduleCode", required = false) String moduleCode,
@Parameter(description = "开始日期", required = true) @RequestParam("startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
@Parameter(description = "结束日期", required = true) @RequestParam("endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
return success(aiAssistantReportService.getReportCountByDate(reporterId, moduleCode, startDate, endDate));
}
}

View File

@@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
@Schema(description = "管理后台 - AI 决策助手报告分页 Request VO")
@Data
public class AiAssistantReportPageReqVO extends PageParam {
@Schema(description = "报告人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long reporterId;
@Schema(description = "模块编码")
private String moduleCode;
@Schema(description = "报告时间-开始")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate reportTimeStart;
@Schema(description = "报告时间-结束")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate reportTimeEnd;
}

View File

@@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - AI 决策助手报告单据 Response VO")
@Data
public class AiAssistantReportRespVO {
@Schema(description = "主键ID")
private Long id;
@Schema(description = "模块名称")
private String moduleName;
@Schema(description = "模块编码")
private String moduleCode;
@Schema(description = "报告人")
private String reporter;
@Schema(description = "报告人ID")
private Long reporterId;
@Schema(description = "报告时间(年月日)")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate reportTime;
@Schema(description = "报告内容")
private String reportContent;
@Schema(description = "模块截图URL")
private String screenshotUrl;
@Schema(description = "创建时间")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
@Schema(description = "管理后台 - AI 决策助手报告单据 保存 Request VO")
@Data
public class AiAssistantReportSaveReqVO {
@Schema(description = "模块名称(当前组件名称)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "模块名称不能为空")
private String moduleName;
@Schema(description = "模块编码,如 SupplierPerformance:main")
private String moduleCode;
@Schema(description = "报告人", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "报告人不能为空")
private String reporter;
@Schema(description = "报告人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报告人ID不能为空")
private Long reporterId;
@Schema(description = "报告时间(年月日)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报告时间不能为空")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate reportTime;
@Schema(description = "报告内容")
private String reportContent;
@Schema(description = "模块截图URL")
private String screenshotUrl;
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
@Schema(description = "按日期聚合报告数量(用于轨迹图)")
@Data
public class ReportCountByDateVO {
@Schema(description = "报告日期")
private LocalDate reportTime;
@Schema(description = "该日提交数量")
private Long count;
}

View File

@@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.ydoyun.dal.dataobject.aiassistantreport;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import lombok.*;
import java.time.LocalDate;
/**
* AI 决策助手报告单据 DO
*
* @author 衣朵云
*/
@TableName("ydoyun_ai_assistant_report")
@KeySequence("ydoyun_ai_assistant_report_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AiAssistantReportDO extends TenantBaseDO {
@TableId
private Long id;
/** 模块名称(当前组件名称) */
private String moduleName;
/** 模块编码,如 SupplierPerformance:main */
private String moduleCode;
/** 报告人 */
private String reporter;
/** 报告人ID */
private Long reporterId;
/** 报告时间(年月日) */
private LocalDate reportTime;
/** 报告内容 */
private String reportContent;
/** 模块截图URL */
private String screenshotUrl;
}

View File

@@ -0,0 +1,82 @@
package cn.iocoder.yudao.module.ydoyun.dal.mysql.aiassistantreport;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportPageReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.ReportCountByDateVO;
import cn.iocoder.yudao.module.ydoyun.dal.dataobject.aiassistantreport.AiAssistantReportDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDate;
import java.util.List;
/**
* AI 决策助手报告单据 Mapper
*
* @author 衣朵云
*/
@Mapper
public interface AiAssistantReportMapper extends BaseMapperX<AiAssistantReportDO> {
default List<AiAssistantReportDO> selectListByReporterAndModule(Long reporterId, String moduleCode) {
return selectList(new LambdaQueryWrapperX<AiAssistantReportDO>()
.eq(AiAssistantReportDO::getReporterId, reporterId)
.eqIfPresent(AiAssistantReportDO::getModuleCode, moduleCode)
.orderByDesc(AiAssistantReportDO::getReportTime)
.orderByDesc(AiAssistantReportDO::getCreateTime)
.last("LIMIT 50"));
}
default List<AiAssistantReportDO> selectListByDate(Long reporterId, String moduleCode, LocalDate reportDate) {
return selectList(new LambdaQueryWrapperX<AiAssistantReportDO>()
.eq(AiAssistantReportDO::getReporterId, reporterId)
.eqIfPresent(AiAssistantReportDO::getModuleCode, moduleCode)
.eq(AiAssistantReportDO::getReportTime, reportDate)
.orderByDesc(AiAssistantReportDO::getCreateTime));
}
/**
* 查询指定范围内有报告的去重日期列表(用于日历展示)
*/
@Select("<script>"
+ "SELECT DISTINCT report_time FROM ydoyun_ai_assistant_report "
+ "WHERE reporter_id = #{reporterId} AND deleted = 0 "
+ "<if test='moduleCode != null and moduleCode != \"\"'> AND module_code = #{moduleCode} </if>"
+ "AND report_time BETWEEN #{startDate} AND #{endDate} "
+ "ORDER BY report_time"
+ "</script>")
List<LocalDate> selectDistinctReportDates(
@Param("reporterId") Long reporterId,
@Param("moduleCode") String moduleCode,
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate);
default PageResult<AiAssistantReportDO> selectPage(AiAssistantReportPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiAssistantReportDO>()
.eq(AiAssistantReportDO::getReporterId, reqVO.getReporterId())
.eqIfPresent(AiAssistantReportDO::getModuleCode, reqVO.getModuleCode())
.geIfPresent(AiAssistantReportDO::getReportTime, reqVO.getReportTimeStart())
.leIfPresent(AiAssistantReportDO::getReportTime, reqVO.getReportTimeEnd())
.orderByDesc(AiAssistantReportDO::getReportTime)
.orderByDesc(AiAssistantReportDO::getCreateTime));
}
/**
* 按日期聚合报告提交数量(用于轨迹图)
*/
@Select("<script>"
+ "SELECT report_time AS reportTime, COUNT(*) AS count FROM ydoyun_ai_assistant_report "
+ "WHERE reporter_id = #{reporterId} AND deleted = 0 "
+ "<if test='moduleCode != null and moduleCode != \"\"'> AND module_code = #{moduleCode} </if>"
+ "AND report_time BETWEEN #{startDate} AND #{endDate} "
+ "GROUP BY report_time ORDER BY report_time"
+ "</script>")
List<ReportCountByDateVO> selectReportCountByDate(
@Param("reporterId") Long reporterId,
@Param("moduleCode") String moduleCode,
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate);
}

View File

@@ -0,0 +1,76 @@
package cn.iocoder.yudao.module.ydoyun.service.aiassistantreport;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportPageReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportRespVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportSaveReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.ReportCountByDateVO;
import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;
/**
* AI 决策助手报告单据 Service
*
* @author 衣朵云
*/
public interface AiAssistantReportService {
/**
* 保存报告单据
*
* @param saveReqVO 保存参数
* @return 主键ID
*/
Long saveReport(@Valid AiAssistantReportSaveReqVO saveReqVO);
/**
* 查询当前人当前模块的历史报告列表
*
* @param reporterId 报告人ID
* @param moduleCode 模块编码(可选,为空时查询该用户所有模块)
* @return 报告列表按报告时间倒序最多50条
*/
List<AiAssistantReportRespVO> getMyReportList(Long reporterId, String moduleCode);
/**
* 查询指定日期范围内有报告的日期列表(去重,用于日历点状图)
*
* @param reporterId 报告人ID
* @param moduleCode 模块编码(可选)
* @param startDate 开始日期
* @param endDate 结束日期
* @return 有报告的日期列表
*/
List<LocalDate> getMyReportDates(Long reporterId, String moduleCode, LocalDate startDate, LocalDate endDate);
/**
* 按日期查询报告列表(用于日历点击查看详情)
*
* @param reporterId 报告人ID
* @param moduleCode 模块编码(可选)
* @param reportDate 报告日期
* @return 该日期的报告列表
*/
List<AiAssistantReportRespVO> getListByDate(Long reporterId, String moduleCode, LocalDate reportDate);
/**
* 分页查询当前人历史报告(按最新记录排序)
*
* @param reqVO 分页及查询条件
* @return 分页结果
*/
PageResult<AiAssistantReportRespVO> getMyReportPage(AiAssistantReportPageReqVO reqVO);
/**
* 按日期聚合报告提交数量(用于轨迹图,与分页列表解耦)
*
* @param reporterId 报告人ID
* @param moduleCode 模块编码(可选)
* @param startDate 开始日期
* @param endDate 结束日期
* @return 每日提交数量列表
*/
List<ReportCountByDateVO> getReportCountByDate(Long reporterId, String moduleCode, LocalDate startDate, LocalDate endDate);
}

View File

@@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.ydoyun.service.aiassistantreport;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportPageReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportRespVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.AiAssistantReportSaveReqVO;
import cn.iocoder.yudao.module.ydoyun.controller.admin.aiassistantreport.vo.ReportCountByDateVO;
import cn.iocoder.yudao.module.ydoyun.dal.dataobject.aiassistantreport.AiAssistantReportDO;
import cn.iocoder.yudao.module.ydoyun.dal.mysql.aiassistantreport.AiAssistantReportMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;
/**
* AI 决策助手报告单据 Service 实现类
*
* @author 衣朵云
*/
@Service
@Validated
public class AiAssistantReportServiceImpl implements AiAssistantReportService {
@Resource
private AiAssistantReportMapper aiAssistantReportMapper;
@Override
public Long saveReport(AiAssistantReportSaveReqVO saveReqVO) {
AiAssistantReportDO entity = BeanUtils.toBean(saveReqVO, AiAssistantReportDO.class);
aiAssistantReportMapper.insert(entity);
return entity.getId();
}
@Override
public List<AiAssistantReportRespVO> getMyReportList(Long reporterId, String moduleCode) {
List<AiAssistantReportDO> list = aiAssistantReportMapper.selectListByReporterAndModule(reporterId, moduleCode);
return BeanUtils.toBean(list, AiAssistantReportRespVO.class);
}
@Override
public List<LocalDate> getMyReportDates(Long reporterId, String moduleCode, LocalDate startDate, LocalDate endDate) {
return aiAssistantReportMapper.selectDistinctReportDates(reporterId, moduleCode, startDate, endDate);
}
@Override
public List<AiAssistantReportRespVO> getListByDate(Long reporterId, String moduleCode, LocalDate reportDate) {
List<AiAssistantReportDO> list = aiAssistantReportMapper.selectListByDate(reporterId, moduleCode, reportDate);
return BeanUtils.toBean(list, AiAssistantReportRespVO.class);
}
@Override
public PageResult<AiAssistantReportRespVO> getMyReportPage(AiAssistantReportPageReqVO reqVO) {
PageResult<AiAssistantReportDO> page = aiAssistantReportMapper.selectPage(reqVO);
return BeanUtils.toBean(page, AiAssistantReportRespVO.class);
}
@Override
public List<ReportCountByDateVO> getReportCountByDate(Long reporterId, String moduleCode, LocalDate startDate, LocalDate endDate) {
return aiAssistantReportMapper.selectReportCountByDate(reporterId, moduleCode, startDate, endDate);
}
}