diff --git a/coolstore-partner-common/src/main/java/com/cool/store/annotation/PlatformDB.java b/coolstore-partner-common/src/main/java/com/cool/store/annotation/PlatformDB.java new file mode 100644 index 000000000..6b1b91fac --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/annotation/PlatformDB.java @@ -0,0 +1,14 @@ +package com.cool.store.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 平台库数据源 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface PlatformDB { +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java b/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java index 6dfd1f3a7..abae182db 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/constants/CommonConstants.java @@ -211,5 +211,23 @@ public class CommonConstants { public static final String WX_SELF_AUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=1#wechat_redirect"; + /** + * 密码最大错误次数 + */ + public static final int MAX_ERROR_PASSWORD_COUNT = 5; + /** + * 用户密码 + */ + public static final String USER_AUTH_KEY = "user_auth_key"; + + /** + * accessToken有效期,单位秒 + */ + public static final int ACTION_TOKEN_EXPIRE = 24 * 60 * 60; + + /** + * refreshToken有效期,单位秒 + */ + public static final int REFRESH_TOKEN_EXPIRE = 30 * 24 * 60 * 60; } diff --git a/coolstore-partner-common/src/main/java/com/cool/store/datasource/DataSourceContextHolder.java b/coolstore-partner-common/src/main/java/com/cool/store/datasource/DataSourceContextHolder.java new file mode 100644 index 000000000..dd0b32ff0 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/datasource/DataSourceContextHolder.java @@ -0,0 +1,25 @@ +package com.cool.store.datasource; + +/** + *

+ * 数据源上下文 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +public class DataSourceContextHolder { + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + public static void setDataSourceType(String dataSourceType) { + contextHolder.set(dataSourceType); + } + + public static String getDataSourceType() { + return contextHolder.get(); + } + + public static void clearDataSourceType() { + contextHolder.remove(); + } +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/datasource/DynamicDataSource.java b/coolstore-partner-common/src/main/java/com/cool/store/datasource/DynamicDataSource.java new file mode 100644 index 000000000..66bf25663 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/datasource/DynamicDataSource.java @@ -0,0 +1,53 @@ +package com.cool.store.datasource; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.datasource.AbstractDataSource; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + *

+ * 动态数据源 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Component +@Primary +public class DynamicDataSource extends AbstractDataSource { + + @Autowired + private DataSource defaultDataSource; + + @Autowired + private DataSource platformDataSource; + + @Override + public Connection getConnection() throws SQLException { + DataSource currentDB = getCurrentDB(); + return currentDB.getConnection(); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + DataSource currentDB = getCurrentDB(); + Connection connection = currentDB.getConnection(username, password); + connection.setCatalog(DataSourceContextHolder.getDataSourceType()); + return connection; + } + + protected DataSource getCurrentDB() { + String dbName = DataSourceContextHolder.getDataSourceType(); + if (StringUtils.isBlank(dbName)) { + return defaultDataSource; + } + return platformDataSource; + } + +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java index 1941b2721..d88e4dfca 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java @@ -40,6 +40,7 @@ public enum ErrorCodeEnum { LOGIN_ERROR(400004, "登录失败", null), ENTERPRISE_INIT(400006, "企业正在初始化,请稍后访问!",null), NOT_AUTH(400007, "暂无权限,请联系管理员!", null), + REFRESH_TOKEN_INVALID(400008, "refresh token invalid", null), USER_FREEZE(1021019,"账号被冻结,请联系管理员",null), ENTERPRISE_NOT_EXIST(1021020,"企业不存在",null), USER_NOT_EXIST(1021021,"用户不存在",null), @@ -62,6 +63,11 @@ public enum ErrorCodeEnum { DATA_CONVERT_ERROR(400002, "日期转换异常!", null), PARENT_NODE_NOT_EXIST(400002, "父节点不存在", null), LOGIN_ERROR_MOBILE_ERROR(418, "登录失败 获取手机号失败!!", null), + PASSWORD_ERROR_MAX_COUNT(1021084, "密码错误{0}次,今日账号已锁定",null), + PASSWORD_MISSING(1021085, "密码不能为空!",null), + IMPROVE_USER_INFO(1021086,"请联系管理员,完善用户信息!",null), + PASSWORD_ERROR(1021087, "密码输入错误",null), + PASSWORD_ERROR_MULTI(1021088, "密码错误{0}次,请使用验证码登录",null), //红圈通 HQT_SHOP_DECORATION_ATTRIBUTES(1022000, "获取红圈通装修属性错误", null), HQT_PARAMS_ERROR(1022001, "构建红圈通请求参数错误", null), diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java new file mode 100644 index 000000000..f7b95f109 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java @@ -0,0 +1,25 @@ +package com.cool.store.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 登录类型 枚举类 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Getter +@AllArgsConstructor +public enum LoginTypeEnum { + + PASSWORD("账号密码", "passwordLoginServiceImpl"), + + ; + + private final String message; + + private final String clazzName; +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/MatterTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/MatterTypeEnum.java index bcc9697d8..20dc79ba2 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/MatterTypeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/MatterTypeEnum.java @@ -14,6 +14,7 @@ public enum MatterTypeEnum { SERVICE_PACKAGE(4,"服务包"), RESTOCK(5,"补货"), INVENTORY(6,"盘点"), + REALTIME(7, "即时消息"), ; MatterTypeEnum(Integer code, String message) { diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/ModuleCodeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/ModuleCodeEnum.java index 3bfa89f8a..aefa1d85c 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/ModuleCodeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/ModuleCodeEnum.java @@ -16,7 +16,7 @@ public enum ModuleCodeEnum { DISH(3,"菜品",Arrays.asList(MatterTypeEnum.NOTICE)), FRANCHISE(4,"加盟",Arrays.asList(MatterTypeEnum.NOTICE)), //其他(投诉与客户服务、临时通知) - OTHER(5,"其他",Arrays.asList(MatterTypeEnum.NOTICE)), + OTHER(5,"其他",Arrays.asList(MatterTypeEnum.NOTICE, MatterTypeEnum.REALTIME)), ; ModuleCodeEnum(Integer code, String message,List matterTypeEnums) { diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/SceneEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/SceneEnum.java index d5fc87540..abeb053f0 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/SceneEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/notice/SceneEnum.java @@ -18,6 +18,7 @@ public enum SceneEnum { RESTOCK(35, "补货", "", MatterTypeEnum.LOGISTICS), INVENTORY(40, "盘点", "", MatterTypeEnum.LOGISTICS), + REALTIME(45, "即时消息", "", MatterTypeEnum.REALTIME), ; private Integer sceneCode; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/executor/ThreadPoolTaskConfig.java b/coolstore-partner-common/src/main/java/com/cool/store/executor/ThreadPoolTaskConfig.java new file mode 100644 index 000000000..75bc5a1b2 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/executor/ThreadPoolTaskConfig.java @@ -0,0 +1,45 @@ +package com.cool.store.executor; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.ThreadPoolExecutor; + +/** + *

+ * 线程池配置类 + *

+ * + * @author wangff + * @since 2025/9/5 + */ +@Configuration +public class ThreadPoolTaskConfig { + + /** + * 通用线程池 + */ + @Bean + public TaskExecutor generalThreadPool() { + int cores = Runtime.getRuntime().availableProcessors(); + + ThreadPoolTaskExecutor executor = new MdcTaskExecutor(); + // 核心线程数目 + executor.setCorePoolSize(cores*2); + // 指定最大线程数 + executor.setMaxPoolSize(200); + // 队列中最大的数目 + executor.setQueueCapacity(5000); + // 线程名称前缀 + executor.setThreadNamePrefix("generalThreadPool_"); + // 对拒绝task的处理策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + // 线程空闲后的最大存活时间 + executor.setKeepAliveSeconds(60); + // 加载 + executor.initialize(); + return executor; + } +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java new file mode 100644 index 000000000..7838c1fd5 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java @@ -0,0 +1,41 @@ +package com.cool.store.utils; + +import com.github.pagehelper.PageInfo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + *

+ * bean转换工具 + *

+ * + * @author wangff + * @since 2025/3/6 + */ +public class BeanUtil extends cn.hutool.core.bean.BeanUtil { + + public static List toList(List list, Class clazz) { + if (list == null || list.isEmpty()) { + return Collections.emptyList(); + } + List result = new ArrayList<>(list.size()); + for (T t : list) { + R r = toBean(t, clazz); + result.add(r); + } + return result; + } + + public static PageInfo toPage(PageInfo page, Class clazz) { + PageInfo newPage = new PageInfo<>(); + newPage.setPages(page.getPages()); + newPage.setTotal(page.getTotal()); + newPage.setPageNum(page.getPageNum()); + newPage.setPageSize(page.getPageSize()); + List list = toList(page.getList(), clazz); + newPage.setList(list); + return newPage; + } +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/SpringContextUtil.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/SpringContextUtil.java new file mode 100644 index 000000000..183f34d94 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/SpringContextUtil.java @@ -0,0 +1,34 @@ +package com.cool.store.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + *

+ * Spring上下文工具 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Component +public class SpringContextUtil implements ApplicationContextAware { + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextUtil.applicationContext = applicationContext; + } + + /** + * 获取bean + * @param name beanName + * @param clazz bean类型 + * @return bean + */ + public static T getBean(String name, Class clazz) { + return applicationContext.getBean(name, clazz); + } +} diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java index 8cde88a4d..32cc9f21e 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/EnterpriseUserDAO.java @@ -4,8 +4,8 @@ import com.cool.store.constants.CommonConstants; import com.cool.store.dto.UserDTO; import com.cool.store.dto.openPreparation.UserNameDTO; import com.cool.store.entity.EnterpriseUserDO; +import com.cool.store.entity.login.UserLoginDO; import com.cool.store.mapper.EnterpriseUserMapper; -import com.cool.store.response.oppty.UserResponse; import com.cool.store.utils.StringUtil; import com.google.common.collect.Lists; import org.apache.commons.collections4.CollectionUtils; @@ -175,4 +175,13 @@ public class EnterpriseUserDAO { } return enterpriseUserMapper.searchUserByUserIdsAndKeyword(userIdList, keyword); } + + /** + * 从平台库根据唯一id获取用户登录信息 + * @param unionid 唯一id + * @return 用户登录信息 + */ + public UserLoginDO getUserLoginByUnionid(String unionid) { + return enterpriseUserMapper.getUserLoginByUnionid(unionid); + } } \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java index 8ccd2bb57..ae0c77f3d 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java @@ -1,8 +1,10 @@ package com.cool.store.mapper; +import com.cool.store.annotation.PlatformDB; import com.cool.store.dto.UserDTO; import com.cool.store.dto.openPreparation.UserNameDTO; import com.cool.store.entity.EnterpriseUserDO; +import com.cool.store.entity.login.UserLoginDO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -103,4 +105,12 @@ public interface EnterpriseUserMapper { List searchUserByUserIdsAndKeyword( @Param("userIdList") List userIdList, @Param("keyword") String keyword); List getUserIdsByRegionIdList( @Param("regionIdList") List regionIdList); + + /** + * 从平台库根据唯一id获取用户登录信息 + * @param unionid 唯一id + * @return 用户登录信息 + */ + @PlatformDB + UserLoginDO getUserLoginByUnionid(@Param("unionid") String unionid); } \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml index 26e3a697a..4b3246910 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml @@ -235,4 +235,10 @@ + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/StoreMessageMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/StoreMessageMapper.xml index f83adb924..59ccfff2e 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/StoreMessageMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/StoreMessageMapper.xml @@ -25,7 +25,7 @@ - + INSERT INTO zxjp_store_message ( store_id, store_code, diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java new file mode 100644 index 000000000..e309d2826 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java @@ -0,0 +1,27 @@ +package com.cool.store.dto.login; + +import com.cool.store.enums.LoginTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + *

+ * 登录DTO + *

+ * + * @author wangff + * @since 2025/9/3 + */ +@Data +public class UserLoginDTO { + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("密码") + private String password; + + @NotNull(message = "登录类型不能为空") + private LoginTypeEnum loginType; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserRefreshLoginDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserRefreshLoginDTO.java new file mode 100644 index 000000000..acfa484c3 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserRefreshLoginDTO.java @@ -0,0 +1,18 @@ +package com.cool.store.dto.login; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * RefreshToken登录DTO + *

+ * + * @author wangff + * @since 2025/9/5 + */ +@Data +public class UserRefreshLoginDTO { + @ApiModelProperty("RefreshToken") + private String refreshToken; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/login/UserLoginDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/login/UserLoginDO.java new file mode 100644 index 000000000..c8965d44b --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/login/UserLoginDO.java @@ -0,0 +1,33 @@ +package com.cool.store.entity.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 用户登录信息 + *

+ * + * @author wangff + * @since 2025/9/3 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserLoginDO { + /** + * 用户id + */ + private String userId; + + /** + * 手机号 + */ + private String mobile; + + /** + * 密码 + */ + private String password; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/StoreMasterDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/request/StoreMasterDTO.java index 0a771beac..642bc5d6d 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/request/StoreMasterDTO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/StoreMasterDTO.java @@ -49,6 +49,12 @@ public class StoreMasterDTO { @ApiModelProperty("省市区") private String area; + @ApiModelProperty("省") + private String province; + @ApiModelProperty("市") + private String city; + @ApiModelProperty("区/县") + private String district; @ApiModelProperty("乡镇") private String town; @ApiModelProperty("门店地址") diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/notice/BatchPublishRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/notice/BatchPublishRequest.java index 2d824e021..832d5c5bd 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/request/notice/BatchPublishRequest.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/notice/BatchPublishRequest.java @@ -22,4 +22,6 @@ public class BatchPublishRequest { @ApiModelProperty( "默认处理人信息 type[person position userGroup organization]") List userInfoList; + @ApiModelProperty("事项类型") + private Integer matterType; } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/userholder/RefreshUser.java b/coolstore-partner-model/src/main/java/com/cool/store/userholder/RefreshUser.java new file mode 100644 index 000000000..b8a84fc0f --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/userholder/RefreshUser.java @@ -0,0 +1,33 @@ +package com.cool.store.userholder; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * RefreshToken用户信息 + *

+ * + * @author wangff + * @since 2025/9/5 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RefreshUser { + /** + * 用户Id + */ + private String userId; + + /** + * RefreshToken + */ + private String refreshToken; + + /** + * 手机号 + */ + private String mobile; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/login/UserBaseInfoVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/login/UserBaseInfoVO.java new file mode 100644 index 000000000..cceaadf5c --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/login/UserBaseInfoVO.java @@ -0,0 +1,35 @@ +package com.cool.store.vo.login; + +import com.cool.store.entity.SysRoleDO; +import lombok.Data; + +/** + *

+ * 登录用户基本信息VO + *

+ * + * @author wangff + * @since 2025/9/5 + */ +@Data +public class UserBaseInfoVO { + private String id; + + private String userId; + + private String name; + + private Boolean isAdmin; + + private String mobile; + + private String email; + + private String avatar; + + private String roles; + + private String language; + + private SysRoleDO sysRoleDO; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/login/UserLoginVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/login/UserLoginVO.java new file mode 100644 index 000000000..ac6370bdb --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/login/UserLoginVO.java @@ -0,0 +1,38 @@ +package com.cool.store.vo.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 用户登录VO + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserLoginVO { + /** + * 登录token + */ + private String accessToken; + + /** + * 刷新token + */ + private String refreshToken; + + /** + * accessToken过期时间 + */ + private Integer expire; + + /** + * 用户信息 + */ + private UserBaseInfoVO user; +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseService.java index f00f75d0b..2fb88f946 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/EnterpriseService.java @@ -1,5 +1,8 @@ package com.cool.store.service; +import com.cool.store.userholder.CurrentUser; +import com.cool.store.userholder.RefreshUser; + /** * @Author suzhuhong * @Date 2025/5/29 16:34 @@ -13,7 +16,10 @@ public interface EnterpriseService { * @param mobile * @return */ - String getAccessToken(String mobile); - + CurrentUser getLoginInfo(String mobile); + /** + * 获取并缓存refreshToken + */ + RefreshUser getRefreshUser(String userId, String mobile); } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseServiceImpl.java index 7f5c7ac66..79b08e9d3 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/EnterpriseServiceImpl.java @@ -1,6 +1,7 @@ package com.cool.store.service.impl; import com.alibaba.fastjson.JSON; +import com.cool.store.constants.CommonConstants; import com.cool.store.constants.RedisConstant; import com.cool.store.dao.EnterpriseUserDAO; import com.cool.store.entity.EnterpriseUserDO; @@ -12,8 +13,10 @@ import com.cool.store.exception.ServiceException; import com.cool.store.mapper.SysRoleMapper; import com.cool.store.service.EnterpriseService; import com.cool.store.userholder.CurrentUser; +import com.cool.store.userholder.RefreshUser; import com.cool.store.utils.RedisUtilPool; import com.cool.store.utils.poi.DateUtils; +import com.cool.store.utils.poi.constant.Constants; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.crypto.RandomNumberGenerator; @@ -48,7 +51,7 @@ public class EnterpriseServiceImpl implements EnterpriseService { private String eid; @Override - public String getAccessToken(String mobile) { + public CurrentUser getLoginInfo(String mobile) { CurrentUser currentUser = new CurrentUser(); EnterpriseUserDO enterpriseUser = enterpriseUserDAO.selectByMobile(mobile); if (Objects.isNull(enterpriseUser)){ @@ -107,8 +110,20 @@ public class EnterpriseServiceImpl implements EnterpriseService { currentUser.setAppType("qw_self_dkf"); currentUser.setUnionid(enterpriseUser.getUnionid()); currentUser.setUserType(enterpriseUser.getUserType()); - redisUtilPool.setString(RedisConstant.ACCESS_TOKEN_PREFIX + currentUser.getAccessToken(), JSON.toJSONString(currentUser), 24 * 60 * 60); - return currentUser.getAccessToken(); + redisUtilPool.setString(RedisConstant.ACCESS_TOKEN_PREFIX + currentUser.getAccessToken(), JSON.toJSONString(currentUser), CommonConstants.ACTION_TOKEN_EXPIRE); + return currentUser; + } + + @Override + public RefreshUser getRefreshUser(String userId, String mobile) { + if (StringUtils.isBlank(mobile)) { + EnterpriseUserDO userInfo = enterpriseUserDAO.getUserInfoById(userId); + mobile = userInfo.getMobile(); + } + String refreshToken = getToken(); + RefreshUser refreshUser = new RefreshUser(userId, refreshToken, mobile); + redisUtilPool.setString(RedisConstant.REFRESH_TOKEN_PREFIX + refreshToken, JSON.toJSONString(refreshUser), CommonConstants.REFRESH_TOKEN_EXPIRE); + return refreshUser; } public static void main(String[] args) { diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageIssueService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageIssueService.java new file mode 100644 index 000000000..b96dc18f7 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageIssueService.java @@ -0,0 +1,78 @@ +package com.cool.store.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollStreamUtil; +import cn.hutool.core.util.ArrayUtil; +import com.alibaba.fastjson.JSONObject; +import com.cool.store.dao.MessageTemplateDAO; +import com.cool.store.entity.MessageTemplateDO; +import com.cool.store.entity.StoreMessageDO; +import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.exception.ServiceException; +import com.cool.store.vo.notice.StoreMessageVO; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.messaging.MessagingException; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + *

+ * 消息下发 服务类 + *

+ * + * @author wangff + * @since 2025/9/5 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class MessageIssueService { + private final MessageTemplateDAO messageTemplateDAO; + private final SimpMessagingTemplate simpMessagingTemplate; + + /** + * 下发即时通知消息 + * + * @param list 门店消息列表 + */ + @Async("generalThreadPool") + public void issueMessage(List list) { + if (CollectionUtils.isEmpty(list)) return; + log.info("下发即时通知, messageList:{}", JSONObject.toJSONString(list)); + try { + Set messageTemplateIds = CollStreamUtil.toSet(list, StoreMessageDO::getMessageTemplateId); + List messageTemplateList = messageTemplateDAO.getByIds(new ArrayList<>(messageTemplateIds)); + Map messageTemplateMap = CollStreamUtil.toMap(messageTemplateList, MessageTemplateDO::getId, v -> v); + + for (StoreMessageDO storeMessageDO : list) { + if (StringUtils.isNotBlank(storeMessageDO.getOperatorList())) { + String[] userIds = storeMessageDO.getOperatorList().split(","); + if (ArrayUtil.isNotEmpty(userIds)) { + MessageTemplateDO messageTemplateDO = messageTemplateMap.get(storeMessageDO.getMessageTemplateId()); + if (Objects.isNull(messageTemplateDO)) { + throw new ServiceException(ErrorCodeEnum.MESSAGE_NOT_EXIST); + } + StoreMessageVO storeMessageVO = BeanUtil.toBean(storeMessageDO, StoreMessageVO.class); + BeanUtil.copyProperties(messageTemplateDO, storeMessageVO, "id"); + String message = JSONObject.toJSONString(storeMessageVO); + for (String userId : userIds) { + try { + simpMessagingTemplate.convertAndSend("/queue/message/" + userId, message); + } catch (MessagingException e) { + log.info("即时通知下发异常, userId:{}, error:{}", userId, e.getMessage()); + } + } + } + } + } + } catch (Exception e) { + log.info("即时通知下发异常", e); + } + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageTemplateServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageTemplateServiceImpl.java index 8ed0160bd..76c985caa 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageTemplateServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/MessageTemplateServiceImpl.java @@ -3,7 +3,6 @@ package com.cool.store.service.impl; import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSONObject; import com.cool.store.context.LoginUserInfo; -import com.cool.store.context.PartnerUserHolder; import com.cool.store.dao.*; import com.cool.store.dto.notice.CommonDTO; import com.cool.store.dto.notice.MessageTemplateCountDTO; @@ -26,11 +25,9 @@ import com.cool.store.vo.PartnerUserInfoVO; import com.cool.store.vo.notice.*; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; -import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.ibatis.annotations.Param; import org.springframework.beans.BeanUtils; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.annotation.Async; @@ -73,6 +70,8 @@ public class MessageTemplateServiceImpl implements MessageTemplateService { RedisUtilPool redisUtilPool; @Resource TaskExecutor noticeThreadPool; + @Resource + MessageIssueService messageIssueService; @@ -178,6 +177,7 @@ public class MessageTemplateServiceImpl implements MessageTemplateService { List storeAreaDTOS = getStoreRange(request.getStoreInfoList()); List storeIds = storeAreaDTOS.stream().map(StoreAreaDTO::getStoreId).collect(Collectors.toList()); Map> authUser = getAuthUser(request.getUserInfoList(), storeIds); + List realtimeMessageList = new ArrayList<>(); list.stream().forEach(x -> { List result = new ArrayList<>(); storeAreaDTOS.forEach(y->{ @@ -199,6 +199,9 @@ public class MessageTemplateServiceImpl implements MessageTemplateService { result.add(storeMessageDO); }); storeMessageDAO.batchInsert(result); + if (MatterTypeEnum.REALTIME.getCode().equals(request.getMatterType())) { + realtimeMessageList.addAll(result); + } }); //存在第一个成功 第二个失败 会有问题 todo @@ -207,6 +210,8 @@ public class MessageTemplateServiceImpl implements MessageTemplateService { JSONObject.toJSONString(request.getStoreInfoList()), JSONObject.toJSONString(request.getUserInfoList()), userId); + // 即时消息下发 + messageIssueService.issueMessage(realtimeMessageList); } catch (Exception e) { log.info("发布流程异常,已取消发布"); } finally { @@ -357,6 +362,7 @@ public class MessageTemplateServiceImpl implements MessageTemplateService { batchPublishRequest.setIds(Arrays.asList(messageTemplateDO.getId())); batchPublishRequest.setStoreInfoList(JSONObject.parseArray(storeInfo, CommonDTO.class)); batchPublishRequest.setUserInfoList(JSONObject.parseArray(userInfo, CommonDTO.class)); + batchPublishRequest.setMatterType(matterConfig.getMatterType()); try { batchPublishMessageTemplate(batchPublishRequest,""); } catch (ServiceException e) { diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncMainSysServerImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncMainSysServerImpl.java index dac429721..e90791f27 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncMainSysServerImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/SyncMainSysServerImpl.java @@ -160,6 +160,9 @@ public class SyncMainSysServerImpl implements SyncMainSysServer { PointDetailInfoDO pointDetail = pointDetailDAO.getPointDetailInfoByPointId(shopInfo.getPointId()); if (info != null){ storeMasterDTO.setArea(info.getProvince()+info.getCity()+info.getDistrict()); + storeMasterDTO.setProvince(info.getProvince()); + storeMasterDTO.setCity(info.getCity()); + storeMasterDTO.setDistrict(info.getDistrict()); storeMasterDTO.setTown(info.getTownship()); storeMasterDTO.setStoreAddress(info.getAddress()); storeMasterDTO.setLocationAddress(info.getAddress()); diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java new file mode 100644 index 000000000..c7de70b03 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java @@ -0,0 +1,106 @@ +package com.cool.store.service.login; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONObject; +import com.cool.store.constants.CommonConstants; +import com.cool.store.constants.RedisConstant; +import com.cool.store.context.CurrentUserHolder; +import com.cool.store.context.LoginUserInfo; +import com.cool.store.dao.EnterpriseUserDAO; +import com.cool.store.dto.login.UserLoginDTO; +import com.cool.store.dto.login.UserRefreshLoginDTO; +import com.cool.store.entity.EnterpriseUserDO; +import com.cool.store.entity.login.UserLoginDO; +import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.EnterpriseService; +import com.cool.store.userholder.CurrentUser; +import com.cool.store.userholder.RefreshUser; +import com.cool.store.utils.RedisUtilPool; +import com.cool.store.utils.poi.constant.Constants; +import com.cool.store.vo.login.UserBaseInfoVO; +import com.cool.store.vo.login.UserLoginVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.time.LocalDate; + +/** + *

+ * 登录基础服务类 + *

+ * + * @author wangff + * @since 2025/9/3 + */ +@Slf4j +@Service +public abstract class LoginBaseService implements LoginStrategy { + @Resource + private RedisUtilPool redisUtilPool; + @Resource + private EnterpriseUserDAO enterpriseUserDAO; + @Resource + private EnterpriseService enterpriseService; + + /** + * 策略登录实现方法 + */ + public abstract ResponseResult userLogin(UserLoginDTO param, UserLoginDO userLoginDO); + + @Override + public ResponseResult login(UserLoginDTO param) { + log.info("login:{}", JSONObject.toJSONString(param)); + String errorPasswordCountKey = MessageFormat.format(RedisConstant.ERROR_PASSWORD_COUNT_KEY, LocalDate.now(), param.getMobile()); + String errorCount = redisUtilPool.getString(errorPasswordCountKey); + //判断密码错误次数 + if (StringUtils.isNotBlank(errorCount)) { + if (Integer.parseInt(errorCount) >= CommonConstants.MAX_ERROR_PASSWORD_COUNT) { + return ResponseResult.fail(ErrorCodeEnum.PASSWORD_ERROR_MAX_COUNT, errorCount); + } + } + EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(param.getMobile()); + UserLoginDO userLoginDO = enterpriseUserDAO.getUserLoginByUnionid(enterpriseUserDO.getUnionid()); + return userLogin(param, userLoginDO); + } + + @Override + public ResponseResult refreshLogin(UserRefreshLoginDTO param) { + String refreshTokenKey = RedisConstant.REFRESH_TOKEN_PREFIX + param.getRefreshToken(); + String refreshUserStr = redisUtilPool.getString(refreshTokenKey); + if (StringUtils.isBlank(refreshUserStr)) { + return ResponseResult.fail(ErrorCodeEnum.REFRESH_TOKEN_INVALID); + } + RefreshUser refreshUser = JSONObject.parseObject(refreshUserStr, RefreshUser.class); + if (StringUtils.isBlank(refreshUser.getMobile())) { + return ResponseResult.fail(ErrorCodeEnum.REFRESH_TOKEN_INVALID); + } + UserLoginDO userLoginDO = new UserLoginDO(refreshUser.getUserId(), refreshUser.getMobile(), null); + return ResponseResult.success(getUserLoginInfo(userLoginDO)); + } + + @Override + public ResponseResult logout() { + LoginUserInfo currentUser = CurrentUserHolder.getUser(); + String accessToken = currentUser.getAccessToken(); + String key = RedisConstant.ACCESS_TOKEN_PREFIX + accessToken; + redisUtilPool.delKey(key); + return ResponseResult.success(); + } + + /** + * 获取登录accessToken + * + * @param userLoginDO 用户登录信息 + * @return accessToken + */ + public UserLoginVO getUserLoginInfo(UserLoginDO userLoginDO) { + CurrentUser currentUser = enterpriseService.getLoginInfo(userLoginDO.getMobile()); + UserBaseInfoVO userBAseInfoVO = BeanUtil.toBean(currentUser, UserBaseInfoVO.class); + RefreshUser refreshUser = enterpriseService.getRefreshUser(userLoginDO.getUserId(), userLoginDO.getMobile()); + return new UserLoginVO(currentUser.getAccessToken(), refreshUser.getRefreshToken(), CommonConstants.ACTION_TOKEN_EXPIRE, userBAseInfoVO); + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginStrategy.java b/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginStrategy.java new file mode 100644 index 000000000..fefd75d54 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginStrategy.java @@ -0,0 +1,30 @@ +package com.cool.store.service.login; + +import com.cool.store.dto.login.UserLoginDTO; +import com.cool.store.dto.login.UserRefreshLoginDTO; +import com.cool.store.response.ResponseResult; + +/** + *

+ * 登录策略 + *

+ * + * @author wangff + * @since 2025/9/3 + */ +public interface LoginStrategy { + /** + * 登录基础方法 + */ + ResponseResult login(UserLoginDTO param); + + /** + * refreshToken登录 + */ + ResponseResult refreshLogin(UserRefreshLoginDTO param); + + /** + * 登出 + */ + ResponseResult logout(); +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/PasswordLoginServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/PasswordLoginServiceImpl.java new file mode 100644 index 000000000..f863e543d --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/PasswordLoginServiceImpl.java @@ -0,0 +1,55 @@ +package com.cool.store.service.login.impl; + +import com.aliyun.core.utils.StringUtils; +import com.cool.store.constants.CommonConstants; +import com.cool.store.constants.RedisConstant; +import com.cool.store.dto.login.UserLoginDTO; +import com.cool.store.entity.login.UserLoginDO; +import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.login.LoginBaseService; +import com.cool.store.utils.Md5Utils; +import com.cool.store.utils.RedisUtilPool; +import com.cool.store.utils.poi.constant.Constants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.text.MessageFormat; +import java.time.LocalDate; + +/** + *

+ * 密码登录服务实现类 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class PasswordLoginServiceImpl extends LoginBaseService { + private final RedisUtilPool redisUtilPool; + + @Override + public ResponseResult userLogin(UserLoginDTO param, UserLoginDO userLoginDO) { + if (StringUtils.isBlank(param.getPassword())) { + return ResponseResult.fail(ErrorCodeEnum.PASSWORD_MISSING); + } + if (StringUtils.isBlank(userLoginDO.getPassword())) { + return ResponseResult.fail(ErrorCodeEnum.IMPROVE_USER_INFO); + } + String password = Md5Utils.md5(param.getPassword() + CommonConstants.USER_AUTH_KEY); + if (!password.equals(userLoginDO.getPassword())) { + String errorPasswordCountKey = MessageFormat.format(RedisConstant.ERROR_PASSWORD_COUNT_KEY, LocalDate.now(), param.getMobile()); + Long errorNum = redisUtilPool.incrby(errorPasswordCountKey, 1); + redisUtilPool.expire(errorPasswordCountKey, 24 * 60 * 60); + if(errorNum == 1){ + return ResponseResult.fail(ErrorCodeEnum.PASSWORD_ERROR); + } + return ResponseResult.fail(ErrorCodeEnum.PASSWORD_ERROR_MULTI, errorNum.toString()); + } + return ResponseResult.success(getUserLoginInfo(userLoginDO)); + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/utils/poi/constant/Constants.java b/coolstore-partner-service/src/main/java/com/cool/store/utils/poi/constant/Constants.java index f4262d9e7..b08d231e6 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/utils/poi/constant/Constants.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/utils/poi/constant/Constants.java @@ -220,6 +220,4 @@ public class Constants public static final String WANG_LEI_JOB_NUMBER = "19060164"; - - } diff --git a/coolstore-partner-web/pom.xml b/coolstore-partner-web/pom.xml index 22e75fcb9..fe6d27e01 100644 --- a/coolstore-partner-web/pom.xml +++ b/coolstore-partner-web/pom.xml @@ -35,6 +35,65 @@ + + + dev + + dev + + + + dev2 + + dev2 + + + + local + + true + + + local + + + + test + + test + + + + test3 + + test3 + + + + ab + + ab + + + + online + + online + + + + hd + + hd + + + + zcb + + zcb + + + diff --git a/coolstore-partner-web/src/main/java/com/cool/store/PartnerWebApplication.java b/coolstore-partner-web/src/main/java/com/cool/store/PartnerWebApplication.java index 9f1f66664..05d745b0d 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/PartnerWebApplication.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/PartnerWebApplication.java @@ -40,4 +40,16 @@ public class PartnerWebApplication { return defaultDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build(); } + @Bean + @ConfigurationProperties("platform.datasource") + public DataSourceProperties platformDataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + @ConfigurationProperties("spring.datasource.hikari") + public DataSource platformDataSource() { + return platformDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build(); + } + } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/aspect/DataSourceAspect.java b/coolstore-partner-web/src/main/java/com/cool/store/aspect/DataSourceAspect.java new file mode 100644 index 000000000..87e0f0a85 --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/aspect/DataSourceAspect.java @@ -0,0 +1,37 @@ +package com.cool.store.aspect; + +import com.cool.store.annotation.PlatformDB; +import com.cool.store.datasource.DataSourceContextHolder; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; + +/** + *

+ * 数据源切换 切面 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Aspect +@Component +public class DataSourceAspect { + + @Before("@annotation(platformDB)") + public void before(PlatformDB platformDB) { + DataSourceContextHolder.setDataSourceType("platform"); + } + + @After("@annotation(platformDB)") + public void after(PlatformDB platformDB) { + DataSourceContextHolder.clearDataSourceType(); + } + + @AfterThrowing("@annotation(platformDB)") + public void afterThrowing(PlatformDB platformDB) { + DataSourceContextHolder.clearDataSourceType(); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java b/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java index 5fb922201..7f0e14992 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/config/SignValidateFilter.java @@ -60,7 +60,8 @@ public class SignValidateFilter implements Filter { "/zxjp/**/api/audit/result", "/zxjp/**/api/license", "/zxjp/mini/line/getRegionPayPic", - "/zxjp/mini/miniProgram/getUserInfoByToken" + "/zxjp/mini/miniProgram/getUserInfoByToken", + "/zxjp/ws/**" ); diff --git a/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java b/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java index 2115f4f26..93d16ade2 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java @@ -52,7 +52,10 @@ public class TokenValidateFilter implements Filter { "/zxjp/pc/sysRole/**", "/zxjp/**/api/audit/result", "/zxjp/pc/video/**", - "/zxjp/**/api/license" + "/zxjp/**/api/license", + "/zxjp/pc/v3/login/accountLogin", + "/zxjp/pc/v3/login/refreshLogin", + "/zxjp/ws/**" ); diff --git a/coolstore-partner-web/src/main/java/com/cool/store/config/websocket/WebSocketConfig.java b/coolstore-partner-web/src/main/java/com/cool/store/config/websocket/WebSocketConfig.java new file mode 100644 index 000000000..79118b4b2 --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/config/websocket/WebSocketConfig.java @@ -0,0 +1,72 @@ +package com.cool.store.config.websocket; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +/** + *

+ * WebSocket配置类 + *

+ * + * @author wangff + * @since 2025/9/2 + */ +@Configuration +@EnableWebSocketMessageBroker +@Slf4j +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws/zxzs") + .setAllowedOrigins("*") + .withSockJS(); // 启用SockJS支持 + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + // 配置消息代理 + registry.enableSimpleBroker("/topic", "/queue") // 启用简单代理,用于广播和点对点消息 + .setHeartbeatValue(new long[]{0, 10000}) + .setTaskScheduler(webSocketTaskScheduler()); + registry.setApplicationDestinationPrefixes("/app"); // 设置应用程序端点前缀 +// registry.setUserDestinationPrefix("/user"); + } + + @Bean + public TaskScheduler webSocketTaskScheduler() { + ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setPoolSize(1); + taskScheduler.setThreadNamePrefix("websocket-heartbeat-"); + taskScheduler.initialize(); + return taskScheduler; + } + +// @Override +// public void configureClientInboundChannel(ChannelRegistration registration) { +// registration.interceptors(new ChannelInterceptor() { +// @Override +// public Message preSend(Message message, MessageChannel channel) { +// StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message); +// +// if (StompCommand.CONNECT.equals(accessor.getCommand())) { +// // 从STOMP头部获取login字段作为用户标识 +// String login = accessor.getLogin(); +// log.info("用户login:{}", login); +// if (login != null && !login.isEmpty()) { +// // 设置用户身份 +// accessor.setUser(() -> login); +// } +// } +// return message; +// } +// }); +// } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java new file mode 100644 index 000000000..9eb1b27c7 --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java @@ -0,0 +1,47 @@ +package com.cool.store.controller.webb; + +import com.cool.store.dto.login.UserLoginDTO; +import com.cool.store.dto.login.UserRefreshLoginDTO; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.login.LoginBaseService; +import com.cool.store.service.login.LoginStrategy; +import com.cool.store.utils.SpringContextUtil; +import com.cool.store.vo.login.UserLoginVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + *

+ * 登录 前端控制器 + *

+ * + * @author wangff + * @since 2025/9/4 + */ +@Api(tags = "登录") +@RestController +@RequestMapping("/pc/v3/login") +@RequiredArgsConstructor +public class LoginController { + private final LoginBaseService loginBaseService; + + @ApiOperation("账号密码登录") + @PostMapping("/accountLogin") + public ResponseResult accountLogin(@RequestBody UserLoginDTO param) { + return SpringContextUtil.getBean(param.getLoginType().getClazzName(), LoginStrategy.class).login(param); + } + + @ApiOperation("refresh登录") + @PostMapping("/refreshLogin") + public ResponseResult refreshLogin(@RequestBody UserRefreshLoginDTO param) { + return loginBaseService.refreshLogin(param); + } + + @ApiOperation("登出") + @PostMapping("/logout") + public ResponseResult logout() { + return loginBaseService.logout(); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java new file mode 100644 index 000000000..c821855df --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java @@ -0,0 +1,34 @@ +package com.cool.store.controller.webb; + +import com.cool.store.common.PageBasicInfo; +import com.cool.store.context.CurrentUserHolder; +import com.cool.store.response.MiniShopsResponse; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.StoreService; +import com.github.pagehelper.PageInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + *

+ * PC门店 前端控制器 + *

+ * + * @author wangff + * @since 2025/9/9 + */ +@Api(tags = "PC门店") +@RestController +@RequestMapping("/pc/stores") +@RequiredArgsConstructor +public class PCStoreController { + private final StoreService storeService; + + @ApiOperation("当前用户门店列表") + @PostMapping("/userStoreList") + public ResponseResult> getCurrentUserStoreList(@RequestBody PageBasicInfo request) { + return ResponseResult.success(storeService.getStoreListByMobile(CurrentUserHolder.getUser().getMobile(), request.getPageNum(), request.getPageSize(), null, null)); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniShopAccountController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniShopAccountController.java index 0a8f5341a..e7982e7fa 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniShopAccountController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniShopAccountController.java @@ -8,7 +8,6 @@ import com.cool.store.dto.ShopAccount.ShopAccountDTO; import com.cool.store.request.GetPasswordDTO; import com.cool.store.response.ResponseResult; import com.cool.store.service.*; -import com.cool.store.vo.PartnerUserInfoVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.validation.annotation.Validated; @@ -95,7 +94,7 @@ public class MiniShopAccountController { @ApiOperation("获取标品登录token") @GetMapping("/getAccessToken") public ResponseResult getAccessToken() { - return ResponseResult.success(enterpriseService.getAccessToken(PartnerUserHolder.getUser().getMobile())); + return ResponseResult.success(enterpriseService.getLoginInfo(PartnerUserHolder.getUser().getMobile()).getAccessToken()); } } diff --git a/coolstore-partner-web/src/main/resources/application-ab.properties b/coolstore-partner-web/src/main/resources/application-ab.properties index 76aff14c4..242f7308a 100644 --- a/coolstore-partner-web/src/main/resources/application-ab.properties +++ b/coolstore-partner-web/src/main/resources/application-ab.properties @@ -4,6 +4,10 @@ default.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3 default.datasource.username=coolstore default.datasource.password=CSCErYcXniNYm7bT +platform.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_config?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true +platform.datasource.username=coolstore +platform.datasource.password=CSCErYcXniNYm7bT + #redis redis.host.uri=http://userInfo:Cx111111@tstore-coolcollege.redis.rds.aliyuncs.com:6379/0 diff --git a/coolstore-partner-web/src/main/resources/application-hd.properties b/coolstore-partner-web/src/main/resources/application-hd.properties index c06c32835..335d6cf18 100644 --- a/coolstore-partner-web/src/main/resources/application-hd.properties +++ b/coolstore-partner-web/src/main/resources/application-hd.properties @@ -1,9 +1,13 @@ #mysql config -default.datasource.url=jdbc:mysql://store10-coolcollege.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_10027?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true +default.datasource.url=jdbc:mysql://zx-coolstore.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_10027?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true default.datasource.username=coolstore default.datasource.password=CSCErYcXniNYm7bT +platform.datasource.url=jdbc:mysql://zx-coolstore.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_config?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true +platform.datasource.username=coolstore +platform.datasource.password=CSCErYcXniNYm7bT + #redis redis.host.uri=http://userInfo:Cx111111@store-coolcollege.redis.rds.aliyuncs.com:6379/0 diff --git a/coolstore-partner-web/src/main/resources/application-local.properties b/coolstore-partner-web/src/main/resources/application-local.properties index 78aa1eacb..087420e81 100644 --- a/coolstore-partner-web/src/main/resources/application-local.properties +++ b/coolstore-partner-web/src/main/resources/application-local.properties @@ -4,6 +4,10 @@ default.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3 default.datasource.username=coolstore default.datasource.password=CSCErYcXniNYm7bT +platform.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_config?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true +platform.datasource.username=coolstore +platform.datasource.password=CSCErYcXniNYm7bT + #redis redis.host.uri=http://userInfo:Cx111111@tstore-coolcollege-open.redis.rds.aliyuncs.com:6379/0 @@ -133,3 +137,8 @@ special.user.id=wpayJeDAAAhGIFgUJpJN-zg39JuNbYhg_woayJeDAAA0TC8mkCJeXouw94hYA-D3 ask.bot.url=https://test.auth.wx.askbot.cn +hqt.token.url=https://tc.cloud.hecom.cn +hqt.token.username=18161486722 +hqt.token.grant_type=client_credentials +hqt.token.client.id=WrPffdGpcWkcPsbN +hqt.token.client.secret=rYe9Cwug5LwQNIBJAiW0a7weF9CAhYCD \ No newline at end of file diff --git a/coolstore-partner-web/src/main/resources/application-online.properties b/coolstore-partner-web/src/main/resources/application-online.properties index af4c35790..b9c73dda2 100644 --- a/coolstore-partner-web/src/main/resources/application-online.properties +++ b/coolstore-partner-web/src/main/resources/application-online.properties @@ -3,6 +3,10 @@ default.datasource.url=jdbc:mysql://zx-coolstore.mysql.rds.aliyuncs.com:3306/coo default.datasource.username=coolstore default.datasource.password=CSCErYcXniNYm7bT +platform.datasource.url=jdbc:mysql://zx-coolstore.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_config?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true +platform.datasource.username=coolstore +platform.datasource.password=CSCErYcXniNYm7bT + #redis redis.host.uri=http://userInfo:Cx111111@store-coolcollege.redis.rds.aliyuncs.com:6379/0 diff --git a/coolstore-partner-web/src/main/resources/application-test.properties b/coolstore-partner-web/src/main/resources/application-test.properties index cb59a966b..eea16e79c 100644 --- a/coolstore-partner-web/src/main/resources/application-test.properties +++ b/coolstore-partner-web/src/main/resources/application-test.properties @@ -4,6 +4,10 @@ default.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3 default.datasource.username=coolstore default.datasource.password=CSCErYcXniNYm7bT +platform.datasource.url=jdbc:mysql://dingpushcoolcollege.mysql.rds.aliyuncs.com:3306/coolcollege_intelligent_config?useSSL=false&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true +platform.datasource.username=coolstore +platform.datasource.password=CSCErYcXniNYm7bT + #redis redis.host.uri=http://userInfo:Cx111111@tstore-coolcollege-open.redis.rds.aliyuncs.com:6379/0