From aedaa54341a4f720d997a3141ccb84baf55c0fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 27 Mar 2019 00:17:35 +0800 Subject: [PATCH 01/12] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82=20=E5=A4=9A=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pigx-common/pigx-common-bom/pom.xml | 12 ++ .../core/constant/SecurityConstants.java | 4 + .../resources/config/pigx-codegen-dev.yml | 2 +- .../resources/config/pigx-mp-manager-dev.yml | 31 ++++ .../service/impl/SysMenuServiceImpl.java | 2 +- .../com/pig4cloud/pigx/admin/BitMapTest.java | 86 ++++++++++ pigx-visual/pigx-mp-manager/Dockerfile | 15 ++ pigx-visual/pigx-mp-manager/pom.xml | 85 ++++++++++ .../pigx/mp/PigxMpManagerApplication.java | 40 +++++ .../pigx/mp/builder/AbstractBuilder.java | 21 +++ .../pigx/mp/builder/ImageBuilder.java | 24 +++ .../pigx/mp/builder/TextBuilder.java | 22 +++ .../pigx/mp/config/WxMpConfiguration.java | 149 ++++++++++++++++++ .../mp/config/WxMpInRedisConfigStorage.java | 120 ++++++++++++++ .../mp/controller/WxAccountController.java | 126 +++++++++++++++ .../controller/WxAccountFansController.java | 106 +++++++++++++ .../mp/controller/WxPortalController.java | 119 ++++++++++++++ .../mp/controller/WxRedirectController.java | 37 +++++ .../pig4cloud/pigx/mp/entity/WxAccount.java | 92 +++++++++++ .../pigx/mp/entity/WxAccountFans.java | 111 +++++++++++++ .../pigx/mp/handler/AbstractHandler.java | 9 ++ .../pigx/mp/handler/KfSessionHandler.java | 24 +++ .../pigx/mp/handler/LocationHandler.java | 34 ++++ .../pig4cloud/pigx/mp/handler/LogHandler.java | 26 +++ .../pigx/mp/handler/MenuHandler.java | 36 +++++ .../pig4cloud/pigx/mp/handler/MsgHandler.java | 49 ++++++ .../pigx/mp/handler/NullHandler.java | 24 +++ .../pigx/mp/handler/ScanHandler.java | 24 +++ .../mp/handler/StoreCheckNotifyHandler.java | 27 ++++ .../pigx/mp/handler/SubscribeHandler.java | 72 +++++++++ .../pigx/mp/handler/UnsubscribeHandler.java | 29 ++++ .../pigx/mp/mapper/WxAccountFansMapper.java | 30 ++++ .../pigx/mp/mapper/WxAccountMapper.java | 30 ++++ .../pigx/mp/service/WxAccountFansService.java | 30 ++++ .../pigx/mp/service/WxAccountService.java | 38 +++++ .../impl/WxAccountFansServiceImpl.java | 34 ++++ .../mp/service/impl/WxAccountServiceImpl.java | 69 ++++++++ .../src/main/resources/bootstrap.yml | 25 +++ .../resources/mapper/WxAccountFansMapper.xml | 45 ++++++ .../main/resources/mapper/WxAccountMapper.xml | 40 +++++ pigx-visual/pom.xml | 1 + 41 files changed, 1898 insertions(+), 2 deletions(-) create mode 100644 pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml create mode 100644 pigx-upms/pigx-upms-biz/src/test/java/com/pig4cloud/pigx/admin/BitMapTest.java create mode 100644 pigx-visual/pigx-mp-manager/Dockerfile create mode 100755 pigx-visual/pigx-mp-manager/pom.xml create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/PigxMpManagerApplication.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/AbstractBuilder.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/ImageBuilder.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/TextBuilder.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpConfiguration.java create mode 100644 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpInRedisConfigStorage.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxRedirectController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/AbstractHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/KfSessionHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LocationHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MenuHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MsgHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/NullHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/ScanHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/StoreCheckNotifyHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/UnsubscribeHandler.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountFansMapper.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountMapper.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java create mode 100644 pigx-visual/pigx-mp-manager/src/main/resources/bootstrap.yml create mode 100755 pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml create mode 100755 pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountMapper.xml diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index ba9003c6d..f1dae42c6 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -19,6 +19,7 @@ 2.6.0 3.1.0 8.0.13 + 3.3.0 @@ -92,6 +93,17 @@ mysql-connector-java ${mysql.connector.version} + + + com.github.binarywang + weixin-java-mp + ${mp.weixin.version} + + + com.github.binarywang + weixin-java-common + ${mp.weixin.version} + diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java index 75a18f63c..5225be97f 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java @@ -155,4 +155,8 @@ public interface SecurityConstants { */ String DETAILS_LICENSE = "license"; + /** + * AES 加密 + */ + String AES = "aes"; } diff --git a/pigx-config/src/main/resources/config/pigx-codegen-dev.yml b/pigx-config/src/main/resources/config/pigx-codegen-dev.yml index 47d1fcfce..6e3d9f3e1 100644 --- a/pigx-config/src/main/resources/config/pigx-codegen-dev.yml +++ b/pigx-config/src/main/resources/config/pigx-codegen-dev.yml @@ -12,6 +12,6 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root - url: jdbc:mysql://pigx-mysql:3306/pigxx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 + url: jdbc:mysql://pigx-mysql:3306/coffeewx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 resources: static-locations: classpath:/static/,classpath:/views/ diff --git a/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml b/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml new file mode 100644 index 000000000..d25267789 --- /dev/null +++ b/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml @@ -0,0 +1,31 @@ +## spring security 配置 +security: + oauth2: + client: + client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==) + client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==) + scope: server + ignore-urls: + - /actuator/** + - /v2/api-docs + - /*/portal + +# 数据源配置 +spring: + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: root + url: jdbc:mysql://pigx-mysql:3306/coffeewx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 + resources: + static-locations: classpath:/static/,classpath:/views/ + + +# 租户表维护 +pigx: + tenant: + column: tenant_id + tables: + - t_wx_account + - t_wx_account_fans \ No newline at end of file diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java index d0c86958d..fb4ec98c3 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java @@ -52,7 +52,7 @@ public class SysMenuServiceImpl extends ServiceImpl impl private final SysRoleMenuMapper sysRoleMenuMapper; @Override - @Cacheable(value = "menu_details#2000", key = "#roleId + '_menu'") + @Cacheable(value = "menu_details", key = "#roleId + '_menu'") public List findMenuByRoleId(Integer roleId) { return baseMapper.listMenusByRoleId(roleId); } diff --git a/pigx-upms/pigx-upms-biz/src/test/java/com/pig4cloud/pigx/admin/BitMapTest.java b/pigx-upms/pigx-upms-biz/src/test/java/com/pig4cloud/pigx/admin/BitMapTest.java new file mode 100644 index 000000000..f9344df9e --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/test/java/com/pig4cloud/pigx/admin/BitMapTest.java @@ -0,0 +1,86 @@ +package com.pig4cloud.pigx.admin; + +import java.util.BitSet; + +/** + * @author lengleng + * @date 2019-03-26 + */ +public class BitMapTest { + private int[] bigArray; + + public BitMapTest(long size) { + bigArray = new int[(int) (size / 32 + 1)]; + } + + public void set1(int num) { + //确定数组 index + int arrayIndex = num >> 5; + //确定bit index + int bitIndex = num & 31; + //设置0 + bigArray[arrayIndex] |= 1 << bitIndex; + + System.out.println(bigArray[arrayIndex]); + } + + public void set0(int num) { + //确定数组 index + int arrayIndex = num >> 5; + //确定bit index + int bitIndex = num & 31; + //设置0 + bigArray[arrayIndex] &= ~(1 << bitIndex); + System.out.println(get32BitBinString(bigArray[arrayIndex])); + } + + public boolean isExist(int num) { + //确定数组 index + int arrayIndex = num >> 5; + //确定bit index + int bitIndex = num & 31; + + //判断是否存在 + return (bigArray[arrayIndex] & ((1 << bitIndex))) != 0; + } + + /** + * 将整型数字转换为二进制字符串,一共32位,不舍弃前面的0 + * + * @param number 整型数字 + * @return 二进制字符串 + */ + private static String get32BitBinString(int number) { + StringBuilder sBuilder = new StringBuilder(); + for (int i = 0; i < 32; i++) { + sBuilder.append(number & 1); + number = number >>> 1; + } + return sBuilder.reverse().toString(); + } + + public static void main(String[] args) { + + int[] array = new int[]{1, 2, 3, 22, 0, 3, 63}; + BitSet bitSet = new BitSet(1); + System.out.println(bitSet.size()); //64 + bitSet = new BitSet(65); + System.out.println(bitSet.size()); //128 + bitSet = new BitSet(23); + System.out.println(bitSet.size()); //64 + + //将数组内容组bitmap + for (int i = 0; i < array.length; i++) { + bitSet.set(array[i], true); + } + + System.out.println(bitSet.get(22)); + System.out.println(bitSet.get(60)); + + System.out.println("下面开始遍历BitSet:"); + for (int i = 0; i < bitSet.size(); i++) { + System.out.println(bitSet.get(i)); + } + } + +} diff --git a/pigx-visual/pigx-mp-manager/Dockerfile b/pigx-visual/pigx-mp-manager/Dockerfile new file mode 100644 index 000000000..702a7171c --- /dev/null +++ b/pigx-visual/pigx-mp-manager/Dockerfile @@ -0,0 +1,15 @@ +FROM anapsix/alpine-java:8_server-jre_unlimited + +MAINTAINER wangiegie@gmail.com + +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime + +RUN mkdir -p /pigx-mp-manager + +WORKDIR /pigx-mp-manager + +EXPOSE 5003 + +ADD ./pigx-visual/pigx-mp-manager/target/pigx-mp-manager.jar ./ + +CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-mp-manager.jar diff --git a/pigx-visual/pigx-mp-manager/pom.xml b/pigx-visual/pigx-mp-manager/pom.xml new file mode 100755 index 000000000..cb9b513c3 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + + com.pig4cloud + pigx-visual + 2.6.0 + + + pigx-mp-manager + jar + + 微信公众号管理模块 + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + com.pig4cloud + pigx-common-data + + + + com.baomidou + mybatis-plus-boot-starter + + + mysql + mysql-connector-java + + + + com.pig4cloud + pigx-common-core + + + + com.pig4cloud + pigx-common-swagger + + + + com.pig4cloud + pigx-common-security + + + com.pig4cloud + pigx-common-log + + + + com.github.binarywang + weixin-java-mp + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-undertow + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + com.spotify + docker-maven-plugin + + + + diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/PigxMpManagerApplication.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/PigxMpManagerApplication.java new file mode 100755 index 000000000..ee64a45b6 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/PigxMpManagerApplication.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.mp; + +import com.pig4cloud.pigx.common.security.annotation.EnablePigxFeignClients; +import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer; +import com.pig4cloud.pigx.common.swagger.annotation.EnablePigxSwagger2; +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.client.SpringCloudApplication; + +/** + * @author lengleng + * @date 2019/03/25 + * 代码生成模块 + */ +@EnablePigxSwagger2 +@SpringCloudApplication +@EnablePigxFeignClients +@EnablePigxResourceServer +public class PigxMpManagerApplication { + + public static void main(String[] args) { + SpringApplication.run(PigxMpManagerApplication.class, args); + } +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/AbstractBuilder.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/AbstractBuilder.java new file mode 100755 index 000000000..7a94beb73 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/AbstractBuilder.java @@ -0,0 +1,21 @@ +package com.pig4cloud.pigx.mp.builder; + +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public abstract class AbstractBuilder { + /** + * 构建返回微信消息报文 + * + * @param content + * @param wxMessage + * @param service + * @return + */ + public abstract WxMpXmlOutMessage build(String content, + WxMpXmlMessage wxMessage, WxMpService service); +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/ImageBuilder.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/ImageBuilder.java new file mode 100755 index 000000000..07d8686f6 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/ImageBuilder.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.mp.builder; + +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public class ImageBuilder extends AbstractBuilder { + + @Override + public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage, + WxMpService service) { + + WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId(content) + .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) + .build(); + + return m; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/TextBuilder.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/TextBuilder.java new file mode 100755 index 000000000..a212ddc27 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/builder/TextBuilder.java @@ -0,0 +1,22 @@ +package com.pig4cloud.pigx.mp.builder; + +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public class TextBuilder extends AbstractBuilder { + + @Override + public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage, + WxMpService service) { + WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(content) + .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) + .build(); + return m; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpConfiguration.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpConfiguration.java new file mode 100755 index 000000000..6211b502a --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpConfiguration.java @@ -0,0 +1,149 @@ +package com.pig4cloud.pigx.mp.config; + +import com.google.common.collect.Maps; +import com.pig4cloud.pigx.mp.handler.*; +import com.pig4cloud.pigx.mp.service.WxAccountService; +import me.chanjar.weixin.mp.api.WxMpMessageRouter; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.constant.WxMpEventConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.stream.Collectors; + +import static me.chanjar.weixin.common.api.WxConsts.*; + +/** + * @author Binary Wang + * @author lengleng + *

