录音统计
This commit is contained in:
173
src/main/java/com/rj/controller/AudioStatisticsController.java
Normal file
173
src/main/java/com/rj/controller/AudioStatisticsController.java
Normal file
@@ -0,0 +1,173 @@
|
||||
package com.rj.controller;
|
||||
|
||||
import com.rj.common.Result;
|
||||
import com.rj.entity.AudioManagementStatistics;
|
||||
import com.rj.scheduler.AudioStatisticsScheduler;
|
||||
import com.rj.service.IAudioManagementStatisticsService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门店录音统计控制器
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Tag(name = "门店录音统计", description = "门店录音统计相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/api/audio-statistics")
|
||||
public class AudioStatisticsController {
|
||||
|
||||
@Autowired
|
||||
private IAudioManagementStatisticsService audioStatisticsService;
|
||||
|
||||
@Autowired
|
||||
private AudioStatisticsScheduler audioStatisticsScheduler;
|
||||
|
||||
/**
|
||||
* 手动生成指定日期的统计数据
|
||||
*/
|
||||
@Operation(summary = "手动生成指定日期的统计数据", description = "手动触发指定日期的门店录音统计")
|
||||
@PostMapping("/generate")
|
||||
public Result generateStatistics(
|
||||
@Parameter(description = "统计日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
|
||||
try {
|
||||
int count = audioStatisticsScheduler.manualGenerateStatistics(date);
|
||||
Result result = Result.ok(count);
|
||||
result.setMsg("统计生成成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("统计生成失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定日期范围的统计数据
|
||||
*/
|
||||
@Operation(summary = "查询指定日期范围的统计数据", description = "查询指定日期范围内的门店录音统计数据")
|
||||
@GetMapping("/range")
|
||||
public Result getStatisticsByDateRange(
|
||||
@Parameter(description = "开始日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@Parameter(description = "结束日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
try {
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDateRange(startDate, endDate);
|
||||
Result result = Result.ok(statistics);
|
||||
result.setMsg("查询成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定门店的统计数据
|
||||
*/
|
||||
@Operation(summary = "查询指定门店的统计数据", description = "查询指定门店在指定日期范围内的录音统计数据")
|
||||
@GetMapping("/dealership/{dealershipId}")
|
||||
public Result getStatisticsByDealership(
|
||||
@Parameter(description = "门店ID")
|
||||
@PathVariable Long dealershipId,
|
||||
@Parameter(description = "开始日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@Parameter(description = "结束日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
try {
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDealership(dealershipId, startDate, endDate);
|
||||
Result result = Result.ok(statistics);
|
||||
result.setMsg("查询成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定销售人员的统计数据
|
||||
*/
|
||||
@Operation(summary = "查询指定销售人员的统计数据", description = "查询指定销售人员在指定日期范围内的录音统计数据")
|
||||
@GetMapping("/sales/{salesId}")
|
||||
public Result getStatisticsBySales(
|
||||
@Parameter(description = "销售人员ID")
|
||||
@PathVariable String salesId,
|
||||
@Parameter(description = "开始日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@Parameter(description = "结束日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
try {
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsBySales(salesId, startDate, endDate);
|
||||
Result result = Result.ok(statistics);
|
||||
result.setMsg("查询成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定项目的统计数据
|
||||
*/
|
||||
@Operation(summary = "查询指定项目的统计数据", description = "查询指定项目在指定日期范围内的录音统计数据")
|
||||
@GetMapping("/project/{projectId}")
|
||||
public Result getStatisticsByProject(
|
||||
@Parameter(description = "项目ID")
|
||||
@PathVariable String projectId,
|
||||
@Parameter(description = "开始日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@Parameter(description = "结束日期,格式:yyyy-MM-dd")
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
try {
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByProject(projectId, startDate, endDate);
|
||||
Result result = Result.ok(statistics);
|
||||
result.setMsg("查询成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定日期的统计数据
|
||||
*/
|
||||
@Operation(summary = "查询指定日期的统计数据", description = "查询指定日期的所有门店录音统计数据")
|
||||
@GetMapping("/date/{date}")
|
||||
public Result getStatisticsByDate(
|
||||
@Parameter(description = "统计日期,格式:yyyy-MM-dd")
|
||||
@PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
|
||||
try {
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDateRange(date, date);
|
||||
Result result = Result.ok(statistics);
|
||||
result.setMsg("查询成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取统计概览(最近7天)
|
||||
*/
|
||||
@Operation(summary = "获取统计概览", description = "获取最近7天的门店录音统计概览")
|
||||
@GetMapping("/overview")
|
||||
public Result getStatisticsOverview() {
|
||||
try {
|
||||
LocalDate endDate = LocalDate.now().minusDays(1); // 昨天
|
||||
LocalDate startDate = endDate.minusDays(6); // 7天前
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDateRange(startDate, endDate);
|
||||
Result result = Result.ok(statistics);
|
||||
result.setMsg("查询成功");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return Result.error("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
107
src/main/java/com/rj/entity/AudioManagementStatistics.java
Normal file
107
src/main/java/com/rj/entity/AudioManagementStatistics.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package com.rj.entity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 门店录音统计表
|
||||
* </p>
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("audio_management_statistics")
|
||||
@Schema(description="门店录音统计表")
|
||||
public class AudioManagementStatistics implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "门店ID")
|
||||
@TableField("dealership_id")
|
||||
private Long dealershipId;
|
||||
|
||||
@Schema(description = "门店名称")
|
||||
@TableField("dealership_name")
|
||||
private String dealershipName;
|
||||
|
||||
@Schema(description = "门店录音总时长(秒)")
|
||||
@TableField("dealership_total_duration")
|
||||
private Long dealershipTotalDuration;
|
||||
|
||||
@Schema(description = "门店录音数量")
|
||||
@TableField("dealership_recording_count")
|
||||
private Integer dealershipRecordingCount;
|
||||
|
||||
@Schema(description = "门店录音平均时长(秒)")
|
||||
@TableField("dealership_avg_duration")
|
||||
private BigDecimal dealershipAvgDuration;
|
||||
|
||||
@Schema(description = "销售人员ID")
|
||||
@TableField("sales_id")
|
||||
private String salesId;
|
||||
|
||||
@Schema(description = "销售人员姓名")
|
||||
@TableField("sales_name")
|
||||
private String salesName;
|
||||
|
||||
@Schema(description = "销售人员录音总时长(秒)")
|
||||
@TableField("sales_total_duration")
|
||||
private Long salesTotalDuration;
|
||||
|
||||
@Schema(description = "销售人员录音数量")
|
||||
@TableField("sales_recording_count")
|
||||
private Integer salesRecordingCount;
|
||||
|
||||
@Schema(description = "销售人员录音平均时长(秒)")
|
||||
@TableField("sales_avg_duration")
|
||||
private BigDecimal salesAvgDuration;
|
||||
|
||||
@Schema(description = "项目ID")
|
||||
@TableField("project_id")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
@TableField("project_name")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "项目录音总时长(秒)")
|
||||
@TableField("project_total_duration")
|
||||
private Long projectTotalDuration;
|
||||
|
||||
@Schema(description = "项目录音数量")
|
||||
@TableField("project_recording_count")
|
||||
private Integer projectRecordingCount;
|
||||
|
||||
@Schema(description = "项目录音平均时长(秒)")
|
||||
@TableField("project_avg_duration")
|
||||
private BigDecimal projectAvgDuration;
|
||||
|
||||
@Schema(description = "统计日期")
|
||||
@TableField("statistics_date")
|
||||
private LocalDate statisticsDate;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
@TableField("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
215
src/main/java/com/rj/example/AudioStatisticsExample.java
Normal file
215
src/main/java/com/rj/example/AudioStatisticsExample.java
Normal file
@@ -0,0 +1,215 @@
|
||||
package com.rj.example;
|
||||
|
||||
import com.rj.entity.AudioManagementStatistics;
|
||||
import com.rj.scheduler.AudioStatisticsScheduler;
|
||||
import com.rj.service.IAudioManagementStatisticsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门店录音统计功能使用示例
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Component
|
||||
public class AudioStatisticsExample {
|
||||
|
||||
@Autowired
|
||||
private IAudioManagementStatisticsService audioStatisticsService;
|
||||
|
||||
@Autowired
|
||||
private AudioStatisticsScheduler audioStatisticsScheduler;
|
||||
|
||||
/**
|
||||
* 示例1:手动生成指定日期的统计数据
|
||||
*/
|
||||
public void exampleGenerateStatistics() {
|
||||
System.out.println("=== 示例1:手动生成指定日期的统计数据 ===");
|
||||
|
||||
// 生成昨天的统计数据
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
int count = audioStatisticsScheduler.manualGenerateStatistics(yesterday);
|
||||
|
||||
System.out.println("生成统计记录数: " + count);
|
||||
System.out.println("统计日期: " + yesterday);
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例2:查询最近7天的统计数据
|
||||
*/
|
||||
public void exampleQueryRecentStatistics() {
|
||||
System.out.println("=== 示例2:查询最近7天的统计数据 ===");
|
||||
|
||||
LocalDate endDate = LocalDate.now().minusDays(1); // 昨天
|
||||
LocalDate startDate = endDate.minusDays(6); // 7天前
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDateRange(startDate, endDate);
|
||||
|
||||
System.out.println("查询到统计记录数: " + statistics.size());
|
||||
System.out.println("查询日期范围: " + startDate + " 到 " + endDate);
|
||||
|
||||
// 打印统计信息
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
System.out.println("门店: " + stat.getDealershipName() +
|
||||
", 日期: " + stat.getStatisticsDate() +
|
||||
", 录音数量: " + stat.getDealershipRecordingCount() +
|
||||
", 总时长: " + stat.getDealershipTotalDuration() + "秒" +
|
||||
", 平均时长: " + stat.getDealershipAvgDuration() + "秒");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例3:查询指定门店的统计数据
|
||||
*/
|
||||
public void exampleQueryDealershipStatistics() {
|
||||
System.out.println("=== 示例3:查询指定门店的统计数据 ===");
|
||||
|
||||
Long dealershipId = 1L; // 假设门店ID为1
|
||||
LocalDate startDate = LocalDate.now().minusDays(30); // 最近30天
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDealership(dealershipId, startDate, endDate);
|
||||
|
||||
System.out.println("门店ID: " + dealershipId);
|
||||
System.out.println("查询到统计记录数: " + statistics.size());
|
||||
|
||||
// 计算该门店的总统计
|
||||
long totalDuration = 0;
|
||||
int totalCount = 0;
|
||||
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
totalDuration += stat.getDealershipTotalDuration();
|
||||
totalCount += stat.getDealershipRecordingCount();
|
||||
}
|
||||
|
||||
System.out.println("门店总录音时长: " + totalDuration + "秒");
|
||||
System.out.println("门店总录音数量: " + totalCount);
|
||||
if (totalCount > 0) {
|
||||
System.out.println("门店平均录音时长: " + (totalDuration / totalCount) + "秒");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例4:查询指定销售人员的统计数据
|
||||
*/
|
||||
public void exampleQuerySalesStatistics() {
|
||||
System.out.println("=== 示例4:查询指定销售人员的统计数据 ===");
|
||||
|
||||
String salesId = "sales001"; // 假设销售人员ID
|
||||
LocalDate startDate = LocalDate.now().minusDays(30); // 最近30天
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsBySales(salesId, startDate, endDate);
|
||||
|
||||
System.out.println("销售人员ID: " + salesId);
|
||||
System.out.println("查询到统计记录数: " + statistics.size());
|
||||
|
||||
// 计算该销售人员的总统计
|
||||
long totalDuration = 0;
|
||||
int totalCount = 0;
|
||||
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
totalDuration += stat.getSalesTotalDuration();
|
||||
totalCount += stat.getSalesRecordingCount();
|
||||
}
|
||||
|
||||
System.out.println("销售人员总录音时长: " + totalDuration + "秒");
|
||||
System.out.println("销售人员总录音数量: " + totalCount);
|
||||
if (totalCount > 0) {
|
||||
System.out.println("销售人员平均录音时长: " + (totalDuration / totalCount) + "秒");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例5:查询指定项目的统计数据
|
||||
*/
|
||||
public void exampleQueryProjectStatistics() {
|
||||
System.out.println("=== 示例5:查询指定项目的统计数据 ===");
|
||||
|
||||
String projectId = "project001"; // 假设项目ID
|
||||
LocalDate startDate = LocalDate.now().minusDays(30); // 最近30天
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByProject(projectId, startDate, endDate);
|
||||
|
||||
System.out.println("项目ID: " + projectId);
|
||||
System.out.println("查询到统计记录数: " + statistics.size());
|
||||
|
||||
// 计算该项目的总统计
|
||||
long totalDuration = 0;
|
||||
int totalCount = 0;
|
||||
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
totalDuration += stat.getProjectTotalDuration();
|
||||
totalCount += stat.getProjectRecordingCount();
|
||||
}
|
||||
|
||||
System.out.println("项目总录音时长: " + totalDuration + "秒");
|
||||
System.out.println("项目总录音数量: " + totalCount);
|
||||
if (totalCount > 0) {
|
||||
System.out.println("项目平均录音时长: " + (totalDuration / totalCount) + "秒");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例6:批量生成历史统计数据
|
||||
*/
|
||||
public void exampleBatchGenerateStatistics() {
|
||||
System.out.println("=== 示例6:批量生成历史统计数据 ===");
|
||||
|
||||
// 生成最近30天的统计数据
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
LocalDate startDate = endDate.minusDays(29);
|
||||
|
||||
int totalCount = 0;
|
||||
for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
|
||||
try {
|
||||
int count = audioStatisticsScheduler.manualGenerateStatistics(date);
|
||||
totalCount += count;
|
||||
System.out.println("日期 " + date + " 生成统计记录数: " + count);
|
||||
} catch (Exception e) {
|
||||
System.err.println("日期 " + date + " 统计失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("批量生成完成,总记录数: " + totalCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行所有示例
|
||||
*/
|
||||
public void runAllExamples() {
|
||||
System.out.println("开始运行门店录音统计功能示例...");
|
||||
System.out.println();
|
||||
|
||||
try {
|
||||
exampleGenerateStatistics();
|
||||
System.out.println();
|
||||
|
||||
exampleQueryRecentStatistics();
|
||||
System.out.println();
|
||||
|
||||
exampleQueryDealershipStatistics();
|
||||
System.out.println();
|
||||
|
||||
exampleQuerySalesStatistics();
|
||||
System.out.println();
|
||||
|
||||
exampleQueryProjectStatistics();
|
||||
System.out.println();
|
||||
|
||||
exampleBatchGenerateStatistics();
|
||||
System.out.println();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("示例运行失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("示例运行完成!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.rj.mapper;
|
||||
|
||||
import com.rj.entity.AudioManagementStatistics;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
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;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 门店录音统计表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface AudioManagementStatisticsMapper extends BaseMapper<AudioManagementStatistics> {
|
||||
|
||||
/**
|
||||
* 按门店统计指定日期的录音数据
|
||||
* @param date 统计日期
|
||||
* @return 门店统计结果列表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
"dealership_id, " +
|
||||
"dealership_name, " +
|
||||
"SUM(duration * 60) as total_duration_seconds, " +
|
||||
"COUNT(*) as recording_count, " +
|
||||
"AVG(duration * 60) as avg_duration_seconds " +
|
||||
"FROM audio_management " +
|
||||
"WHERE DATE(recording_time) = #{date} " +
|
||||
"AND dealership_id IS NOT NULL " +
|
||||
"AND dealership_id != '' " +
|
||||
"GROUP BY dealership_id, dealership_name")
|
||||
List<Map<String, Object>> getDealershipStatisticsByDate(@Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 按销售人员统计指定日期的录音数据
|
||||
* @param date 统计日期
|
||||
* @return 销售人员统计结果列表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
"sales_id, " +
|
||||
"sales_name, " +
|
||||
"SUM(duration * 60) as total_duration_seconds, " +
|
||||
"COUNT(*) as recording_count, " +
|
||||
"AVG(duration * 60) as avg_duration_seconds " +
|
||||
"FROM audio_management " +
|
||||
"WHERE DATE(recording_time) = #{date} " +
|
||||
"AND sales_id IS NOT NULL " +
|
||||
"AND sales_id != '' " +
|
||||
"GROUP BY sales_id, sales_name")
|
||||
List<Map<String, Object>> getSalesStatisticsByDate(@Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 按项目统计指定日期的录音数据
|
||||
* @param date 统计日期
|
||||
* @return 项目统计结果列表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
"project_id, " +
|
||||
"project_name, " +
|
||||
"SUM(duration * 60) as total_duration_seconds, " +
|
||||
"COUNT(*) as recording_count, " +
|
||||
"AVG(duration * 60) as avg_duration_seconds " +
|
||||
"FROM audio_management " +
|
||||
"WHERE DATE(recording_time) = #{date} " +
|
||||
"AND project_id IS NOT NULL " +
|
||||
"AND project_id != '' " +
|
||||
"GROUP BY project_id, project_name")
|
||||
List<Map<String, Object>> getProjectStatisticsByDate(@Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 检查指定日期的统计数据是否已存在
|
||||
* @param date 统计日期
|
||||
* @return 统计记录数量
|
||||
*/
|
||||
@Select("SELECT COUNT(*) FROM audio_management_statistics WHERE statistics_date = #{date}")
|
||||
int countByStatisticsDate(@Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 删除指定日期的统计数据
|
||||
* @param date 统计日期
|
||||
* @return 删除的记录数
|
||||
*/
|
||||
int deleteByStatisticsDate(@Param("date") LocalDate date);
|
||||
}
|
||||
58
src/main/java/com/rj/scheduler/AudioStatisticsScheduler.java
Normal file
58
src/main/java/com/rj/scheduler/AudioStatisticsScheduler.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package com.rj.scheduler;
|
||||
|
||||
import com.rj.service.IAudioManagementStatisticsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 门店录音统计定时任务
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AudioStatisticsScheduler {
|
||||
|
||||
@Autowired
|
||||
private IAudioManagementStatisticsService audioStatisticsService;
|
||||
|
||||
/**
|
||||
* 每天凌晨2点执行门店录音统计
|
||||
* 统计昨天的录音数据
|
||||
*/
|
||||
@Scheduled(cron = "0 0 2 * * ?")
|
||||
public void generateDailyAudioStatistics() {
|
||||
try {
|
||||
log.info("开始执行门店录音统计任务...");
|
||||
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
int count = audioStatisticsService.generateStatisticsByDate(yesterday);
|
||||
|
||||
log.info("门店录音统计任务执行完成,统计日期:{},生成记录数:{}", yesterday, count);
|
||||
} catch (Exception e) {
|
||||
log.error("门店录音统计任务执行失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动触发统计任务(用于测试或补录数据)
|
||||
* @param date 要统计的日期
|
||||
* @return 生成的记录数
|
||||
*/
|
||||
public int manualGenerateStatistics(LocalDate date) {
|
||||
try {
|
||||
log.info("手动执行门店录音统计任务,统计日期:{}", date);
|
||||
int count = audioStatisticsService.generateStatisticsByDate(date);
|
||||
log.info("手动门店录音统计任务执行完成,统计日期:{},生成记录数:{}", date, count);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error("手动门店录音统计任务执行失败,统计日期:{}", date, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.rj.service;
|
||||
|
||||
import com.rj.entity.AudioManagementStatistics;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 门店录音统计表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
public interface IAudioManagementStatisticsService extends IService<AudioManagementStatistics> {
|
||||
|
||||
/**
|
||||
* 生成指定日期的门店录音统计数据
|
||||
* @param date 统计日期
|
||||
* @return 生成的统计记录数量
|
||||
*/
|
||||
int generateStatisticsByDate(LocalDate date);
|
||||
|
||||
/**
|
||||
* 生成昨天的门店录音统计数据
|
||||
* @return 生成的统计记录数量
|
||||
*/
|
||||
int generateYesterdayStatistics();
|
||||
|
||||
/**
|
||||
* 查询指定日期范围的统计数据
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 统计记录列表
|
||||
*/
|
||||
List<AudioManagementStatistics> getStatisticsByDateRange(LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 查询指定门店的统计数据
|
||||
* @param dealershipId 门店ID
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 统计记录列表
|
||||
*/
|
||||
List<AudioManagementStatistics> getStatisticsByDealership(Long dealershipId, LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 查询指定销售人员的统计数据
|
||||
* @param salesId 销售人员ID
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 统计记录列表
|
||||
*/
|
||||
List<AudioManagementStatistics> getStatisticsBySales(String salesId, LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 查询指定项目的统计数据
|
||||
* @param projectId 项目ID
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 统计记录列表
|
||||
*/
|
||||
List<AudioManagementStatistics> getStatisticsByProject(String projectId, LocalDate startDate, LocalDate endDate);
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package com.rj.service.impl;
|
||||
|
||||
import com.rj.entity.AudioManagementStatistics;
|
||||
import com.rj.mapper.AudioManagementStatisticsMapper;
|
||||
import com.rj.service.IAudioManagementStatisticsService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 门店录音统计表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Service
|
||||
public class AudioManagementStatisticsServiceImpl extends ServiceImpl<AudioManagementStatisticsMapper, AudioManagementStatistics> implements IAudioManagementStatisticsService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int generateStatisticsByDate(LocalDate date) {
|
||||
// 先删除该日期的统计数据(如果存在)
|
||||
baseMapper.deleteByStatisticsDate(date);
|
||||
|
||||
// 查询该日期的门店录音统计数据
|
||||
List<Map<String, Object>> dealershipStatsList = baseMapper.getDealershipStatisticsByDate(date);
|
||||
|
||||
// 查询该日期的销售人员录音统计数据
|
||||
List<Map<String, Object>> salesStatsList = baseMapper.getSalesStatisticsByDate(date);
|
||||
|
||||
// 查询该日期的项目录音统计数据
|
||||
List<Map<String, Object>> projectStatsList = baseMapper.getProjectStatisticsByDate(date);
|
||||
|
||||
int count = 0;
|
||||
|
||||
// 处理门店统计数据
|
||||
for (Map<String, Object> stat : dealershipStatsList) {
|
||||
AudioManagementStatistics statistics = new AudioManagementStatistics();
|
||||
|
||||
// 设置门店信息
|
||||
Object dealershipIdObj = stat.get("dealership_id");
|
||||
if (dealershipIdObj != null) {
|
||||
try {
|
||||
statistics.setDealershipId(Long.valueOf(dealershipIdObj.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果dealership_id是UUID格式,使用hashCode作为ID
|
||||
statistics.setDealershipId((long) dealershipIdObj.toString().hashCode());
|
||||
}
|
||||
} else {
|
||||
statistics.setDealershipId(0L);
|
||||
}
|
||||
|
||||
Object dealershipNameObj = stat.get("dealership_name");
|
||||
statistics.setDealershipName(dealershipNameObj != null ? dealershipNameObj.toString() : "未知门店");
|
||||
|
||||
// 设置门店录音统计数据
|
||||
Object totalDurationObj = stat.get("total_duration_seconds");
|
||||
if (totalDurationObj != null) {
|
||||
statistics.setDealershipTotalDuration(Long.valueOf(totalDurationObj.toString()));
|
||||
} else {
|
||||
statistics.setDealershipTotalDuration(0L);
|
||||
}
|
||||
|
||||
Object recordingCountObj = stat.get("recording_count");
|
||||
if (recordingCountObj != null) {
|
||||
statistics.setDealershipRecordingCount(Integer.valueOf(recordingCountObj.toString()));
|
||||
} else {
|
||||
statistics.setDealershipRecordingCount(0);
|
||||
}
|
||||
|
||||
// 计算门店平均时长
|
||||
if (statistics.getDealershipRecordingCount() > 0 && statistics.getDealershipTotalDuration() > 0) {
|
||||
BigDecimal avgDuration = BigDecimal.valueOf(statistics.getDealershipTotalDuration())
|
||||
.divide(BigDecimal.valueOf(statistics.getDealershipRecordingCount()), 2, RoundingMode.HALF_UP);
|
||||
statistics.setDealershipAvgDuration(avgDuration);
|
||||
} else {
|
||||
statistics.setDealershipAvgDuration(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 查找该门店对应的销售人员统计数据
|
||||
String dealershipId = dealershipIdObj != null ? dealershipIdObj.toString() : "";
|
||||
Map<String, Object> salesStat = findSalesStatByDealership(salesStatsList, dealershipId);
|
||||
|
||||
if (salesStat != null) {
|
||||
// 设置销售人员信息
|
||||
Object salesIdObj = salesStat.get("sales_id");
|
||||
statistics.setSalesId(salesIdObj != null ? salesIdObj.toString() : "");
|
||||
|
||||
Object salesNameObj = salesStat.get("sales_name");
|
||||
statistics.setSalesName(salesNameObj != null ? salesNameObj.toString() : "未知销售");
|
||||
|
||||
// 设置销售人员录音统计数据
|
||||
Object salesTotalDurationObj = salesStat.get("total_duration_seconds");
|
||||
if (salesTotalDurationObj != null) {
|
||||
statistics.setSalesTotalDuration(Long.valueOf(salesTotalDurationObj.toString()));
|
||||
} else {
|
||||
statistics.setSalesTotalDuration(0L);
|
||||
}
|
||||
|
||||
Object salesRecordingCountObj = salesStat.get("recording_count");
|
||||
if (salesRecordingCountObj != null) {
|
||||
statistics.setSalesRecordingCount(Integer.valueOf(salesRecordingCountObj.toString()));
|
||||
} else {
|
||||
statistics.setSalesRecordingCount(0);
|
||||
}
|
||||
|
||||
// 计算销售人员平均时长
|
||||
if (statistics.getSalesRecordingCount() > 0 && statistics.getSalesTotalDuration() > 0) {
|
||||
BigDecimal salesAvgDuration = BigDecimal.valueOf(statistics.getSalesTotalDuration())
|
||||
.divide(BigDecimal.valueOf(statistics.getSalesRecordingCount()), 2, RoundingMode.HALF_UP);
|
||||
statistics.setSalesAvgDuration(salesAvgDuration);
|
||||
} else {
|
||||
statistics.setSalesAvgDuration(BigDecimal.ZERO);
|
||||
}
|
||||
} else {
|
||||
// 如果没有找到对应的销售人员数据,设置为空
|
||||
statistics.setSalesId("");
|
||||
statistics.setSalesName("");
|
||||
statistics.setSalesTotalDuration(0L);
|
||||
statistics.setSalesRecordingCount(0);
|
||||
statistics.setSalesAvgDuration(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 查找该门店对应的项目统计数据
|
||||
String dealershipIdForProject = dealershipIdObj != null ? dealershipIdObj.toString() : "";
|
||||
Map<String, Object> projectStat = findProjectStatByDealership(projectStatsList, dealershipIdForProject);
|
||||
|
||||
if (projectStat != null) {
|
||||
// 设置项目信息
|
||||
Object projectIdObj = projectStat.get("project_id");
|
||||
statistics.setProjectId(projectIdObj != null ? projectIdObj.toString() : "");
|
||||
|
||||
Object projectNameObj = projectStat.get("project_name");
|
||||
statistics.setProjectName(projectNameObj != null ? projectNameObj.toString() : "未知项目");
|
||||
|
||||
// 设置项目录音统计数据
|
||||
Object projectTotalDurationObj = projectStat.get("total_duration_seconds");
|
||||
if (projectTotalDurationObj != null) {
|
||||
statistics.setProjectTotalDuration(Long.valueOf(projectTotalDurationObj.toString()));
|
||||
} else {
|
||||
statistics.setProjectTotalDuration(0L);
|
||||
}
|
||||
|
||||
Object projectRecordingCountObj = projectStat.get("recording_count");
|
||||
if (projectRecordingCountObj != null) {
|
||||
statistics.setProjectRecordingCount(Integer.valueOf(projectRecordingCountObj.toString()));
|
||||
} else {
|
||||
statistics.setProjectRecordingCount(0);
|
||||
}
|
||||
|
||||
// 计算项目平均时长
|
||||
if (statistics.getProjectRecordingCount() > 0 && statistics.getProjectTotalDuration() > 0) {
|
||||
BigDecimal projectAvgDuration = BigDecimal.valueOf(statistics.getProjectTotalDuration())
|
||||
.divide(BigDecimal.valueOf(statistics.getProjectRecordingCount()), 2, RoundingMode.HALF_UP);
|
||||
statistics.setProjectAvgDuration(projectAvgDuration);
|
||||
} else {
|
||||
statistics.setProjectAvgDuration(BigDecimal.ZERO);
|
||||
}
|
||||
} else {
|
||||
// 如果没有找到对应的项目数据,设置为空
|
||||
statistics.setProjectId("");
|
||||
statistics.setProjectName("");
|
||||
statistics.setProjectTotalDuration(0L);
|
||||
statistics.setProjectRecordingCount(0);
|
||||
statistics.setProjectAvgDuration(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 设置统计日期和时间
|
||||
statistics.setStatisticsDate(date);
|
||||
statistics.setCreatedAt(LocalDateTime.now());
|
||||
statistics.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
// 保存统计记录
|
||||
save(statistics);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据门店ID查找对应的销售人员统计数据
|
||||
* @param salesStatsList 销售人员统计列表
|
||||
* @param dealershipId 门店ID
|
||||
* @return 销售人员统计数据
|
||||
*/
|
||||
private Map<String, Object> findSalesStatByDealership(List<Map<String, Object>> salesStatsList, String dealershipId) {
|
||||
// 这里需要根据业务逻辑来确定门店和销售人员的对应关系
|
||||
// 由于原始数据中可能没有直接的关联关系,这里返回第一个销售人员数据作为示例
|
||||
// 实际使用时需要根据具体的业务逻辑来调整
|
||||
if (!salesStatsList.isEmpty()) {
|
||||
return salesStatsList.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据门店ID查找对应的项目统计数据
|
||||
* @param projectStatsList 项目统计列表
|
||||
* @param dealershipId 门店ID
|
||||
* @return 项目统计数据
|
||||
*/
|
||||
private Map<String, Object> findProjectStatByDealership(List<Map<String, Object>> projectStatsList, String dealershipId) {
|
||||
// 这里需要根据业务逻辑来确定门店和项目的对应关系
|
||||
// 由于原始数据中可能没有直接的关联关系,这里返回第一个项目数据作为示例
|
||||
// 实际使用时需要根据具体的业务逻辑来调整
|
||||
if (!projectStatsList.isEmpty()) {
|
||||
return projectStatsList.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int generateYesterdayStatistics() {
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
return generateStatisticsByDate(yesterday);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AudioManagementStatistics> getStatisticsByDateRange(LocalDate startDate, LocalDate endDate) {
|
||||
LambdaQueryWrapper<AudioManagementStatistics> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.between(AudioManagementStatistics::getStatisticsDate, startDate, endDate)
|
||||
.orderByAsc(AudioManagementStatistics::getStatisticsDate)
|
||||
.orderByAsc(AudioManagementStatistics::getDealershipId);
|
||||
return list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AudioManagementStatistics> getStatisticsByDealership(Long dealershipId, LocalDate startDate, LocalDate endDate) {
|
||||
LambdaQueryWrapper<AudioManagementStatistics> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AudioManagementStatistics::getDealershipId, dealershipId)
|
||||
.between(AudioManagementStatistics::getStatisticsDate, startDate, endDate)
|
||||
.orderByAsc(AudioManagementStatistics::getStatisticsDate);
|
||||
return list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AudioManagementStatistics> getStatisticsBySales(String salesId, LocalDate startDate, LocalDate endDate) {
|
||||
LambdaQueryWrapper<AudioManagementStatistics> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AudioManagementStatistics::getSalesId, salesId)
|
||||
.between(AudioManagementStatistics::getStatisticsDate, startDate, endDate)
|
||||
.orderByAsc(AudioManagementStatistics::getStatisticsDate);
|
||||
return list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AudioManagementStatistics> getStatisticsByProject(String projectId, LocalDate startDate, LocalDate endDate) {
|
||||
LambdaQueryWrapper<AudioManagementStatistics> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(AudioManagementStatistics::getProjectId, projectId)
|
||||
.between(AudioManagementStatistics::getStatisticsDate, startDate, endDate)
|
||||
.orderByAsc(AudioManagementStatistics::getStatisticsDate);
|
||||
return list(queryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.rj.mapper.AudioManagementStatisticsMapper">
|
||||
|
||||
<!-- 删除指定日期的统计数据 -->
|
||||
<delete id="deleteByStatisticsDate" parameterType="java.time.LocalDate">
|
||||
DELETE FROM audio_management_statistics
|
||||
WHERE statistics_date = #{date}
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
73
src/main/sql/audio_management_statistics.sql
Normal file
73
src/main/sql/audio_management_statistics.sql
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
|
||||
-- 用于存储门店录音相关数据, 基础的原始数据,可以用于统计分析
|
||||
|
||||
CREATE TABLE `audio_management` (
|
||||
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键,UUID',
|
||||
`recording_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '录音名称',
|
||||
`recording_time` datetime NULL DEFAULT NULL COMMENT '录音时间',
|
||||
`info_card_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '信息卡',
|
||||
`sales_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所属销售ID',
|
||||
`sales_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所属销售名称',
|
||||
`duration` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '录音时长(分钟)',
|
||||
`customer_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '客户ID',
|
||||
`customer_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '客户姓名',
|
||||
`customer_phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '客户手机号',
|
||||
`upload_time` datetime NULL DEFAULT NULL COMMENT '上传时间',
|
||||
`intention_level` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '意向级别(高意向, 中意向 , 低意向)',
|
||||
`dealership_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所属门店ID',
|
||||
`dealership_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所属门店名称',
|
||||
`project_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所属项目ID',
|
||||
`project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所属项目名称',
|
||||
`script_model` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '话术模型',
|
||||
`upload_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上传状态',
|
||||
`sync_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '同步状态',
|
||||
`is_merged` tinyint(1) NULL DEFAULT 0 COMMENT '是否合并(0否1是)',
|
||||
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '录音备注',
|
||||
`company_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '公司类型',
|
||||
`edit_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '编辑状态',
|
||||
`edit_time` datetime NULL DEFAULT NULL COMMENT '编辑时间',
|
||||
`info_card_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '信息卡类型(如意向车型、购买情况、来访目的、试驾结果、付款方式、试驾专员等)',
|
||||
`info_card_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '信息卡内容',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '录音管理表,含信息卡字段' ROW_FORMAT = Dynamic;
|
||||
|
||||
|
||||
|
||||
-- 用于存储门店录音相关的统计数据
|
||||
CREATE TABLE `audio_management_statistics` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`dealership_id` bigint(20) NOT NULL COMMENT '门店ID',
|
||||
`dealership_name` varchar(100) NOT NULL COMMENT '门店名称',
|
||||
|
||||
-- 门店录音总时长相关字段
|
||||
`dealership_total_duration` bigint(20) NOT NULL DEFAULT 0 COMMENT '门店录音总时长(秒)',
|
||||
`dealership_recording_count` int(11) NOT NULL DEFAULT 0 COMMENT '门店录音数量',
|
||||
`dealership_avg_duration` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '门店录音平均时长(秒)',
|
||||
|
||||
-- 个人录音相关字段
|
||||
`personal_total_duration` bigint(20) NOT NULL DEFAULT 0 COMMENT '个人录音总时长(秒)',
|
||||
`personal_recording_count` int(11) NOT NULL DEFAULT 0 COMMENT '个人录音数量',
|
||||
`personal_avg_duration` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '个人录音平均时长(秒)',
|
||||
|
||||
-- 项目录音相关字段
|
||||
`project_recording_count` int(11) NOT NULL DEFAULT 0 COMMENT '项目录音总数',
|
||||
`project_avg_duration` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '项目录音平均时长(秒)',
|
||||
|
||||
-- 统计日期
|
||||
`statistics_date` date NOT NULL COMMENT '统计日期',
|
||||
|
||||
-- 时间戳字段
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_statistics_date` (`statistics_date`) COMMENT '统计日期索引',
|
||||
KEY `idx_dealership_id` (`dealership_id`) COMMENT '门店ID索引',
|
||||
KEY `idx_created_at` (`created_at`) COMMENT '创建时间索引'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='门店录音统计表';
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.rj.service;
|
||||
|
||||
import com.rj.entity.AudioManagementStatistics;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* 门店录音统计服务测试类
|
||||
*
|
||||
* @author 李中华 ,spllzh
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
public class AudioManagementStatisticsServiceTest {
|
||||
|
||||
@Autowired
|
||||
private IAudioManagementStatisticsService audioStatisticsService;
|
||||
|
||||
@Test
|
||||
public void testGenerateStatisticsByDate() {
|
||||
// 测试生成指定日期的统计数据
|
||||
LocalDate testDate = LocalDate.now().minusDays(1);
|
||||
int count = audioStatisticsService.generateStatisticsByDate(testDate);
|
||||
|
||||
assertTrue(count >= 0, "统计记录数应该大于等于0");
|
||||
System.out.println("生成统计记录数: " + count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateYesterdayStatistics() {
|
||||
// 测试生成昨天的统计数据
|
||||
int count = audioStatisticsService.generateYesterdayStatistics();
|
||||
|
||||
assertTrue(count >= 0, "统计记录数应该大于等于0");
|
||||
System.out.println("生成昨天统计记录数: " + count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatisticsByDateRange() {
|
||||
// 测试查询日期范围的统计数据
|
||||
LocalDate startDate = LocalDate.now().minusDays(7);
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDateRange(startDate, endDate);
|
||||
|
||||
assertNotNull(statistics, "统计列表不应该为null");
|
||||
System.out.println("查询到统计记录数: " + statistics.size());
|
||||
|
||||
// 打印统计信息
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
System.out.println("门店: " + stat.getDealershipName() +
|
||||
", 日期: " + stat.getStatisticsDate() +
|
||||
", 录音数量: " + stat.getDealershipRecordingCount() +
|
||||
", 总时长: " + stat.getDealershipTotalDuration() + "秒" +
|
||||
", 平均时长: " + stat.getDealershipAvgDuration() + "秒");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatisticsByDealership() {
|
||||
// 测试查询指定门店的统计数据
|
||||
Long dealershipId = 1L; // 假设门店ID为1
|
||||
LocalDate startDate = LocalDate.now().minusDays(7);
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByDealership(dealershipId, startDate, endDate);
|
||||
|
||||
assertNotNull(statistics, "统计列表不应该为null");
|
||||
System.out.println("查询到门店统计记录数: " + statistics.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatisticsBySales() {
|
||||
// 测试查询指定销售人员的统计数据
|
||||
String salesId = "sales001"; // 假设销售人员ID
|
||||
LocalDate startDate = LocalDate.now().minusDays(30); // 最近30天
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsBySales(salesId, startDate, endDate);
|
||||
|
||||
assertNotNull(statistics, "统计列表不应该为null");
|
||||
System.out.println("查询到销售人员统计记录数: " + statistics.size());
|
||||
|
||||
// 打印销售人员统计信息
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
System.out.println("销售人员: " + stat.getSalesName() +
|
||||
", 日期: " + stat.getStatisticsDate() +
|
||||
", 录音数量: " + stat.getSalesRecordingCount() +
|
||||
", 总时长: " + stat.getSalesTotalDuration() + "秒" +
|
||||
", 平均时长: " + stat.getSalesAvgDuration() + "秒");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatisticsByProject() {
|
||||
// 测试查询指定项目的统计数据
|
||||
String projectId = "project001"; // 假设项目ID
|
||||
LocalDate startDate = LocalDate.now().minusDays(30); // 最近30天
|
||||
LocalDate endDate = LocalDate.now().minusDays(1);
|
||||
|
||||
List<AudioManagementStatistics> statistics = audioStatisticsService.getStatisticsByProject(projectId, startDate, endDate);
|
||||
|
||||
assertNotNull(statistics, "统计列表不应该为null");
|
||||
System.out.println("查询到项目统计记录数: " + statistics.size());
|
||||
|
||||
// 打印项目统计信息
|
||||
for (AudioManagementStatistics stat : statistics) {
|
||||
System.out.println("项目: " + stat.getProjectName() +
|
||||
", 日期: " + stat.getStatisticsDate() +
|
||||
", 录音数量: " + stat.getProjectRecordingCount() +
|
||||
", 总时长: " + stat.getProjectTotalDuration() + "秒" +
|
||||
", 平均时长: " + stat.getProjectAvgDuration() + "秒");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user