1
This commit is contained in:
@@ -12,6 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
@@ -1147,24 +1149,6 @@ public class InstructionServiceImpl implements IInstructionService {
|
||||
stringRedisTemplate.opsForValue().set(orderNumberKey, orderNumberForDedup, 1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
// 第二重判断:地址 24 小时去重校验(白名单放行)
|
||||
if (stringRedisTemplate != null) {
|
||||
String addressKey = "address:" + address;
|
||||
String existed = stringRedisTemplate.opsForValue().get(addressKey);
|
||||
if (existed != null) {
|
||||
if (!(existed.contains("李波") || existed.contains("吴胜硕") || existed.contains("小硕硕"))) {
|
||||
// 如果强制生成,跳过地址重复检查
|
||||
if (!forceGenerate) {
|
||||
// 返回特殊错误码,前端会识别并弹出验证码
|
||||
return "ERROR_CODE:ADDRESS_DUPLICATE\n此地址已经存在,请勿重复生成订单";
|
||||
}
|
||||
// forceGenerate为true时,跳过地址重复检查,继续执行
|
||||
}
|
||||
}
|
||||
// 只有在不强制生成或地址不存在时才设置Redis(强制生成时也更新Redis记录)
|
||||
stringRedisTemplate.opsForValue().set(addressKey, address, 1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
String today = new java.text.SimpleDateFormat("yyyy-MM-dd ").format(new Date());
|
||||
String todayNoSpace = today.trim();
|
||||
String keyWithSpace = "order_count:" + today; // 带空格
|
||||
@@ -1188,14 +1172,40 @@ public class InstructionServiceImpl implements IInstructionService {
|
||||
StringBuilder out = new StringBuilder();
|
||||
int total = Math.max(1, num);
|
||||
|
||||
// 第二重:同日 + 型号 + 地址 槽位。重复提交视为「更新」——复用当日已分配序号,不递增全局 order_count;强制生成则始终新占号并覆盖槽位。
|
||||
String slotDigest = digestShengSlot(model, address);
|
||||
String slotKey = "sheng_slot:" + todayNoSpace + ":" + slotDigest;
|
||||
Integer reusedCounter = null;
|
||||
if (stringRedisTemplate != null && !forceGenerate && total == 1) {
|
||||
String slotVal = stringRedisTemplate.opsForValue().get(slotKey);
|
||||
if (slotVal != null && !slotVal.isEmpty()) {
|
||||
try {
|
||||
int c = Integer.parseInt(slotVal.trim());
|
||||
if (c >= 1) {
|
||||
reusedCounter = c;
|
||||
}
|
||||
} catch (NumberFormatException ignore) {
|
||||
reusedCounter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int startCount = 1;
|
||||
if (reusedCounter != null) {
|
||||
startCount = reusedCounter;
|
||||
if (stringRedisTemplate != null) {
|
||||
stringRedisTemplate.opsForValue().set(slotKey, String.valueOf(reusedCounter), 1, TimeUnit.DAYS);
|
||||
}
|
||||
} else if (stringRedisTemplate != null) {
|
||||
try {
|
||||
String s = stringRedisTemplate.opsForValue().get(redisKey);
|
||||
int count = s != null ? Integer.parseInt(s) : 0;
|
||||
startCount = count + 1;
|
||||
int endCount = count + total;
|
||||
stringRedisTemplate.opsForValue().set(redisKey, String.valueOf(endCount), 30, TimeUnit.DAYS);
|
||||
if (total == 1) {
|
||||
stringRedisTemplate.opsForValue().set(slotKey, String.valueOf(startCount), 1, TimeUnit.DAYS);
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
@@ -1217,6 +1227,26 @@ public class InstructionServiceImpl implements IInstructionService {
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同日「生」指令槽位键摘要:规范化后的 型号 + 地址,避免仅按地址误伤「同址不同型号」。
|
||||
*/
|
||||
private String digestShengSlot(String model, String address) {
|
||||
String m = normalizeWhitespace(model == null ? "" : model);
|
||||
String a = normalizeWhitespace(address == null ? "" : address);
|
||||
String raw = m + "\u0001" + a;
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] d = md.digest(raw.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
for (byte b : d) {
|
||||
sb.append(String.format("%02x", b));
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return Integer.toHexString(Objects.hash(m, a));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从分销标记中提取订单编号
|
||||
* 例如:从 "H-TF(10.10 腾锋 JY202510093195)" 中提取 "JY202510093195"
|
||||
|
||||
@@ -1000,6 +1000,22 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
||||
String cleanTitle = cleanTitleOrRemark(title.trim());
|
||||
String cleanRemark = StringUtils.isNotEmpty(remark) ? cleanTitleOrRemark(remark.trim()) : "";
|
||||
|
||||
boolean generateSeed = isTrue(req.get("generateSeedNote"));
|
||||
if (generateSeed) {
|
||||
if (StringUtils.isEmpty(asString(req.get("goods_title")))) {
|
||||
req.put("goods_title", cleanTitle);
|
||||
}
|
||||
if (StringUtils.isEmpty(asString(req.get("goods_model")))) {
|
||||
req.put("goods_model", cleanRemark);
|
||||
}
|
||||
String seedError = validateSeedRequiredFields(req);
|
||||
if (seedError != null) {
|
||||
result.put("success", false);
|
||||
result.put("error", seedError);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
String wenanBase = getPromptTemplateWithDefault("xianyu:wenan_base", DEFAULT_XIANYU_WENAN_BASE);
|
||||
String jiaonixiadanExtra = getPromptTemplateWithDefault("xianyu:jiaonixiadan_extra", DEFAULT_XIANYU_JIAONIXIADAN_EXTRA);
|
||||
|
||||
@@ -1028,14 +1044,7 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
||||
result.put("daixiadan", daixiadanBuilder.toString());
|
||||
result.put("jiaonixiadan", jiaonixiadanBuilder.toString());
|
||||
|
||||
boolean generateSeed = isTrue(req.get("generateSeedNote"));
|
||||
if (generateSeed) {
|
||||
String seedError = validateSeedRequiredFields(req);
|
||||
if (seedError != null) {
|
||||
result.put("success", false);
|
||||
result.put("error", seedError);
|
||||
return result;
|
||||
}
|
||||
try {
|
||||
String seedPrompt = buildSeedPrompt(req);
|
||||
String seedNote = callJarvisLlm(seedPrompt, asString(req.get("profileId")));
|
||||
@@ -1045,9 +1054,8 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
||||
result.put("seedNote", seedNote.trim());
|
||||
} catch (Exception e) {
|
||||
log.error("生成闲鱼种草文案失败", e);
|
||||
result.put("success", false);
|
||||
result.put("error", "种草文案生成失败: " + e.getMessage());
|
||||
return result;
|
||||
result.put("seedNote", "");
|
||||
result.put("seedNoteError", "种草文案生成失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user