peicj 1 deň pred
rodič
commit
f9dfc18ea8

+ 68 - 13
ruoyi-admin/src/main/java/com/ruoyi/aicall/controller/ApiController.java

@@ -1420,16 +1420,30 @@ public class ApiController extends BaseController {
     //ai外呼记录查询
     private TableDataInfo getAiCallRecordsTable(ApiCallRecordQueryParams queryParams) {
         Map<String, Object> params = new HashMap<>();
-        params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
-        params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
         if (null != queryParams.getTimeLenStart()) {
-            params.put("timeLenSecondStart", queryParams.getTimeLenStart().toString());
+            params.put("timeLenStart", queryParams.getTimeLenStart());
         }
         if (null != queryParams.getTimeLenEnd()) {
-            params.put("timeLenSecondEnd", queryParams.getTimeLenEnd().toString());
+            params.put("timeLenEnd", queryParams.getTimeLenEnd());
+        }
+        if (null != queryParams.getCalloutTimeStart()) {
+            params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
+        }
+        if (null != queryParams.getCalloutTimeEnd()) {
+            params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
+        }
+        if (null != queryParams.getAnsweredTimeStart()) {
+            params.put("answeredTimeStart", queryParams.getAnsweredTimeStart());
+        }
+        if (null != queryParams.getAnsweredTimeEnd()) {
+            params.put("answeredTimeEnd", queryParams.getAnsweredTimeEnd());
+        }
+        if (null != queryParams.getCallEndTimeStart()) {
+            params.put("callEndTimeStart", queryParams.getCallEndTimeStart());
+        }
+        if (null != queryParams.getCallEndTimeEnd()) {
+            params.put("callEndTimeEnd", queryParams.getCallEndTimeEnd());
         }
-
-        startPage(queryParams.getPageNum(), queryParams.getPageSize());
         CcCallPhone ccCallPhone = new CcCallPhone();
         if (null != queryParams.getBatchId() && queryParams.getBatchId() > 0) {
             ccCallPhone.setBatchId(queryParams.getBatchId());
@@ -1440,7 +1454,8 @@ public class ApiController extends BaseController {
         ccCallPhone.setCallstatus(queryParams.getCallstatus());
         ccCallPhone.setCallerNumber(queryParams.getCallerNumber());
         ccCallPhone.setParams(params);
-        List<CcCallPhone> list = ccCallPhoneService.selectCcCallPhoneList(ccCallPhone);
+        startPage(queryParams.getPageNum(), queryParams.getPageSize());
+        List<CcCallPhone> list = ccCallPhoneService.selectCcCallPhoneYlrzList(ccCallPhone);
         list.forEach(callPhoneRecord -> {
             if(StringUtils.isNotBlank(callPhoneRecord.getWavfile())){
                 if (callPhoneRecord.getWavfile().startsWith("/")) {
@@ -1449,28 +1464,53 @@ public class ApiController extends BaseController {
                     callPhoneRecord.setWavfile("/recordings/files?filename=" + callPhoneRecord.getWavfile());
                 }
             }
+            callPhoneRecord.setCallstatusName( CcCallPhone.getCallStatusName(callPhoneRecord.getCallstatus()));
+            callPhoneRecord.setCalloutTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getCalloutTime())));
+            callPhoneRecord.setAnsweredTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getAnsweredTime())));
+            callPhoneRecord.setCallEndTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getCallEndTime())));
+            callPhoneRecord.setTimeLenSec(DateUtils.formatTimeLength(callPhoneRecord.getTimeLen()/1000));
         });
         return getDataTable(list);
     }
     //人工外呼记录查询
     private TableDataInfo getOutboundRecordsTable(ApiCallRecordQueryParams queryParams) {
         Map<String, Object> params = new HashMap<>();
-        params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
-        params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
         if (null != queryParams.getTimeLenStart()) {
-            params.put("timeLenSecondStart", queryParams.getTimeLenStart().toString());
+            params.put("timeLenStart", queryParams.getTimeLenStart());
         }
         if (null != queryParams.getTimeLenEnd()) {
-            params.put("timeLenSecondEnd", queryParams.getTimeLenEnd().toString());
+            params.put("timeLenEnd", queryParams.getTimeLenEnd());
+        }
+        if (null != queryParams.getCalloutTimeStart()) {
+            params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
+        }
+        if (null != queryParams.getCalloutTimeEnd()) {
+            params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
+        }
+        if (null != queryParams.getAnsweredTimeStart()) {
+            params.put("answeredTimeStart", queryParams.getAnsweredTimeStart());
+        }
+        if (null != queryParams.getAnsweredTimeEnd()) {
+            params.put("answeredTimeEnd", queryParams.getAnsweredTimeEnd());
+        }
+        if (null != queryParams.getEndTimeStart()) {
+            params.put("endTimeStart", queryParams.getEndTimeStart());
+        }
+        if (null != queryParams.getEndTimeEnd()) {
+            params.put("endTimeEnd", queryParams.getEndTimeEnd());
+        }
+        CcCallPhone ccCallPhone = new CcCallPhone();
+        if (null != queryParams.getBatchId() && queryParams.getBatchId() > 0) {
+            ccCallPhone.setBatchId(queryParams.getBatchId());
         }
 
-        startPage(queryParams.getPageNum(), queryParams.getPageSize());
         CcOutboundCdr outboundCdr = new CcOutboundCdr();
         outboundCdr.setUuid(queryParams.getUuid());
         outboundCdr.setCaller(queryParams.getTelephone());
         outboundCdr.setOpnum(queryParams.getExtnum());
         outboundCdr.setParams(params);
-        List<CcOutboundCdr> list = outboundCdrService.selectCcOutboundCdrList(outboundCdr);
+        startPage(queryParams.getPageNum(), queryParams.getPageSize());
+        List<CcOutboundCdr> list = outboundCdrService.selectCcOutboundCdrYlrzList(outboundCdr);
         list.forEach(callPhoneRecord -> {
             if(StringUtils.isNotBlank(callPhoneRecord.getRecordFilename())){
                 if (callPhoneRecord.getRecordFilename().startsWith("/")) {
@@ -1478,6 +1518,11 @@ public class ApiController extends BaseController {
                 }else{
                     callPhoneRecord.setWavFileUrl("/recordings/files?filename=" + callPhoneRecord.getRecordFilename());
                 }
+                callPhoneRecord.setStartTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getStartTime())));
+                callPhoneRecord.setAnsweredTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getAnsweredTime())));
+                callPhoneRecord.setEndTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getEndTime())));
+                callPhoneRecord.setTimeLenSec(DateUtils.formatTimeLength(callPhoneRecord.getTimeLen()/1000));
+                callPhoneRecord.setTimeLenValidStr(DateUtils.formatTimeLength(callPhoneRecord.getTimeLenValid()/1000));
             }
 
         });
