This commit is contained in:
Leo
2025-12-22 22:56:19 +08:00
parent 77dcc149c3
commit 40dd64482c
4 changed files with 276 additions and 46 deletions

View File

@@ -0,0 +1,70 @@
package com.ruoyi.web.controller.jarvis;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.jarvis.service.IPhoneReplaceConfigService;
/**
* 手机号替换配置Controller
*
* @author ruoyi
*/
@RestController
@RequestMapping("/jarvis/phoneReplaceConfig")
public class PhoneReplaceConfigController extends BaseController
{
@Autowired
private IPhoneReplaceConfigService phoneReplaceConfigService;
/**
* 获取指定类型的手机号列表
*/
@GetMapping("/{type}")
public AjaxResult getPhoneList(@PathVariable("type") String type)
{
List<String> phoneList = phoneReplaceConfigService.getPhoneList(type);
return AjaxResult.success(phoneList);
}
/**
* 设置指定类型的手机号列表
*/
@Log(title = "手机号替换配置", businessType = BusinessType.UPDATE)
@PutMapping("/{type}")
public AjaxResult setPhoneList(@PathVariable("type") String type, @RequestBody List<String> phoneList)
{
return toAjax(phoneReplaceConfigService.setPhoneList(type, phoneList));
}
/**
* 添加手机号到指定类型
*/
@Log(title = "手机号替换配置", businessType = BusinessType.UPDATE)
@PostMapping("/{type}/add")
public AjaxResult addPhone(@PathVariable("type") String type, @RequestBody String phone)
{
return toAjax(phoneReplaceConfigService.addPhone(type, phone));
}
/**
* 从指定类型删除手机号
*/
@Log(title = "手机号替换配置", businessType = BusinessType.UPDATE)
@PostMapping("/{type}/remove")
public AjaxResult removePhone(@PathVariable("type") String type, @RequestBody String phone)
{
return toAjax(phoneReplaceConfigService.removePhone(type, phone));
}
}

View File

@@ -0,0 +1,56 @@
package com.ruoyi.jarvis.service;
import java.util.List;
/**
* 手机号替换配置Service接口
*
* @author ruoyi
*/
public interface IPhoneReplaceConfigService
{
/**
* 获取指定类型的手机号列表
*
* @param type 类型(腾锋或昭迎)
* @return 手机号列表
*/
public List<String> getPhoneList(String type);
/**
* 设置指定类型的手机号列表
*
* @param type 类型(腾锋或昭迎)
* @param phoneList 手机号列表
* @return 结果
*/
public int setPhoneList(String type, List<String> phoneList);
/**
* 添加手机号到指定类型
*
* @param type 类型(腾锋或昭迎)
* @param phone 手机号
* @return 结果
*/
public int addPhone(String type, String phone);
/**
* 从指定类型删除手机号
*
* @param type 类型(腾锋或昭迎)
* @param phone 手机号
* @return 结果
*/
public int removePhone(String type, String phone);
/**
* 获取下一个循环使用的手机号
*
* @param type 类型(腾锋或昭迎)
* @param originalPhone 原始手机号
* @return 替换后的手机号
*/
public String getNextPhone(String type, String originalPhone);
}

View File

