Commit 7a7a4e0ed87fa29fdca1ddbc3631297722c43043

Authored by 张志伟
2 parents 7333a626 5a057770

Merge remote-tracking branch 'origin/test'

fw-valhalla-dao/src/main/java/cn/fw/valhalla/dao/mapper/CustomerImportMapper.java deleted
1   -package cn.fw.valhalla.dao.mapper;
2   -
3   -import cn.fw.valhalla.domain.db.customer.CustomerImport;
4   -import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5   -import org.springframework.stereotype.Repository;
6   -
7   -/**
8   - * @author : kurisu
9   - * @className : CustomerImportMapper
10   - * @description : 档案导入处理
11   - * @date: 2020-11-18 15:03
12   - */
13   -@Repository
14   -public interface CustomerImportMapper extends BaseMapper<CustomerImport> {
15   -}
fw-valhalla-dao/src/main/resources/mapper/CustomerImportMapper.xml deleted
1   -<?xml version="1.0" encoding="UTF-8"?>
2   -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3   -<mapper namespace="cn.fw.valhalla.dao.mapper.CustomerImportMapper">
4   -</mapper>
fw-valhalla-domain/pom.xml
... ... @@ -19,6 +19,11 @@
19 19 <artifactId>fw-valhalla-common</artifactId>
20 20 <optional>true</optional>
21 21 </dependency>
  22 + <dependency>
  23 + <groupId>cn.fw</groupId>
  24 + <artifactId>fw-common-web</artifactId>
  25 + <optional>true</optional>
  26 + </dependency>