@@ -1505,4 +1550,14 @@ public class ApiController extends BaseController {
         startPage(queryParams.getPageNum(), queryParams.getPageSize());
         return getDataTable(ccGatewaysService.selectCcGatewaysList(queryParams));
     }
+
+    /**
+     * 获取外呼任务接通数据
+     * @param batchIds 任务id集合
+     */
+    @PostMapping("/task/connectSum")
+    @ResponseBody
+    public AjaxResult taskConnectSum(@RequestBody List<Long> batchIds){
+        return AjaxResult.success(ccCallPhoneService.statByBatchIds(batchIds));
+    }
 }

+ 55 - 2
ruoyi-admin/src/main/java/com/ruoyi/aicall/domain/CcCallPhone.java

@@ -162,7 +162,6 @@ public class CcCallPhone implements Serializable {
     private Map<String, Object> params = new HashMap<>();
 
     /** 批次名称 */
-    @Excel(name = "批次名称", readConverterExp = "批次名称")
     private String batchName;
 
     /** manual agent answered time. */
@@ -171,5 +170,59 @@ public class CcCallPhone implements Serializable {
     /** The duration of the manual agent service time. */
     private String manualAnsweredTimeLen;
 
-
+    private String callstatusName;
+    private String calloutTimeStr;
+    private String answeredTimeStr;
+    private String callEndTimeStr;
+    private String timeLenSec;
+
+    /**
+     * 根据呼叫状态码获取状态名称
+     * @param status 状态码
+     * @return 状态名称
+     */
+    public static String getCallStatusName(Integer status) {
+        if (status == null) {
+            return "未知";
+        }
+        switch (status) {
+            case 0:
+                return "未拨打";
+            case 1:
+                return "已进入呼叫队列";
+            case 2:
+                return "正在拨号";
+            case 3:
+            case 30:
+                return "未接通";
+            case 4:
+                return "已接通";
+            case 5:
+                return "通话中断";
+            case 6:
+                return "成功转人工或 AI";
+            case 7:
+                return "线路故障";
+            case 31:
+                return "客户正在通话中";
+            case 32:
+                return "关机";
+            case 33:
+                return "空号";
+            case 34:
+                return "无人接听";
+            case 35:
+                return "停机";
+            case 36:
+                return "网络忙";
+            case 37:
+                return "语音助手";
+            case 38:
+                return "暂时无法接通";
+            case 39:
+                return "呼叫限制";
+            default:
+                return "未知状态";
+        }
+    }
 }

+ 8 - 0
ruoyi-admin/src/main/java/com/ruoyi/aicall/mapper/CcCallPhoneMapper.java

@@ -69,6 +69,12 @@ public interface CcCallPhoneMapper
      * @return
      */
     CallTaskStatModel statByBatchId(Long batchId);
+    /**
+     * 根据batchIds统计外呼数据
+     * @param batchIds
+     * @return
+     */
+    public List<CallTaskStatModel> statByBatchIds(List<Long> batchIds);
 
     /**
      * 批量入库
@@ -91,4 +97,6 @@ public interface CcCallPhoneMapper
     void delCallPhoneByBatchId(Long batchId);
 
     List<String> isDuplicateEntry(@Param("batchId") Long batchId,@Param("phoneList")  List<CommonPhoneModel> phoneList);
+
+    List<CcCallPhone> selectCcCallPhoneYlrzList(CcCallPhone ccCallPhone);
 }

+ 16 - 7
ruoyi-admin/src/main/java/com/ruoyi/aicall/model/ApiCallRecordQueryParams.java

@@ -20,25 +20,34 @@ public class ApiCallRecordQueryParams implements Serializable {
     /** 类型(01:呼入, 02:AI外呼, 03:人工外呼) */
     private String callType;
 
+    /** callType=02时可用 */
+    private Long batchId;
+
     /** 呼入caller/AI外呼telephone/人工外呼callee */
     private String telephone;
 
-    /** 呼入inboundTime/AI外呼calloutTime/人工外呼startTime */
-    private String calloutTimeStart;
-    private String calloutTimeEnd;
-
 
     /** 通话总时长起止 */
     private Integer timeLenStart;
     private Integer timeLenEnd;
 
+    /** 呼入inboundTime/AI外呼calloutTime/人工外呼startTime */
+    private String calloutTimeStart;
+    private String calloutTimeEnd;
+    /** 接听时间起止 */
+    private String answeredTimeStart;
+    private String answeredTimeEnd;
+    /** 自动外呼挂机时间起止 */
+    private String callEndTimeStart;
+    private String callEndTimeEnd;
+    /** 手动外呼挂机时间起止 */
+    private String endTimeStart;
+    private String endTimeEnd;
+
 
     /** 分机号 */
     private String extnum;
 
-    /** callType=02时可用 */
-    private Long batchId;
-
     /** callType=02时可用 */
     /** 0. 未拨打;1. 排队中;2. 正在拨打 ;3. 未接通 ;6. 成功转接;7. 线路故障 */
     private Integer callstatus;

+ 1 - 0
ruoyi-admin/src/main/java/com/ruoyi/aicall/model/CallTaskStatModel.java

@@ -15,4 +15,5 @@ public class CallTaskStatModel {
 
     /** 接通名单量 */
     private Integer connectCount = 0;
+
 }

+ 8 - 0
ruoyi-admin/src/main/java/com/ruoyi/aicall/service/ICcCallPhoneService.java

@@ -69,6 +69,12 @@ public interface ICcCallPhoneService
      * @return
      */
     public CallTaskStatModel statByBatchId(Long batchId);
+    /**
+     * 根据batchIds统计外呼数据
+     * @param batchIds
+     * @return
+     */
+    public List<CallTaskStatModel> statByBatchIds(List<Long> batchIds);
 
     /**
      * 批量入库
@@ -89,4 +95,6 @@ public interface ICcCallPhoneService
     void delCallPhoneByBatchId(Long batchId);
 
     List<String> isDuplicateEntry(Long batchId, List<CommonPhoneModel> phoneList);
+
+    List<CcCallPhone> selectCcCallPhoneYlrzList(CcCallPhone ccCallPhone);
 }

+ 66 - 0
ruoyi-admin/src/main/java/com/ruoyi/aicall/service/impl/CcCallPhoneServiceImpl.java

@@ -1,5 +1,6 @@
 package com.ruoyi.aicall.service.impl;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -109,6 +110,55 @@ public class CcCallPhoneServiceImpl implements ICcCallPhoneService
         return ccCallPhoneMapper.selectCcCallPhoneList(ccCallPhone);
     }
 
+    /**
+     * 查询外呼号码列表
+     *
+     * @param ccCallPhone 外呼号码
+     * @return 外呼号码
+     */
+    @Override
+    public List<CcCallPhone> selectCcCallPhoneYlrzList(CcCallPhone ccCallPhone)
+    {
+        Map<String, Object> params = ccCallPhone.getParams();
+        if (null == params) {
+            params = new HashMap<>();
+        }
+        if (null != params.get("timeLenStart")
+                && !"".equals(params.get("timeLenStart"))) {
+            params.put("timeLenStart", Double.valueOf((String)params.get("timeLenStart")) * 60 * 1000L);
+        }
+        if (null != params.get("timeLenEnd")
+                && !"".equals(params.get("timeLenEnd"))) {
+            params.put("timeLenEnd", Double.valueOf((String)params.get("timeLenEnd")) * 60 * 1000L);
+        }
+        if (null != params.get("calloutTimeStart")
+                && !"".equals(params.get("calloutTimeStart"))) {
+            params.put("calloutTimeStart", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("calloutTimeStart")).getTime());
+        }
+        if (null != params.get("calloutTimeEnd")
+                && !"".equals(params.get("calloutTimeEnd"))) {
+            params.put("calloutTimeEnd", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("calloutTimeEnd")).getTime());
+        }
+        if (null != params.get("answeredTimeStart")
+                && !"".equals(params.get("answeredTimeStart"))) {
+            params.put("answeredTimeStart", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("answeredTimeStart")).getTime());
+        }
+        if (null != params.get("answeredTimeEnd")
+                && !"".equals(params.get("answeredTimeEnd"))) {
+            params.put("answeredTimeEnd", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("answeredTimeEnd")).getTime());
+        }
+        if (null != params.get("callEndTimeStart")
+                && !"".equals(params.get("callEndTimeStart"))) {
+            params.put("callEndTimeStart", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("callEndTimeStart")).getTime());
+        }
+        if (null != params.get("callEndTimeEnd")
+                && !"".equals(params.get("callEndTimeEnd"))) {
+            params.put("callEndTimeEnd", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("callEndTimeEnd")).getTime());
+        }
+        ccCallPhone.setParams(params);
+        return ccCallPhoneMapper.selectCcCallPhoneYlrzList(ccCallPhone);
+    }
+
     /**
      * 新增外呼号码
      * 
@@ -171,6 +221,22 @@ public class CcCallPhoneServiceImpl implements ICcCallPhoneService
         }
         return callTaskStatModel;
     }
+    @Override
+    public List<CallTaskStatModel> statByBatchIds(List<Long> batchIds) {
+        List<CallTaskStatModel> callTaskStatModels = ccCallPhoneMapper.statByBatchIds(batchIds);
+        callTaskStatModels.forEach(callTaskStatModel -> {
+            if (null == callTaskStatModel.getPhoneCount()) {
+                callTaskStatModel.setPhoneCount(0);
+            }
+            if (null == callTaskStatModel.getCallCount()) {
+                callTaskStatModel.setCallCount(0);
+            }
+            if (null == callTaskStatModel.getConnectCount()) {
+                callTaskStatModel.setConnectCount(0);
+            }
+        });
+        return callTaskStatModels;
+    }
 
     @Override
     public void batchInsertCcCallPhone(List<CcCallPhone> phoneList) {

+ 5 - 0
ruoyi-admin/src/main/java/com/ruoyi/cc/domain/CcOutboundCdr.java

@@ -71,4 +71,9 @@ public class CcOutboundCdr implements Serializable {
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     private Map<String, Object> params;
 
+    private String startTimeStr;
+    private String answeredTimeStr;
+    private String endTimeStr;
+    private String timeLenSec;
+    private String timeLenValidStr;
 }

+ 2 - 0
ruoyi-admin/src/main/java/com/ruoyi/cc/service/ICcOutboundCdrService.java

@@ -58,4 +58,6 @@ public interface ICcOutboundCdrService
      * @return 结果
      */
     public int deleteCcOutboundCdrById(String id);
