CAMPAIGN_CHANNEL;
+ @Value("${yo.common-service.call-data.timeout-seconds:120}")
+ private long callDataTimeoutSeconds;
+
+ public CommonCallDataServiceImpl(final RedissonClient redisson) {
+ this.CACHE = redisson.getMapCache("CALL_DATA");
+ this.CAMPAIGN_CHANNEL = redisson.getMapCache("CAMPAIGN_CHANNEL");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void saveIvrCallData(final String agentId, final String callData) {
+ log.info("Save IVR call data [{}] -> [{}].", agentId, callData);
+ put(ivrCacheKey(agentId), callData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getIvrCallData(final String agentId) {
+ log.debug("Get IVR call data [{}].", agentId);
+ return CACHE.get(ivrCacheKey(agentId));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void saveCampaignCallData(String callUuid, String callData) {
+ log.info("Save campaign call data [{}] -> [{}].", callUuid, callData);
+ put(callUuid, callData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getCampaignCallData(final String callUuid) {
+ log.debug("Get campaign call data [{}].", callUuid);
+ return CACHE.get(callUuid);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getCampaignChannel(final Integer campaignId) {
+ final int val = CAMPAIGN_CHANNEL.getOrDefault(campaignId, 0);
+ log.debug("Get campaign [{}] channel [{}].", campaignId, val);
+ return val;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int incrCampaignChannel(final Integer campaignId) {
+ final int val = CAMPAIGN_CHANNEL.addAndGet(campaignId, 1);
+ log.debug("Increase campaign [{}] channel [{}].", campaignId, val);
+ return val;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int decrCampaignChannel(final Integer campaignId) {
+ final int val = CAMPAIGN_CHANNEL.addAndGet(campaignId, -1);
+ log.debug("Decrease campaign [{}] channel [{}].", campaignId, val);
+ return val;
+ }
+
+ private void put(final String key, final String value) {
+ log.debug("Call data cache [{}] -> [{}].", key, value);
+ CACHE.put(
+ key, value, callDataTimeoutSeconds, TimeUnit.SECONDS);
+ }
+
+ private String ivrCacheKey(final String agentId) {
+ return "IVR_CALL_DATA:" + agentId;
+ }
+}
diff --git a/lib/service-common/src/main/resources/spring/spring-yo-service-common.xml b/lib/service-common/src/main/resources/spring/spring-yo-service-common.xml
index 7cfbf221..d0df1395 100644
--- a/lib/service-common/src/main/resources/spring/spring-yo-service-common.xml
+++ b/lib/service-common/src/main/resources/spring/spring-yo-service-common.xml
@@ -8,4 +8,5 @@
+
diff --git a/lib/service-common/src/test/java/com/pudonghot/yo/service/CommonCallDataServiceTest.java b/lib/service-common/src/test/java/com/pudonghot/yo/service/CommonCallDataServiceTest.java
new file mode 100644
index 00000000..e6a8c624
--- /dev/null
+++ b/lib/service-common/src/test/java/com/pudonghot/yo/service/CommonCallDataServiceTest.java
@@ -0,0 +1,26 @@
+package com.pudonghot.yo.service;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Donghuang
+ * @date Jul 23, 2020 19:44:47
+ */
+@Slf4j
+@SpringBootTest(classes = TestDriver.class)
+@RunWith(SpringJUnit4ClassRunner.class)
+public class CommonCallDataServiceTest {
+ @Autowired
+ private CommonCallDataService callDataService;
+
+ @Test
+ public void testRun() {
+ log.info("Channels [{}].", callDataService.incrCampaignChannel(1));
+ log.info("Channels [{}].", callDataService.decrCampaignChannel(2));
+ }
+}
diff --git a/lib/util/src/main/java/com/pudonghot/yo/common/util/MobileUtils.java b/lib/util/src/main/java/com/pudonghot/yo/common/util/MobileUtils.java
deleted file mode 100644
index 0bd348f3..00000000
--- a/lib/util/src/main/java/com/pudonghot/yo/common/util/MobileUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.pudonghot.yo.common.util;
-
-import org.apache.commons.lang3.StringUtils;
-
-
-/**
- * 手机号工具类
- * Created by bingpo on 17/12/28.
- */
-public class MobileUtils {
-
- public static final int MOBILE_LENGTH = 11;
- private static final String MOBILE_REG_EXP = "^1(3[0-9]|4[579]|5[0-35-9]|7[0135678]|8[0-9])\\d{8}$";
-
- /**
- * 验证手机号码
- *
- * 移动号码段:134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
- * 联通号码段:130,131,132,145,155,156,171,175,176,185,186
- * 电信号码段:133,149,153,170,173,177,180,181,189
- *
- * @param mobile 手机号
- * @return 是否为手机号
- */
- public static boolean checkMobile(String mobile) {
- return StringUtils.length(mobile) == MOBILE_LENGTH && mobile.matches(MOBILE_REG_EXP);
- }
-
- /**
- * 处理手机号
- *
- * @param mobile 手机号
- * @return 处理后的手机号
- */
- public static String formatMobile(String mobile) {
- if (StringUtils.length(mobile) > MOBILE_LENGTH) {
- return mobile.substring(mobile.length() - MOBILE_LENGTH);
- }
- return mobile;
- }
-
- /**
- * 去掉手机号的前缀
- *
- * @param mobileStr mobileStr
- * @return 去掉前缀后的手机号
- */
- public static String trimMobilePrefix(String mobileStr) {
- if (StringUtils.length(mobileStr) > MOBILE_LENGTH) {
- final String mobile = mobileStr.substring(mobileStr.length() - MOBILE_LENGTH);
- return checkMobile(mobile) ? mobile : mobileStr;
- }
- return mobileStr;
- }
-
-}
diff --git a/lib/util/src/main/java/com/pudonghot/yo/util/PhoneNumberUtils.java b/lib/util/src/main/java/com/pudonghot/yo/util/PhoneNumberUtils.java
new file mode 100644
index 00000000..5bad999d
--- /dev/null
+++ b/lib/util/src/main/java/com/pudonghot/yo/util/PhoneNumberUtils.java
@@ -0,0 +1,41 @@
+package com.pudonghot.yo.util;
+
+/**
+ * @author Donghuang
+ * @date Jul 20, 2020 18:27:52
+ */
+public class PhoneNumberUtils {
+
+ public static final int MOBILE_LENGTH = 11;
+ private static final String MOBILE_REG_EXP = "^1[3-9]\\d{8}$";
+
+ /**
+ * 验证手机号码
+ *
+ * 移动号码段:134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
+ * 联通号码段:130,131,132,145,155,156,171,175,176,185,186
+ * 电信号码段:133,149,153,170,173,177,180,181,189
+ *
+ * @param mobile 手机号
+ * @return 是否为手机号
+ */
+ public static boolean isMobile(final String mobile) {
+ return mobile.length() == MOBILE_LENGTH
+ && mobile.matches(MOBILE_REG_EXP);
+ }
+
+ /**
+ * cleanup mobile
+ * 01378888666 -> 1378888666
+ * @param mobile mobile number
+ * @return mobile cleaned
+ */
+ public static String cleanupMobile(final String mobile) {
+ if (mobile.length() > MOBILE_LENGTH) {
+ final String trim = mobile.substring(
+ mobile.length() - MOBILE_LENGTH);
+ return isMobile(trim) ? trim : mobile;
+ }
+ return mobile;
+ }
+}
diff --git a/lib/util/src/main/java/com/pudonghot/yo/util/TimeUtils.java b/lib/util/src/main/java/com/pudonghot/yo/util/TimeUtils.java
index 51675094..40645f4d 100644
--- a/lib/util/src/main/java/com/pudonghot/yo/util/TimeUtils.java
+++ b/lib/util/src/main/java/com/pudonghot/yo/util/TimeUtils.java
@@ -13,7 +13,7 @@ public class TimeUtils {
* 00:00 - 23:59
*/
public static final Pattern TIME_PATTERN =
- Pattern.compile("^((?:[01]?[0-9])|(?:2[0-3])):([0-5]?[0-9])$");
+ Pattern.compile("^([01]?[0-9]|2[0-3]):([0-5]?[0-9])(?::([0-5]?[0-9]))?$");
/**
* @param time HH:mm
@@ -23,8 +23,10 @@ public class TimeUtils {
if (StringUtils.isNotBlank(time)) {
final Matcher matcher = TIME_PATTERN.matcher(time);
if (matcher.find()) {
+ final String sec = matcher.group(3);
return Integer.parseInt(matcher.group(1)) * 60 * 60 +
- Integer.parseInt(matcher.group(2)) * 60;
+ Integer.parseInt(matcher.group(2)) * 60 +
+ (StringUtils.isNotBlank(sec) ? Integer.parseInt(sec) : 0);
}
}
return null;
diff --git a/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CallController.java b/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CallController.java
index bd7919d0..0b24d146 100644
--- a/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CallController.java
+++ b/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CallController.java
@@ -1,6 +1,5 @@
package com.pudonghot.yo.openapi.controller;
-import com.pudonghot.yo.fsagent.api.IvrTransferService;
import lombok.extern.slf4j.Slf4j;
import com.pudonghot.yo.model.domain.Agent;
import org.apache.commons.lang3.StringUtils;
@@ -13,6 +12,7 @@ import com.pudonghot.yo.model.exception.AssertUtils;
import com.pudonghot.yo.openapi.service.AgentService;
import com.pudonghot.yo.openapi.auth.SessionAbility;
import com.pudonghot.yo.service.CommonChannelService;
+import com.pudonghot.yo.fsagent.api.IvrTransferService;
import com.pudonghot.yo.openapi.request.ReqAgentDialout;
import com.pudonghot.yo.fsagent.api.request.ReqAgentDial;
import com.pudonghot.yo.service.CommonAgentStatusService;
diff --git a/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CampaignController.java b/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CampaignController.java
new file mode 100644
index 00000000..6cd38213
--- /dev/null
+++ b/openapi/src/main/java/com/pudonghot/yo/openapi/controller/CampaignController.java
@@ -0,0 +1,48 @@
+package com.pudonghot.yo.openapi.controller;
+
+import javax.validation.Valid;
+import lombok.extern.slf4j.Slf4j;
+import com.pudonghot.yo.model.domain.Agent;
+import org.springframework.stereotype.Controller;
+import com.pudonghot.yo.openapi.request.ReqCampaign;
+import com.pudonghot.yo.openapi.auth.SessionAbility;
+import com.pudonghot.yo.openapi.service.AgentService;
+import com.pudonghot.yo.service.CommonAgentStatusService;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Donghuang
+ * @date Jul 02, 2020 11:53:21
+ */
+@Slf4j
+@Controller
+public class CampaignController implements SessionAbility {
+
+ @Autowired
+ private AgentService agentService;
+ @Autowired
+ private CommonAgentStatusService agentStatusService;
+
+ @RequestMapping("/resource/task/{account}")
+ public void addToQueue(
+ @PathVariable("account")
+ final String account,
+ @Valid final ReqCampaign form) {
+ final Agent agent = agentService.findValid(
+ form.getTenantId(), account);
+ agentStatusService.findValidAgentStatus(agent);
+ // TODO Add agent to queue
+ }
+
+ @RequestMapping("/resource/task/start")
+ public void start(@Valid final ReqCampaign form) {
+ // TODO start campaign
+ }
+
+ @RequestMapping("/resource/task/stop")
+ public void stop(@Valid final ReqCampaign form) {
+ // TODO stop campaign
+ }
+}
diff --git a/openapi/src/main/java/com/pudonghot/yo/openapi/controller/DialController.java b/openapi/src/main/java/com/pudonghot/yo/openapi/controller/DialController.java
deleted file mode 100644
index e326e2c9..00000000
--- a/openapi/src/main/java/com/pudonghot/yo/openapi/controller/DialController.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.pudonghot.yo.openapi.controller;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Controller;
-import com.pudonghot.yo.fsagent.api.DialService;
-import com.pudonghot.yo.openapi.dto.request.AgentDial;
-import com.pudonghot.yo.fsagent.api.request.ReqAgentDial;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import com.pudonghot.yo.openapi.dto.response.AgentDialResp;
-
-/**
- * @author Donghuang
- * Jan 03, 2020 18:20:59
- */
-@Slf4j
-@Controller
-@RequestMapping("/v1")
-public class DialController {
- @Autowired
- private DialService dialService;
-
- @RequestMapping("/dial")
- public AgentDialResp dial(final AgentDial req) {
- return new AgentDialResp(dialService.agentDial(
- req.copy(new ReqAgentDial())).getUuid());
- }
-}
diff --git a/openapi/src/main/java/com/pudonghot/yo/openapi/request/ReqCampaign.java b/openapi/src/main/java/com/pudonghot/yo/openapi/request/ReqCampaign.java
new file mode 100644
index 00000000..236c6858
--- /dev/null
+++ b/openapi/src/main/java/com/pudonghot/yo/openapi/request/ReqCampaign.java
@@ -0,0 +1,27 @@
+package com.pudonghot.yo.openapi.request;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author Donghuang
+ * @date Jul 09, 2020 11:09:01
+ */
+@Getter
+@Setter
+@ToString
+public class ReqCampaign extends BaseForm {
+ @NotBlank
+ private String campaignKey;
+ private String campaignName;
+
+ public void setTaskid(final String taskId) {
+ this.campaignKey = taskId;
+ }
+
+ public void setTaskname(final String taskName) {
+ this.campaignName = taskName;
+ }
+}
diff --git a/openapi/src/main/resources/application.properties b/openapi/src/main/resources/application.properties
index 7a11dac0..14745ebd 100644
--- a/openapi/src/main/resources/application.properties
+++ b/openapi/src/main/resources/application.properties
@@ -31,6 +31,6 @@ yo.openapi.default-tenant=GOBLIN
# Dubbo
## Dubbo Registry
-dubbo.registry.address=zookeeper://172.16.67.223:2181
+dubbo.registry.address=zookeeper://172.18.4.35:2181
dubbo.registry.file=${user.home}/dubbo-cache/${spring.application.name}/dubbo.cache
yo.fsagent.dubbo.service.version=1.0.0
diff --git a/state/src/main/java/com/pudonghot/yo/state/service/impl/AgentStatusScheduleServiceImpl.java b/state/src/main/java/com/pudonghot/yo/state/service/impl/AgentStatusScheduleServiceImpl.java
index 684a784f..0e384ccd 100644
--- a/state/src/main/java/com/pudonghot/yo/state/service/impl/AgentStatusScheduleServiceImpl.java
+++ b/state/src/main/java/com/pudonghot/yo/state/service/impl/AgentStatusScheduleServiceImpl.java
@@ -1,7 +1,7 @@
package com.pudonghot.yo.state.service.impl;
-import java.util.Date;
import java.util.Map;
+import java.util.Date;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import com.wacai.tigon.mybatis.Search;
@@ -60,6 +60,8 @@ public class AgentStatusScheduleServiceImpl implements AgentStatusScheduleServic
update.put(AgentStatus.REGISTERED, false);
agentStatusMapper.update(update,
new Search(AgentStatus.CHECK_REG_KEY, checkRegKey));
+ log.info("ACW cleanup.");
+ agentStatusMapper.acwCleanup();
}
private Map checkRegKeyUpdate(final String checkRegKey) {