Merge branch 'master' into cc_20251029_smz
This commit is contained in:
@@ -283,4 +283,10 @@ public class RedisConstant {
|
||||
public static final String SUBMIT_BUILD_KEY = "submit_build_key_";
|
||||
|
||||
public static final String GET_AI_MODULE = "get_ai_module_";
|
||||
|
||||
public static final String HUOMA_STORE_DEVICE_RESOURCE_KEY = "huoma_store_device_resource";
|
||||
|
||||
public static final String HUO_MA_STORE_ID = "huo_ma_store_id";
|
||||
|
||||
public static final String HUO_MA_TOKEN= "huo_ma_token:{0}";
|
||||
}
|
||||
|
||||
@@ -310,9 +310,11 @@ public enum ErrorCodeEnum {
|
||||
MESSAGE_NOT_HANDLED(1610008,"当前消息无需处理,请确认消息处理类型!",null),
|
||||
MESSAGE_PUBLISH(1610009,"您选择通知任务正在发布中,请稍后重试!",null),
|
||||
|
||||
NOT_FLAGSHIP_STORE(16100005,"非直营店,无法跳过缴费阶段!",null),
|
||||
NOT_FLAGSHIP_STORE_NOT_EXIST(16100006,"当前阶段加盟类型不能变更!",null),
|
||||
JOIN_MODE_NOT_ALLOW_OPERATE(16100007,"加盟部人员只能新建加盟店或联营店,请确认!",null),
|
||||
NOT_FLAGSHIP_STORE(1610010,"非直营店,无法跳过缴费阶段!",null),
|
||||
NOT_FLAGSHIP_STORE_NOT_EXIST(1610011,"当前阶段加盟类型不能变更!",null),
|
||||
JOIN_MODE_NOT_ALLOW_OPERATE(1610012,"加盟部人员只能新建加盟店或联营店,请确认!",null),
|
||||
STORE_NOT_FIND(1610013,"门店不存在",null),
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.cool.store.enums;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author suzhuhong
|
||||
* @Date 2025/11/5 16:03
|
||||
* @Version 1.0
|
||||
*/
|
||||
public enum SpecialTagEnum {
|
||||
|
||||
ELECTRONIC_PRICE_LIST("电子价目牌"),
|
||||
ACTIVITY_CAROUSEL("活动轮播"),
|
||||
ACTIVITY_PACKAGE("活动套餐"),
|
||||
PROMOTIONAL_VIDEO("宣传视频");
|
||||
|
||||
private final String tagName;
|
||||
|
||||
SpecialTagEnum(String tagName) {
|
||||
this.tagName = tagName;
|
||||
}
|
||||
|
||||
public String getTagName() {
|
||||
return tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据标签名称获取枚举值
|
||||
*/
|
||||
public static SpecialTagEnum fromTagName(String tagName) {
|
||||
for (SpecialTagEnum tag : values()) {
|
||||
if (tag.getTagName().equals(tagName)) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有标签名称列表
|
||||
*/
|
||||
public static List<String> getAllTagNames() {
|
||||
return Arrays.stream(values())
|
||||
.map(SpecialTagEnum::getTagName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子价目牌标签名称
|
||||
* @return
|
||||
*/
|
||||
public static List<String> getElectronicPriceTagName() {
|
||||
return Arrays.asList(ELECTRONIC_PRICE_LIST.getTagName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.cool.store.enums;
|
||||
|
||||
/**
|
||||
* Created by Administrator on 2020/1/20.
|
||||
*/
|
||||
public enum StoreStatusEnum {
|
||||
|
||||
//营业
|
||||
OPEN("open","在营"),
|
||||
//闭店
|
||||
CLOSED("closed","闭店解约"),
|
||||
//未开业
|
||||
NOT_OPEN("not_open","未开业"),
|
||||
//迁址
|
||||
CHANGE_ADDRESS("change_address","迁址"),
|
||||
//退单
|
||||
CHARGEBACK("chargeback","退单"),
|
||||
//暂停营业
|
||||
CLOSE_UP("close_up","暂停营业");
|
||||
;
|
||||
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String name;
|
||||
|
||||
StoreStatusEnum(String value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static StoreStatusEnum parse(String value) {
|
||||
for (StoreStatusEnum storeStatusEnum : StoreStatusEnum.values()) {
|
||||
if (storeStatusEnum.getValue().equals(value)) {
|
||||
return storeStatusEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getName(String value) {
|
||||
for (StoreStatusEnum storeStatusEnum : StoreStatusEnum.values()) {
|
||||
if (storeStatusEnum.getValue().equals(value)) {
|
||||
return storeStatusEnum.name;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getCode(String flag) {
|
||||
switch (flag) {
|
||||
case "营业":
|
||||
case "在营":
|
||||
return "open";
|
||||
case "闭店":
|
||||
case "闭店解约":
|
||||
return "closed";
|
||||
case "未开业":
|
||||
return "not_open";
|
||||
case "迁址":
|
||||
return "change_address";
|
||||
case "退单":
|
||||
return "chargeback";
|
||||
case "暂停营业":
|
||||
return "close_up";
|
||||
}
|
||||
return "open";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.cool.store.enums.wechat;
|
||||
|
||||
/**
|
||||
* @Author suzhuhong
|
||||
* @Date 2025/10/16 15:19
|
||||
* @Version 1.0
|
||||
*/
|
||||
public enum WechatTemplateDetailEnum {
|
||||
|
||||
CHARACTER_STRING2("编号","character_string2"),
|
||||
THING10("项目名称","thing10"),
|
||||
TIME14("完成时间","time14"),
|
||||
THING25("客户名称","thing25"),
|
||||
THING60("位置","thing60"),
|
||||
|
||||
|
||||
THING6("工单标题","thing6"),
|
||||
TIME33("创建时间","time33"),
|
||||
CHARACTER_STRING14("工单编号","character_string14"),
|
||||
|
||||
|
||||
;
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
private String code;
|
||||
|
||||
WechatTemplateDetailEnum(String name, String code) {
|
||||
this.name = name;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.cool.store.enums.wechat;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cool.store.enums.wechat.WechatTemplateDetailEnum.*;
|
||||
|
||||
/**
|
||||
* @Author suzhuhong
|
||||
* @Date 2025/10/10 14:39
|
||||
* @Version 1.0
|
||||
*/
|
||||
public enum WechatTemplateEnum {
|
||||
|
||||
QUESTION_NOTICE("QUESTION_NOTICE", "T3sp5gBItHKD8oCeEiQMjn7JXpngFiz3dDcaArk84xY", "收到工单通知",
|
||||
Arrays.asList(CHARACTER_STRING2,THING10,TIME14,THING25,THING60)),
|
||||
|
||||
NEW_QUESTION_NOTICE("new_question_notice", "35rmoQ5wEHvUgCgSIJ2CpOb1DOJgWOiy8J7DXT_e4_Y", "新工单提醒",
|
||||
Arrays.asList(THING6,TIME33,CHARACTER_STRING14)),
|
||||
|
||||
;
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String templateId;
|
||||
private final String title;
|
||||
private final List<WechatTemplateDetailEnum> contentList;
|
||||
|
||||
WechatTemplateEnum(String code, String templateId, String title, List<WechatTemplateDetailEnum> contentList) {
|
||||
this.code = code;
|
||||
this.templateId = templateId;
|
||||
this.title = title;
|
||||
this.contentList = contentList;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public List<WechatTemplateDetailEnum> getContentList() {
|
||||
return contentList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code获取枚举
|
||||
*/
|
||||
public static WechatTemplateEnum getByCode(String code) {
|
||||
for (WechatTemplateEnum template : values()) {
|
||||
if (template.getCode().equals(code)) {
|
||||
return template;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模板ID获取枚举
|
||||
*/
|
||||
public static WechatTemplateEnum getByTemplateId(String templateId) {
|
||||
for (WechatTemplateEnum template : values()) {
|
||||
if (template.getTemplateId().equals(templateId)) {
|
||||
return template;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.cool.store.utils;
|
||||
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -28,6 +29,18 @@ public class BeanUtil extends cn.hutool.core.bean.BeanUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T, R> List<R> toList(List<T> list, Class<R> clazz, CopyOptions copyOptions) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<R> result = new ArrayList<>(list.size());
|
||||
for (T t : list) {
|
||||
R r = toBean(t, clazz, copyOptions);
|
||||
result.add(r);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T, R> PageInfo<R> toPage(PageInfo<T> page, Class<R> clazz) {
|
||||
PageInfo<R> newPage = new PageInfo<>();
|
||||
newPage.setPages(page.getPages());
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.cool.store.utils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Author suzhuhong
|
||||
* @Date 2025/11/4 17:34
|
||||
* @Version 1.0
|
||||
*/
|
||||
public class BrowserVersionUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 检测是否为旧版Chrome浏览器(版本小于60)
|
||||
* @param userAgent 浏览器User-Agent字符串
|
||||
* @return true-是旧版Chrome,false-不是旧版Chrome
|
||||
*/
|
||||
public static boolean isOldChromeBrowser(String userAgent) {
|
||||
if (userAgent == null || userAgent.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否是Chrome浏览器
|
||||
if (!userAgent.contains("Chrome")) {
|
||||
return false; // 不是Chrome浏览器
|
||||
}
|
||||
|
||||
// 提取Chrome版本号
|
||||
Integer chromeVersion = extractChromeVersion(userAgent);
|
||||
|
||||
if (chromeVersion == null) {
|
||||
return false; // 无法提取版本号
|
||||
}
|
||||
|
||||
// 判断版本是否小于60
|
||||
return chromeVersion < 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从User-Agent中提取Chrome主版本号
|
||||
* @param userAgent 浏览器User-Agent字符串
|
||||
* @return Chrome主版本号,如果无法提取返回null
|
||||
*/
|
||||
public static Integer extractChromeVersion(String userAgent) {
|
||||
// 正则表达式匹配 Chrome/版本号 模式
|
||||
Pattern pattern = Pattern.compile("Chrome/(\\d+)");
|
||||
Matcher matcher = pattern.matcher(userAgent);
|
||||
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
return Integer.parseInt(matcher.group(1));
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("版本号格式错误: " + matcher.group(1));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.cool.store.utils;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
import com.cool.store.exception.ServiceException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author suzhuhong
|
||||
* @Date 2025/10/10 14:21
|
||||
* @Version 1.0
|
||||
* OkHttp工具类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class OkHttpUtil {
|
||||
|
||||
@Autowired
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
*/
|
||||
public String doGet(String url) throws IOException {
|
||||
return doGet(url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求 - 带请求头
|
||||
*/
|
||||
public String doGet(String url, Map<String, String> headers) throws IOException {
|
||||
Request.Builder builder = new Request.Builder().url(url);
|
||||
|
||||
// 添加请求头
|
||||
if (headers != null && !headers.isEmpty()) {
|
||||
headers.forEach(builder::addHeader);
|
||||
}
|
||||
|
||||
Request request = builder.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Unexpected code: " + response);
|
||||
}
|
||||
ResponseBody body = response.body();
|
||||
return body != null ? body.string() : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求 - JSON数据
|
||||
*/
|
||||
public String doPostJson(String url, Object data) throws IOException {
|
||||
return doPostJson(url, data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求 - JSON数据,带请求头
|
||||
*/
|
||||
public String doPostJson(String url, Object data, Map<String, String> headers) throws IOException {
|
||||
//打印日志
|
||||
logRequest(url, data);
|
||||
|
||||
String json = objectMapper.writeValueAsString(data);
|
||||
RequestBody requestBody = RequestBody.create( JSON,json);
|
||||
Request.Builder builder = new Request.Builder()
|
||||
.url(url)
|
||||
.post(requestBody);
|
||||
|
||||
// 添加请求头
|
||||
if (headers != null && !headers.isEmpty()) {
|
||||
headers.forEach(builder::addHeader);
|
||||
}
|
||||
|
||||
Request request = builder.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
|
||||
"HTTP请求失败,状态码: " + response.code());
|
||||
}
|
||||
ResponseBody body = response.body();
|
||||
|
||||
String responseBody = body != null ? body.string() : null;
|
||||
|
||||
logResponse(url, response.code(), responseBody);
|
||||
return responseBody;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步GET请求
|
||||
*/
|
||||
public void doGetAsync(String url, Callback callback) {
|
||||
doGetAsync(url, null, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步GET请求 - 带请求头
|
||||
*/
|
||||
public void doGetAsync(String url, Map<String, String> headers, Callback callback) {
|
||||
Request.Builder builder = new Request.Builder().url(url);
|
||||
|
||||
if (headers != null && !headers.isEmpty()) {
|
||||
headers.forEach(builder::addHeader);
|
||||
}
|
||||
|
||||
Request request = builder.build();
|
||||
okHttpClient.newCall(request).enqueue(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步POST请求
|
||||
*/
|
||||
public void doPostAsync(String url, Object data, Callback callback) {
|
||||
doPostAsync(url, data, null, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步POST请求 - 带请求头
|
||||
*/
|
||||
public void doPostAsync(String url, Object data, Map<String, String> headers, Callback callback) {
|
||||
try {
|
||||
String json = objectMapper.writeValueAsString(data);
|
||||
RequestBody requestBody = RequestBody.create( JSON,json);
|
||||
|
||||
Request.Builder builder = new Request.Builder()
|
||||
.url(url)
|
||||
.post(requestBody);
|
||||
|
||||
if (headers != null && !headers.isEmpty()) {
|
||||
headers.forEach(builder::addHeader);
|
||||
}
|
||||
|
||||
Request request = builder.build();
|
||||
okHttpClient.newCall(request).enqueue(callback);
|
||||
} catch (IOException e) {
|
||||
callback.onFailure(null, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void logRequest(String url, Object requestBody) {
|
||||
if (log.isInfoEnabled()) {
|
||||
try {
|
||||
log.info("\n======= 请求开始 =======\n" +
|
||||
"API地址: {}\n" +
|
||||
"请求参数: {}\n" +
|
||||
"======= 请求结束 =======",
|
||||
url,
|
||||
objectMapper.writerWithDefaultPrettyPrinter()
|
||||
.writeValueAsString(requestBody));
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warn("日志JSON序列化失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void logResponse(String url, int statusCode, String responseBody) {
|
||||
if (log.isInfoEnabled()) {
|
||||
try {
|
||||
// 尝试美化JSON输出
|
||||
Object json = objectMapper.readValue(responseBody, Object.class);
|
||||
String prettyResponse = objectMapper.writerWithDefaultPrettyPrinter()
|
||||
.writeValueAsString(json);
|
||||
|
||||
log.info("\n======= 响应开始 =======\n" +
|
||||
"API地址: {}\n" +
|
||||
"HTTP状态码: {}\n" +
|
||||
"响应内容: {}\n" +
|
||||
"======= 响应结束 =======",
|
||||
url,
|
||||
statusCode,
|
||||
prettyResponse);
|
||||
} catch (Exception e) {
|
||||
// 非JSON响应或解析失败时直接输出原始内容
|
||||
log.info("\n======= 响应开始 =======\n" +
|
||||
"API地址: {}\n" +
|
||||
"HTTP状态码: {}\n" +
|
||||
"原始响应: {}\n" +
|
||||
"======= 响应结束 =======",
|
||||
url,
|
||||
statusCode,
|
||||
responseBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user