diff --git a/mcwl-admin/pom.xml b/mcwl-admin/pom.xml index 85736cc..ee4a6bb 100644 --- a/mcwl-admin/pom.xml +++ b/mcwl-admin/pom.xml @@ -37,7 +37,7 @@ 1.6.2 - + mysql mysql-connector-java @@ -68,6 +68,13 @@ mcwl-generator + + + org.springframework.boot + spring-boot-starter-amqp + 3.1.2 + + @@ -95,9 +102,9 @@ false ${project.artifactId} - + ${project.artifactId} - \ No newline at end of file + diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/rabbitmq/config/CodeMQConfig.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/rabbitmq/config/CodeMQConfig.java new file mode 100644 index 0000000..1c6ac0e --- /dev/null +++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/rabbitmq/config/CodeMQConfig.java @@ -0,0 +1,23 @@ +package com.mcwl.web.controller.rabbitmq.config; + +import com.mcwl.common.constant.QueueConstants; +import org.springframework.amqp.core.Queue; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 初始化发送短信服雾队列 + * + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +@Configuration +public class CodeMQConfig { + + @Bean + public Queue queue() { + return new Queue(QueueConstants.CODE_QUEUE, true); + } +} diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/rabbitmq/consumer/CodeConsumer.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/rabbitmq/consumer/CodeConsumer.java new file mode 100644 index 0000000..4710bb5 --- /dev/null +++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/rabbitmq/consumer/CodeConsumer.java @@ -0,0 +1,24 @@ +package com.mcwl.web.controller.rabbitmq.consumer; + +import com.mcwl.common.constant.QueueConstants; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + +/** + * 手机号登录短信验证码消费者 + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +@Slf4j +@Component +public class CodeConsumer { + + @RabbitListener(queues = QueueConstants.CODE_QUEUE) + public void code(String msg) { + + log.info("消费者获取到的数据:{}", msg); + } +} diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/system/SysLoginController.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/system/SysLoginController.java index 0ea8c26..6300ff2 100644 --- a/mcwl-admin/src/main/java/com/mcwl/web/controller/system/SysLoginController.java +++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/system/SysLoginController.java @@ -2,6 +2,7 @@ package com.mcwl.web.controller.system; import com.mcwl.common.annotation.Anonymous; import com.mcwl.common.constant.Constants; +import com.mcwl.common.constant.QueueConstants; import com.mcwl.common.constant.RedisConstants; import com.mcwl.common.core.domain.AjaxResult; import com.mcwl.common.core.domain.entity.SysMenu; @@ -12,12 +13,13 @@ import com.mcwl.common.core.domain.model.PhoneLoginBody; import com.mcwl.common.core.redis.RedisCache; import com.mcwl.common.utils.CodeUtils; import com.mcwl.common.utils.SecurityUtils; -import com.mcwl.common.utils.uuid.TelSmsUtils; +import com.mcwl.common.utils.StringUtils; import com.mcwl.framework.web.service.SysLoginService; import com.mcwl.framework.web.service.SysPermissionService; import com.mcwl.framework.web.service.TokenService; import com.mcwl.system.service.ISysMenuService; import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -51,11 +53,24 @@ public class SysLoginController @Autowired private RedisCache redisCache; + @Autowired + private RabbitTemplate rabbitTemplate; + @Anonymous @GetMapping("/getCode") public AjaxResult code(@RequestParam String phone){ + if (StringUtils.isEmpty(phone)){ + return AjaxResult.error("请输入手机号"); + } + + //校验验证码是否存在 + if (redisCache.hasKey(RedisConstants.CODE_PHONE+phone)){ + + return AjaxResult.error("请勿重复发送"); + } + //生成验证码 String s = CodeUtils.generateCaptcha(); @@ -67,7 +82,9 @@ public class SysLoginController // 构建 sendDataMap Map sendDataMap = new HashMap<>(); sendDataMap.put("code:", s); - TelSmsUtils.sendSms(phone,"SMS_460535072",sendDataMap); +// TelSmsUtils.sendSms(phone,"SMS_460535072",sendDataMap); + + rabbitTemplate.convertAndSend(QueueConstants.CODE_QUEUE,s); return AjaxResult.success(); diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/system/WXController.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/system/WXController.java new file mode 100644 index 0000000..8c87da4 --- /dev/null +++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/system/WXController.java @@ -0,0 +1,117 @@ +package com.mcwl.web.controller.system; + +import com.mcwl.common.annotation.Anonymous; +import com.mcwl.common.constant.CacheConstants; +import com.mcwl.common.core.domain.AjaxResult; +import com.mcwl.common.core.domain.entity.SysUser; +import com.mcwl.common.core.domain.model.LoginUser; +import com.mcwl.common.core.redis.RedisCache; +import com.mcwl.common.utils.uuid.IdUtils; +import com.mcwl.framework.web.service.SysPermissionService; +import com.mcwl.framework.web.service.TokenService; +import com.mcwl.system.domain.SysUserThirdAccount; +import com.mcwl.system.service.ISysUserThirdAccountService; +import com.mcwl.system.service.IWXService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * 对接微信扫码登录 + * + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +@RestController +@RequestMapping("/wx") +public class WXController { + + @Autowired + private RedisCache redisCache; + + @Resource + private ISysUserThirdAccountService iSysUserThirdAccountService; + + @Resource + private IWXService iwxService; + + @Resource + private TokenService tokenService; + + @Resource + private SysPermissionService permissionService; + + + /** + * 扫码登录用uuid生成 + */ + @Anonymous + @GetMapping("/uuid/get") + public AjaxResult getUUID() throws IOException { + AjaxResult ajax = AjaxResult.success(); + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.WX_OPENID_KEY + uuid; + redisCache.setCacheObject(verifyKey, null, 1, TimeUnit.MINUTES); + ajax.put("uuid", uuid); + return ajax; + } + + /** + * uuid绑定openid + */ + @Anonymous + @GetMapping("/uuid/bind/openid") + public AjaxResult bindOpenid(@RequestParam("code") String code, @RequestParam("uuid") String uuid) throws IOException { + AjaxResult ajax = AjaxResult.success(); + SysUserThirdAccount user = iwxService.getOpenid(code); + String openid = user.getOpenid(); + String wxNickName = user.getOpenName(); + String verifyKey = CacheConstants.WX_OPENID_KEY + uuid; + long expire = redisCache.getExpire(verifyKey); + redisCache.setCacheObject(verifyKey, openid); + if (expire > 0) { + redisCache.expire(verifyKey, expire, TimeUnit.SECONDS); + } + ajax.put("openid", openid); + ajax.put("wxNickName", wxNickName); + return ajax; + } + + /** + * uuid登录 + */ + @Anonymous + @GetMapping("/uuid/login") + public AjaxResult loginByOpenId(@RequestParam("uuid") String uuid) throws IOException { + AjaxResult ajax = AjaxResult.success(); + String verifyKey = CacheConstants.WX_OPENID_KEY + uuid; + String openid = redisCache.getCacheObject(verifyKey); + ajax.put("status", 0); + System.out.println("openid:{}" + openid); + if (openid != null) { + SysUser user = iSysUserThirdAccountService.selectUserByOpenId(openid); + System.out.println("用户:{}" + user); + if (user == null) { + System.out.println("用户不存在"); + return AjaxResult.error("用户不存在"); + } + LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user)); + // 生成token + String token = tokenService.createToken(loginUser); + ajax.put("token", token); + ajax.put("status", 1); + redisCache.deleteObject(verifyKey); + } + + return ajax; + } + +} diff --git a/mcwl-admin/src/main/resources/application-druid.yml b/mcwl-admin/src/main/resources/application-druid.yml index 98ecb56..fccb2a3 100644 --- a/mcwl-admin/src/main/resources/application-druid.yml +++ b/mcwl-admin/src/main/resources/application-druid.yml @@ -1,5 +1,22 @@ # 数据源配置 spring: + #mq + rabbitmq: + host: 1.13.246.108 + port: 5672 + username: guest + password: guest + virtualHost: / + listener: + simple: + prefetch: 1 # 每次之能获取一条 + acknowledge-mode: manual # 设置消费端手动ack确认 + retry: + enabled: true # 是否支持重试 + # 生产者配置 + publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange) + publisher-returns: true #确认消息已发送到队列(Queue) + datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver @@ -59,6 +76,14 @@ spring: wall: config: multi-statement-allow: true + +# 公众号配置 +wechat: + # 应用ID + appid: wx82d4c3c96f0ffa5b + # 应用密钥 + secret: abbabcf1da711a3bbd95387ec83edcac + mybatis-plus: # Mapper XML文件位置 mapper-locations: classpath:mapper/**/*.xml @@ -76,4 +101,4 @@ mybatis-plus: logic-delete-value: '2' logic-not-delete-value: '0' # 数据库字段下划线命名规则 - table-underline: true \ No newline at end of file + table-underline: true diff --git a/mcwl-admin/src/main/resources/application.yml b/mcwl-admin/src/main/resources/application.yml index fcc5e86..4485d30 100644 --- a/mcwl-admin/src/main/resources/application.yml +++ b/mcwl-admin/src/main/resources/application.yml @@ -97,14 +97,48 @@ token: # 令牌有效期(默认30分钟) expireTime: 30 -# MyBatis配置 -mybatis: - # 搜索指定包别名 - typeAliasesPackage: com.mcwl.**.domain - # 配置mapper的扫描,找到所有的mapper.xml映射文件 +# MyBatis Plus配置 +mybatis-plus: + # 不支持多包, 如有需要可在注解配置 或 提升扫包等级 + # 例如 com.**.**.mapper + mapperPackage: com.mcwl.**.mapper + # 对应的 XML 文件位置 mapperLocations: classpath*:mapper/**/*Mapper.xml - # 加载全局的配置文件 - configLocation: classpath:mybatis/mybatis-config.xml + # 实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: com.mcwl.**.domain + # 启动时是否检查 MyBatis XML 文件的存在,默认不检查 + checkConfigLocation: false + configuration: + # 自动驼峰命名规则(camel case)映射 + mapUnderscoreToCamelCase: true + # MyBatis 自动映射策略 + # NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射 + autoMappingBehavior: PARTIAL + # MyBatis 自动映射时未知列或未知属性处理策 + # NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息 + autoMappingUnknownColumnBehavior: NONE + # 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl + # 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl + # 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl + logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl + global-config: + # 是否打印 Logo banner + banner: false + dbConfig: + # 主键类型 + # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID + idType: ASSIGN_ID + # 逻辑已删除值 + logicDeleteValue: 2 + # 逻辑未删除值 + logicNotDeleteValue: 0 + # 字段验证策略之 insert,在 insert 的时候的字段验证策略 + # IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL + insertStrategy: NOT_NULL + # 字段验证策略之 update,在 update 的时候的字段验证策略 + updateStrategy: NOT_NULL + # 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件 + where-strategy: NOT_NULL # PageHelper分页插件 pagehelper: diff --git a/mcwl-admin/src/main/resources/mybatis/mybatis-config.xml b/mcwl-admin/src/main/resources/mybatis/mybatis-config.xml deleted file mode 100644 index ac47c03..0000000 --- a/mcwl-admin/src/main/resources/mybatis/mybatis-config.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/mcwl-common/pom.xml b/mcwl-common/pom.xml index 7eaba4a..8efb183 100644 --- a/mcwl-common/pom.xml +++ b/mcwl-common/pom.xml @@ -293,6 +293,13 @@ 2.0.1 + + + com.baomidou + mybatis-plus-boot-starter + 3.5.0 + + diff --git a/mcwl-common/src/main/java/com/mcwl/common/constant/CacheConstants.java b/mcwl-common/src/main/java/com/mcwl/common/constant/CacheConstants.java index 7b6297c..aa05d09 100644 --- a/mcwl-common/src/main/java/com/mcwl/common/constant/CacheConstants.java +++ b/mcwl-common/src/main/java/com/mcwl/common/constant/CacheConstants.java @@ -2,7 +2,7 @@ package com.mcwl.common.constant; /** * 缓存的key 常量 - * + * * @author mcwl */ public class CacheConstants @@ -41,4 +41,11 @@ public class CacheConstants * 登录账户密码错误次数 redis key */ public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + + /** + * 微信openid redis key + */ + public static final String WX_OPENID_KEY = "wx_openid:"; + + public static final String WE_CHAT = "we_chat"; } diff --git a/mcwl-common/src/main/java/com/mcwl/common/constant/QueueConstants.java b/mcwl-common/src/main/java/com/mcwl/common/constant/QueueConstants.java new file mode 100644 index 0000000..f1449ed --- /dev/null +++ b/mcwl-common/src/main/java/com/mcwl/common/constant/QueueConstants.java @@ -0,0 +1,15 @@ +package com.mcwl.common.constant; + +/** + * rabbitmq队列常量 + * + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +public class QueueConstants { + + //发送手机号验证码短信的mq队列 + public static final String CODE_QUEUE = "codeQueue"; +} diff --git a/mcwl-framework/src/main/java/com/mcwl/framework/config/MyBatisConfig.java b/mcwl-framework/src/main/java/com/mcwl/framework/config/MyBatisConfig.java index dd66524..cf36daa 100644 --- a/mcwl-framework/src/main/java/com/mcwl/framework/config/MyBatisConfig.java +++ b/mcwl-framework/src/main/java/com/mcwl/framework/config/MyBatisConfig.java @@ -1,132 +1,153 @@ -package com.mcwl.framework.config; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import javax.sql.DataSource; -import org.apache.ibatis.io.VFS; -import org.apache.ibatis.session.SqlSessionFactory; -import org.mybatis.spring.SqlSessionFactoryBean; -import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.type.classreading.CachingMetadataReaderFactory; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.util.ClassUtils; -import com.mcwl.common.utils.StringUtils; - -/** - * Mybatis支持*匹配扫描包 - * - * @author mcwl - */ -@Configuration -public class MyBatisConfig -{ - @Autowired - private Environment env; - - static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; - - public static String setTypeAliasesPackage(String typeAliasesPackage) - { - ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); - MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); - List allResult = new ArrayList(); - try - { - for (String aliasesPackage : typeAliasesPackage.split(",")) - { - List result = new ArrayList(); - aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX - + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; - Resource[] resources = resolver.getResources(aliasesPackage); - if (resources != null && resources.length > 0) - { - MetadataReader metadataReader = null; - for (Resource resource : resources) - { - if (resource.isReadable()) - { - metadataReader = metadataReaderFactory.getMetadataReader(resource); - try - { - result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); - } - catch (ClassNotFoundException e) - { - e.printStackTrace(); - } - } - } - } - if (result.size() > 0) - { - HashSet hashResult = new HashSet(result); - allResult.addAll(hashResult); - } - } - if (allResult.size() > 0) - { - typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); - } - else - { - throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包"); - } - } - catch (IOException e) - { - e.printStackTrace(); - } - return typeAliasesPackage; - } - - public Resource[] resolveMapperLocations(String[] mapperLocations) - { - ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); - List resources = new ArrayList(); - if (mapperLocations != null) - { - for (String mapperLocation : mapperLocations) - { - try - { - Resource[] mappers = resourceResolver.getResources(mapperLocation); - resources.addAll(Arrays.asList(mappers)); - } - catch (IOException e) - { - // ignore - } - } - } - return resources.toArray(new Resource[resources.size()]); - } - - @Bean - public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception - { - String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); - String mapperLocations = env.getProperty("mybatis.mapperLocations"); - String configLocation = env.getProperty("mybatis.configLocation"); - typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); - VFS.addImplClass(SpringBootVFS.class); - - final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); - sessionFactory.setDataSource(dataSource); - sessionFactory.setTypeAliasesPackage(typeAliasesPackage); - sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); - sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); - return sessionFactory.getObject(); - } -} +//package com.mcwl.framework.config; +// +//import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS; +//import org.apache.ibatis.io.VFS; +//import org.apache.ibatis.session.SqlSessionFactory; +//import org.mybatis.spring.SqlSessionFactoryBean; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.core.env.Environment; +//import org.springframework.core.io.DefaultResourceLoader; +//import org.springframework.core.io.Resource; +//import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +//import org.springframework.core.io.support.ResourcePatternResolver; +//import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +//import org.springframework.core.type.classreading.MetadataReader; +//import org.springframework.core.type.classreading.MetadataReaderFactory; +//import org.springframework.util.ClassUtils; +//import org.springframework.util.StringUtils; +// +//import javax.sql.DataSource; +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.HashSet; +//import java.util.List; +// +///** +// * Mybatis支持*匹配扫描包 +// * +// * @author mcwl +// */ +//@Configuration +//public class MyBatisConfig +//{ +// @Autowired +// private Environment env; +// +// static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; +// +// public static String setTypeAliasesPackage(String typeAliasesPackage) +// { +// ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); +// MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); +// List allResult = new ArrayList(); +// try +// { +// for (String aliasesPackage : typeAliasesPackage.split(",")) +// { +// List result = new ArrayList(); +// aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +// + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; +// Resource[] resources = resolver.getResources(aliasesPackage); +// if (resources != null && resources.length > 0) +// { +// MetadataReader metadataReader = null; +// for (Resource resource : resources) +// { +// if (resource.isReadable()) +// { +// metadataReader = metadataReaderFactory.getMetadataReader(resource); +// try +// { +// result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); +// } +// catch (ClassNotFoundException e) +// { +// e.printStackTrace(); +// } +// } +// } +// } +// if (result.size() > 0) +// { +// HashSet hashResult = new HashSet(result); +// allResult.addAll(hashResult); +// } +// } +// if (allResult.size() > 0) +// { +// typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); +// } +// else +// { +// throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包"); +// } +// } +// catch (IOException e) +// { +// e.printStackTrace(); +// } +// return typeAliasesPackage; +// } +// +// public Resource[] resolveMapperLocations(String[] mapperLocations) +// { +// ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); +// List resources = new ArrayList(); +// if (mapperLocations != null) +// { +// for (String mapperLocation : mapperLocations) +// { +// try +// { +// Resource[] mappers = resourceResolver.getResources(mapperLocation); +// resources.addAll(Arrays.asList(mappers)); +// } +// catch (IOException e) +// { +// // ignore +// } +// } +// } +// return resources.toArray(new Resource[resources.size()]); +// } +// +// @Bean +// public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception +// { +// String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); +// String mapperLocations = env.getProperty("mybatis.mapperLocations"); +// String configLocation = env.getProperty("mybatis.configLocation"); +// typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); +// VFS.addImplClass(SpringBootVFS.class); +// +// final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); +// sessionFactory.setDataSource(dataSource); +// sessionFactory.setTypeAliasesPackage(typeAliasesPackage); +// sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); +// sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); +// return sessionFactory.getObject(); +// } +// +//// @Bean +//// public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception +//// { +//// String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); +//// String mapperLocations = env.getProperty("mybatis.mapperLocations"); +//// String configLocation = env.getProperty("mybatis.configLocation"); +//// typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); +//// VFS.addImplClass(SpringBootVFS.class); +//// +//// //final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); +//// // SqlSessionFactoryBean 替换为 ⬇ MybatisSqlSessionFactoryBean +//// final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean(); +//// sessionFactory.setDataSource(dataSource); +//// sessionFactory.setTypeAliasesPackage(typeAliasesPackage); +//// sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); +//// sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); +//// return sessionFactory.getObject(); +//// } +// +//} diff --git a/mcwl-framework/src/main/java/com/mcwl/framework/config/MybatisPlusConfig.java b/mcwl-framework/src/main/java/com/mcwl/framework/config/MybatisPlusConfig.java new file mode 100644 index 0000000..3c7e5a9 --- /dev/null +++ b/mcwl-framework/src/main/java/com/mcwl/framework/config/MybatisPlusConfig.java @@ -0,0 +1,60 @@ +package com.mcwl.framework.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * MybatisPlus + * @author DaiZibo + * @date 2024/12/31 + * @apiNote + */ + + +@EnableTransactionManagement(proxyTargetClass = true) +@Configuration +public class MybatisPlusConfig { + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 分页插件 + interceptor.addInnerInterceptor(paginationInnerInterceptor()); + // 乐观锁插件 + interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor()); + // 阻断插件 + interceptor.addInnerInterceptor(blockAttackInnerInterceptor()); + return interceptor; + } + + /** + * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html + */ + public PaginationInnerInterceptor paginationInnerInterceptor() { + PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); + // 设置数据库类型为mysql + paginationInnerInterceptor.setDbType(DbType.MYSQL); + // 设置最大单页限制数量,默认 500 条,-1 不受限制 + paginationInnerInterceptor.setMaxLimit(-1L); + return paginationInnerInterceptor; + } + + /** + * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html + */ + public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() { + return new OptimisticLockerInnerInterceptor(); + } + + /** + * 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html + */ + public BlockAttackInnerInterceptor blockAttackInnerInterceptor() { + return new BlockAttackInnerInterceptor(); + } +} diff --git a/mcwl-framework/src/main/java/com/mcwl/framework/web/service/PermissionService.java b/mcwl-framework/src/main/java/com/mcwl/framework/web/service/PermissionService.java index edfdf0f..4790c4f 100644 --- a/mcwl-framework/src/main/java/com/mcwl/framework/web/service/PermissionService.java +++ b/mcwl-framework/src/main/java/com/mcwl/framework/web/service/PermissionService.java @@ -1,14 +1,15 @@ package com.mcwl.framework.web.service; -import java.util.Set; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; import com.mcwl.common.constant.Constants; import com.mcwl.common.core.domain.entity.SysRole; import com.mcwl.common.core.domain.model.LoginUser; import com.mcwl.common.utils.SecurityUtils; import com.mcwl.common.utils.StringUtils; import com.mcwl.framework.security.context.PermissionContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Set; /** * McWl首创 自定义权限实现,ss取自SpringSecurity首字母 diff --git a/mcwl-system/src/main/java/com/mcwl/system/domain/SysUserThirdAccount.java b/mcwl-system/src/main/java/com/mcwl/system/domain/SysUserThirdAccount.java new file mode 100644 index 0000000..68d4b53 --- /dev/null +++ b/mcwl-system/src/main/java/com/mcwl/system/domain/SysUserThirdAccount.java @@ -0,0 +1,106 @@ +package com.mcwl.system.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 第三方登录表 + * + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +@TableName("sys_user_third_account") +public class SysUserThirdAccount { + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 用户ID + */ + @TableField(value = "user_id") + private Long userId; + + /** + * 第三方唯一ID + */ + @TableField(value = "openid") + private String openid; + + /** + * 第三方昵称 + */ + @TableField(value = "open_name") + private String openName; + + /** + * 第三方头像 + */ + @TableField(value = "src") + private String src; + + /** + * 第三方(qq/微信) + */ + @TableField(value = "bind_type") + private String bindType; + + /** + * 标志是否绑定 + */ + @TableField(value = "bind_flag") + private String bindFlag; + + /** + * 绑定时间 + */ + @TableField(value = "bind_date") + private Date bindDate; + + /** + * 创建者 + */ + @TableField(value = "create_by") + private String createBy; + + /** + * 创建时间 + */ + @TableField(value = "create_time") + private Date createTime; + + /** + * 更新着 + */ + @TableField(value = "update_by") + private String updateBy; + + /** + * 更新时间 + */ + @TableField(value = "update_time") + private Date updateTime; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableField(value = "del_flag") + private Integer delFlag; +} diff --git a/mcwl-system/src/main/java/com/mcwl/system/mapper/SysUserThirdAccountMapper.java b/mcwl-system/src/main/java/com/mcwl/system/mapper/SysUserThirdAccountMapper.java new file mode 100644 index 0000000..8f33ec2 --- /dev/null +++ b/mcwl-system/src/main/java/com/mcwl/system/mapper/SysUserThirdAccountMapper.java @@ -0,0 +1,13 @@ +package com.mcwl.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mcwl.system.domain.SysUserThirdAccount; + +/** + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +public interface SysUserThirdAccountMapper extends BaseMapper { +} diff --git a/mcwl-system/src/main/java/com/mcwl/system/service/ISysUserThirdAccountService.java b/mcwl-system/src/main/java/com/mcwl/system/service/ISysUserThirdAccountService.java new file mode 100644 index 0000000..91230cc --- /dev/null +++ b/mcwl-system/src/main/java/com/mcwl/system/service/ISysUserThirdAccountService.java @@ -0,0 +1,15 @@ +package com.mcwl.system.service; + +import com.mcwl.common.core.domain.entity.SysUser; + +/** + * 第三方登录表 + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +public interface ISysUserThirdAccountService { + SysUser selectUserByOpenId(String openid); + +} diff --git a/mcwl-system/src/main/java/com/mcwl/system/service/IWXService.java b/mcwl-system/src/main/java/com/mcwl/system/service/IWXService.java new file mode 100644 index 0000000..a2a1a3b --- /dev/null +++ b/mcwl-system/src/main/java/com/mcwl/system/service/IWXService.java @@ -0,0 +1,14 @@ +package com.mcwl.system.service; + +import com.mcwl.system.domain.SysUserThirdAccount; + +/** + * 微信登录业务层 + * @author DaiZibo + * @date 2024/12/31 + * @apiNote + */ + +public interface IWXService { + SysUserThirdAccount getOpenid(String code); +} diff --git a/mcwl-system/src/main/java/com/mcwl/system/service/impl/IWXServiceImpl.java b/mcwl-system/src/main/java/com/mcwl/system/service/impl/IWXServiceImpl.java new file mode 100644 index 0000000..efc26f7 --- /dev/null +++ b/mcwl-system/src/main/java/com/mcwl/system/service/impl/IWXServiceImpl.java @@ -0,0 +1,67 @@ +package com.mcwl.system.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.mcwl.system.domain.SysUserThirdAccount; +import com.mcwl.system.service.IWXService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; + +/** + * 微信登录 业务处理层 + * + * @author DaiZibo + * @date 2024/12/31 + * @apiNote + */ + +@Service +public class IWXServiceImpl implements IWXService { + + @Value("${wechat.appid}") + private String appId; + + @Value("${wechat.secret}") + private String secret; + + @Override + public SysUserThirdAccount getOpenid(String code) { + + RestTemplate restTemplate = new RestTemplate(); + JSONObject jsonData = null; + + // 构建获取access_token的URL + String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + + "appid=" + appId + + "&secret=" + secret + + "&code=" + code + + "&grant_type=authorization_code"; + + System.out.println("url: " + url); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + + System.out.println("responseEntity: " + responseEntity); + if (responseEntity.getStatusCodeValue() == 200 && responseEntity.getBody() != null) { + jsonData = JSONObject.parseObject(responseEntity.getBody()); + } + + String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?lang=zh_CN" + + "&access_token=" + jsonData.getString("access_token") + + "&openid=" + jsonData.getString("openid"); + + ResponseEntity responseUserEntity = restTemplate.getForEntity(userInfoUrl, String.class); + if (responseUserEntity.getStatusCodeValue() == 200 && responseUserEntity.getBody() != null) { + JSONObject jsonUserData = JSONObject.parseObject(new String(responseUserEntity.getBody().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); + System.out.println("jsonUserData: " + jsonUserData); + SysUserThirdAccount sysUserThirdAccount = new SysUserThirdAccount(); + sysUserThirdAccount.setOpenid(jsonUserData.getString("openid")); + sysUserThirdAccount.setOpenName(jsonUserData.getString("nickname")); + return sysUserThirdAccount; + } + + return null; + } +} diff --git a/mcwl-system/src/main/java/com/mcwl/system/service/impl/SysUserThirdAccountServiceImpl.java b/mcwl-system/src/main/java/com/mcwl/system/service/impl/SysUserThirdAccountServiceImpl.java new file mode 100644 index 0000000..b9a46d2 --- /dev/null +++ b/mcwl-system/src/main/java/com/mcwl/system/service/impl/SysUserThirdAccountServiceImpl.java @@ -0,0 +1,50 @@ +package com.mcwl.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.mcwl.common.core.domain.entity.SysUser; +import com.mcwl.system.domain.SysUserThirdAccount; +import com.mcwl.system.mapper.SysUserThirdAccountMapper; +import com.mcwl.system.service.ISysUserService; +import com.mcwl.system.service.ISysUserThirdAccountService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 第三方登录表 业务层处理 + * @author DaiZibo + * @date 2024/12/30 + * @apiNote + */ + +@Service +public class SysUserThirdAccountServiceImpl implements ISysUserThirdAccountService { + + + @Resource + private ISysUserService sysUserService; + + @Resource + private SysUserThirdAccountMapper sysUserThirdAccountMapper; + + @Override + public SysUser selectUserByOpenId(String openid) { + + //根据openid查询第三方登录表数据 + LambdaQueryWrapper sysUserThirdAccountLambdaQueryWrapper = new LambdaQueryWrapper<>(); + sysUserThirdAccountLambdaQueryWrapper.eq(SysUserThirdAccount::getBindType,"WeChat"); + sysUserThirdAccountLambdaQueryWrapper.eq(SysUserThirdAccount::getOpenid,openid); + sysUserThirdAccountLambdaQueryWrapper.eq(SysUserThirdAccount::getDelFlag,0); + SysUserThirdAccount sysUserThirdAccount = sysUserThirdAccountMapper.selectOne(sysUserThirdAccountLambdaQueryWrapper); + + //未查询到返回空对象 + if (sysUserThirdAccount == null){ + + return new SysUser(); + } + + //根据信息查登录人信息 + return sysUserService.selectUserById(sysUserThirdAccount.getUserId()); + } + +} diff --git a/pom.xml b/pom.xml index bb609ff..b77ba50 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,13 @@ + + + com.baomidou + mybatis-plus-boot-starter + 3.5.0 + + org.springframework