22 27 <!-- util -->
23 28 <dependency>
24 29 <groupId>org.hibernate.validator</groupId>
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/customer/CustomerImport.java deleted
1   -package cn.fw.valhalla.domain.db.customer;
2   -
3   -import cn.fw.common.data.entity.BaseEntity;
4   -import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7   -
8   -import java.util.Date;
9   -
10   -/**
11   - * @author : kurisu
12   - * @className : CustomerImport
13   - * @description : 档案导入数据
14   - * @date: 2020-11-18 14:59
15   - */
16   -@Data
17   -@ToString(callSuper = true)
18   -@EqualsAndHashCode(callSuper = true)
19   -public class CustomerImport extends BaseEntity<CustomerImport, Long> {
20   - private String plateNo;
21   - private String adviserName;
22   - private Long adviserId;
23   - private String brandName;
24   - private String seriesName;
25   - private String specName;
26   - private String specCode;
27   - private String name;
28   - private Long shopId;
29   - private String engineNo;
30   - private String mobile;
31   - private Integer currentMileage;
32   - private Date arrivalTime;
33   - private String frameNo;
34   - private Integer mark;
35   - private Boolean needAssigning;
36   - private Long oldId;
37   -}
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/ipt/CustomerInitClue.kt
... ... @@ -15,22 +15,22 @@ import java.time.LocalDateTime
15 15 */
16 16 @NoArg
17 17 data class CustomerInitClue(
18   - var plateNo: String?,
  18 + val plateNo: String?,
19 19 val vin: String,
20   - var brandName: String?,
21   - var seriesName: String?,
22   - var specName: String?,
23   - var engineNo: String?,
24   - var buyDate: LocalDate?,
25   - var customerName: String?,
  20 + val brandName: String?,
  21 + val seriesName: String?,
  22 + val specName: String?,
  23 + val engineNo: String?,
  24 + val buyDate: LocalDate?,
  25 + val customerName: String?,
26 26 val customerMobile: String,
27   - var arrivalTime: LocalDateTime?,
28   - var arrivalMileage: Int?,
29   - var senderName: String?,
  27 + val arrivalTime: LocalDateTime?,
  28 + val arrivalMileage: Int?,
  29 + val senderName: String?,
30 30 val senderMobile: String,
31 31 val adviserId: Long,
32   - var adviserName: String?,
  32 + val adviserName: String?,
33 33 val shopId: Long,
34 34 val groupId: Long,
35   - var yn: Boolean,
  35 + val yn: Boolean,
36 36 ) : BaseAuditableTimeEntity<CustomerInitClue, Long>()
37 37 \ No newline at end of file
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/ipt/CustomerInitClueCallLog.kt
... ... @@ -17,6 +17,6 @@ data class CustomerInitClueCallLog(
17 17 val clueId: Long,
18 18 val callId: String,
19 19 val talkTime: Int,
20   - var recording: String,
  20 + val recording: String?,
21 21 val uploadTime: LocalDateTime,
22 22 ) : BaseEntity<CustomerInitClueCallLog, Long>()
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/CallReportDTO.java deleted
1   -package cn.fw.valhalla.domain.dto;
2   -
3   -import cn.fw.valhalla.domain.enums.CallTypeEnum;
4   -import lombok.Data;
5   -
6   -import java.time.LocalDateTime;
7   -import java.util.Date;
8   -
9   -/**
10   - * @author : kurisu
11   - * @className : CallReportDTO
12   - * @description : 通话记录
13   - * @date: 2021-01-19 15:57
14   - */
15   -@Data
16   -public class CallReportDTO {
17   - /**
18   - * 通话id
19   - */
20   - private String callId;
21   - /**
22   - * 工作人员id
23   - */
24   - private Long staffId;
25   - /**
26   - * 工作人员名称
27   - */
28   - private String staffName;
29   - /**
30   - * 用户号码
31   - */
32   - private String staffMobile;
33   - /**
34   - * 目标号码
35   - */
36   - private String peerNo;
37   - /**
38   - * 呼叫时间
39   - */
40   - private Date callTime;
41   - /**
42   - * 通话时间 (秒)
43   - */
44   - private Long talkTime;
45   - /**
46   - * 呼叫类型
47   - */
48   - private CallTypeEnum dialType;
49   - /**
50   - * 集团id
51   - */
52   - private Long groupId;
53   -}
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/CallReportDTO.kt 0 → 100644
  1 +package cn.fw.valhalla.domain.dto
  2 +
  3 +import cn.fw.common.annotation.NoArg
  4 +import com.fasterxml.jackson.databind.annotation.JsonDeserialize
  5 +import com.fasterxml.jackson.databind.annotation.JsonSerialize
  6 +import java.time.LocalDateTime
  7 +
  8 +/**
  9 + * 通话记录mq的DTO
  10 + *
  11 + * @author : kurisu
  12 + * @version : 2.0
  13 + * @desc : 通话记录mq的DTO
  14 + * @date : 2024-03-29 15:15
  15 + */
  16 +@NoArg
  17 +data class CallReportDTO(
  18 + /**
  19 + * 拨号id (查询录音用)
  20 + */
  21 + val callId: String,
  22 + /**
  23 + * 员工id
  24 + */
  25 + val staffId: Long,
  26 + /**
  27 + * 用户号码
  28 + */
  29 + val staffMobile: String,
  30 + /**
  31 + * 目标号码
  32 + */
  33 + val peerNo: String,
  34 + /**
  35 + * 呼叫时间
  36 + */
  37 + @JsonDeserialize(using = cn.fw.common.web.serializer.LocalDateTimeSerializerProcessor.LocalDateTimeDeserializer::class)
  38 + @JsonSerialize(using = cn.fw.common.web.serializer.LocalDateTimeSerializerProcessor.LocalDateTimeSerializer::class)
  39 + val callTime: LocalDateTime,
  40 + /**
  41 + * 呼叫类型
  42 + */
  43 + val callType: Int,
  44 + /**
  45 + * 通话时间 (秒)
  46 + */
  47 + val talkTime: Int
  48 +)
0 49 \ No newline at end of file
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/ehr/EhrRpcService.java
... ... @@ -104,7 +104,7 @@ public class EhrRpcService extends AbsBaseRpcService {
104 104 return staffInfoDTO;
105 105 }
106 106 } catch (Exception e) {
107   - e.printStackTrace();
  107 + log.error("通过号码查询用户信息失败", e);
108 108 }
109 109 return null;
110 110 }
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/pstn/PstnRpcService.kt
... ... @@ -28,6 +28,6 @@ class PstnRpcService(private val pstnApiService: PstnApiService) {
28 28 } catch (e: Exception) {
29 29 logError("pstn统调用失败", e)
30 30 }
31   - return ""
  31 + return null
32 32 }
33 33 }
34 34 \ No newline at end of file
... ...
fw-valhalla-server/pom.xml
... ... @@ -172,7 +172,7 @@
172 172 <profile>
173 173 <id>local-dev</id>
174 174 <properties>
175   - <activatedProfiles>dev,local</activatedProfiles>
  175 + <activatedProfiles>test,local</activatedProfiles>