+
+    List<CcOutboundCdr> selectCcOutboundCdrYlrzList(CcOutboundCdr outboundCdr);
 }

+ 48 - 0
ruoyi-admin/src/main/java/com/ruoyi/cc/service/impl/CcOutboundCdrServiceImpl.java

@@ -102,6 +102,54 @@ public class CcOutboundCdrServiceImpl implements ICcOutboundCdrService
         ccOutboundCdr.setParams(params);
         return ccOutboundCdrMapper.selectCcOutboundCdrList(ccOutboundCdr);
     }
+    /**
+     * 查询外呼记录列表
+     *
+     * @param ccOutboundCdr 外呼记录
+     * @return 外呼记录
+     */
+    @Override
+    public List<CcOutboundCdr> selectCcOutboundCdrYlrzList(CcOutboundCdr ccOutboundCdr)
+    {
+        Map<String, Object> params = ccOutboundCdr.getParams();
+        if (null == params) {
+            params = new HashMap<>();
+        }
+        if (null != params.get("timeLenStart")
+                && !"".equals(params.get("timeLenStart"))) {
+            params.put("timeLenStart", Double.valueOf((String)params.get("timeLenStart")) * 60 * 1000L);
+        }
+        if (null != params.get("timeLenEnd")
+                && !"".equals(params.get("timeLenEnd"))) {
+            params.put("timeLenEnd", Double.valueOf((String)params.get("timeLenEnd")) * 60 * 1000L);
+        }
+        if (null != params.get("calloutTimeStart")
+                && !"".equals(params.get("calloutTimeStart"))) {
+            params.put("calloutTimeStart", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("calloutTimeStart")).getTime());
+        }
+        if (null != params.get("calloutTimeEnd")
+                && !"".equals(params.get("calloutTimeEnd"))) {
+            params.put("calloutTimeEnd", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("calloutTimeEnd")).getTime());
+        }
+        if (null != params.get("answeredTimeStart")
+                && !"".equals(params.get("answeredTimeStart"))) {
+            params.put("answeredTimeStart", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("answeredTimeStart")).getTime());
+        }
+        if (null != params.get("answeredTimeEnd")
+                && !"".equals(params.get("answeredTimeEnd"))) {
+            params.put("answeredTimeEnd", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("answeredTimeEnd")).getTime());
+        }
+        if (null != params.get("endTimeStart")
+                && !"".equals(params.get("endTimeStart"))) {
+            params.put("endTimeStart", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("endTimeStart")).getTime());
+        }
+        if (null != params.get("endTimeEnd")
+                && !"".equals(params.get("endTimeEnd"))) {
+            params.put("endTimeEnd", DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", (String)params.get("endTimeEnd")).getTime());
+        }
+        ccOutboundCdr.setParams(params);
+        return ccOutboundCdrMapper.selectCcOutboundCdrList(ccOutboundCdr);
+    }
 
     /**
      * 新增外呼记录

+ 67 - 0
ruoyi-admin/src/main/resources/mapper/aicall/CcCallPhoneMapper.xml

@@ -226,6 +226,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         FROM cc_call_phone
         WHERE batch_id = #{batchId}
     </select>
+    <select id="statByBatchIds" parameterType="java.util.List" resultType="com.ruoyi.aicall.model.CallTaskStatModel">
+        SELECT batch_id AS batchId,
+               COUNT(1) AS phoneCount,
+               SUM(CASE WHEN callout_time > 0 THEN 1 ELSE 0 END) AS callCount,
+               SUM(CASE WHEN answered_time > 0 THEN 1 ELSE 0 END) AS connectCount
+        FROM cc_call_phone
+        WHERE batch_id IN
+        <foreach item="item" collection="list" open="(" separator="," close=")">
+            #{item}
+         </foreach>
+        GROUP BY batch_id
+    </select>
 
     <insert id="batchInsertCcCallPhone" parameterType="java.util.List">
         INSERT INTO cc_call_phone (
@@ -291,4 +303,59 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{phone.phoneNum}
         </foreach>
     </select>
+
+    <select id="selectCcCallPhoneYlrzList" parameterType="CcCallPhone" resultMap="CcCallPhoneResult">
+        select ccp.*, cct.batch_name as batchName from cc_call_phone ccp left join cc_call_task cct on cct.batch_id = ccp.batch_id
+        <where>
+            <if test="uuid != null and uuid != '' "> and ccp.uuid = #{uuid}</if>
+            <if test="batchId != null "> and ccp.batch_id = #{batchId}</if>
+            <if test="telephone != null  and telephone != ''"> and ccp.telephone = #{telephone}</if>
+            <if test="custName != null  and custName != ''"> and ccp.cust_name = #{custName}</if>
+            <if test="callstatus != null "> and ccp.callstatus = #{callstatus}</if>
+            <if test="params.calloutTimeStart != null and params.calloutTimeStart != ''"><!-- 开始时间检索 -->
+                AND ccp.callout_time &gt;= #{params.calloutTimeStart}
+            </if>
+            <if test="params.calloutTimeEnd != null and params.calloutTimeEnd != ''"><!-- 结束时间检索 -->
+                AND ccp.callout_time &lt;= #{params.calloutTimeEnd}
+            </if>
+            <if test="params.callEndTimeStart != null and params.callEndTimeStart != ''"><!-- 开始时间检索 -->
+                AND ccp.call_end_time &gt;= #{params.callEndTimeStart}
+            </if>
+            <if test="params.callEndTimeEnd != null and params.callEndTimeEnd != ''"><!-- 结束时间检索 -->
+                AND ccp.call_end_time &lt;= #{params.callEndTimeEnd}
+            </if>
+            <if test="params.timeLenStart != null and params.timeLenStart != ''"><!-- 开始时间检索 -->
+                AND ccp.time_len &gt;= #{params.timeLenStart}
+            </if>
+            <if test="params.timeLenEnd != null and params.timeLenEnd != ''"><!-- 结束时间检索 -->
+                AND ccp.time_len &lt;= #{params.timeLenEnd}
+            </if>
+            <if test="params.connectedTimeStart != null and params.connectedTimeStart != ''"><!-- 开始时间检索 -->
+                AND ccp.connected_time &gt;= #{params.connectedTimeStart}
+            </if>
+            <if test="params.connectedTimeEnd != null and params.connectedTimeEnd != ''"><!-- 结束时间检索 -->
+                AND ccp.connected_time &lt;= #{connectedTimeEnd}
+            </if>
+            <if test="params.answeredTimeStart != null and params.answeredTimeStart != ''"><!-- 开始时间检索 -->
+                AND ccp.answered_time &gt;= #{params.answeredTimeStart}
+            </if>
+            <if test="params.answeredTimeEnd != null and params.answeredTimeEnd != ''"><!-- 结束时间检索 -->
+                AND ccp.answered_time &lt;= #{params.answeredTimeEnd}
+            </if>
+            <if test="batchId != null and batchId != ''">
+                AND ccp.batch_id = #{batchId}
+            </if>
+            <if test="intent != null and intent != ''">
+                AND ccp.intent = #{intent}
+            </if>
+            <if test="billingStatus != null ">
+                and ccp.billing_status = #{billingStatus}
+            </if>
+            <if test="callerNumber != null and callerNumber != '' ">
+                and ccp.caller_number = #{callerNumber}
+            </if>
+            AND ccp.callstatus >= 3 AND ccp.call_end_time > 0
+        </where>
+        order by ccp.call_end_time desc
+    </select>
 </mapper>

+ 33 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java

@@ -192,4 +192,37 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
     public static String format(Date date, String dateFormat) {
         return DateFormatUtils.format(date, dateFormat);
     }
+
+    /**
+     * 格式化时间长度(秒转为可读格式,自动省略为 0 的单位)
+     * @param timeLenSeconds 时间长度(秒)
+     * @return 格式化后的时间字符串,如:1 天 2 小时 3 分 4 秒、36 秒、1 小时 5 分等
+     */
+    public static String formatTimeLength(long timeLenSeconds) {
+        if (timeLenSeconds <= 0) {
+            return "0 秒";
+        }
+
+        long days = timeLenSeconds / (24 * 3600);
+        long hours = (timeLenSeconds % (24 * 3600)) / 3600;
+        long minutes = (timeLenSeconds % 3600) / 60;
+        long seconds = timeLenSeconds % 60;
+
+        StringBuilder result = new StringBuilder();
+
+        if (days > 0) {
+            result.append(days).append("天");
+        }
+        if (hours > 0) {
+            result.append(hours).append("小时");
+        }
+        if (minutes > 0) {
+            result.append(minutes).append("分");
+        }
+        if (seconds > 0 || result.length() == 0) {
+            result.append(seconds).append("秒");
+        }
+
+        return result.toString();
+    }
 }