@@ -6,6 +6,7 @@ import com.ruoyi.jarvis.service.IInstructionService;
import com.ruoyi.jarvis.service.IOrderRowsService; import com.ruoyi.jarvis.service.IOrderRowsService;
import com.ruoyi.jarvis.service.IJDOrderService; import com.ruoyi.jarvis.service.IJDOrderService;
import com.ruoyi.jarvis.service.IProductJdConfigService; import com.ruoyi.jarvis.service.IProductJdConfigService;
import com.ruoyi.jarvis.service.IPhoneReplaceConfigService;
import com.ruoyi.jarvis.service.SuperAdminService; import com.ruoyi.jarvis.service.SuperAdminService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -23,7 +24,6 @@ import java.util.stream.Collectors;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* 将 jd 项目中 JDUtil 的指令能力,抽取为无微信依赖的本地执行版。 * 将 jd 项目中 JDUtil 的指令能力,抽取为无微信依赖的本地执行版。
@@ -43,6 +43,8 @@ public class InstructionServiceImpl implements IInstructionService {
@Resource @Resource
private IProductJdConfigService productJdConfigService; private IProductJdConfigService productJdConfigService;
@Resource @Resource
private IPhoneReplaceConfigService phoneReplaceConfigService;
@Resource
private com.ruoyi.jarvis.service.ITencentDocService tencentDocService; private com.ruoyi.jarvis.service.ITencentDocService tencentDocService;
@Resource @Resource
private com.ruoyi.jarvis.service.ITencentDocTokenService tencentDocTokenService; private com.ruoyi.jarvis.service.ITencentDocTokenService tencentDocTokenService;
@@ -638,31 +640,7 @@ public class InstructionServiceImpl implements IInstructionService {
// ===== TF/H/生 处理 ===== // ===== TF/H/生 处理 =====
// 产品京东配置已迁移到Redis通过productJdConfigService获取 // 产品京东配置已迁移到Redis通过productJdConfigService获取
// 手机号替换配置已迁移到Redis通过phoneReplaceConfigService获取
private static final List<String> phoneWithTF = new ArrayList<>();
private static final AtomicInteger tfPhoneIndex = new AtomicInteger(0);
static {
/*
留着三个
13243039070
15639125541
15514786055
*/
phoneWithTF.add("15639125541");
phoneWithTF.add("13243039070");
phoneWithTF.add("15514786055");
}
private String nextTfPhone(String defaultPhone) {
if (phoneWithTF.isEmpty()) {
return defaultPhone;
}
final int size = phoneWithTF.size();
int currentIndex = tfPhoneIndex.getAndUpdate(value -> (value + 1) % size);
return phoneWithTF.get(currentIndex);
}
private String handleTF(String input) { private String handleTF(String input) {
return handleTF(input, false); return handleTF(input, false);
@@ -686,6 +664,15 @@ public class InstructionServiceImpl implements IInstructionService {
* 型号地址电话的处理逻辑不变将10.10 腾锋 JY202510093195 设置成分销标识这个字段比如之前是H-TF现在改成H-TF(10.10 腾锋 JY202510093195) * 型号地址电话的处理逻辑不变将10.10 腾锋 JY202510093195 设置成分销标识这个字段比如之前是H-TF现在改成H-TF(10.10 腾锋 JY202510093195)
* */ * */
if (parts.length >= 7) { // 至少需要分销信息(3) + 型号(1) + 数量(1) + 姓名(1) + 电话(1) = 7个字段 if (parts.length >= 7) { // 至少需要分销信息(3) + 型号(1) + 数量(1) + 姓名(1) + 电话(1) = 7个字段
// 提取第二个字段,判断是"腾锋"还是"昭迎"
String typeField = parts.length > 1 ? parts[1].trim() : "";
String replaceType = null;
if ("腾锋".equals(typeField)) {
replaceType = "腾锋";
} else if ("昭迎".equals(typeField)) {
replaceType = "昭迎";
}
// 处理分销标记: 只保留H-TF不包含其他内容第三方单号已单独存储 // 处理分销标记: 只保留H-TF不包含其他内容第三方单号已单独存储
String fenxiaoInfo = "H-TF"; String fenxiaoInfo = "H-TF";
// 提取第三方单号第3个字段格式如JY202511051374用于单独存储不添加到分销标记中 // 提取第三方单号第3个字段格式如JY202511051374用于单独存储不添加到分销标记中
@@ -702,27 +689,25 @@ public class InstructionServiceImpl implements IInstructionService {
// 提取电话第7个字段 // 提取电话第7个字段
String phone = parts[6]; String phone = parts[6];
// 将触发号码替换为 phoneWithTF 列表中的号码,按顺序循环 String originalPhone = phone;
if (("13243039070".equals(phone) ) && !phoneWithTF.isEmpty()) {
String originalPhone = phone; // 如果识别到"腾锋"或"昭迎",则进行手机号替换
if (stringRedisTemplate != null) { if (replaceType != null && phoneReplaceConfigService != null) {
try { List<String> phoneList = phoneReplaceConfigService.getPhoneList(replaceType);
String sequenceKey = "phone_tf_cycle_index"; if (phoneList != null && !phoneList.isEmpty()) {
Long index = stringRedisTemplate.opsForValue().increment(sequenceKey); // 检查当前手机号是否在需要替换的列表中
if (index == null) { boolean needReplace = false;
phone = nextTfPhone(originalPhone); if ("腾锋".equals(replaceType)) {
} else { // 腾锋如果手机号是13243039070则需要替换
int phoneIndex = (int) ((index - 1) % phoneWithTF.size()); needReplace = "13243039070".equals(phone);
phone = phoneWithTF.get(phoneIndex); } else if ("昭迎".equals(replaceType)) {
if (index % phoneWithTF.size() == 0) { // 昭迎如果手机号是17703916233或17530176250则需要替换
stringRedisTemplate.opsForValue().set(sequenceKey, "0"); needReplace = "17703916233".equals(phone) || "17530176250".equals(phone);
} }
}
} catch (Exception e) { if (needReplace) {
phone = nextTfPhone(originalPhone); phone = phoneReplaceConfigService.getNextPhone(replaceType, originalPhone);
} }
} else {
phone = nextTfPhone(originalPhone);
} }
} }

View File

@@ -0,0 +1,119 @@
package com.ruoyi.jarvis.service.impl;
import com.ruoyi.jarvis.service.IPhoneReplaceConfigService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSON;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 手机号替换配置Service业务层处理
*
* @author ruoyi
*/
@Service
public class PhoneReplaceConfigServiceImpl implements IPhoneReplaceConfigService
{
@Resource
private StringRedisTemplate stringRedisTemplate;
// Redis key前缀
private static final String REDIS_KEY_PREFIX = "phone_replace_config:";
// 循环索引key前缀
private static final String CYCLE_INDEX_KEY_PREFIX = "phone_cycle_index:";
@Override
public List<String> getPhoneList(String type) {
if (stringRedisTemplate == null) {
return new ArrayList<>();
}
try {
String key = REDIS_KEY_PREFIX + type;
String value = stringRedisTemplate.opsForValue().get(key);
if (value == null || value.isEmpty()) {
return new ArrayList<>();
}
return JSON.parseArray(value, String.class);
} catch (Exception e) {
return new ArrayList<>();
}
}
@Override
public int setPhoneList(String type, List<String> phoneList) {
if (stringRedisTemplate == null) {
return 0;
}
try {
String key = REDIS_KEY_PREFIX + type;
if (phoneList == null || phoneList.isEmpty()) {
stringRedisTemplate.delete(key);
} else {
String value = JSON.toJSONString(phoneList);
stringRedisTemplate.opsForValue().set(key, value);
}
return 1;
} catch (Exception e) {
return 0;
}
}
@Override
public int addPhone(String type, String phone) {
List<String> phoneList = getPhoneList(type);
if (!phoneList.contains(phone)) {
phoneList.add(phone);
return setPhoneList(type, phoneList);
}
return 1;
}
@Override
public int removePhone(String type, String phone) {
List<String> phoneList = getPhoneList(type);
phoneList.remove(phone);
return setPhoneList(type, phoneList);
}
@Override
public String getNextPhone(String type, String originalPhone) {
List<String> phoneList = getPhoneList(type);
if (phoneList == null || phoneList.isEmpty()) {
return originalPhone;
}
if (stringRedisTemplate == null) {
// 如果没有Redis使用简单的轮询基于时间戳
int index = (int) (System.currentTimeMillis() % phoneList.size());
return phoneList.get(index);
}
try {
String sequenceKey = CYCLE_INDEX_KEY_PREFIX + type;
Long index = stringRedisTemplate.opsForValue().increment(sequenceKey);
if (index == null) {
// 如果获取失败,使用时间戳
int idx = (int) (System.currentTimeMillis() % phoneList.size());
return phoneList.get(idx);
}
int phoneIndex = (int) ((index - 1) % phoneList.size());
String phone = phoneList.get(phoneIndex) != null ? phoneList.get(phoneIndex) : originalPhone;
// 当完成一轮循环后重置索引为0
if (index % phoneList.size() == 0) {
stringRedisTemplate.opsForValue().set(sequenceKey, "0");
}
return phone;
} catch (Exception e) {
// 异常时使用时间戳方式
int idx = (int) (System.currentTimeMillis() % phoneList.size());
return phoneList.get(idx);
}
}
}