176 176 </properties>
177 177 <activation>
178 178 <activeByDefault>true</activeByDefault>
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/CallHistoryTask.kt 0 → 100644
  1 +package cn.fw.valhalla.controller.task
  2 +
  3 +import cn.fw.valhalla.domain.db.ipt.CustomerInitClueCallLog
  4 +import cn.fw.valhalla.domain.dto.CallReportDTO
  5 +import cn.fw.valhalla.rpc.ehr.EhrRpcService
  6 +import cn.fw.valhalla.service.bus.ipt.CustomerInitClueBizService
  7 +import cn.fw.valhalla.service.data.CustomerInitClueCallLogService
  8 +import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
  9 +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
  10 +import com.fasterxml.jackson.module.kotlin.readValue
  11 +import kotlinx.coroutines.CoroutineScope
  12 +import kotlinx.coroutines.Dispatchers
  13 +import kotlinx.coroutines.launch
  14 +import org.slf4j.LoggerFactory
  15 +import org.springframework.beans.factory.annotation.Value
  16 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
  17 +import org.springframework.data.redis.core.StringRedisTemplate
  18 +import org.springframework.scheduling.annotation.Scheduled
  19 +import org.springframework.stereotype.Component
  20 +import java.time.LocalDateTime
  21 +
  22 +/**
  23 + * 车辆进站处理task
  24 + *
  25 + * @author : kurisu
  26 + * @version : 1.0
  27 + * @desc : 车辆进站处理task
  28 + * @date : 2024-03-01 09:51
  29 + */
  30 +@Component
  31 +@ConditionalOnProperty(prefix = "task", name = ["switch"], havingValue = "on")
  32 +class CallHistoryTask(
  33 + private val stringRedisTemplate: StringRedisTemplate,
  34 + private val ehrRpcService: EhrRpcService,
  35 + private val customerInitClueBizService: CustomerInitClueBizService,
  36 + private val customerInitClueCallLogService: CustomerInitClueCallLogService,
  37 + @Value("\${spring.cache.custom.global-prefix}:mq:call:log")
  38 + private val callReportKey: String
  39 +) {
  40 + private val logger = LoggerFactory.getLogger(javaClass)
  41 +
  42 +
  43 + /**
  44 + * 持久化通话记录
  45 + */
  46 + @Scheduled(initialDelay = 1000 * 10, fixedRate = 1000 * 15)
  47 + fun dealCallHistory() {
  48 + val listOps = stringRedisTemplate.boundListOps(callReportKey)
  49 + val dataList = mutableListOf<String>()
  50 + for (i in 0..100) {
  51 + val dataStr = listOps.leftPop()
  52 + dataStr?.let {
  53 + dataList.add(dataStr)
  54 + }
  55 + }
  56 + val mapper = jacksonObjectMapper()
  57 + CoroutineScope(Dispatchers.IO).launch {
  58 + dataList.forEach {
  59 + launch {
  60 + try {
  61 + val callReportDTO = mapper.readValue<CallReportDTO>(it)
  62 + val invalid = callReportDTO.callTime.isBefore(
  63 + LocalDateTime.now().minusMinutes(10)
  64 + ) && callReportDTO.staffId <= 0
  65 + if (!invalid) {
  66 + var res = false
  67 + if (callReportDTO.staffId <= 0) {
  68 + val staffId = ehrRpcService.queryStaffInfoByMobile(callReportDTO.staffMobile)?.id ?: -1
  69 + if (staffId > 0) {
  70 + res = customerInitClueBizService.saveCallLog(callReportDTO.copy(staffId = staffId))
  71 + }
  72 + } else {
  73 + res = customerInitClueBizService.saveCallLog(callReportDTO)
  74 + }
  75 + if (!res) {
  76 + listOps.rightPush(it)
  77 + }
  78 + }
  79 + } catch (e: Exception) {
  80 + logger.error("持久化通话记录失败, id: $it", e)
  81 + listOps.rightPush(it)
  82 + }
  83 + }
  84 + }
  85 + }
  86 + }
  87 +
  88 + /**
  89 + * 拉取化通话录音
  90 + */
  91 + @Scheduled(initialDelay = 1000 * 10, fixedRate = 1000 * 30)
  92 + fun dealCallRecordings() {
  93 + val list = customerInitClueCallLogService.list(
  94 + KtQueryWrapper(CustomerInitClueCallLog::class.java)
  95 + .gt(CustomerInitClueCallLog::talkTime, 0)
  96 + .isNull(CustomerInitClueCallLog::recording)
  97 + .last(" limit 100")
  98 + )
  99 + CoroutineScope(Dispatchers.IO).launch {
  100 + list?.forEach {
  101 + launch {
  102 + try {
  103 + customerInitClueBizService.fillRecordingsPath(it)
  104 + } catch (e: Exception) {
  105 + logger.error("拉取通话录音失败, id: ${it.id}", e)
  106 + }
  107 + }
  108 + }
  109 + }
  110 + }
  111 +}
