diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/PhoneReplaceConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/PhoneReplaceConfigController.java new file mode 100644 index 0000000..c89ffab --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/PhoneReplaceConfigController.java @@ -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 phoneList = phoneReplaceConfigService.getPhoneList(type); + return AjaxResult.success(phoneList); + } + + /** + * 设置指定类型的手机号列表 + */ + @Log(title = "手机号替换配置", businessType = BusinessType.UPDATE) + @PutMapping("/{type}") + public AjaxResult setPhoneList(@PathVariable("type") String type, @RequestBody List 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)); + } +} + diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IPhoneReplaceConfigService.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IPhoneReplaceConfigService.java new file mode 100644 index 0000000..632702b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IPhoneReplaceConfigService.java @@ -0,0 +1,56 @@ +package com.ruoyi.jarvis.service; + +import java.util.List; + +/** + * 手机号替换配置Service接口 + * + * @author ruoyi + */ +public interface IPhoneReplaceConfigService +{ + /** + * 获取指定类型的手机号列表 + * + * @param type 类型(腾锋或昭迎) + * @return 手机号列表 + */ + public List getPhoneList(String type); + + /** + * 设置指定类型的手机号列表 + * + * @param type 类型(腾锋或昭迎) + * @param phoneList 手机号列表 + * @return 结果 + */ + public int setPhoneList(String type, List 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); +} + diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java index 6951ae3..155b5f5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java @@ -6,6 +6,7 @@ import com.ruoyi.jarvis.service.IInstructionService; import com.ruoyi.jarvis.service.IOrderRowsService; import com.ruoyi.jarvis.service.IJDOrderService; import com.ruoyi.jarvis.service.IProductJdConfigService; +import com.ruoyi.jarvis.service.IPhoneReplaceConfigService; import com.ruoyi.jarvis.service.SuperAdminService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -23,7 +24,6 @@ import java.util.stream.Collectors; import org.springframework.data.redis.core.StringRedisTemplate; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; /** * 将 jd 项目中 JDUtil 的指令能力,抽取为无微信依赖的本地执行版。 @@ -43,6 +43,8 @@ public class InstructionServiceImpl implements IInstructionService { @Resource private IProductJdConfigService productJdConfigService; @Resource + private IPhoneReplaceConfigService phoneReplaceConfigService; + @Resource private com.ruoyi.jarvis.service.ITencentDocService tencentDocService; @Resource private com.ruoyi.jarvis.service.ITencentDocTokenService tencentDocTokenService; @@ -638,31 +640,7 @@ public class InstructionServiceImpl implements IInstructionService { // ===== TF/H/生 处理 ===== // 产品京东配置已迁移到Redis,通过productJdConfigService获取 - - private static final List 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); - } + // 手机号替换配置已迁移到Redis,通过phoneReplaceConfigService获取 private String handleTF(String input) { return handleTF(input, false); @@ -686,6 +664,15 @@ public class InstructionServiceImpl implements IInstructionService { * 型号,地址,电话的处理逻辑不变,将10.10 腾锋 JY202510093195 设置成分销标识这个字段,比如之前是H-TF,现在改成H-TF(10.10 腾锋 JY202510093195) * */ 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,不包含其他内容(第三方单号已单独存储) String fenxiaoInfo = "H-TF"; // 提取第三方单号(第3个字段,格式如:JY202511051374),用于单独存储,不添加到分销标记中 @@ -702,27 +689,25 @@ public class InstructionServiceImpl implements IInstructionService { // 提取电话(第7个字段) String phone = parts[6]; - // 将触发号码替换为 phoneWithTF 列表中的号码,按顺序循环 - if (("13243039070".equals(phone) ) && !phoneWithTF.isEmpty()) { - String originalPhone = phone; - if (stringRedisTemplate != null) { - try { - String sequenceKey = "phone_tf_cycle_index"; - Long index = stringRedisTemplate.opsForValue().increment(sequenceKey); - if (index == null) { - phone = nextTfPhone(originalPhone); - } else { - int phoneIndex = (int) ((index - 1) % phoneWithTF.size()); - phone = phoneWithTF.get(phoneIndex); - if (index % phoneWithTF.size() == 0) { - stringRedisTemplate.opsForValue().set(sequenceKey, "0"); - } - } - } catch (Exception e) { - phone = nextTfPhone(originalPhone); + String originalPhone = phone; + + // 如果识别到"腾锋"或"昭迎",则进行手机号替换 + if (replaceType != null && phoneReplaceConfigService != null) { + List phoneList = phoneReplaceConfigService.getPhoneList(replaceType); + if (phoneList != null && !phoneList.isEmpty()) { + // 检查当前手机号是否在需要替换的列表中 + boolean needReplace = false; + if ("腾锋".equals(replaceType)) { + // 腾锋:如果手机号是13243039070,则需要替换 + needReplace = "13243039070".equals(phone); + } else if ("昭迎".equals(replaceType)) { + // 昭迎:如果手机号是17703916233或17530176250,则需要替换 + needReplace = "17703916233".equals(phone) || "17530176250".equals(phone); + } + + if (needReplace) { + phone = phoneReplaceConfigService.getNextPhone(replaceType, originalPhone); } - } else { - phone = nextTfPhone(originalPhone); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/PhoneReplaceConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/PhoneReplaceConfigServiceImpl.java new file mode 100644 index 0000000..c44558f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/PhoneReplaceConfigServiceImpl.java @@ -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 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 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 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 phoneList = getPhoneList(type); + phoneList.remove(phone); + return setPhoneList(type, phoneList); + } + + @Override + public String getNextPhone(String type, String originalPhone) { + List 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); + } + } +} +