+ * 微信公众号基础配置,初始化配置 + */ +@Configuration +public class WxMpConfiguration { + public static Map getRouters() { + return routers; + } + + public static Map getMpServices() { + return mpServices; + } + + private WxAccountService accountService; + private LogHandler logHandler; + private NullHandler nullHandler; + private KfSessionHandler kfSessionHandler; + private StoreCheckNotifyHandler storeCheckNotifyHandler; + private LocationHandler locationHandler; + private MenuHandler menuHandler; + private MsgHandler msgHandler; + private UnsubscribeHandler unsubscribeHandler; + private SubscribeHandler subscribeHandler; + private ScanHandler scanHandler; + private RedisTemplate redisTemplate; + + private static Map routers = Maps.newHashMap(); + private static Map mpServices = Maps.newHashMap(); + + @Autowired + public WxMpConfiguration(WxAccountService accountService, LogHandler logHandler, NullHandler nullHandler + , KfSessionHandler kfSessionHandler, StoreCheckNotifyHandler storeCheckNotifyHandler + , LocationHandler locationHandler, MenuHandler menuHandler + , MsgHandler msgHandler, UnsubscribeHandler unsubscribeHandler + , SubscribeHandler subscribeHandler, ScanHandler scanHandler + , RedisTemplate pigxRedisTemplate) { + this.accountService = accountService; + this.logHandler = logHandler; + this.nullHandler = nullHandler; + this.kfSessionHandler = kfSessionHandler; + this.storeCheckNotifyHandler = storeCheckNotifyHandler; + this.locationHandler = locationHandler; + this.menuHandler = menuHandler; + this.msgHandler = msgHandler; + this.unsubscribeHandler = unsubscribeHandler; + this.subscribeHandler = subscribeHandler; + this.scanHandler = scanHandler; + this.redisTemplate = pigxRedisTemplate; + } + + @PostConstruct + public void initServices() { + mpServices = accountService.list().stream().map(a -> { + WxMpInRedisConfigStorage configStorage = new WxMpInRedisConfigStorage(redisTemplate); + configStorage.setAppId(a.getAppid()); + configStorage.setSecret(a.getAppsecret()); + configStorage.setToken(a.getToken()); + configStorage.setAesKey(a.getAeskey()); + + WxMpService service = new WxMpServiceImpl(); + service.setWxMpConfigStorage(configStorage); + routers.put(a.getAppid(), this.newRouter(service)); + return service; + }).collect(Collectors.toMap(s -> s.getWxMpConfigStorage().getAppId(), a -> a)); + } + + private WxMpMessageRouter newRouter(WxMpService wxMpService) { + final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService); + + // 记录所有事件的日志 (异步执行) + newRouter.rule().handler(this.logHandler).next(); + + // 接收客服会话管理事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION) + .handler(this.kfSessionHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION) + .handler(this.kfSessionHandler) + .end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION) + .handler(this.kfSessionHandler).end(); + + // 门店审核事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.POI_CHECK_NOTIFY) + .handler(this.storeCheckNotifyHandler).end(); + + // 自定义菜单事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(MenuButtonType.CLICK).handler(this.menuHandler).end(); + + // 点击菜单连接事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(MenuButtonType.VIEW).handler(this.nullHandler).end(); + + // 关注事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.SUBSCRIBE).handler(this.subscribeHandler) + .end(); + + // 取消关注事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.UNSUBSCRIBE) + .handler(this.unsubscribeHandler).end(); + + // 上报地理位置事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.LOCATION).handler(this.locationHandler) + .end(); + + // 接收地理位置消息 + newRouter.rule().async(false).msgType(XmlMsgType.LOCATION) + .handler(this.locationHandler).end(); + + // 扫码事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.SCAN).handler(this.scanHandler).end(); + + // 默认 + newRouter.rule().async(false).handler(this.msgHandler).end(); + + return newRouter; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpInRedisConfigStorage.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpInRedisConfigStorage.java new file mode 100644 index 000000000..a045b6ca5 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpInRedisConfigStorage.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018-2025, 云集汇通 All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the yunjihuitong.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + */ + +package com.pig4cloud.pigx.mp.config; + +import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; +import me.chanjar.weixin.mp.enums.TicketType; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.concurrent.TimeUnit; + +/** + * @author lengleng + * @date 2019/03/26 + *

+ * 微信SDK redis扩展 + */ +public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage { + + private final static String ACCESS_TOKEN_KEY = "wechat:access_token_"; + + private final static String JSAPI_TICKET_KEY = "wechat:jsapi_ticket_"; + + private final static String CARDAPI_TICKET_KEY = "wechat:cardapi_ticket_"; + + private final RedisTemplate redisTemplate; + + private String accessTokenKey; + + private String jsapiTicketKey; + + private String cardapiTicketKey; + + public WxMpInRedisConfigStorage(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + /** + * 每个公众号生成独有的存储key + * + * @param appId + */ + @Override + public void setAppId(String appId) { + super.setAppId(appId); + this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); + this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(appId); + this.cardapiTicketKey = CARDAPI_TICKET_KEY.concat(appId); + } + + @Override + public String getAccessToken() { + return redisTemplate.opsForValue().get(this.accessTokenKey); + } + + @Override + public boolean isAccessTokenExpired() { + return redisTemplate.getExpire(accessTokenKey) < 2L; + } + + @Override + public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { + redisTemplate.opsForValue().set(accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + @Override + public void expireAccessToken() { + redisTemplate.expire(this.accessTokenKey, 0, TimeUnit.SECONDS); + } + + @Override + public String getJsapiTicket() { + return redisTemplate.opsForValue().get(this.jsapiTicketKey); + } + + + @Override + public String getCardApiTicket() { + return redisTemplate.opsForValue().get(cardapiTicketKey); + } + + + @Override + public String getTicket(TicketType type) { + return redisTemplate.opsForValue().get(getTicketRedisKey(type)); + } + + @Override + public boolean isTicketExpired(TicketType type) { + return redisTemplate.getExpire(this.getTicketRedisKey(type)) < 2; + } + + @Override + public synchronized void updateTicket(TicketType type, String jsapiTicket, int expiresInSeconds) { + redisTemplate.opsForValue().set(getTicketRedisKey(type), jsapiTicket, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + @Override + public void expireTicket(TicketType type) { + redisTemplate.expire(getTicketRedisKey(type), 0, TimeUnit.SECONDS); + } + + private String getTicketRedisKey(TicketType type) { + return String.format("wechat:ticket:key:%s:%s", this.appId, type.getCode()); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java new file mode 100755 index 000000000..322d0dc9b --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import com.pig4cloud.pigx.mp.entity.WxAccount; +import com.pig4cloud.pigx.mp.service.WxAccountService; +import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + + +/** + * 公众号账户 + * + * @author lengleng + * @date 2019-03-26 22:07:53 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/wxaccount") +public class WxAccountController { + private final WxMpConfiguration wxMpConfiguration; + private final WxAccountService wxAccountService; + + /** + * 分页查询 + * + * @param page 分页对象 + * @param wxAccount 公众号账户 + * @return + */ + @GetMapping("/page") + public R getWxAccountPage(Page page, WxAccount wxAccount) { + return new R<>(wxAccountService.page(page, Wrappers.query(wxAccount))); + } + + + /** + * 通过id查询公众号账户 + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Integer id) { + return new R<>(wxAccountService.getById(id)); + } + + /** + * 新增公众号账户 + * + * @param wxAccount 公众号账户 + * @return R + */ + @SysLog("新增公众号账户") + @PostMapping + @PreAuthorize("@pms.hasPermission('mp_wxaccount_add')") + public R save(@RequestBody WxAccount wxAccount) { + wxAccountService.save(wxAccount); + wxMpConfiguration.initServices(); + return new R<>(); + } + + /** + * 修改公众号账户 + * + * @param wxAccount 公众号账户 + * @return R + */ + @SysLog("修改公众号账户") + @PutMapping + @PreAuthorize("@pms.hasPermission('mp_wxaccount_edit')") + public R updateById(@RequestBody WxAccount wxAccount) { + wxAccountService.updateById(wxAccount); + wxMpConfiguration.initServices(); + return new R<>(); + } + + /** + * 通过id删除公众号账户 + * + * @param id id + * @return R + */ + @SysLog("删除公众号账户") + @DeleteMapping("/{id}") + @PreAuthorize("@pms.hasPermission('mp_wxaccount_del')") + public R removeById(@PathVariable Integer id) { + wxAccountService.removeById(id); + wxMpConfiguration.initServices(); + return new R<>(); + } + + /** + * 生成公众号二维码 + * + * @param appId + * @return + */ + @SysLog("生成公众号二维码") + @PostMapping("/qr/{appId}") + @PreAuthorize("@pms.hasPermission('mp_wxaccount_add')") + public R qr(@PathVariable String appId) { + return wxAccountService.generateQr(appId); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java new file mode 100755 index 000000000..550ca3d80 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.mp.entity.WxAccountFans; +import com.pig4cloud.pigx.mp.service.WxAccountFansService; +import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + + +/** + * 微信公众号粉丝管理 + * + * @author lengleng + * @date 2019-03-26 22:08:08 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/wxaccountfans") +public class WxAccountFansController { + + private final WxAccountFansService wxAccountFansService; + + /** + * 分页查询 + * + * @param page 分页对象 + * @param wxAccountFans 微信公众号粉丝 + * @return + */ + @GetMapping("/page") + public R getWxAccountFansPage(Page page, WxAccountFans wxAccountFans) { + return new R<>(wxAccountFansService.page(page, Wrappers.query(wxAccountFans))); + } + + + /** + * 通过id查询微信公众号粉丝 + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Integer id) { + return new R<>(wxAccountFansService.getById(id)); + } + + /** + * 新增微信公众号粉丝 + * + * @param wxAccountFans 微信公众号粉丝 + * @return R + */ + @SysLog("新增微信公众号粉丝") + @PostMapping + @PreAuthorize("@pms.hasPermission('mp_wxaccountfans_add')") + public R save(@RequestBody WxAccountFans wxAccountFans) { + return new R<>(wxAccountFansService.save(wxAccountFans)); + } + + /** + * 修改微信公众号粉丝 + * + * @param wxAccountFans 微信公众号粉丝 + * @return R + */ + @SysLog("修改微信公众号粉丝") + @PutMapping + @PreAuthorize("@pms.hasPermission('mp_wxaccountfans_edit')") + public R updateById(@RequestBody WxAccountFans wxAccountFans) { + return new R<>(wxAccountFansService.updateById(wxAccountFans)); + } + + /** + * 通过id删除微信公众号粉丝 + * + * @param id id + * @return R + */ + @SysLog("删除微信公众号粉丝") + @DeleteMapping("/{id}") + @PreAuthorize("@pms.hasPermission('mp_wxaccountfans_del')") + public R removeById(@PathVariable Integer id) { + return new R<>(wxAccountFansService.removeById(id)); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java new file mode 100755 index 000000000..a9afd103c --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java @@ -0,0 +1,119 @@ +package com.pig4cloud.pigx.mp.controller; + +import cn.hutool.core.util.StrUtil; +import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; + +/** + * @author Binary Wang + * @author lengleng + *

+ * 微信接入入口 + */ +@Slf4j +@RestController +@RequestMapping("/{appId}/portal") +public class WxPortalController { + + /** + * 微信接入校验处理 + * + * @param appId 多公众号标志位 + * @param signature 微信签名 + * @param timestamp 时间戳 + * @param nonce 随机数 + * @param echostr 随机字符串 + * @return + */ + @GetMapping(produces = "text/plain;charset=utf-8") + public String authGet(@PathVariable("appId") String appId, + @RequestParam(name = "signature", required = false) String signature, + @RequestParam(name = "timestamp", required = false) String timestamp, + @RequestParam(name = "nonce", required = false) String nonce, + @RequestParam(name = "echostr", required = false) String echostr) { + + log.info("接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature, timestamp, nonce, echostr); + + if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { + throw new IllegalArgumentException("请求参数非法,请核实!"); + } + + final WxMpService wxService = WxMpConfiguration.getMpServices().get(appId); + + if (wxService == null) { + throw new IllegalArgumentException(String.format("未找到对应appid=[%d]的配置,请核实!", appId)); + } + + if (wxService.checkSignature(timestamp, nonce, signature)) { + return echostr; + } + + return "非法请求"; + } + + /** + * 微信消息处理 + * + * @param appId 多公众号标志位 + * @param requestBody 请求报文体 + * @param signature 微信签名 + * @param encType 加签方式 + * @param msgSignature 微信签名 + * @param timestamp 时间戳 + * @param nonce 随机数 + * @return + */ + @PostMapping(produces = "application/xml; charset=UTF-8") + public String post(@PathVariable("appId") String appId, + @RequestBody String requestBody, + @RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestParam("openid") String openid, + @RequestParam(name = "encrypt_type", required = false) String encType, + @RequestParam(name = "msg_signature", required = false) String msgSignature) { + final WxMpService wxService = WxMpConfiguration.getMpServices().get(appId); + + log.info("接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}]," + + " timestamp=[{}], nonce=[{}], requestBody=[{}] ", + openid, signature, encType, msgSignature, timestamp, nonce, requestBody); + + if (!wxService.checkSignature(timestamp, nonce, signature)) { + throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); + } + + String out = null; + + // 明文模式 + if (StrUtil.isBlank(encType)) { + WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody); + WxMpXmlOutMessage outMessage = WxMpConfiguration.getRouters().get(appId).route(inMessage); + if (outMessage != null) { + out = outMessage.toXml(); + } + } + + // aes加密模式 + if (SecurityConstants.AES.equalsIgnoreCase(encType)) { + WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(), + timestamp, nonce, msgSignature); + + log.debug("消息解密后内容为:{} ", inMessage.toString()); + + WxMpXmlOutMessage outMessage = WxMpConfiguration.getRouters().get(appId).route(inMessage); + if (outMessage != null) { + out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage()); + } + } + + log.debug("组装回复信息:{}", out); + return out; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxRedirectController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxRedirectController.java new file mode 100755 index 000000000..e0c48c36b --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxRedirectController.java @@ -0,0 +1,37 @@ +package com.pig4cloud.pigx.mp.controller; + +import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @author Edward + */ +@Controller +@RequestMapping("/wx/redirect/{appid}") +public class WxRedirectController { + + + @RequestMapping("/greet") + public String greetUser(@PathVariable String appid, @RequestParam String code, ModelMap map) { + + WxMpService mpService = WxMpConfiguration.getMpServices().get(appid); + + try { + WxMpOAuth2AccessToken accessToken = mpService.oauth2getAccessToken(code); + WxMpUser user = mpService.oauth2getUserInfo(accessToken, null); + map.put("user", user); + } catch (WxErrorException e) { + e.printStackTrace(); + } + + return "greet_user"; + } +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java new file mode 100755 index 000000000..76623d276 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 公众号账户 + * + * @author lengleng + * @date 2019-03-26 22:07:53 + */ +@Data +@TableName("t_wx_account") +@EqualsAndHashCode(callSuper = true) +public class WxAccount extends Model { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId + private Integer id; + /** + * 公众号名称 + */ + private String name; + /** + * 公众号账户 + */ + private String account; + /** + * 公众号appid + */ + private String appid; + /** + * 公众号密钥 + */ + private String appsecret; + /** + * 公众号url + */ + private String url; + /** + * 公众号token + */ + private String token; + /** + * 加密密钥 + */ + private String aeskey; + /** + * 二维码图片URL + */ + private String qrUrl; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 是否删除 -1:已删除 0:正常 + */ + @TableLogic + private String delFlag; + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java new file mode 100755 index 000000000..a2ec8af50 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 微信公众号粉丝 + * + * @author lengleng + * @date 2019-03-26 22:08:08 + */ +@Data +@TableName("t_wx_account_fans") +@EqualsAndHashCode(callSuper = true) +public class WxAccountFans extends Model { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId + private Integer id; + /** + * 用户标识 + */ + private String openid; + /** + * 订阅状态,0未关注,1已关注 + */ + private String subscribeStatus; + /** + * 订阅时间 + */ + private LocalDateTime subscribeTime; + /** + * 昵称 + */ + private String nickname; + /** + * 性别,1男,2女,0未知 + */ + private String gender; + /** + * 语言 + */ + private String language; + /** + * 国家 + */ + private String country; + /** + * 省份 + */ + private String province; + /** + * 城市 + */ + private String city; + /** + * 头像地址 + */ + private String headimgUrl; + /** + * 备注 + */ + private String remark; + /** + * 微信公众号ID + */ + private String wxAccountId; + /** + * 微信公众号appid + */ + private String wxAccountAppid; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 更新时间 + */ + private LocalDateTime updateTime; + /** + * 是否删除 -1:已删除 0:正常 + */ + @TableLogic + private String delFlag; + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/AbstractHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/AbstractHandler.java new file mode 100755 index 000000000..c59c54c4e --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/AbstractHandler.java @@ -0,0 +1,9 @@ +package com.pig4cloud.pigx.mp.handler; + +import me.chanjar.weixin.mp.api.WxMpMessageHandler; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public abstract class AbstractHandler implements WxMpMessageHandler { +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/KfSessionHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/KfSessionHandler.java new file mode 100755 index 000000000..a6792b40c --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/KfSessionHandler.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.mp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class KfSessionHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService wxMpService, + WxSessionManager sessionManager) { + return null; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LocationHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LocationHandler.java new file mode 100755 index 000000000..76c442ce0 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LocationHandler.java @@ -0,0 +1,34 @@ +package com.pig4cloud.pigx.mp.handler; + +import com.pig4cloud.pigx.mp.builder.TextBuilder; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Slf4j +@Component +public class LocationHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService wxMpService, + WxSessionManager sessionManager) { + //上报地理位置事件 + log.info("上报地理位置,纬度 : {},经度 : {},精度 : {}", + wxMessage.getLatitude(), wxMessage.getLongitude(), wxMessage.getPrecision()); + + //TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用 + + String content = "感谢反馈,您的的地理位置已收到!"; + return new TextBuilder().build(content, wxMessage, null); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java new file mode 100755 index 000000000..0294e435c --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java @@ -0,0 +1,26 @@ +package com.pig4cloud.pigx.mp.handler; + +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Slf4j +@Component +public class LogHandler extends AbstractHandler { + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService wxMpService, + WxSessionManager sessionManager) { + log.info("接收到请求消息,内容:{}", wxMessage.getContent()); + return null; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MenuHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MenuHandler.java new file mode 100755 index 000000000..630c33535 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MenuHandler.java @@ -0,0 +1,36 @@ +package com.pig4cloud.pigx.mp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class MenuHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService weixinService, + WxSessionManager sessionManager) { + + String msg = String.format("type:%s, event:%s, key:%s", + wxMessage.getMsgType(), wxMessage.getEvent(), + wxMessage.getEventKey()); + if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) { + return null; + } + + return WxMpXmlOutMessage.TEXT().content(msg) + .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) + .build(); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MsgHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MsgHandler.java new file mode 100755 index 000000000..21feece52 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/MsgHandler.java @@ -0,0 +1,49 @@ +package com.pig4cloud.pigx.mp.handler; + +import com.pig4cloud.pigx.mp.builder.TextBuilder; +import lombok.SneakyThrows; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.Map; + +import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class MsgHandler extends AbstractHandler { + + @Override + @SneakyThrows + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService weixinService, + WxSessionManager sessionManager) { + + if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) { + //TODO 可以选择将消息保存到本地 + } + + //当用户输入关键词如“你好”,“客服”等,并且有客服在线时,把消息转发给在线客服 + if (StringUtils.startsWithAny(wxMessage.getContent(), "你好", "客服") + && weixinService.getKefuService().kfOnlineList() + .getKfOnlineList().size() > 0) { + return WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE() + .fromUser(wxMessage.getToUser()) + .toUser(wxMessage.getFromUser()).build(); + } + + + //TODO 组装回复消息 + String content = "收到信息内容:" + wxMessage.getContent(); + + return new TextBuilder().build(content, wxMessage, weixinService); + + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/NullHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/NullHandler.java new file mode 100755 index 000000000..5f961b871 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/NullHandler.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.mp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class NullHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService wxMpService, + WxSessionManager sessionManager) { + return null; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/ScanHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/ScanHandler.java new file mode 100755 index 000000000..0173764f6 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/ScanHandler.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.mp.handler; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class ScanHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map map, + WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException { + // 扫码事件处理 + return null; + } +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/StoreCheckNotifyHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/StoreCheckNotifyHandler.java new file mode 100755 index 000000000..1d75ea153 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/StoreCheckNotifyHandler.java @@ -0,0 +1,27 @@ +package com.pig4cloud.pigx.mp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 门店审核事件处理 + * + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class StoreCheckNotifyHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService wxMpService, + WxSessionManager sessionManager) { + // TODO 处理门店审核事件 + return null; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java new file mode 100755 index 000000000..a90c174d3 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java @@ -0,0 +1,72 @@ +package com.pig4cloud.pigx.mp.handler; + +import com.pig4cloud.pigx.mp.builder.TextBuilder; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Slf4j +@Component +public class SubscribeHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService weixinService, + WxSessionManager sessionManager) throws WxErrorException { + + log.info("新关注用户 OPENID: " + wxMessage.getFromUser()); + + // 获取微信用户基本信息 + try { + WxMpUser userWxInfo = weixinService.getUserService() + .userInfo(wxMessage.getFromUser(), null); + if (userWxInfo != null) { + // TODO 可以添加关注用户到本地数据库 + } + } catch (WxErrorException e) { + if (e.getError().getErrorCode() == 48001) { + log.info("该公众号没有获取用户信息权限!"); + } + } + + + WxMpXmlOutMessage responseResult = null; + try { + responseResult = this.handleSpecial(wxMessage); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + if (responseResult != null) { + return responseResult; + } + + try { + return new TextBuilder().build("感谢关注", wxMessage, weixinService); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + return null; + } + + /** + * 处理特殊请求,比如如果是扫码进来的,可以做相应处理 + */ + private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) + throws Exception { + //TODO + return null; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/UnsubscribeHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/UnsubscribeHandler.java new file mode 100755 index 000000000..7dde34f32 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/UnsubscribeHandler.java @@ -0,0 +1,29 @@ +package com.pig4cloud.pigx.mp.handler; + +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Slf4j +@Component +public class UnsubscribeHandler extends AbstractHandler { + + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, + Map context, WxMpService wxMpService, + WxSessionManager sessionManager) { + String openId = wxMessage.getFromUser(); + log.info("取消关注用户 OPENID: " + openId); + // TODO 可以更新本地数据库为取消关注状态 + return null; + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountFansMapper.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountFansMapper.java new file mode 100755 index 000000000..010329ea7 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountFansMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.pig4cloud.pigx.mp.entity.WxAccountFans; + +/** + * 微信公众号粉丝 + * + * @author lengleng + * @date 2019-03-26 22:08:08 + */ +public interface WxAccountFansMapper extends BaseMapper { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountMapper.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountMapper.java new file mode 100755 index 000000000..899c95124 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxAccountMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.pig4cloud.pigx.mp.entity.WxAccount; + +/** + * 公众号账户 + * + * @author lengleng + * @date 2019-03-26 22:07:53 + */ +public interface WxAccountMapper extends BaseMapper { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java new file mode 100755 index 000000000..e0c374795 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.mp.entity.WxAccountFans; + +/** + * 微信公众号粉丝 + * + * @author lengleng + * @date 2019-03-26 22:08:08 + */ +public interface WxAccountFansService extends IService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java new file mode 100755 index 000000000..926091d84 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.mp.entity.WxAccount; + +/** + * 公众号账户 + * + * @author lengleng + * @date 2019-03-26 22:07:53 + */ +public interface WxAccountService extends IService { + + /** + * 生成公众号二维码 + * + * @param appId + * @return + */ + R generateQr(String appId); +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java new file mode 100755 index 000000000..45b45fc99 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.mp.entity.WxAccountFans; +import com.pig4cloud.pigx.mp.mapper.WxAccountFansMapper; +import com.pig4cloud.pigx.mp.service.WxAccountFansService; +import org.springframework.stereotype.Service; + +/** + * 微信公众号粉丝 + * + * @author lengleng + * @date 2019-03-26 22:08:08 + */ +@Service +public class WxAccountFansServiceImpl extends ServiceImpl implements WxAccountFansService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java new file mode 100755 index 000000000..d5cbe95e3 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import com.pig4cloud.pigx.mp.entity.WxAccount; +import com.pig4cloud.pigx.mp.mapper.WxAccountMapper; +import com.pig4cloud.pigx.mp.service.WxAccountService; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import org.springframework.stereotype.Service; + +/** + * 公众号账户 + * + * @author lengleng + * @date 2019-03-26 22:07:53 + */ +@Slf4j +@Service +public class WxAccountServiceImpl extends ServiceImpl implements WxAccountService { + + /** + * 生成公众号二维码 + * + * @param appId + * @return + */ + + @Override + public R generateQr(String appId) { + WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId); + try { + WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateLastTicket(1); + String url = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket()); + + WxAccount wxAccount = baseMapper + .selectOne(Wrappers.query().lambda() + .eq(WxAccount::getAppid, appId)); + wxAccount.setQrUrl(url); + baseMapper.updateById(wxAccount); + } catch (WxErrorException e) { + log.error(" 获取公众号二维码失败", e); + return R.builder().code(CommonConstants.FAIL).msg("更新公众号二维码失败").build(); + } + + return R.builder().build(); + } +} diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/bootstrap.yml b/pigx-visual/pigx-mp-manager/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..672fc6f1f --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/resources/bootstrap.yml @@ -0,0 +1,25 @@ +server: + port: 6000 + +spring: + application: + name: @artifactId@ + #配置中心 + cloud: + config: + fail-fast: true + name: ${spring.application.name} + profile: ${spring.profiles.active} + discovery: + enabled: true + service-id: pigx-config + profiles: + active: dev + +# 注册中心配置 +eureka: + instance: + prefer-ip-address: true + client: + service-url: + defaultZone: http://pig:pig@pigx-eureka:8761/eureka/ diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml new file mode 100755 index 000000000..347559fab --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountMapper.xml new file mode 100755 index 000000000..a5aba8ec8 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pigx-visual/pom.xml b/pigx-visual/pom.xml index 9661d6c4d..d397cab3a 100644 --- a/pigx-visual/pom.xml +++ b/pigx-visual/pom.xml @@ -37,6 +37,7 @@ pigx-daemon-elastic-job pigx-daemon-quartz pigx-monitor + pigx-mp-manager pigx-sso-client-demo pigx-tx-manager pigx-zipkin From db78501eff2c72b0f734ab5ff62f7bc121e0a01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 27 Mar 2019 22:05:52 +0800 Subject: [PATCH 02/12] =?UTF-8?q?:bug:=20Fixing=20a=20bug.=20=E7=A7=9F?= =?UTF-8?q?=E6=88=B7=E4=B8=BA=E7=A9=BA=20mbp=20=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pigx/common/data/tenant/PigxTenantHandler.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java index 64eaf0dae..af49345f5 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/tenant/PigxTenantHandler.java @@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; +import net.sf.jsqlparser.expression.NullValue; import org.springframework.beans.factory.annotation.Autowired; /** @@ -43,6 +44,10 @@ public class PigxTenantHandler implements TenantHandler { public Expression getTenantId() { Integer tenantId = TenantContextHolder.getTenantId(); log.debug("当前租户为 >> {}", tenantId); + + if (tenantId == null) { + return new NullValue(); + } return new LongValue(tenantId); } @@ -64,6 +69,12 @@ public class PigxTenantHandler implements TenantHandler { */ @Override public boolean doTableFilter(String tableName) { + Integer tenantId = TenantContextHolder.getTenantId(); + // 租户中ID 为空,查询全部,不进行过滤 + if (tenantId == null) { + return Boolean.TRUE; + } + return !properties.getTables().contains(tableName); } } From f4fa687c783a59f607899ca76edae1ca18138aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 27 Mar 2019 22:06:20 +0800 Subject: [PATCH 03/12] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82=20=E5=85=AC=E4=BC=97=E5=8F=B7?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E3=80=81=E7=B2=89=E4=B8=9D=E3=80=81=E6=B6=88?= =?UTF-8?q?=E6=81=AF=20=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/config/pigx-mp-manager-dev.yml | 2 + .../pigx/mp/config/WxMpContextHolder.java | 55 ++++++++ .../mp/controller/WxAccountController.java | 10 ++ .../controller/WxAccountFansController.java | 11 ++ .../mp/controller/WxFansMsgController.java | 106 +++++++++++++++ .../mp/controller/WxFansMsgResController.java | 106 +++++++++++++++ .../pigx/mp/controller/WxMenuController.java | 106 +++++++++++++++ .../mp/controller/WxPortalController.java | 4 + .../pig4cloud/pigx/mp/entity/WxAccount.java | 4 + .../pigx/mp/entity/WxAccountFans.java | 5 + .../pig4cloud/pigx/mp/entity/WxFansMsg.java | 125 ++++++++++++++++++ .../pigx/mp/entity/WxFansMsgRes.java | 69 ++++++++++ .../com/pig4cloud/pigx/mp/entity/WxMenu.java | 93 +++++++++++++ .../pig4cloud/pigx/mp/handler/LogHandler.java | 42 +++++- .../pigx/mp/mapper/WxFansMsgMapper.java | 30 +++++ .../pigx/mp/mapper/WxFansMsgResMapper.java | 30 +++++ .../pigx/mp/mapper/WxMenuMapper.java | 30 +++++ .../pigx/mp/service/WxAccountFansService.java | 7 + .../pigx/mp/service/WxFansMsgResService.java | 30 +++++ .../pigx/mp/service/WxFansMsgService.java | 30 +++++ .../pigx/mp/service/WxMenuService.java | 30 +++++ .../impl/WxAccountFansServiceImpl.java | 109 ++++++++++++++- .../service/impl/WxFansMsgResServiceImpl.java | 34 +++++ .../mp/service/impl/WxFansMsgServiceImpl.java | 34 +++++ .../mp/service/impl/WxMenuServiceImpl.java | 34 +++++ .../resources/mapper/WxAccountFansMapper.xml | 1 + .../main/resources/mapper/WxFansMsgMapper.xml | 46 +++++++ .../resources/mapper/WxFansMsgResMapper.xml | 35 +++++ .../main/resources/mapper/WxMenuMapper.xml | 41 ++++++ 29 files changed, 1254 insertions(+), 5 deletions(-) create mode 100644 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpContextHolder.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsg.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgMapper.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgResMapper.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgService.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgResServiceImpl.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgServiceImpl.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java create mode 100755 pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgMapper.xml create mode 100755 pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgResMapper.xml create mode 100755 pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml diff --git a/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml b/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml index d25267789..49280daac 100644 --- a/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml +++ b/pigx-config/src/main/resources/config/pigx-mp-manager-dev.yml @@ -18,6 +18,8 @@ spring: username: root password: root url: jdbc:mysql://pigx-mysql:3306/coffeewx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 + hikari: + connection-init-sql: SET NAMES utf8mb4 resources: static-locations: classpath:/static/,classpath:/views/ diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpContextHolder.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpContextHolder.java new file mode 100644 index 000000000..9f73e4a01 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/config/WxMpContextHolder.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.mp.config; + +import com.alibaba.ttl.TransmittableThreadLocal; +import lombok.experimental.UtilityClass; + +/** + * @author lengleng + * @date 2019/03/27 + * 微信上下文工具类 + */ +@UtilityClass +public class WxMpContextHolder { + + private final ThreadLocal THREAD_LOCAL_APPID = new TransmittableThreadLocal<>(); + + + /** + * TTL 设置appId + * + * @param appId + */ + public void setAppId(String appId) { + THREAD_LOCAL_APPID.set(appId); + } + + /** + * 获取TTL中的appId + * + * @return + */ + public String getAppId() { + return THREAD_LOCAL_APPID.get(); + } + + public void clear() { + THREAD_LOCAL_APPID.remove(); + } +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java index 322d0dc9b..e7fb20a8a 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java @@ -123,4 +123,14 @@ public class WxAccountController { return wxAccountService.generateQr(appId); } + /** + * 获取公众号列表 + * + * @return + */ + @GetMapping("/list") + public R list() { + return new R<>(wxAccountService.list()); + } + } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java index 550ca3d80..5ec3ec169 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountFansController.java @@ -103,4 +103,15 @@ public class WxAccountFansController { return new R<>(wxAccountFansService.removeById(id)); } + /** + * 同步粉丝 + * + * @param appId + * @return + */ + @PostMapping("/sync/{appId}") + public R sync(@PathVariable String appId) { + return new R(wxAccountFansService.syncAccountFans(appId)); + } + } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java new file mode 100755 index 000000000..cb5081911 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.mp.entity.WxFansMsg; +import com.pig4cloud.pigx.mp.service.WxFansMsgService; +import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + + +/** + * 微信粉丝消息管理 + * + * @author lengleng + * @date 2019-03-27 20:45:27 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/wxfansmsg") +public class WxFansMsgController { + + private final WxFansMsgService wxFansMsgService; + + /** + * 分页查询 + * + * @param page 分页对象 + * @param wxFansMsg lengleng + * @return + */ + @GetMapping("/page") + public R getWxFansMsgPage(Page page, WxFansMsg wxFansMsg) { + return new R<>(wxFansMsgService.page(page, Wrappers.query(wxFansMsg))); + } + + + /** + * 通过id查询lengleng + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Integer id) { + return new R<>(wxFansMsgService.getById(id)); + } + + /** + * 新增lengleng + * + * @param wxFansMsg lengleng + * @return R + */ + @SysLog("新增lengleng") + @PostMapping + @PreAuthorize("@pms.hasPermission('mp_wxfansmsg_add')") + public R save(@RequestBody WxFansMsg wxFansMsg) { + return new R<>(wxFansMsgService.save(wxFansMsg)); + } + + /** + * 修改lengleng + * + * @param wxFansMsg lengleng + * @return R + */ + @SysLog("修改lengleng") + @PutMapping + @PreAuthorize("@pms.hasPermission('mp_wxfansmsg_edit')") + public R updateById(@RequestBody WxFansMsg wxFansMsg) { + return new R<>(wxFansMsgService.updateById(wxFansMsg)); + } + + /** + * 通过id删除lengleng + * + * @param id id + * @return R + */ + @SysLog("删除lengleng") + @DeleteMapping("/{id}") + @PreAuthorize("@pms.hasPermission('mp_wxfansmsg_del')") + public R removeById(@PathVariable Integer id) { + return new R<>(wxFansMsgService.removeById(id)); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java new file mode 100755 index 000000000..a7d3a14bb --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.mp.entity.WxFansMsgRes; +import com.pig4cloud.pigx.mp.service.WxFansMsgResService; +import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + + +/** + * 微信粉丝消息回复管理 + * + * @author lengleng + * @date 2019-03-27 20:45:48 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/wxfansmsgres") +public class WxFansMsgResController { + + private final WxFansMsgResService wxFansMsgResService; + + /** + * 分页查询 + * + * @param page 分页对象 + * @param wxFansMsgRes lengleng + * @return + */ + @GetMapping("/page") + public R getWxFansMsgResPage(Page page, WxFansMsgRes wxFansMsgRes) { + return new R<>(wxFansMsgResService.page(page, Wrappers.query(wxFansMsgRes))); + } + + + /** + * 通过id查询lengleng + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Integer id) { + return new R<>(wxFansMsgResService.getById(id)); + } + + /** + * 新增lengleng + * + * @param wxFansMsgRes lengleng + * @return R + */ + @SysLog("新增lengleng") + @PostMapping + @PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_add')") + public R save(@RequestBody WxFansMsgRes wxFansMsgRes) { + return new R<>(wxFansMsgResService.save(wxFansMsgRes)); + } + + /** + * 修改lengleng + * + * @param wxFansMsgRes lengleng + * @return R + */ + @SysLog("修改lengleng") + @PutMapping + @PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_edit')") + public R updateById(@RequestBody WxFansMsgRes wxFansMsgRes) { + return new R<>(wxFansMsgResService.updateById(wxFansMsgRes)); + } + + /** + * 通过id删除lengleng + * + * @param id id + * @return R + */ + @SysLog("删除lengleng") + @DeleteMapping("/{id}") + @PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_del')") + public R removeById(@PathVariable Integer id) { + return new R<>(wxFansMsgResService.removeById(id)); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java new file mode 100755 index 000000000..80f5abd02 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.mp.entity.WxMenu; +import com.pig4cloud.pigx.mp.service.WxMenuService; +import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + + +/** + * 微信菜单管理 + * + * @author lengleng + * @date 2019-03-27 20:45:18 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/wxmenu") +public class WxMenuController { + + private final WxMenuService wxMenuService; + + /** + * 分页查询 + * + * @param page 分页对象 + * @param wxMenu lengleng + * @return + */ + @GetMapping("/page") + public R getWxMenuPage(Page page, WxMenu wxMenu) { + return new R<>(wxMenuService.page(page, Wrappers.query(wxMenu))); + } + + + /** + * 通过id查询lengleng + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Integer id) { + return new R<>(wxMenuService.getById(id)); + } + + /** + * 新增lengleng + * + * @param wxMenu lengleng + * @return R + */ + @SysLog("新增lengleng") + @PostMapping + @PreAuthorize("@pms.hasPermission('mp_wxmenu_add')") + public R save(@RequestBody WxMenu wxMenu) { + return new R<>(wxMenuService.save(wxMenu)); + } + + /** + * 修改lengleng + * + * @param wxMenu lengleng + * @return R + */ + @SysLog("修改lengleng") + @PutMapping + @PreAuthorize("@pms.hasPermission('mp_wxmenu_edit')") + public R updateById(@RequestBody WxMenu wxMenu) { + return new R<>(wxMenuService.updateById(wxMenu)); + } + + /** + * 通过id删除lengleng + * + * @param id id + * @return R + */ + @SysLog("删除lengleng") + @DeleteMapping("/{id}") + @PreAuthorize("@pms.hasPermission('mp_wxmenu_del')") + public R removeById(@PathVariable Integer id) { + return new R<>(wxMenuService.removeById(id)); + } + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java index a9afd103c..583f530d5 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxPortalController.java @@ -3,6 +3,7 @@ package com.pig4cloud.pigx.mp.controller; import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import com.pig4cloud.pigx.mp.config.WxMpContextHolder; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; @@ -78,6 +79,8 @@ public class WxPortalController { @RequestParam("openid") String openid, @RequestParam(name = "encrypt_type", required = false) String encType, @RequestParam(name = "msg_signature", required = false) String msgSignature) { + + WxMpContextHolder.setAppId(appId); final WxMpService wxService = WxMpConfiguration.getMpServices().get(appId); log.info("接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}]," @@ -113,6 +116,7 @@ public class WxPortalController { } log.debug("组装回复信息:{}", out); + WxMpContextHolder.clear(); return out; } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java index 76623d276..76b94ca73 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java @@ -89,4 +89,8 @@ public class WxAccount extends Model { @TableLogic private String delFlag; + /** + * 租户 + */ + private Integer tenantId; } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java index a2ec8af50..a10a8f8f8 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java @@ -94,6 +94,11 @@ public class WxAccountFans extends Model { * 微信公众号appid */ private String wxAccountAppid; + + /** + * 微信公众号名 + */ + private String wxAccountName; /** * 创建时间 */ diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsg.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsg.java new file mode 100755 index 000000000..e892019c5 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsg.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 微信消息 + * + * @author lengleng + * @date 2019-03-27 20:45:27 + */ +@Data +@TableName("t_wx_fans_msg") +@EqualsAndHashCode(callSuper = true) +public class WxFansMsg extends Model { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId + private Integer id; + /** + * 用户标识 + */ + private String openid; + /** + * 昵称 + */ + private String nickname; + /** + * 头像地址 + */ + private String headimgUrl; + /** + * 微信账号ID + */ + private Integer wxAccountId; + + /** + * 微信公众号appid + */ + private String wxAccountAppid; + + /** + * 微信公众号名 + */ + private String wxAccountName; + + /** + * 消息ID + */ + private Long msgId; + + /** + * 消息类型 + */ + private String msgType; + /** + * 内容 + */ + private String content; + /** + * 最近一条回复内容 + */ + private String resContent; + /** + * 是否已回复 + */ + private String isRes; + /** + * 微信素材ID + */ + private String mediaId; + /** + * 微信图片URL + */ + private String picUrl; + /** + * 本地图片路径 + */ + private String picPath; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 是否删除 -1:已删除 0:正常 + */ + @TableLogic + private String delFlag; + + /** + * 租户 + */ + private Integer tenantId; + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java new file mode 100755 index 000000000..610b22119 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 微信粉丝消息回复表 + * + * @author lengleng + * @date 2019-03-27 20:45:48 + */ +@Data +@TableName("t_wx_fans_msg_res") +@EqualsAndHashCode(callSuper = true) +public class WxFansMsgRes extends Model { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId + private Integer id; + /** + * 粉丝消息ID + */ + private String fansMsgId; + /** + * 回复内容 + */ + private String resContent; + /** + * 用户ID + */ + private String userId; + /** + * 用户名 + */ + private String userName; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java new file mode 100755 index 000000000..165b90a2b --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 微信菜单表 + * + * @author lengleng + * @date 2019-03-27 20:45:18 + */ +@Data +@TableName("t_wx_menu") +@EqualsAndHashCode(callSuper = true) +public class WxMenu extends Model { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId + private Integer id; + /** + * 父ID + */ + private String parentId; + /** + * 菜单名称 + */ + private String menuName; + /** + * 菜单类型 1文本消息;2图文消息;3网址链接;4小程序 + */ + private String menuType; + /** + * 菜单等级 + */ + private String menuLevel; + /** + * 模板ID + */ + private String tplId; + /** + * 菜单URL + */ + private String menuUrl; + /** + * 排序 + */ + private String menuSort; + /** + * 微信账号ID + */ + private String wxAccountId; + /** + * 小程序appid + */ + private String miniprogramAppid; + /** + * 小程序页面路径 + */ + private String miniprogramPagepath; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java index 0294e435c..f5d65d103 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/LogHandler.java @@ -1,26 +1,62 @@ package com.pig4cloud.pigx.mp.handler; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.mp.entity.WxAccount; +import com.pig4cloud.pigx.mp.entity.WxFansMsg; +import com.pig4cloud.pigx.mp.service.WxAccountService; +import com.pig4cloud.pigx.mp.service.WxFansMsgService; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import me.chanjar.weixin.mp.bean.result.WxMpUser; import org.springframework.stereotype.Component; import java.util.Map; /** - * @author Binary Wang(https://github.com/binarywang) + * @author lengleng + *

+ * 保存微信消息 */ @Slf4j @Component +@AllArgsConstructor public class LogHandler extends AbstractHandler { + private final WxFansMsgService wxFansMsgService; + private final WxAccountService wxAccountService; + @Override + @SneakyThrows public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) { - log.info("接收到请求消息,内容:{}", wxMessage.getContent()); + log.debug("接收到请求消息,内容:{}", wxMessage.getContent()); + + WxAccount wxAccount = wxAccountService.getOne(Wrappers.lambdaQuery() + .eq(WxAccount::getAccount, wxMessage.getToUser())); + + + WxMpUser wxmpUser = wxMpService.getUserService() + .userInfo(wxMessage.getFromUser()); + + WxFansMsg wxFansMsg = new WxFansMsg(); + wxFansMsg.setOpenid(wxmpUser.getOpenId()); + wxFansMsg.setNickname(wxmpUser.getNickname()); + wxFansMsg.setHeadimgUrl(wxmpUser.getHeadImgUrl()); + wxFansMsg.setWxAccountId(wxAccount.getId()); + wxFansMsg.setWxAccountName(wxAccount.getName()); + wxFansMsg.setWxAccountAppid(wxAccount.getAppid()); + wxFansMsg.setMsgType(wxMessage.getMsgType()); + wxFansMsg.setMsgId(wxMessage.getMsgId()); + wxFansMsg.setContent(wxMessage.getContent()); + wxFansMsg.setTenantId(wxAccount.getTenantId()); + wxFansMsgService.save(wxFansMsg); + + log.debug("保存微信用户信息成功 {}", wxFansMsg); return null; } - } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgMapper.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgMapper.java new file mode 100755 index 000000000..2719ed380 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.pig4cloud.pigx.mp.entity.WxFansMsg; + +/** + * lengleng + * + * @author pigx code generator + * @date 2019-03-27 20:45:27 + */ +public interface WxFansMsgMapper extends BaseMapper { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgResMapper.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgResMapper.java new file mode 100755 index 000000000..c6f790868 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxFansMsgResMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.pig4cloud.pigx.mp.entity.WxFansMsgRes; + +/** + * lengleng + * + * @author pigx code generator + * @date 2019-03-27 20:45:48 + */ +public interface WxFansMsgResMapper extends BaseMapper { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java new file mode 100755 index 000000000..7b7756a56 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.pig4cloud.pigx.mp.entity.WxMenu; + +/** + * lengleng + * + * @author pigx code generator + * @date 2019-03-27 20:45:18 + */ +public interface WxMenuMapper extends BaseMapper { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java index e0c374795..5094ba7dd 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountFansService.java @@ -27,4 +27,11 @@ import com.pig4cloud.pigx.mp.entity.WxAccountFans; */ public interface WxAccountFansService extends IService { + /** + * 同步指定公众号粉丝 + * + * @param appId + * @return + */ + Boolean syncAccountFans(String appId); } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java new file mode 100755 index 000000000..2cbfc3eeb --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.mp.entity.WxFansMsgRes; + +/** + * 微信消息回复业务 + * + * @author lengleng + * @date 2019-03-27 20:45:48 + */ +public interface WxFansMsgResService extends IService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgService.java new file mode 100755 index 000000000..b3aa4b860 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgService.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.mp.entity.WxFansMsg; + +/** + * 微信消息业务 + * + * @author lengleng + * @date 2019-03-27 20:45:27 + */ +public interface WxFansMsgService extends IService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java new file mode 100755 index 000000000..4ae680302 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.mp.entity.WxMenu; + +/** + * 微信菜单业务 + * + * @author lengleng + * @date 2019-03-27 20:45:18 + */ +public interface WxMenuService extends IService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java index 45b45fc99..08f0c01f9 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java @@ -16,19 +16,124 @@ */ package com.pig4cloud.pigx.mp.service.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import com.pig4cloud.pigx.mp.entity.WxAccount; import com.pig4cloud.pigx.mp.entity.WxAccountFans; import com.pig4cloud.pigx.mp.mapper.WxAccountFansMapper; +import com.pig4cloud.pigx.mp.mapper.WxAccountMapper; import com.pig4cloud.pigx.mp.service.WxAccountFansService; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpUserService; +import me.chanjar.weixin.mp.bean.result.WxMpUserList; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; /** - * 微信公众号粉丝 - * * @author lengleng * @date 2019-03-26 22:08:08 + *

+ * 微信公众号粉丝 */ +@Slf4j @Service +@AllArgsConstructor public class WxAccountFansServiceImpl extends ServiceImpl implements WxAccountFansService { + private static final int SIZE = 100; + private final WxAccountMapper wxAccountMapper; + /** + * 获取公众号粉丝,生产建议异步 + * + * @param appId + * @return + */ + @Async + @Override + @SneakyThrows + @Transactional(rollbackFor = Exception.class) + public Boolean syncAccountFans(String appId) { + WxAccount wxAccount = wxAccountMapper + .selectOne(Wrappers.query().lambda() + .eq(WxAccount::getAppid, appId)); + + WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId); + WxMpUserService wxMpUserService = wxMpService.getUserService(); + fetchUser(null, wxAccount, wxMpUserService); + return Boolean.TRUE; + } + + /** + * 获取微信用户 + * + * @param nextOpenid + * @param wxAccount + * @param wxMpUserService + * @throws WxErrorException + */ + private void fetchUser(String nextOpenid, WxAccount wxAccount, WxMpUserService wxMpUserService) throws WxErrorException { + WxMpUserList wxMpUserList = wxMpUserService.userList(nextOpenid); + + // openId 分组 每组 100个 openid + CollUtil.split(wxMpUserList.getOpenids(), SIZE) + .stream().filter(CollUtil::isNotEmpty) + .forEach(openIdList -> { + log.info("开始批量获取用户信息 {}", openIdList); + List wxAccountFansList = new ArrayList<>(); + try { + wxMpUserService.userInfoList(openIdList).forEach(wxMpUser -> { + WxAccountFans wxAccountFans = baseMapper + .selectOne(Wrappers.query().lambda() + .eq(WxAccountFans::getOpenid, wxMpUser.getOpenId())); + // 为空初始化一个新的对象 + if (wxAccountFans == null) { + wxAccountFans = new WxAccountFans(); + } + + wxAccountFans.setOpenid(wxMpUser.getOpenId()); + wxAccountFans.setSubscribeStatus(wxMpUser.getSubscribe() ? "1" : "0"); + wxAccountFans.setSubscribeTime(LocalDateTime + .ofInstant(Instant.ofEpochMilli(wxMpUser.getSubscribeTime() * 1000L) + , ZoneId.systemDefault())); + wxAccountFans.setNickname(wxMpUser.getNickname()); + wxAccountFans.setGender(String.valueOf(wxMpUser.getSex())); + wxAccountFans.setLanguage(wxMpUser.getLanguage()); + wxAccountFans.setCountry(wxMpUser.getCountry()); + wxAccountFans.setProvince(wxMpUser.getProvince()); + wxAccountFans.setCity(wxMpUser.getCity()); + wxAccountFans.setHeadimgUrl(wxMpUser.getHeadImgUrl()); + wxAccountFans.setRemark(wxMpUser.getRemark()); + wxAccountFans.setWxAccountId(String.valueOf(wxAccount.getId())); + wxAccountFans.setWxAccountAppid(wxAccount.getAppid()); + wxAccountFans.setWxAccountName(wxAccount.getName()); + wxAccountFansList.add(wxAccountFans); + }); + this.saveOrUpdateBatch(wxAccountFansList); + log.info("批量插入用户信息完成 {}", openIdList); + } catch (WxErrorException e) { + log.error("批量同步粉丝失败", e); + } + }); + + // 如果nextOpenId 不为空,则继续获取 + if (StrUtil.isNotBlank(wxMpUserList.getNextOpenid())) { + fetchUser(wxMpUserList.getNextOpenid(), wxAccount, wxMpUserService); + } + + log.info("批量同步微信用户信息完成"); + } } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgResServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgResServiceImpl.java new file mode 100755 index 000000000..f66ee7538 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgResServiceImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.mp.entity.WxFansMsgRes; +import com.pig4cloud.pigx.mp.mapper.WxFansMsgResMapper; +import com.pig4cloud.pigx.mp.service.WxFansMsgResService; +import org.springframework.stereotype.Service; + +/** + * 微信消息回复业务 + * + * @author lengleng + * @date 2019-03-27 20:45:48 + */ +@Service +public class WxFansMsgResServiceImpl extends ServiceImpl implements WxFansMsgResService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgServiceImpl.java new file mode 100755 index 000000000..73c701f0d --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxFansMsgServiceImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.mp.entity.WxFansMsg; +import com.pig4cloud.pigx.mp.mapper.WxFansMsgMapper; +import com.pig4cloud.pigx.mp.service.WxFansMsgService; +import org.springframework.stereotype.Service; + +/** + * 微信消息业务 + * + * @author lengleng + * @date 2019-03-27 20:45:27 + */ +@Service +public class WxFansMsgServiceImpl extends ServiceImpl implements WxFansMsgService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java new file mode 100755 index 000000000..d7bfa7bcc --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.mp.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.mp.entity.WxMenu; +import com.pig4cloud.pigx.mp.mapper.WxMenuMapper; +import com.pig4cloud.pigx.mp.service.WxMenuService; +import org.springframework.stereotype.Service; + +/** + * 微信菜单业务 + * + * @author lengleng + * @date 2019-03-27 20:45:18 + */ +@Service +public class WxMenuServiceImpl extends ServiceImpl implements WxMenuService { + +} diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml index 347559fab..834219ace 100755 --- a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxAccountFansMapper.xml @@ -38,6 +38,7 @@ + diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgMapper.xml new file mode 100755 index 000000000..5bcded334 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgResMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgResMapper.xml new file mode 100755 index 000000000..4ebb02559 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxFansMsgResMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml new file mode 100755 index 000000000..432502833 --- /dev/null +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + From 98af4e3da9b8363c757c693cb6eabebd188ccab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sat, 30 Mar 2019 08:01:13 +0800 Subject: [PATCH 04/12] =?UTF-8?q?:fire:=20Removing=20code=20or=20files.=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4mybatis-plus=20=E7=83=AD=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/template/index.vue.vm | 22 +---- .../mp/controller/WxFansMsgController.java | 20 ++-- .../mp/controller/WxFansMsgResController.java | 22 ++--- .../pigx/mp/controller/WxMenuController.java | 60 +++++------- .../pigx/mp/entity/WxAccountFans.java | 2 +- .../pigx/mp/entity/WxFansMsgRes.java | 4 +- .../mp/entity/{WxMenu.java => WxMpMenu.java} | 53 ++++------ .../pigx/mp/mapper/WxMenuMapper.java | 4 +- .../pigx/mp/service/WxFansMsgResService.java | 8 ++ .../pigx/mp/service/WxMenuService.java | 30 +++++- .../impl/WxAccountFansServiceImpl.java | 2 +- .../service/impl/WxFansMsgResServiceImpl.java | 56 +++++++++++ .../mp/service/impl/WxMenuServiceImpl.java | 98 ++++++++++++++++++- .../main/resources/mapper/WxMenuMapper.xml | 15 --- 14 files changed, 262 insertions(+), 134 deletions(-) rename pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/{WxMenu.java => WxMpMenu.java} (72%) diff --git a/pigx-visual/pigx-codegen/src/main/resources/template/index.vue.vm b/pigx-visual/pigx-codegen/src/main/resources/template/index.vue.vm index 6fd88767a..c27431e56 100755 --- a/pigx-visual/pigx-codegen/src/main/resources/template/index.vue.vm +++ b/pigx-visual/pigx-codegen/src/main/resources/template/index.vue.vm @@ -62,10 +62,6 @@ tableOption: tableOption } }, - created() { - }, - mounted: function () { - }, computed: { ...mapGetters(['permissions']), permissionList() { @@ -98,11 +94,7 @@ return delObj(row.$pk.lowerAttrName) }).then(data => { _this.tableData.splice(index, 1) - _this.$message({ - showClose: true, - message: '删除成功', - type: 'success' - }) + _this.$message.success('删除成功') this.getList(this.page) }).catch(function (err) { }) @@ -117,11 +109,7 @@ handleUpdate: function (row, index, done) { putObj(row).then(data => { this.tableData.splice(index, 1, Object.assign({}, row)) - this.$message({ - showClose: true, - message: '修改成功', - type: 'success' - }) + _this.$message.success('修改成功') done() this.getList(this.page) }) @@ -135,11 +123,7 @@ handleSave: function (row, done) { addObj(row).then(data => { this.tableData.push(Object.assign({}, row)) - this.$message({ - showClose: true, - message: '添加成功', - type: 'success' - }) + _this.$message.success('添加成功') done() this.getList(this.page) }) diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java index cb5081911..d1200085c 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgController.java @@ -44,7 +44,7 @@ public class WxFansMsgController { * 分页查询 * * @param page 分页对象 - * @param wxFansMsg lengleng + * @param wxFansMsg 消息 * @return */ @GetMapping("/page") @@ -54,7 +54,7 @@ public class WxFansMsgController { /** - * 通过id查询lengleng + * 通过id查询消息 * * @param id id * @return R @@ -65,12 +65,12 @@ public class WxFansMsgController { } /** - * 新增lengleng + * 新增消息 * - * @param wxFansMsg lengleng + * @param wxFansMsg 消息 * @return R */ - @SysLog("新增lengleng") + @SysLog("新增消息") @PostMapping @PreAuthorize("@pms.hasPermission('mp_wxfansmsg_add')") public R save(@RequestBody WxFansMsg wxFansMsg) { @@ -78,12 +78,12 @@ public class WxFansMsgController { } /** - * 修改lengleng + * 修改消息 * - * @param wxFansMsg lengleng + * @param wxFansMsg 消息 * @return R */ - @SysLog("修改lengleng") + @SysLog("修改消息") @PutMapping @PreAuthorize("@pms.hasPermission('mp_wxfansmsg_edit')") public R updateById(@RequestBody WxFansMsg wxFansMsg) { @@ -91,12 +91,12 @@ public class WxFansMsgController { } /** - * 通过id删除lengleng + * 通过id删除消息 * * @param id id * @return R */ - @SysLog("删除lengleng") + @SysLog("删除消息") @DeleteMapping("/{id}") @PreAuthorize("@pms.hasPermission('mp_wxfansmsg_del')") public R removeById(@PathVariable Integer id) { diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java index a7d3a14bb..9213af46f 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxFansMsgResController.java @@ -44,7 +44,7 @@ public class WxFansMsgResController { * 分页查询 * * @param page 分页对象 - * @param wxFansMsgRes lengleng + * @param wxFansMsgRes 回复 * @return */ @GetMapping("/page") @@ -54,7 +54,7 @@ public class WxFansMsgResController { /** - * 通过id查询lengleng + * 通过id查询回复 * * @param id id * @return R @@ -65,25 +65,25 @@ public class WxFansMsgResController { } /** - * 新增lengleng + * 新增回复 * - * @param wxFansMsgRes lengleng + * @param wxFansMsgRes 回复 * @return R */ - @SysLog("新增lengleng") + @SysLog("新增回复") @PostMapping @PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_add')") public R save(@RequestBody WxFansMsgRes wxFansMsgRes) { - return new R<>(wxFansMsgResService.save(wxFansMsgRes)); + return wxFansMsgResService.saveAndSend(wxFansMsgRes); } /** - * 修改lengleng + * 修改回复 * - * @param wxFansMsgRes lengleng + * @param wxFansMsgRes 回复 * @return R */ - @SysLog("修改lengleng") + @SysLog("修改回复") @PutMapping @PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_edit')") public R updateById(@RequestBody WxFansMsgRes wxFansMsgRes) { @@ -91,12 +91,12 @@ public class WxFansMsgResController { } /** - * 通过id删除lengleng + * 通过id删除回复 * * @param id id * @return R */ - @SysLog("删除lengleng") + @SysLog("删除回复") @DeleteMapping("/{id}") @PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_del')") public R removeById(@PathVariable Integer id) { diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java index 80f5abd02..978264153 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxMenuController.java @@ -16,11 +16,12 @@ */ package com.pig4cloud.pigx.mp.controller; +import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; -import com.pig4cloud.pigx.mp.entity.WxMenu; +import com.pig4cloud.pigx.mp.entity.WxMpMenu; import com.pig4cloud.pigx.mp.service.WxMenuService; import lombok.AllArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; @@ -43,64 +44,51 @@ public class WxMenuController { /** * 分页查询 * - * @param page 分页对象 - * @param wxMenu lengleng + * @param page 分页对象 + * @param WxMpMenu lengleng * @return */ @GetMapping("/page") - public R getWxMenuPage(Page page, WxMenu wxMenu) { - return new R<>(wxMenuService.page(page, Wrappers.query(wxMenu))); + public R getWxMpMenuPage(Page page, WxMpMenu WxMpMenu) { + return new R<>(wxMenuService.page(page, Wrappers.query(WxMpMenu))); } /** - * 通过id查询lengleng + * 通过appid查询微信菜单 * - * @param id id + * @param appId 公众号 * @return R */ - @GetMapping("/{id}") - public R getById(@PathVariable("id") Integer id) { - return new R<>(wxMenuService.getById(id)); + @GetMapping("/{appId}") + public R getById(@PathVariable("appId") String appId) { + return wxMenuService.getByAppId(appId); } /** - * 新增lengleng + * 新增微信菜单 * - * @param wxMenu lengleng + * @param WxMpMenus 微信菜单列表 * @return R */ - @SysLog("新增lengleng") - @PostMapping + @SysLog("新增微信菜单") + @PostMapping("/{appId}") @PreAuthorize("@pms.hasPermission('mp_wxmenu_add')") - public R save(@RequestBody WxMenu wxMenu) { - return new R<>(wxMenuService.save(wxMenu)); + public R save(@RequestBody JSONObject WxMpMenus, @PathVariable String appId) { + return new R(wxMenuService.save(WxMpMenus, appId)); } /** - * 修改lengleng + * 发布微信菜单 * - * @param wxMenu lengleng + * @param appId 公众号 * @return R */ - @SysLog("修改lengleng") - @PutMapping - @PreAuthorize("@pms.hasPermission('mp_wxmenu_edit')") - public R updateById(@RequestBody WxMenu wxMenu) { - return new R<>(wxMenuService.updateById(wxMenu)); - } - - /** - * 通过id删除lengleng - * - * @param id id - * @return R - */ - @SysLog("删除lengleng") - @DeleteMapping("/{id}") - @PreAuthorize("@pms.hasPermission('mp_wxmenu_del')") - public R removeById(@PathVariable Integer id) { - return new R<>(wxMenuService.removeById(id)); + @SysLog("发布微信菜单") + @PutMapping("/{appId}") + @PreAuthorize("@pms.hasPermission('mp_wxmenu_push')") + public R updateById(@PathVariable String appId) { + return wxMenuService.push(appId); } } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java index a10a8f8f8..a6da434e1 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountFans.java @@ -89,7 +89,7 @@ public class WxAccountFans extends Model { /** * 微信公众号ID */ - private String wxAccountId; + private Integer wxAccountId; /** * 微信公众号appid */ diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java index 610b22119..31e853e91 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxFansMsgRes.java @@ -44,7 +44,7 @@ public class WxFansMsgRes extends Model { /** * 粉丝消息ID */ - private String fansMsgId; + private Integer fansMsgId; /** * 回复内容 */ @@ -52,7 +52,7 @@ public class WxFansMsgRes extends Model { /** * 用户ID */ - private String userId; + private Integer userId; /** * 用户名 */ diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java similarity index 72% rename from pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java rename to pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java index 165b90a2b..895bfe833 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMenu.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.mp.entity; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; @@ -33,7 +34,7 @@ import java.time.LocalDateTime; @Data @TableName("t_wx_menu") @EqualsAndHashCode(callSuper = true) -public class WxMenu extends Model { +public class WxMpMenu extends Model { private static final long serialVersionUID = 1L; /** @@ -41,46 +42,26 @@ public class WxMenu extends Model { */ @TableId private Integer id; + /** - * 父ID + * 菜单 */ - private String parentId; + private String menu; + /** - * 菜单名称 + * 微信公众号ID */ - private String menuName; + private Integer wxAccountId; /** - * 菜单类型 1文本消息;2图文消息;3网址链接;4小程序 + * 微信公众号appid */ - private String menuType; + private String wxAccountAppid; + /** - * 菜单等级 + * 微信公众号名 */ - private String menuLevel; - /** - * 模板ID - */ - private String tplId; - /** - * 菜单URL - */ - private String menuUrl; - /** - * 排序 - */ - private String menuSort; - /** - * 微信账号ID - */ - private String wxAccountId; - /** - * 小程序appid - */ - private String miniprogramAppid; - /** - * 小程序页面路径 - */ - private String miniprogramPagepath; + private String wxAccountName; + /** * 创建时间 */ @@ -90,4 +71,10 @@ public class WxMenu extends Model { */ private LocalDateTime updateTime; + /** + * 是否删除 -1:已删除 0:正常 + */ + @TableLogic + private String delFlag; + } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java index 7b7756a56..7013f4fbd 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/mapper/WxMenuMapper.java @@ -17,7 +17,7 @@ package com.pig4cloud.pigx.mp.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.pig4cloud.pigx.mp.entity.WxMenu; +import com.pig4cloud.pigx.mp.entity.WxMpMenu; /** * lengleng @@ -25,6 +25,6 @@ import com.pig4cloud.pigx.mp.entity.WxMenu; * @author pigx code generator * @date 2019-03-27 20:45:18 */ -public interface WxMenuMapper extends BaseMapper { +public interface WxMenuMapper extends BaseMapper { } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java index 2cbfc3eeb..6b28b69fc 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxFansMsgResService.java @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.mp.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.mp.entity.WxFansMsgRes; /** @@ -27,4 +28,11 @@ import com.pig4cloud.pigx.mp.entity.WxFansMsgRes; */ public interface WxFansMsgResService extends IService { + /** + * 保存并发送回复 + * + * @param wxFansMsgRes + * @return + */ + R saveAndSend(WxFansMsgRes wxFansMsgRes); } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java index 4ae680302..967ac499e 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxMenuService.java @@ -16,8 +16,10 @@ */ package com.pig4cloud.pigx.mp.service; +import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; -import com.pig4cloud.pigx.mp.entity.WxMenu; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.mp.entity.WxMpMenu; /** * 微信菜单业务 @@ -25,6 +27,30 @@ import com.pig4cloud.pigx.mp.entity.WxMenu; * @author lengleng * @date 2019-03-27 20:45:18 */ -public interface WxMenuService extends IService { +public interface WxMenuService extends IService { + /** + * 新增微信公众号按钮 + * + * @param wxMenus json + * @param appId 公众号信息 + * @return + */ + Boolean save(JSONObject wxMenus, String appId); + + /** + * 发布到微信 + * + * @param appId 公众号信息 + * @return + */ + R push(String appId); + + /** + * 通过appid 查询菜单信息 + * + * @param appId + * @return + */ + R getByAppId(String appId); } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java index 08f0c01f9..494b7daf9 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java @@ -117,7 +117,7 @@ public class WxAccountFansServiceImpl extends ServiceImpl implements WxFansMsgResService { + private final WxFansMsgMapper wxFansMsgMapper; + + /** + * 保存并发送回复 + *

+ * 1. 根据消息ID 查询消息的所属 公众号信息 + * 2. 构建文本客服消息并发送 + * 3. 完善回复消息并保存 + * 4. 更新微信消息为已回复 + * + * @param wxFansMsgRes + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R saveAndSend(WxFansMsgRes wxFansMsgRes) { + WxFansMsg wxFansMsg = wxFansMsgMapper.selectById(wxFansMsgRes.getFansMsgId()); + + String wxAccountAppid = wxFansMsg.getWxAccountAppid(); + WxMpService wxMpService = WxMpConfiguration.getMpServices().get(wxAccountAppid); + + try { + wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage + .TEXT() + .toUser(wxFansMsg.getOpenid()) + .content(wxFansMsgRes.getResContent()) + .build()); + } catch (WxErrorException e) { + log.error("发送客服消息失败 ", e); + return R.builder().code(CommonConstants.FAIL).msg(e.getError().getErrorMsg()).build(); + } + + PigxUser user = SecurityUtils.getUser(); + wxFansMsgRes.setUserId(user.getId()); + wxFansMsgRes.setUserName(user.getUsername()); + baseMapper.insert(wxFansMsgRes); + + wxFansMsg.setIsRes("1"); + wxFansMsgMapper.updateById(wxFansMsg); + return R.builder().build(); + } } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java index d7bfa7bcc..272f17966 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java @@ -16,11 +16,27 @@ */ package com.pig4cloud.pigx.mp.service.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.pig4cloud.pigx.mp.entity.WxMenu; +import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.mp.config.WxMpConfiguration; +import com.pig4cloud.pigx.mp.entity.WxAccount; +import com.pig4cloud.pigx.mp.entity.WxMpMenu; +import com.pig4cloud.pigx.mp.mapper.WxAccountMapper; import com.pig4cloud.pigx.mp.mapper.WxMenuMapper; import com.pig4cloud.pigx.mp.service.WxMenuService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpMenuService; +import me.chanjar.weixin.mp.api.WxMpService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; /** * 微信菜单业务 @@ -28,7 +44,85 @@ import org.springframework.stereotype.Service; * @author lengleng * @date 2019-03-27 20:45:18 */ +@Slf4j @Service -public class WxMenuServiceImpl extends ServiceImpl implements WxMenuService { +@AllArgsConstructor +public class WxMenuServiceImpl extends ServiceImpl implements WxMenuService { + private static final String MENU = "menu"; + private final WxAccountMapper wxAccountMapper; + /** + * 新增微信公众号按钮 + * + * @param wxMenus json + * @param appId 公众号 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean save(JSONObject wxMenus, String appId) { + baseMapper.delete(Wrappers.lambdaQuery() + .eq(WxMpMenu::getWxAccountAppid, appId)); + + WxAccount wxAccount = wxAccountMapper + .selectOne(Wrappers.lambdaQuery() + .eq(WxAccount::getAppid, appId)); + WxMpMenu wxMpMenu = new WxMpMenu(); + wxMpMenu.setMenu(wxMenus.toStringPretty()); + wxMpMenu.setWxAccountId(wxAccount.getId()); + wxMpMenu.setWxAccountAppid(wxAccount.getAppid()); + wxMpMenu.setWxAccountName(wxAccount.getName()); + baseMapper.insert(wxMpMenu); + return Boolean.TRUE; + } + + /** + * 发布到微信 + * + * @param appId 公众号信息 + * @return + */ + @Override + public R push(String appId) { + List wxMpMenuList = baseMapper.selectList(Wrappers.lambdaQuery() + .eq(WxMpMenu::getWxAccountAppid, appId)); + + if (CollUtil.isEmpty(wxMpMenuList)) { + return R.builder() + .code(CommonConstants.FAIL) + .msg("微信菜单配置为空,不能发布").build(); + } + + WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId); + WxMpMenuService menuService = wxMpService.getMenuService(); + + // 给数据库保存的加一层 + JSONObject jsonObject = new JSONObject(wxMpMenuList.get(0).getMenu()); + jsonObject.put(MENU, jsonObject); + try { + menuService.menuCreate(jsonObject.toStringPretty()); + } catch (WxErrorException e) { + return R.builder() + .code(CommonConstants.FAIL) + .msg(e.getError().getErrorMsg()).build(); + } + return R.builder().build(); + } + + /** + * 通过appid 查询菜单信息 + * + * @param appId + * @return + */ + @Override + public R getByAppId(String appId) { + List wxMpMenuList = baseMapper.selectList(Wrappers.lambdaQuery() + .eq(WxMpMenu::getWxAccountAppid, appId)); + + if (CollUtil.isEmpty(wxMpMenuList)) { + return R.builder().build(); + } + return R.builder().data(wxMpMenuList.get(0).getMenu()).build(); + } } diff --git a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml index 432502833..3bc199fcd 100755 --- a/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml +++ b/pigx-visual/pigx-mp-manager/src/main/resources/mapper/WxMenuMapper.xml @@ -23,19 +23,4 @@ - - - - - - - - - - - - - - - From 8579f22522b4b4b9f2e3b0d36d323354ee6dd0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sun, 31 Mar 2019 10:56:00 +0800 Subject: [PATCH 05/12] =?UTF-8?q?:bug:=20Fixing=20a=20bug.=20=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=BC=96=E8=BE=91=E7=95=8C=E9=9D=A2=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml index ac2822964..4a265e6f6 100644 --- a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml @@ -149,7 +149,7 @@ `user`.avatar, `user`.wx_openid, `user`.qq_openid, - `user`.dept_id, + `user`.dept_id AS deptId, `user`.create_time AS ucreate_time, `user`.update_time AS uupdate_time, `user`.del_flag AS udel_flag, From 98b851adc273fab28b2a2abdfcf418da5d5f18c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sun, 31 Mar 2019 13:07:02 +0800 Subject: [PATCH 06/12] =?UTF-8?q?:bookmark:=20Releasing=20/=20Version=20ta?= =?UTF-8?q?gs.=202.7.0=20=E9=85=8D=E5=90=88=E5=89=8D=E7=AB=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pigx/admin/controller/DeptController.java | 10 ----- .../pigx/admin/mapper/SysDeptMapper.java | 8 ---- .../pigx/admin/service/SysDeptService.java | 7 --- .../service/impl/SysDeptServiceImpl.java | 44 ++++++------------- .../main/resources/mapper/SysDeptMapper.xml | 24 ---------- 5 files changed, 13 insertions(+), 80 deletions(-) diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/DeptController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/DeptController.java index 28d952fc5..9570d3562 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/DeptController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/DeptController.java @@ -68,16 +68,6 @@ public class DeptController { return new R<>(sysDeptService.selectTree()); } - /** - * 返回当前用户树形菜单集合 - * - * @return 树形菜单 - */ - @GetMapping(value = "/user-tree") - public R getUserTree() { - return new R<>(sysDeptService.getUserTree()); - } - /** * 添加 * diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java index 6df92577f..aeb1e4ae5 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java @@ -22,8 +22,6 @@ package com.pig4cloud.pigx.admin.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.pig4cloud.pigx.admin.api.entity.SysDept; -import java.util.List; - /** *

* 部门管理 Mapper 接口 @@ -34,10 +32,4 @@ import java.util.List; */ public interface SysDeptMapper extends BaseMapper { - /** - * 关联dept——relation - * - * @return 数据列表 - */ - List listDepts(); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java index d7cffea73..54417a797 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java @@ -42,13 +42,6 @@ public interface SysDeptService extends IService { */ List selectTree(); - /** - * 查询用户部门树 - * - * @return - */ - List getUserTree(); - /** * 添加信息部门 * diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java index db853a5fc..82bc07eab 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java @@ -29,7 +29,6 @@ import com.pig4cloud.pigx.admin.api.vo.TreeUtil; import com.pig4cloud.pigx.admin.mapper.SysDeptMapper; import com.pig4cloud.pigx.admin.service.SysDeptRelationService; import com.pig4cloud.pigx.admin.service.SysDeptService; -import com.pig4cloud.pigx.common.security.util.SecurityUtils; import lombok.AllArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -79,11 +78,11 @@ public class SysDeptServiceImpl extends ServiceImpl impl public Boolean removeDeptById(Integer id) { //级联删除部门 List idList = sysDeptRelationService - .list(Wrappers.query().lambda() - .eq(SysDeptRelation::getAncestor, id)) - .stream() - .map(SysDeptRelation::getDescendant) - .collect(Collectors.toList()); + .list(Wrappers.query().lambda() + .eq(SysDeptRelation::getAncestor, id)) + .stream() + .map(SysDeptRelation::getDescendant) + .collect(Collectors.toList()); if (CollUtil.isNotEmpty(idList)) { this.removeByIds(idList); @@ -123,23 +122,6 @@ public class SysDeptServiceImpl extends ServiceImpl impl return getDeptTree(this.list(Wrappers.emptyWrapper())); } - /** - * 查询用户部门树 - * - * @return - */ - @Override - public List getUserTree() { - Integer deptId = SecurityUtils.getUser().getDeptId(); - List descendantIdList = sysDeptRelationService - .list(Wrappers.query().lambda() - .eq(SysDeptRelation::getAncestor, deptId)) - .stream().map(SysDeptRelation::getDescendant) - .collect(Collectors.toList()); - - List deptList = baseMapper.selectBatchIds(descendantIdList); - return getDeptTree(deptList); - } /** * 构建部门树 @@ -149,14 +131,14 @@ public class SysDeptServiceImpl extends ServiceImpl impl */ private List getDeptTree(List depts) { List treeList = depts.stream() - .filter(dept -> !dept.getDeptId().equals(dept.getParentId())) - .map(dept -> { - DeptTree node = new DeptTree(); - node.setId(dept.getDeptId()); - node.setParentId(dept.getParentId()); - node.setName(dept.getName()); - return node; - }).collect(Collectors.toList()); + .filter(dept -> !dept.getDeptId().equals(dept.getParentId())) + .map(dept -> { + DeptTree node = new DeptTree(); + node.setId(dept.getDeptId()); + node.setParentId(dept.getParentId()); + node.setName(dept.getName()); + return node; + }).collect(Collectors.toList()); return TreeUtil.build(treeList, 0); } } diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml index 667c55728..7f0befa96 100644 --- a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml @@ -21,28 +21,4 @@ - - - - - - - - - - - - - dept_id AS deptId, parent_id AS parentId, name, sort, create_time AS createTime, update_time AS updateTime, del_flag AS delFlag - - - - From 04d0b833ca9a1b269fb010cbbc52a8f0c03da321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sun, 31 Mar 2019 20:12:12 +0800 Subject: [PATCH 07/12] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82=E6=94=AF=E6=8C=81=E5=A4=9A=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90=E5=88=87=E6=8D=A2=E4=BB=A3=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/config/pigx-codegen-dev.yml | 6 + pigx-visual/pigx-codegen/pom.xml | 4 + .../pigx/codegen/PigxCodeGenApplication.java | 2 +- .../codegen/config/DynamicDataSource.java | 25 ++++ .../config/DynamicDataSourceConfig.java | 97 ++++++++++++++ .../controller/SysDsConfController.java | 119 ++++++++++++++++++ .../controller/SysGeneratorController.java | 7 +- .../pigx/codegen/entity/GenConfig.java | 4 + .../codegen/entity/SysDatasourceConf.java | 79 ++++++++++++ .../mapper/SysDatasourceConfMapper.java | 30 +++++ .../service/SysDatasourceConfService.java | 30 +++++ .../codegen/service/SysGeneratorService.java | 4 +- .../impl/SysDatasourceConfServiceImpl.java | 34 +++++ .../service/impl/SysGeneratorServiceImpl.java | 11 +- .../util/DynamicDataSourceContextHolder.java | 26 ++++ 15 files changed, 469 insertions(+), 9 deletions(-) create mode 100644 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java create mode 100644 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java create mode 100755 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java create mode 100755 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java create mode 100755 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/mapper/SysDatasourceConfMapper.java create mode 100755 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java create mode 100755 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java create mode 100644 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java diff --git a/pigx-config/src/main/resources/config/pigx-codegen-dev.yml b/pigx-config/src/main/resources/config/pigx-codegen-dev.yml index 6e3d9f3e1..d8800e42a 100644 --- a/pigx-config/src/main/resources/config/pigx-codegen-dev.yml +++ b/pigx-config/src/main/resources/config/pigx-codegen-dev.yml @@ -15,3 +15,9 @@ spring: url: jdbc:mysql://pigx-mysql:3306/coffeewx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 resources: static-locations: classpath:/static/,classpath:/views/ + +pigx: + tenant: + column: tenant_id + tables: + - sys_datasource_conf \ No newline at end of file diff --git a/pigx-visual/pigx-codegen/pom.xml b/pigx-visual/pigx-codegen/pom.xml index af9750be0..a0bcf4fea 100755 --- a/pigx-visual/pigx-codegen/pom.xml +++ b/pigx-visual/pigx-codegen/pom.xml @@ -49,6 +49,10 @@ com.pig4cloud pigx-common-security + + com.pig4cloud + pigx-common-log + velocity diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java index 1939b0796..25a8ae599 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java @@ -17,8 +17,8 @@ package com.pig4cloud.pigx.codegen; -import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer; import com.pig4cloud.pigx.common.security.annotation.EnablePigxFeignClients; +import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer; import com.pig4cloud.pigx.common.swagger.annotation.EnablePigxSwagger2; import org.springframework.boot.SpringApplication; import org.springframework.cloud.client.SpringCloudApplication; diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java new file mode 100644 index 000000000..252b8d87f --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java @@ -0,0 +1,25 @@ +package com.pig4cloud.pigx.codegen.config; + +import com.pig4cloud.pigx.codegen.util.DynamicDataSourceContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * @author lengleng + * @date 2019-03-31 + *

+ * 动态数据源类 + */ +@Slf4j +public class DynamicDataSource extends AbstractRoutingDataSource { + + /** + * 指定路由Key + * + * @return + */ + @Override + protected Object determineCurrentLookupKey() { + return DynamicDataSourceContextHolder.getDataSourceType(); + } +} \ No newline at end of file diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java new file mode 100644 index 000000000..7252f0fb7 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java @@ -0,0 +1,97 @@ +package com.pig4cloud.pigx.codegen.config; + +import com.zaxxer.hikari.HikariDataSource; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.TransactionManagementConfigurer; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * @author lengleng + * @date 2019-03-31 + *

+ * 动态数据源切换配置 + */ +@Slf4j +@Configuration +@AllArgsConstructor +public class DynamicDataSourceConfig implements TransactionManagementConfigurer { + private final Map dataSourceMap = new HashMap<>(8); + private final DataSourceProperties dataSourceProperties; + + @Bean("dynamicDataSource") + public DynamicDataSource dataSource() { + DynamicDataSource ds = new DynamicDataSource(); + HikariDataSource cads = new HikariDataSource(); + cads.setJdbcUrl(dataSourceProperties.getUrl()); + cads.setDriverClassName(dataSourceProperties.getDriverClassName()); + cads.setUsername(dataSourceProperties.getUsername()); + cads.setPassword(dataSourceProperties.getPassword()); + ds.setDefaultTargetDataSource(cads); + dataSourceMap.put(0, cads); + ds.setTargetDataSources(dataSourceMap); + return ds; + } + + /** + * 组装默认配置的数据源,查询数据库配置 + */ + @PostConstruct + public void init() { + DriverManagerDataSource dds = new DriverManagerDataSource(); + dds.setUrl(dataSourceProperties.getUrl()); + dds.setDriverClassName(dataSourceProperties.getDriverClassName()); + dds.setUsername(dataSourceProperties.getUsername()); + dds.setPassword(dataSourceProperties.getPassword()); + + String sql = "select * from sys_datasource_conf where del_flag = '0' "; + List> dbList = new JdbcTemplate(dds).queryForList(sql); + log.info("开始 -> 初始化动态数据源"); + Optional.of(dbList).ifPresent(list -> list.forEach(db -> { + log.info("数据源:{}", db.get("name")); + HikariDataSource ds = new HikariDataSource(); + ds.setJdbcUrl(String.valueOf(db.get("url"))); + ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); + ds.setUsername(String.valueOf(db.get("username"))); + ds.setPassword(String.valueOf(db.get("password"))); + dataSourceMap.put(db.get("id"), ds); + })); + + log.info("完毕 -> 初始化动态数据源,共计 {} 条", dataSourceMap.size()); + } + + /** + * 重新加载数据源配置 + */ + public void reload() { + init(); + DynamicDataSource dataSource = dataSource(); + dataSource.setTargetDataSources(dataSourceMap); + dataSource.afterPropertiesSet(); + } + + + @Bean + public PlatformTransactionManager txManager() { + return new DataSourceTransactionManager(dataSource()); + } + + @Override + public PlatformTransactionManager annotationDrivenTransactionManager() { + return txManager(); + } + + +} \ No newline at end of file diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java new file mode 100755 index 000000000..7d5f21fa2 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.codegen.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.codegen.config.DynamicDataSourceConfig; +import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; +import com.pig4cloud.pigx.codegen.service.SysDatasourceConfService; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + + +/** + * 数据源管理 + * + * @author pigx code generator + * @date 2019-03-31 16:00:20 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/dsconf") +public class SysDsConfController { + private final DynamicDataSourceConfig dynamicDataSourceConfig; + private final SysDatasourceConfService sysDatasourceConfService; + + /** + * 分页查询 + * + * @param page 分页对象 + * @param sysDatasourceConf 数据源表 + * @return + */ + @GetMapping("/page") + public R getSysDatasourceConfPage(Page page, SysDatasourceConf sysDatasourceConf) { + return new R<>(sysDatasourceConfService.page(page, Wrappers.query(sysDatasourceConf))); + } + + /** + * 查询全部数据源 + * + * @return + */ + @GetMapping("/list") + public R list() { + return new R<>(sysDatasourceConfService.list()); + } + + + /** + * 通过id查询数据源表 + * + * @param id id + * @return R + */ + @GetMapping("/{id}") + public R getById(@PathVariable("id") Integer id) { + return new R<>(sysDatasourceConfService.getById(id)); + } + + /** + * 新增数据源表 + * + * @param sysDatasourceConf 数据源表 + * @return R + */ + @SysLog("新增数据源表") + @PostMapping + public R save(@RequestBody SysDatasourceConf sysDatasourceConf) { + sysDatasourceConfService.save(sysDatasourceConf); + dynamicDataSourceConfig.reload(); + return new R<>(); + } + + /** + * 修改数据源表 + * + * @param sysDatasourceConf 数据源表 + * @return R + */ + @SysLog("修改数据源表") + @PutMapping + public R updateById(@RequestBody SysDatasourceConf sysDatasourceConf) { + sysDatasourceConfService.updateById(sysDatasourceConf); + dynamicDataSourceConfig.reload(); + return new R<>(); + } + + /** + * 通过id删除数据源表 + * + * @param id id + * @return R + */ + @SysLog("删除数据源表") + @DeleteMapping("/{id}") + public R removeById(@PathVariable Integer id) { + sysDatasourceConfService.removeById(id); + dynamicDataSourceConfig.reload(); + return new R<>(); + } + +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java index 33ce4aa7a..42eb67911 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysGeneratorController.java @@ -28,7 +28,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; /** * 代码生成器 @@ -46,11 +45,12 @@ public class SysGeneratorController { * 列表 * * @param tableName 参数集 + * @param id 数据源编号 * @return 数据库表 */ @GetMapping("/page") - public R getPage(Page page, String tableName) { - return new R<>(sysGeneratorService.getPage(page, tableName)); + public R getPage(Page page, String tableName, Integer id) { + return new R<>(sysGeneratorService.getPage(page, tableName, id)); } /** @@ -60,7 +60,6 @@ public class SysGeneratorController { @PostMapping("/code") public void generatorCode(@RequestBody GenConfig genConfig, HttpServletResponse response) { byte[] data = sysGeneratorService.generatorCode(genConfig); - response.reset(); response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s.zip", genConfig.getTableName())); response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(data.length)); diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenConfig.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenConfig.java index 5ad6dd6e6..cb270c897 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenConfig.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenConfig.java @@ -26,6 +26,10 @@ import lombok.Data; */ @Data public class GenConfig { + /** + * 数据源ID + */ + private Integer id; /** * 包名 */ diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java new file mode 100755 index 000000000..a66d82ece --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.codegen.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 数据源表 + * + * @author pigx code generator + * @date 2019-03-31 16:00:20 + */ +@Data +@TableName("sys_datasource_conf") +@EqualsAndHashCode(callSuper = true) +public class SysDatasourceConf extends Model { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId + private Integer id; + /** + * 名称 + */ + private String name; + /** + * + */ + private String url; + /** + * + */ + private String username; + /** + * + */ + private String password; + /** + * 创建时间 + */ + private LocalDateTime createDate; + /** + * 更新 + */ + private LocalDateTime updateDate; + /** + * 删除标记 + */ + @TableLogic + private String delFlag; + /** + * 租户ID + */ + private Integer tenantId; + +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/mapper/SysDatasourceConfMapper.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/mapper/SysDatasourceConfMapper.java new file mode 100755 index 000000000..c44231e48 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/mapper/SysDatasourceConfMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.codegen.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; + +/** + * 数据源表 + * + * @author pigx code generator + * @date 2019-03-31 16:00:20 + */ +public interface SysDatasourceConfMapper extends BaseMapper { + +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java new file mode 100755 index 000000000..d84446746 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.codegen.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; + +/** + * 数据源表 + * + * @author pigx code generator + * @date 2019-03-31 16:00:20 + */ +public interface SysDatasourceConfService extends IService { + +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysGeneratorService.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysGeneratorService.java index 08b943e28..4e5644235 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysGeneratorService.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysGeneratorService.java @@ -39,8 +39,10 @@ public interface SysGeneratorService { /** * 分页查询表 + * * @param tableName 表名 + * @param id 数据源ID * @return */ - IPage>> getPage(Page page, String tableName); + IPage>> getPage(Page page, String tableName, Integer id); } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java new file mode 100755 index 000000000..36091f6a0 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.codegen.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; +import com.pig4cloud.pigx.codegen.mapper.SysDatasourceConfMapper; +import com.pig4cloud.pigx.codegen.service.SysDatasourceConfService; +import org.springframework.stereotype.Service; + +/** + * 数据源表 + * + * @author pigx code generator + * @date 2019-03-31 16:00:20 + */ +@Service +public class SysDatasourceConfServiceImpl extends ServiceImpl implements SysDatasourceConfService { + +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java index 339485532..16a688e45 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java @@ -21,8 +21,10 @@ import cn.hutool.core.io.IoUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.codegen.entity.GenConfig; +import com.pig4cloud.pigx.codegen.mapper.SysDatasourceConfMapper; import com.pig4cloud.pigx.codegen.mapper.SysGeneratorMapper; import com.pig4cloud.pigx.codegen.service.SysGeneratorService; +import com.pig4cloud.pigx.codegen.util.DynamicDataSourceContextHolder; import com.pig4cloud.pigx.codegen.util.GenUtils; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; @@ -41,18 +43,20 @@ import java.util.zip.ZipOutputStream; @Service @AllArgsConstructor public class SysGeneratorServiceImpl implements SysGeneratorService { + private final SysDatasourceConfMapper sysDatasourceConfMapper; private final SysGeneratorMapper sysGeneratorMapper; - /** * 分页查询表 * * @param tableName 查询条件 + * @param id * @return */ @Override - public IPage>> getPage(Page page, String tableName) { - return sysGeneratorMapper.queryList(page,tableName); + public IPage>> getPage(Page page, String tableName, Integer id) { + DynamicDataSourceContextHolder.setDataSourceType(id); + return sysGeneratorMapper.queryList(page, tableName); } /** @@ -63,6 +67,7 @@ public class SysGeneratorServiceImpl implements SysGeneratorService { */ @Override public byte[] generatorCode(GenConfig genConfig) { + DynamicDataSourceContextHolder.setDataSourceType(genConfig.getId()); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(outputStream); diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java new file mode 100644 index 000000000..4e0c2d546 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java @@ -0,0 +1,26 @@ +package com.pig4cloud.pigx.codegen.util; + +import lombok.experimental.UtilityClass; + +/** + * @author lengleng + * @date 2019-03-31 + *

+ * 保存上线文中数据库路由 + */ +@UtilityClass +public class DynamicDataSourceContextHolder { + private final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + public void setDataSourceType(Integer dataSourceType) { + CONTEXT_HOLDER.set(dataSourceType); + } + + public Integer getDataSourceType() { + return CONTEXT_HOLDER.get(); + } + + public void clearDataSourceType() { + CONTEXT_HOLDER.remove(); + } +} \ No newline at end of file From c740fd66932c62e9e48c98872a530613fa245192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Mon, 1 Apr 2019 07:34:48 +0800 Subject: [PATCH 08/12] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82=E6=94=AF=E6=8C=81=E5=A4=9A=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90=E5=AF=86=E7=A0=81=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/DynamicDataSourceConfig.java | 25 +++++++----- .../controller/SysDsConfController.java | 14 ++----- .../codegen/entity/SysDatasourceConf.java | 6 +-- .../service/SysDatasourceConfService.java | 14 +++++++ .../impl/SysDatasourceConfServiceImpl.java | 34 ++++++++++++++++ .../pigx/codegen/util/DataSourceConstant.java | 40 +++++++++++++++++++ 6 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstant.java diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java index 7252f0fb7..41f175e25 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java @@ -1,8 +1,11 @@ package com.pig4cloud.pigx.codegen.config; +import com.mysql.cj.jdbc.Driver; +import com.pig4cloud.pigx.codegen.util.DataSourceConstant; import com.zaxxer.hikari.HikariDataSource; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jasypt.encryption.StringEncryptor; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -30,6 +33,7 @@ import java.util.Optional; public class DynamicDataSourceConfig implements TransactionManagementConfigurer { private final Map dataSourceMap = new HashMap<>(8); private final DataSourceProperties dataSourceProperties; + private final StringEncryptor stringEncryptor; @Bean("dynamicDataSource") public DynamicDataSource dataSource() { @@ -56,17 +60,18 @@ public class DynamicDataSourceConfig implements TransactionManagementConfigurer dds.setUsername(dataSourceProperties.getUsername()); dds.setPassword(dataSourceProperties.getPassword()); - String sql = "select * from sys_datasource_conf where del_flag = '0' "; - List> dbList = new JdbcTemplate(dds).queryForList(sql); + List> dbList = new JdbcTemplate(dds).queryForList(DataSourceConstant.QUERY_DS_SQL); log.info("开始 -> 初始化动态数据源"); Optional.of(dbList).ifPresent(list -> list.forEach(db -> { - log.info("数据源:{}", db.get("name")); + log.info("数据源:{}", db.get(DataSourceConstant.DS_NAME)); HikariDataSource ds = new HikariDataSource(); - ds.setJdbcUrl(String.valueOf(db.get("url"))); - ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); - ds.setUsername(String.valueOf(db.get("username"))); - ds.setPassword(String.valueOf(db.get("password"))); - dataSourceMap.put(db.get("id"), ds); + ds.setJdbcUrl(String.valueOf(db.get(DataSourceConstant.DS_JDBC_URL))); + ds.setDriverClassName(Driver.class.getName()); + ds.setUsername((String) db.get(DataSourceConstant.DS_NAME)); + + String decPwd = stringEncryptor.decrypt((String) db.get(DataSourceConstant.DS_USER_PWD)); + ds.setPassword(decPwd); + dataSourceMap.put(db.get(DataSourceConstant.DS_ROUTE_KEY), ds); })); log.info("完毕 -> 初始化动态数据源,共计 {} 条", dataSourceMap.size()); @@ -75,11 +80,12 @@ public class DynamicDataSourceConfig implements TransactionManagementConfigurer /** * 重新加载数据源配置 */ - public void reload() { + public Boolean reload() { init(); DynamicDataSource dataSource = dataSource(); dataSource.setTargetDataSources(dataSourceMap); dataSource.afterPropertiesSet(); + return Boolean.FALSE; } @@ -93,5 +99,4 @@ public class DynamicDataSourceConfig implements TransactionManagementConfigurer return txManager(); } - } \ No newline at end of file diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java index 7d5f21fa2..57cbafe66 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/SysDsConfController.java @@ -18,7 +18,6 @@ package com.pig4cloud.pigx.codegen.controller; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.pig4cloud.pigx.codegen.config.DynamicDataSourceConfig; import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; import com.pig4cloud.pigx.codegen.service.SysDatasourceConfService; import com.pig4cloud.pigx.common.core.util.R; @@ -37,7 +36,6 @@ import org.springframework.web.bind.annotation.*; @AllArgsConstructor @RequestMapping("/dsconf") public class SysDsConfController { - private final DynamicDataSourceConfig dynamicDataSourceConfig; private final SysDatasourceConfService sysDatasourceConfService; /** @@ -83,9 +81,7 @@ public class SysDsConfController { @SysLog("新增数据源表") @PostMapping public R save(@RequestBody SysDatasourceConf sysDatasourceConf) { - sysDatasourceConfService.save(sysDatasourceConf); - dynamicDataSourceConfig.reload(); - return new R<>(); + return new R<>(sysDatasourceConfService.saveDsByEnc(sysDatasourceConf)); } /** @@ -97,9 +93,7 @@ public class SysDsConfController { @SysLog("修改数据源表") @PutMapping public R updateById(@RequestBody SysDatasourceConf sysDatasourceConf) { - sysDatasourceConfService.updateById(sysDatasourceConf); - dynamicDataSourceConfig.reload(); - return new R<>(); + return new R<>(sysDatasourceConfService.updateDsByEnc(sysDatasourceConf)); } /** @@ -111,9 +105,7 @@ public class SysDsConfController { @SysLog("删除数据源表") @DeleteMapping("/{id}") public R removeById(@PathVariable Integer id) { - sysDatasourceConfService.removeById(id); - dynamicDataSourceConfig.reload(); - return new R<>(); + return new R<>(sysDatasourceConfService.removeById(id)); } } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java index a66d82ece..218d8c969 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/SysDatasourceConf.java @@ -47,15 +47,15 @@ public class SysDatasourceConf extends Model { */ private String name; /** - * + * jdbcurl */ private String url; /** - * + * 用户名 */ private String username; /** - * + * 密码 */ private String password; /** diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java index d84446746..8a2100605 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/SysDatasourceConfService.java @@ -26,5 +26,19 @@ import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; * @date 2019-03-31 16:00:20 */ public interface SysDatasourceConfService extends IService { + /** + * 保存数据源并且加密 + * + * @param sysDatasourceConf + * @return + */ + Boolean saveDsByEnc(SysDatasourceConf sysDatasourceConf); + /** + * 更新数据源 + * + * @param sysDatasourceConf + * @return + */ + Boolean updateDsByEnc(SysDatasourceConf sysDatasourceConf); } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java index 36091f6a0..74e923eb3 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java @@ -16,10 +16,14 @@ */ package com.pig4cloud.pigx.codegen.service.impl; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.codegen.config.DynamicDataSourceConfig; import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; import com.pig4cloud.pigx.codegen.mapper.SysDatasourceConfMapper; import com.pig4cloud.pigx.codegen.service.SysDatasourceConfService; +import lombok.AllArgsConstructor; +import org.jasypt.encryption.StringEncryptor; import org.springframework.stereotype.Service; /** @@ -29,6 +33,36 @@ import org.springframework.stereotype.Service; * @date 2019-03-31 16:00:20 */ @Service +@AllArgsConstructor public class SysDatasourceConfServiceImpl extends ServiceImpl implements SysDatasourceConfService { + private final DynamicDataSourceConfig dynamicDataSourceConfig; + private final StringEncryptor stringEncryptor; + /** + * 保存数据源并且加密 + * + * @param sysDatasourceConf + * @return + */ + @Override + public Boolean saveDsByEnc(SysDatasourceConf sysDatasourceConf) { + sysDatasourceConf.setPassword(stringEncryptor.encrypt(sysDatasourceConf.getPassword())); + this.baseMapper.insert(sysDatasourceConf); + return dynamicDataSourceConfig.reload(); + } + + /** + * 更新数据源 + * + * @param sysDatasourceConf + * @return + */ + @Override + public Boolean updateDsByEnc(SysDatasourceConf sysDatasourceConf) { + if (StrUtil.isNotBlank(sysDatasourceConf.getPassword())) { + sysDatasourceConf.setPassword(stringEncryptor.encrypt(sysDatasourceConf.getPassword())); + } + this.baseMapper.updateById(sysDatasourceConf); + return dynamicDataSourceConfig.reload(); + } } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstant.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstant.java new file mode 100644 index 000000000..d69d719b3 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstant.java @@ -0,0 +1,40 @@ +package com.pig4cloud.pigx.codegen.util; + +/** + * @author lengleng + * @date 2019-04-01 + *

+ * 数据源相关常量 + */ +public interface DataSourceConstant { + /** + * 查询数据源的SQL + */ + String QUERY_DS_SQL = "select * from sys_datasource_conf where del_flag = 0"; + + /** + * 动态路由KEY + */ + String DS_ROUTE_KEY = "id"; + + /** + * 数据源名称 + */ + String DS_NAME = "name"; + + /** + * jdbcurl + */ + String DS_JDBC_URL = "url"; + + /** + * 用户名 + */ + String DS_USER_NAME = "username"; + + /** + * 密码 + */ + String DS_USER_PWD = "password"; + +} From 56a2f1ebdf44e1c31f4a755e7038da3798e2a227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Mon, 1 Apr 2019 22:28:19 +0800 Subject: [PATCH 09/12] =?UTF-8?q?:card=5Ffile=5Fbox:=20=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9B=B8=E5=85=B3=E7=9A=84=E5=8F=98?= =?UTF-8?q?=E5=8C=96=E3=80=82=20=E4=B8=8D=E5=86=8D=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E5=A4=A7=E5=B0=8F=E5=86=99=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/5pigxx_job.sql | 62 +++++++++---------- .../daemon/elastic/entity/ExecutionLog.java | 2 +- .../daemon/elastic/entity/StatusTraceLog.java | 2 +- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/db/5pigxx_job.sql b/db/5pigxx_job.sql index 1b19b9956..05c2855ef 100644 --- a/db/5pigxx_job.sql +++ b/db/5pigxx_job.sql @@ -21,8 +21,8 @@ SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for `job_execution_log` -- ---------------------------- -DROP TABLE IF EXISTS `job_execution_log`; -CREATE TABLE `job_execution_log` ( +DROP TABLE IF EXISTS `JOB_EXECUTION_LOG`; +CREATE TABLE `JOB_EXECUTION_LOG` ( `id` varchar(40) NOT NULL, `job_name` varchar(100) NOT NULL, `task_id` varchar(255) NOT NULL, @@ -40,8 +40,8 @@ CREATE TABLE `job_execution_log` ( -- ---------------------------- -- Table structure for `job_status_trace_log` -- ---------------------------- -DROP TABLE IF EXISTS `job_status_trace_log`; -CREATE TABLE `job_status_trace_log` ( +DROP TABLE IF EXISTS `JOB_STATUS_TRACE_LOG`; +CREATE TABLE `JOB_STATUS_TRACE_LOG` ( `id` varchar(40) NOT NULL, `job_name` varchar(100) NOT NULL, `original_task_id` varchar(255) NOT NULL, @@ -60,8 +60,8 @@ CREATE TABLE `job_status_trace_log` ( -- ---------------------------- -- Table structure for `qrtz_blob_triggers` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_blob_triggers`; -CREATE TABLE `qrtz_blob_triggers` ( +DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`; +CREATE TABLE `QRTZ_BLOB_TRIGGERS` ( `sched_name` varchar(120) NOT NULL, `trigger_name` varchar(200) NOT NULL, `trigger_group` varchar(200) NOT NULL, @@ -73,8 +73,8 @@ CREATE TABLE `qrtz_blob_triggers` ( -- ---------------------------- -- Table structure for `qrtz_calendars` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_calendars`; -CREATE TABLE `qrtz_calendars` ( +DROP TABLE IF EXISTS `QRTZ_CALENDARS`; +CREATE TABLE `QRTZ_CALENDARS` ( `sched_name` varchar(120) NOT NULL, `calendar_name` varchar(200) NOT NULL, `calendar` blob NOT NULL, @@ -84,8 +84,8 @@ CREATE TABLE `qrtz_calendars` ( -- ---------------------------- -- Table structure for `qrtz_cron_triggers` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_cron_triggers`; -CREATE TABLE `qrtz_cron_triggers` ( +DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`; +CREATE TABLE `QRTZ_CRON_TRIGGERS` ( `sched_name` varchar(120) NOT NULL, `trigger_name` varchar(200) NOT NULL, `trigger_group` varchar(200) NOT NULL, @@ -99,14 +99,14 @@ CREATE TABLE `qrtz_cron_triggers` ( -- Records of `qrtz_cron_triggers` -- ---------------------------- BEGIN; -INSERT INTO `qrtz_cron_triggers` VALUES ('clusteredScheduler', '测试任务', 'demo', '0 * * * * ? *', 'Asia/Shanghai'); +INSERT INTO `QRTZ_CRON_TRIGGERS` VALUES ('clusteredScheduler', '测试任务', 'demo', '0 * * * * ? *', 'Asia/Shanghai'); COMMIT; -- ---------------------------- -- Table structure for `qrtz_fired_triggers` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_fired_triggers`; -CREATE TABLE `qrtz_fired_triggers` ( +DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`; +CREATE TABLE `QRTZ_FIRED_TRIGGERS` ( `sched_name` varchar(120) NOT NULL, `entry_id` varchar(95) NOT NULL, `trigger_name` varchar(200) NOT NULL, @@ -126,8 +126,8 @@ CREATE TABLE `qrtz_fired_triggers` ( -- ---------------------------- -- Table structure for `qrtz_job_details` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_job_details`; -CREATE TABLE `qrtz_job_details` ( +DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`; +CREATE TABLE `QRTZ_JOB_DETAILS` ( `sched_name` varchar(120) NOT NULL, `job_name` varchar(200) NOT NULL, `job_group` varchar(200) NOT NULL, @@ -145,14 +145,14 @@ CREATE TABLE `qrtz_job_details` ( -- Records of `qrtz_job_details` -- ---------------------------- BEGIN; -INSERT INTO `qrtz_job_details` VALUES ('clusteredScheduler', '测试任务', 'demo', null, 'com.pig4cloud.pigx.daemon.quartz.config.PigxQuartzFactory', '0', '1', '0', '0', 0xaced0005737200156f72672e71756172747a2e4a6f62446174614d61709fb083e8bfa9b0cb020000787200266f72672e71756172747a2e7574696c732e537472696e674b65794469727479466c61674d61708208e8c3fbc55d280200015a0013616c6c6f77735472616e7369656e74446174617872001d6f72672e71756172747a2e7574696c732e4469727479466c61674d617013e62ead28760ace0200025a000564697274794c00036d617074000f4c6a6176612f7574696c2f4d61703b787001737200116a6176612e7574696c2e486173684d61700507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c6478703f4000000000000c7708000000100000000174000b7363686564756c654a6f627372002e636f6d2e70696734636c6f75642e706967782e6461656d6f6e2e71756172747a2e656e746974792e5379734a6f6200000000000000010200174c0009636c6173734e616d657400124c6a6176612f6c616e672f537472696e673b4c0008637265617465427971007e00094c000a63726561746554696d657400194c6a6176612f74696d652f4c6f63616c4461746554696d653b4c000e63726f6e45787072657373696f6e71007e00094c000b657865637574655061746871007e00094c00106a6f624578656375746553746174757371007e00094c00086a6f6247726f757071007e00094c00056a6f6249647400134c6a6176612f6c616e672f496e74656765723b4c00076a6f624e616d6571007e00094c00086a6f624f7264657271007e00094c00096a6f6253746174757371007e00094c000d6a6f6254656e616e745479706571007e00094c00076a6f625479706571007e00094c000a6d6574686f644e616d6571007e00094c00116d6574686f64506172616d7356616c756571007e00094c000d6d697366697265506f6c69637971007e00094c00086e65787454696d6571007e000a4c000c70726576696f757354696d6571007e000a4c000672656d61726b71007e00094c0009737461727454696d6571007e000a4c000874656e616e74496471007e000b4c0008757064617465427971007e00094c000a75706461746554696d6571007e000a78720035636f6d2e62616f6d69646f752e6d796261746973706c75732e657874656e73696f6e2e6163746976657265636f72642e4d6f64656c0000000000000001020000787074000464656d6f74000561646d696e7372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770a05000007e303190e00f17874000d30202a202a202a202a203f202a7400007400013074000464656d6f737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b02000078700000000174000ce6b58be8af95e4bbbbe58aa17400013574000133740001317400013274000a64656d6f4d6574686f6474000970696734636c6f7564740001337371007e0010770905000007e3031916e2787371007e0010770a05000007e30319161ccd78740020e6bc94e7a4ba537072696e67204265616ee79a84e5ae9ae697b6e4bbbbe58aa17371007e0010770a05000007e303191600de7871007e001874000561646d696e7371007e0010770a05000007e303190e00f1787800); +INSERT INTO `QRTZ_JOB_DETAILS` VALUES ('clusteredScheduler', '测试任务', 'demo', null, 'com.pig4cloud.pigx.daemon.quartz.config.PigxQuartzFactory', '0', '1', '0', '0', 0xaced0005737200156f72672e71756172747a2e4a6f62446174614d61709fb083e8bfa9b0cb020000787200266f72672e71756172747a2e7574696c732e537472696e674b65794469727479466c61674d61708208e8c3fbc55d280200015a0013616c6c6f77735472616e7369656e74446174617872001d6f72672e71756172747a2e7574696c732e4469727479466c61674d617013e62ead28760ace0200025a000564697274794c00036d617074000f4c6a6176612f7574696c2f4d61703b787001737200116a6176612e7574696c2e486173684d61700507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c6478703f4000000000000c7708000000100000000174000b7363686564756c654a6f627372002e636f6d2e70696734636c6f75642e706967782e6461656d6f6e2e71756172747a2e656e746974792e5379734a6f6200000000000000010200174c0009636c6173734e616d657400124c6a6176612f6c616e672f537472696e673b4c0008637265617465427971007e00094c000a63726561746554696d657400194c6a6176612f74696d652f4c6f63616c4461746554696d653b4c000e63726f6e45787072657373696f6e71007e00094c000b657865637574655061746871007e00094c00106a6f624578656375746553746174757371007e00094c00086a6f6247726f757071007e00094c00056a6f6249647400134c6a6176612f6c616e672f496e74656765723b4c00076a6f624e616d6571007e00094c00086a6f624f7264657271007e00094c00096a6f6253746174757371007e00094c000d6a6f6254656e616e745479706571007e00094c00076a6f625479706571007e00094c000a6d6574686f644e616d6571007e00094c00116d6574686f64506172616d7356616c756571007e00094c000d6d697366697265506f6c69637971007e00094c00086e65787454696d6571007e000a4c000c70726576696f757354696d6571007e000a4c000672656d61726b71007e00094c0009737461727454696d6571007e000a4c000874656e616e74496471007e000b4c0008757064617465427971007e00094c000a75706461746554696d6571007e000a78720035636f6d2e62616f6d69646f752e6d796261746973706c75732e657874656e73696f6e2e6163746976657265636f72642e4d6f64656c0000000000000001020000787074000464656d6f74000561646d696e7372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770a05000007e303190e00f17874000d30202a202a202a202a203f202a7400007400013074000464656d6f737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b02000078700000000174000ce6b58be8af95e4bbbbe58aa17400013574000133740001317400013274000a64656d6f4d6574686f6474000970696734636c6f7564740001337371007e0010770905000007e3031916e2787371007e0010770a05000007e30319161ccd78740020e6bc94e7a4ba537072696e67204265616ee79a84e5ae9ae697b6e4bbbbe58aa17371007e0010770a05000007e303191600de7871007e001874000561646d696e7371007e0010770a05000007e303190e00f1787800); COMMIT; -- ---------------------------- -- Table structure for `qrtz_locks` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_locks`; -CREATE TABLE `qrtz_locks` ( +DROP TABLE IF EXISTS `QRTZ_LOCKS`; +CREATE TABLE `QRTZ_LOCKS` ( `sched_name` varchar(120) NOT NULL, `lock_name` varchar(40) NOT NULL, PRIMARY KEY (`sched_name`,`lock_name`) USING BTREE @@ -162,14 +162,14 @@ CREATE TABLE `qrtz_locks` ( -- Records of `qrtz_locks` -- ---------------------------- BEGIN; -INSERT INTO `qrtz_locks` VALUES ('clusteredScheduler', 'STATE_ACCESS'), ('clusteredScheduler', 'TRIGGER_ACCESS'); +INSERT INTO `QRTZ_LOCKS` VALUES ('clusteredScheduler', 'STATE_ACCESS'), ('clusteredScheduler', 'TRIGGER_ACCESS'); COMMIT; -- ---------------------------- -- Table structure for `qrtz_paused_trigger_grps` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`; -CREATE TABLE `qrtz_paused_trigger_grps` ( +DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`; +CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` ( `sched_name` varchar(120) NOT NULL, `trigger_group` varchar(200) NOT NULL, PRIMARY KEY (`sched_name`,`trigger_group`) USING BTREE @@ -178,8 +178,8 @@ CREATE TABLE `qrtz_paused_trigger_grps` ( -- ---------------------------- -- Table structure for `qrtz_scheduler_state` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_scheduler_state`; -CREATE TABLE `qrtz_scheduler_state` ( +DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`; +CREATE TABLE `QRTZ_SCHEDULER_STATE` ( `sched_name` varchar(120) NOT NULL, `instance_name` varchar(200) NOT NULL, `last_checkin_time` bigint(13) NOT NULL, @@ -191,7 +191,7 @@ CREATE TABLE `qrtz_scheduler_state` ( -- Records of `qrtz_scheduler_state` -- ---------------------------- BEGIN; -INSERT INTO `qrtz_scheduler_state` VALUES ('clusteredScheduler', 'lengleng1553564320591', '1553568907589', '10000'); +INSERT INTO `QRTZ_SCHEDULER_STATE` VALUES ('clusteredScheduler', 'lengleng1553564320591', '1553568907589', '10000'); COMMIT; -- ---------------------------- @@ -206,14 +206,14 @@ CREATE TABLE `qrtz_simple_triggers` ( `repeat_interval` bigint(12) NOT NULL, `times_triggered` bigint(10) NOT NULL, PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE, - CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) + CONSTRAINT `QRTZ_SIMPLE_TRIGGERS_IBFK_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; -- ---------------------------- -- Table structure for `qrtz_simprop_triggers` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_simprop_triggers`; -CREATE TABLE `qrtz_simprop_triggers` ( +DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`; +CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` ( `sched_name` varchar(120) NOT NULL, `trigger_name` varchar(200) NOT NULL, `trigger_group` varchar(200) NOT NULL, @@ -229,14 +229,14 @@ CREATE TABLE `qrtz_simprop_triggers` ( `bool_prop_1` varchar(1) DEFAULT NULL, `bool_prop_2` varchar(1) DEFAULT NULL, PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`) USING BTREE, - CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) + CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_IBFK_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; -- ---------------------------- -- Table structure for `qrtz_triggers` -- ---------------------------- -DROP TABLE IF EXISTS `qrtz_triggers`; -CREATE TABLE `qrtz_triggers` ( +DROP TABLE IF EXISTS `QRTZ_TRIGGERS`; +CREATE TABLE `QRTZ_TRIGGERS` ( `sched_name` varchar(120) NOT NULL, `trigger_name` varchar(200) NOT NULL, `trigger_group` varchar(200) NOT NULL, @@ -262,7 +262,7 @@ CREATE TABLE `qrtz_triggers` ( -- Records of `qrtz_triggers` -- ---------------------------- BEGIN; -INSERT INTO `qrtz_triggers` VALUES ('clusteredScheduler', '测试任务', 'demo', '测试任务', 'demo', null, '1553568960000', '1553568900000', '5', 'WAITING', 'CRON', '1553564598000', '0', null, '2', ''); +INSERT INTO `QRTZ_TRIGGERS` VALUES ('clusteredScheduler', '测试任务', 'demo', '测试任务', 'demo', null, '1553568960000', '1553568900000', '5', 'WAITING', 'CRON', '1553564598000', '0', null, '2', ''); COMMIT; -- ---------------------------- diff --git a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/ExecutionLog.java b/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/ExecutionLog.java index df7f52671..e1bc379af 100644 --- a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/ExecutionLog.java +++ b/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/ExecutionLog.java @@ -17,7 +17,7 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("job_execution_log") +@TableName("JOB_EXECUTION_LOG") public class ExecutionLog extends Model { private static final long serialVersionUID = 1L; diff --git a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/StatusTraceLog.java b/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/StatusTraceLog.java index dcf1acc38..2e071cea3 100644 --- a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/StatusTraceLog.java +++ b/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/entity/StatusTraceLog.java @@ -16,7 +16,7 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("job_status_trace_log") +@TableName("JOB_STATUS_TRACE_LOG") public class StatusTraceLog extends Model { private static final long serialVersionUID = 1L; From 4219161d47bf238d381e549132aa51d81cbe5faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 3 Apr 2019 21:33:17 +0800 Subject: [PATCH 10/12] :bookmark: Releasing / Version tags.2.8.0 --- docker-compose.yml | 2 +- pigx-auth/pom.xml | 2 +- .../com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java | 3 +++ pigx-common/pigx-common-bom/pom.xml | 2 +- pigx-common/pigx-common-core/pom.xml | 2 +- pigx-common/pigx-common-data/pom.xml | 2 +- pigx-common/pigx-common-gateway/pom.xml | 2 +- pigx-common/pigx-common-job/pom.xml | 2 +- pigx-common/pigx-common-log/pom.xml | 2 +- pigx-common/pigx-common-minio/pom.xml | 2 +- pigx-common/pigx-common-security/pom.xml | 2 +- .../springframework/cloud/openfeign/PigxFeignFallback.java | 5 ++--- pigx-common/pigx-common-swagger/pom.xml | 2 +- pigx-common/pigx-common-transaction/pom.xml | 2 +- pigx-common/pom.xml | 2 +- pigx-config/pom.xml | 2 +- pigx-eureka/pom.xml | 2 +- pigx-gateway/pom.xml | 2 +- pigx-upms/pigx-upms-api/pom.xml | 2 +- pigx-upms/pigx-upms-biz/pom.xml | 2 +- pigx-upms/pom.xml | 2 +- pigx-visual/pigx-activiti/pom.xml | 2 +- pigx-visual/pigx-codegen/pom.xml | 2 +- pigx-visual/pigx-daemon-elastic-job/pom.xml | 2 +- pigx-visual/pigx-daemon-quartz/pom.xml | 2 +- pigx-visual/pigx-monitor/pom.xml | 4 ++-- pigx-visual/pigx-mp-manager/pom.xml | 2 +- pigx-visual/pigx-sso-client-demo/pom.xml | 2 +- pigx-visual/pigx-tx-manager/pom.xml | 2 +- pigx-visual/pigx-zipkin/pom.xml | 2 +- pigx-visual/pom.xml | 2 +- pom.xml | 2 +- 32 files changed, 36 insertions(+), 34 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 30ce43425..4eaafb588 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -# 使用说明 V2.7.0 +# 使用说明 V2.8.0 # 1. 使用docker-compose 宿主机不需要配置host来发现 # 2. 无需修改源码,根目录 docker-compose up 即可 # 3. 静静等待服务启动 diff --git a/pigx-auth/pom.xml b/pigx-auth/pom.xml index 9ca4c3f2e..0138ddba4 100644 --- a/pigx-auth/pom.xml +++ b/pigx-auth/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-auth diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java index fb897a81c..53738f210 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java @@ -111,6 +111,9 @@ public class PigxTokenEndpoint { @Inner @DeleteMapping("/{token}") public R delToken(@PathVariable("token") String token) { + if (token != null) { + throw new RuntimeException("lalalala"); + } OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token); tokenStore.removeAccessToken(oAuth2AccessToken); return new R<>(); diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index 67e1b6b51..872624c8c 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -16,7 +16,7 @@ pigx 公共版本控制 - 2.7.0 + 2.8.0 3.1.0 8.0.13 1.5.22 diff --git a/pigx-common/pigx-common-core/pom.xml b/pigx-common/pigx-common-core/pom.xml index f2f46e6eb..6b4aa513c 100644 --- a/pigx-common/pigx-common-core/pom.xml +++ b/pigx-common/pigx-common-core/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-core diff --git a/pigx-common/pigx-common-data/pom.xml b/pigx-common/pigx-common-data/pom.xml index a51afb387..5b69ce245 100644 --- a/pigx-common/pigx-common-data/pom.xml +++ b/pigx-common/pigx-common-data/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-data diff --git a/pigx-common/pigx-common-gateway/pom.xml b/pigx-common/pigx-common-gateway/pom.xml index 346f29141..7854a5bce 100644 --- a/pigx-common/pigx-common-gateway/pom.xml +++ b/pigx-common/pigx-common-gateway/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-gateway diff --git a/pigx-common/pigx-common-job/pom.xml b/pigx-common/pigx-common-job/pom.xml index 550338fab..f016255db 100644 --- a/pigx-common/pigx-common-job/pom.xml +++ b/pigx-common/pigx-common-job/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-job diff --git a/pigx-common/pigx-common-log/pom.xml b/pigx-common/pigx-common-log/pom.xml index 4ec70cafb..afc2b8813 100644 --- a/pigx-common/pigx-common-log/pom.xml +++ b/pigx-common/pigx-common-log/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-log diff --git a/pigx-common/pigx-common-minio/pom.xml b/pigx-common/pigx-common-minio/pom.xml index aa859eba8..d86c37e9d 100755 --- a/pigx-common/pigx-common-minio/pom.xml +++ b/pigx-common/pigx-common-minio/pom.xml @@ -6,7 +6,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-minio diff --git a/pigx-common/pigx-common-security/pom.xml b/pigx-common/pigx-common-security/pom.xml index 1f244e842..54fd01845 100644 --- a/pigx-common/pigx-common-security/pom.xml +++ b/pigx-common/pigx-common-security/pom.xml @@ -23,7 +23,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-security diff --git a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java b/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java index fb849f19e..21d7c9ff1 100644 --- a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java +++ b/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java @@ -18,7 +18,7 @@ package org.springframework.cloud.openfeign; import cn.hutool.core.util.StrUtil; -import com.pig4cloud.pigx.common.core.constant.CommonConstants; +import cn.hutool.json.JSONUtil; import com.pig4cloud.pigx.common.core.util.R; import feign.FeignException; import lombok.AllArgsConstructor; @@ -57,8 +57,7 @@ public class PigxFeignFallback implements MethodInterceptor { String str = StrUtil.str(content, StandardCharsets.UTF_8); log.error("PigxFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, str); - return R.builder().code(CommonConstants.FAIL) - .msg(str).build(); + return JSONUtil.toBean(str, R.class); } @Override diff --git a/pigx-common/pigx-common-swagger/pom.xml b/pigx-common/pigx-common-swagger/pom.xml index de0de37df..6bc15b33d 100644 --- a/pigx-common/pigx-common-swagger/pom.xml +++ b/pigx-common/pigx-common-swagger/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-swagger diff --git a/pigx-common/pigx-common-transaction/pom.xml b/pigx-common/pigx-common-transaction/pom.xml index 7a4a68163..e32c6d6a7 100644 --- a/pigx-common/pigx-common-transaction/pom.xml +++ b/pigx-common/pigx-common-transaction/pom.xml @@ -5,7 +5,7 @@ com.pig4cloud pigx-common - 2.7.0 + 2.8.0 pigx-common-transaction diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml index d4cc03e9d..5d238a181 100644 --- a/pigx-common/pom.xml +++ b/pigx-common/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-common diff --git a/pigx-config/pom.xml b/pigx-config/pom.xml index 13c3036be..d7481420d 100644 --- a/pigx-config/pom.xml +++ b/pigx-config/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-config diff --git a/pigx-eureka/pom.xml b/pigx-eureka/pom.xml index 48b061c65..205b64354 100644 --- a/pigx-eureka/pom.xml +++ b/pigx-eureka/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-eureka diff --git a/pigx-gateway/pom.xml b/pigx-gateway/pom.xml index cf82cd02e..75e7d739e 100644 --- a/pigx-gateway/pom.xml +++ b/pigx-gateway/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-gateway diff --git a/pigx-upms/pigx-upms-api/pom.xml b/pigx-upms/pigx-upms-api/pom.xml index 164585399..cf377bc86 100644 --- a/pigx-upms/pigx-upms-api/pom.xml +++ b/pigx-upms/pigx-upms-api/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-upms - 2.7.0 + 2.8.0 pigx-upms-api diff --git a/pigx-upms/pigx-upms-biz/pom.xml b/pigx-upms/pigx-upms-biz/pom.xml index e24090894..82ba9cc74 100644 --- a/pigx-upms/pigx-upms-biz/pom.xml +++ b/pigx-upms/pigx-upms-biz/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-upms - 2.7.0 + 2.8.0 pigx-upms-biz diff --git a/pigx-upms/pom.xml b/pigx-upms/pom.xml index ab20d7607..27545bc74 100644 --- a/pigx-upms/pom.xml +++ b/pigx-upms/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-upms diff --git a/pigx-visual/pigx-activiti/pom.xml b/pigx-visual/pigx-activiti/pom.xml index 45542b234..235acb84f 100644 --- a/pigx-visual/pigx-activiti/pom.xml +++ b/pigx-visual/pigx-activiti/pom.xml @@ -23,7 +23,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 pigx-activiti diff --git a/pigx-visual/pigx-codegen/pom.xml b/pigx-visual/pigx-codegen/pom.xml index a0bcf4fea..1805d57a7 100755 --- a/pigx-visual/pigx-codegen/pom.xml +++ b/pigx-visual/pigx-codegen/pom.xml @@ -6,7 +6,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 pigx-codegen diff --git a/pigx-visual/pigx-daemon-elastic-job/pom.xml b/pigx-visual/pigx-daemon-elastic-job/pom.xml index d1111705c..47a291a04 100644 --- a/pigx-visual/pigx-daemon-elastic-job/pom.xml +++ b/pigx-visual/pigx-daemon-elastic-job/pom.xml @@ -23,7 +23,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 pigx-daemon-elastic-job diff --git a/pigx-visual/pigx-daemon-quartz/pom.xml b/pigx-visual/pigx-daemon-quartz/pom.xml index 36fcd37f5..0f6b1860f 100644 --- a/pigx-visual/pigx-daemon-quartz/pom.xml +++ b/pigx-visual/pigx-daemon-quartz/pom.xml @@ -5,7 +5,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 4.0.0 diff --git a/pigx-visual/pigx-monitor/pom.xml b/pigx-visual/pigx-monitor/pom.xml index dd41f551d..bf2432ce0 100644 --- a/pigx-visual/pigx-monitor/pom.xml +++ b/pigx-visual/pigx-monitor/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 pigx-monitor @@ -36,7 +36,7 @@ com.pig4cloud pigx-common-core - 2.7.0 + 2.8.0 org.springframework.boot diff --git a/pigx-visual/pigx-mp-manager/pom.xml b/pigx-visual/pigx-mp-manager/pom.xml index cb9b513c3..60be05627 100755 --- a/pigx-visual/pigx-mp-manager/pom.xml +++ b/pigx-visual/pigx-mp-manager/pom.xml @@ -6,7 +6,7 @@ com.pig4cloud pigx-visual - 2.6.0 + 2.8.0 pigx-mp-manager diff --git a/pigx-visual/pigx-sso-client-demo/pom.xml b/pigx-visual/pigx-sso-client-demo/pom.xml index 4df1a5d21..6fc917786 100644 --- a/pigx-visual/pigx-sso-client-demo/pom.xml +++ b/pigx-visual/pigx-sso-client-demo/pom.xml @@ -29,7 +29,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 diff --git a/pigx-visual/pigx-tx-manager/pom.xml b/pigx-visual/pigx-tx-manager/pom.xml index fe695de20..f94cdc2de 100644 --- a/pigx-visual/pigx-tx-manager/pom.xml +++ b/pigx-visual/pigx-tx-manager/pom.xml @@ -5,7 +5,7 @@ com.pig4cloud pigx-visual - 2.7.0 + 2.8.0 pigx-tx-manager diff --git a/pigx-visual/pigx-zipkin/pom.xml b/pigx-visual/pigx-zipkin/pom.xml index 9aab28503..a70d40d5a 100644 --- a/pigx-visual/pigx-zipkin/pom.xml +++ b/pigx-visual/pigx-zipkin/pom.xml @@ -22,7 +22,7 @@ pigx-visual com.pig4cloud - 2.7.0 + 2.8.0 4.0.0 diff --git a/pigx-visual/pom.xml b/pigx-visual/pom.xml index 98763b39b..d6b1bbc4a 100644 --- a/pigx-visual/pom.xml +++ b/pigx-visual/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 pigx-visual diff --git a/pom.xml b/pom.xml index 6a61426be..8fbf48b0a 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ com.pig4cloud pigx - 2.7.0 + 2.8.0 ${project.artifactId} pom From 4e64acf8a2ffe154cef3b0275fe68dc0c42fc27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sat, 6 Apr 2019 01:19:56 +0800 Subject: [PATCH 11/12] =?UTF-8?q?:arrow=5Fup:=20Upgrading=20dependencies.?= =?UTF-8?q?=20spring=20boot=202.1.4=20:sparkles:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E7=89=B9=E6=80=A7=E3=80=82=20=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=95=B0=E6=8D=AE=E7=BB=9F=E8=AE=A1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pigx-common/pigx-common-bom/pom.xml | 2 +- .../mp/controller/WxAccountController.java | 11 +++ .../pigx/mp/service/WxAccountService.java | 9 +++ .../mp/service/impl/WxAccountServiceImpl.java | 67 +++++++++++++++++++ pom.xml | 8 +-- 5 files changed, 92 insertions(+), 5 deletions(-) diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index 872624c8c..76a64821e 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -18,7 +18,7 @@ 2.8.0 3.1.0 - 8.0.13 + 8.0.15 1.5.22 3.3.0 diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java index e7fb20a8a..e6806732e 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountController.java @@ -133,4 +133,15 @@ public class WxAccountController { return new R<>(wxAccountService.list()); } + /** + * 获取公众号接口数据 + * + * @param appId 公众号 + * @param interval 时间间隔 + * @return + */ + @GetMapping("/statistics") + public R statistics(String appId, String interval) { + return wxAccountService.statistics(appId, interval); + } } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java index 926091d84..ab59a9601 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountService.java @@ -35,4 +35,13 @@ public interface WxAccountService extends IService { * @return */ R generateQr(String appId); + + /** + * 获取公众号统计数据 + * + * @param appId + * @param interval + * @return + */ + R statistics(String appId, String interval); } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java index d5cbe95e3..1f9b6bbb6 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountServiceImpl.java @@ -16,6 +16,7 @@ */ package com.pig4cloud.pigx.mp.service.impl; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.pig4cloud.pigx.common.core.constant.CommonConstants; @@ -26,10 +27,20 @@ import com.pig4cloud.pigx.mp.mapper.WxAccountMapper; import com.pig4cloud.pigx.mp.service.WxAccountService; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpDataCubeService; import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.datacube.WxDataCubeArticleResult; +import me.chanjar.weixin.mp.bean.datacube.WxDataCubeInterfaceResult; +import me.chanjar.weixin.mp.bean.datacube.WxDataCubeMsgResult; +import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + /** * 公众号账户 * @@ -66,4 +77,60 @@ public class WxAccountServiceImpl extends ServiceImpl> result = new ArrayList<>(); + try { + // 获取累计用户数据 + List cumulateList = cubeService.getUserCumulate(start, end).stream() + .map(WxDataCubeUserCumulate::getCumulateUser) + .collect(Collectors.toList()); + result.add(cumulateList); + + // 获取用户分享数据 + List shareList = cubeService.getUserShare(start, end).stream() + .map(WxDataCubeArticleResult::getShareCount) + .collect(Collectors.toList()); + result.add(shareList); + + // 获取消息发送概况数据 + List upstreamList = cubeService.getUpstreamMsg(start, end).stream() + .map(WxDataCubeMsgResult::getMsgCount) + .collect(Collectors.toList()); + result.add(upstreamList); + + // 获取接口调用概况数据 + List interfaceSummaryList = cubeService.getInterfaceSummary(start, end); + List interfaceList = interfaceSummaryList.stream() + .map(WxDataCubeInterfaceResult::getCallbackCount) + .collect(Collectors.toList()); + result.add(interfaceList); + + // 接口日期保存 + List dateList = interfaceSummaryList.stream() + .map(WxDataCubeInterfaceResult::getRefDate) + .collect(Collectors.toList()); + result.add(dateList); + } catch (WxErrorException e) { + log.error(" 获取公众号统计数据报错", e); + return R.builder().code(CommonConstants.FAIL).msg("获取公众号数据失败:" + e.getError().getErrorMsg()).build(); + } + + return R.builder().data(result).build(); + } } diff --git a/pom.xml b/pom.xml index 8fbf48b0a..0aaa086db 100644 --- a/pom.xml +++ b/pom.xml @@ -42,14 +42,14 @@ - 2.1.3.RELEASE + 2.1.4.RELEASE Greenwich.SR1 - Cairo-SR7 + Cairo-SR8 UTF-8 1.8 1.8 2.1.3 - 4.4.5 + 4.5.3 0.0.9 2.9.2 2.10.0 @@ -57,7 +57,7 @@ 4.1.0 2.1.1 2.10.2 - 6.0.2 + 6.0.4 2.1.5 2.3.5.RELEASE 2.1.2.RELEASE From ce8aa3fc959a4bcab3dae006c52e1cc73928f967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Sat, 6 Apr 2019 14:23:01 +0800 Subject: [PATCH 12/12] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82=E8=8F=9C=E5=8D=95=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E7=8A=B6=E6=80=81=EF=BC=8C=E9=99=90=E5=88=B6?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pig4cloud/pigx/mp/entity/WxMpMenu.java | 5 +++++ .../mp/service/impl/WxMenuServiceImpl.java | 21 +++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java index 895bfe833..97fbd79fc 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/entity/WxMpMenu.java @@ -77,4 +77,9 @@ public class WxMpMenu extends Model { @TableLogic private String delFlag; + /** + * 是否发布 0 未发布 1 已发布 + */ + private String pubFlag; + } diff --git a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java index 272f17966..b78b8e8ef 100755 --- a/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java +++ b/pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxMenuServiceImpl.java @@ -48,7 +48,7 @@ import java.util.List; @Service @AllArgsConstructor public class WxMenuServiceImpl extends ServiceImpl implements WxMenuService { - private static final String MENU = "menu"; + private static final String PUB_ED = "1"; private final WxAccountMapper wxAccountMapper; /** @@ -90,22 +90,31 @@ public class WxMenuServiceImpl extends ServiceImpl imple if (CollUtil.isEmpty(wxMpMenuList)) { return R.builder() .code(CommonConstants.FAIL) - .msg("微信菜单配置为空,不能发布").build(); + .msg("微信菜单配置未保存,不能发布").build(); + } + WxMpMenu wxMpMenu = wxMpMenuList.get(0); + // 判断是否发布 + if (PUB_ED.equals(wxMpMenu.getPubFlag())) { + return R.builder() + .code(CommonConstants.FAIL) + .msg("微信菜单配置已发布,不要重复发布").build(); } - WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId); WxMpMenuService menuService = wxMpService.getMenuService(); // 给数据库保存的加一层 - JSONObject jsonObject = new JSONObject(wxMpMenuList.get(0).getMenu()); - jsonObject.put(MENU, jsonObject); try { - menuService.menuCreate(jsonObject.toStringPretty()); + menuService.menuCreate(wxMpMenu.getMenu()); } catch (WxErrorException e) { + log.error("发布微信菜单失败", e.getError().getErrorMsg()); return R.builder() .code(CommonConstants.FAIL) .msg(e.getError().getErrorMsg()).build(); } + + //更新菜单发布标志 + wxMpMenu.setPubFlag(PUB_ED); + baseMapper.updateById(wxMpMenu); return R.builder().build(); }