0 112 \ No newline at end of file
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/CallReportConsumer.kt 0 → 100644
  1 +package cn.fw.valhalla.component.consumer
  2 +
  3 +import cn.fw.common.util.logError
  4 +import cn.fw.common.util.logInfo
  5 +import cn.fw.pstn.sdk.mq.CallReport
  6 +import cn.fw.valhalla.common.utils.DateUtil
  7 +import cn.fw.valhalla.domain.dto.CallReportDTO
  8 +import cn.fw.valhalla.rpc.ehr.EhrRpcService
  9 +import cn.fw.valhalla.rpc.ehr.dto.StaffInfoDTO
  10 +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
  11 +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener
  12 +import org.apache.rocketmq.spring.core.RocketMQListener
  13 +import org.springframework.beans.factory.annotation.Value
  14 +import org.springframework.data.redis.core.StringRedisTemplate
  15 +import org.springframework.stereotype.Component
  16 +
  17 +/**
  18 + * 通话记录监听
  19 + *
  20 + * @author : kurisu
  21 + * @version : 2.0
  22 + * @desc : 通话记录监听
  23 + * @date : 2024-03-29 15:09
  24 + */
  25 +@Component
  26 +@RocketMQMessageListener(topic = "call_report", consumerGroup = "\${spring.application.name}" + "-call_report")
  27 +class CallReportConsumer(
  28 + private val stringRedisTemplate: StringRedisTemplate,
  29 + private val ehrRpcService: EhrRpcService,
  30 + @Value("\${spring.cache.custom.global-prefix}:mq:call:log")
  31 + private val callReportKey: String
  32 +) : RocketMQListener<CallReport> {
  33 +
  34 +
  35 + override fun onMessage(message: CallReport?) {
  36 + logInfo("监听通话记录mq: CallReport=[{}]", message)
  37 + try {
  38 + message?.takeIf { it.talkTime > 0 }?.let {
  39 + val info: StaffInfoDTO? = ehrRpcService.queryStaffInfoByMobile(message.staffMobile)
  40 + val mapper = jacksonObjectMapper()
  41 + val callReportDTO = CallReportDTO(
  42 + callId = message.callId,
  43 + staffId = info?.id ?: -1,
  44 + staffMobile = message.staffMobile,
  45 + peerNo = message.peerNo,
  46 + callTime = DateUtil.date2LocalDateTime(message.callTime),
  47 + callType = message.callType.value,
  48 + talkTime = message.talkTime.toInt(),
  49 + )
  50 + val jsonString = mapper.writeValueAsString(callReportDTO)
  51 + stringRedisTemplate.opsForList().rightPush(callReportKey, jsonString)
  52 + }
  53 + } catch (ex: Exception) {
  54 + logError("消费通话记录mq失败", ex)
  55 + throw ex
  56 + }
  57 + }
  58 +}
0 59 \ No newline at end of file
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/ipt/CustomerInitClueBizService.kt
... ... @@ -4,16 +4,19 @@ import cn.fw.common.data.mybatis.pagination.PageData
4 4 import cn.fw.common.page.AppPage
5 5 import cn.fw.valhalla.domain.db.ipt.CustomerInitClue
6 6 import cn.fw.valhalla.domain.db.ipt.CustomerInitClueCallLog
  7 +import cn.fw.valhalla.domain.dto.CallReportDTO
7 8 import cn.fw.valhalla.domain.query.InitClueQueryVO
8 9 import cn.fw.valhalla.domain.vo.AppPageVO
9 10 import cn.fw.valhalla.domain.vo.ipt.CustomerInitClueVO
10 11 import cn.fw.valhalla.domain.vo.ipt.InitClueCallLogVO
11 12 import cn.fw.valhalla.rpc.member.MemberRpcService
12 13 import cn.fw.valhalla.rpc.oop.OopService
  14 +import cn.fw.valhalla.rpc.pstn.PstnRpcService
13 15 import cn.fw.valhalla.service.data.CustomerInitClueCallLogService
14 16 import cn.fw.valhalla.service.data.CustomerInitClueService
15 17 import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
16 18 import org.springframework.stereotype.Service
  19 +import org.springframework.transaction.annotation.Transactional
17 20 import java.util.*
18 21 import java.util.function.Function
19 22  
... ... @@ -30,7 +33,8 @@ class CustomerInitClueBizService(
30 33 private val customerInitClueService: CustomerInitClueService,
31 34 private val customerInitClueCallLogService: CustomerInitClueCallLogService,
32 35 private val oopService: OopService,
33   - private val memberRpcService: MemberRpcService
  36 + private val memberRpcService: MemberRpcService,
  37 + private val pstnRpcService: PstnRpcService
34 38 ) {
35 39 /**
36 40 * 查询池子数据
... ... @@ -81,6 +85,53 @@ class CustomerInitClueBizService(
81 85 )
82 86 } ?: listOf()
83 87 }
  88 +
  89 + /**
  90 + * 持久化通话记录
  91 + */
  92 + @Transactional(rollbackFor = [Exception::class])
  93 + fun saveCallLog(dto: CallReportDTO): Boolean {
  94 + if (customerInitClueCallLogService.count(
  95 + KtQueryWrapper(CustomerInitClueCallLog::class.java).eq(
  96 + CustomerInitClueCallLog::callId,
  97 + dto.callId
  98 + )
  99 + ) > 0
  100 + ) {
  101 + return true
  102 + }
  103 + val list = customerInitClueService.list(KtQueryWrapper(CustomerInitClue::class.java)
  104 + .eq(CustomerInitClue::yn, true)
  105 + .eq(CustomerInitClue::adviserId, dto.staffId)
  106 + .and {
  107 + it.eq(CustomerInitClue::customerMobile, dto.peerNo)
  108 + .or()
  109 + .eq(CustomerInitClue::senderMobile, dto.peerNo)
  110 + }
  111 + )
  112 + return list?.mapNotNull {
  113 + CustomerInitClueCallLog(
  114 + clueId = it.id,
  115 + callId = dto.callId,
  116 + talkTime = dto.talkTime,
  117 + recording = null,
  118 + uploadTime = dto.callTime
  119 + )
  120 + }?.let {
  121 + customerInitClueCallLogService.saveBatch(it)
  122 + } ?: false
  123 + }
  124 +
  125 + /**
  126 + * 拉取录音地址
  127 + */
  128 + @Transactional(rollbackFor = [Exception::class])
  129 + fun fillRecordingsPath(callLog: CustomerInitClueCallLog) {
  130 + val path = pstnRpcService.queryRecording(callLog.callId)
  131 + path?.let {
  132 + customerInitClueCallLogService.updateById(callLog.copy(recording = it))
  133 + }
  134 + }
84 135 }
85 136  
86 137  
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/CustomerImportService.java deleted
1   -package cn.fw.valhalla.service.data;
2   -
3   -import cn.fw.valhalla.domain.db.customer.CustomerImport;
4   -import com.baomidou.mybatisplus.extension.service.IService;
5   -
6   -/**
7   - * @author : kurisu
8   - * @className : CustomerImportService
9   - * @description : 档案导入处理
10   - * @date: 2020-11-18 15:05
11   - */
12   -public interface CustomerImportService extends IService<CustomerImport> {
13   -}
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/CustomerImportServiceImpl.java deleted
1   -package cn.fw.valhalla.service.data.impl;
2   -
3   -import cn.fw.valhalla.dao.mapper.CustomerImportMapper;
4   -import cn.fw.valhalla.domain.db.customer.CustomerImport;
5   -import cn.fw.valhalla.service.data.CustomerImportService;
6   -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7   -import lombok.extern.slf4j.Slf4j;
8   -import org.springframework.stereotype.Service;
9   -
10   -/**
11   - * @author : kurisu
12   - * @className : CustomerImportServiceImpl
13   - * @description : 档案导入处理
14   - * @date: 2020-11-18 15:05
15   - */
16   -@Service
17   -@Slf4j
18   -public class CustomerImportServiceImpl extends ServiceImpl<CustomerImportMapper, CustomerImport> implements CustomerImportService {
19   -}