mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
Merge branch 'wx' into leng_dev
This commit is contained in:
commit
2cf5293eb8
113 files changed
+4046
-181
No files matched your search
+31
-31
@@ -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;
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# 使用说明 V2.7.0
|
||||
# 使用说明 V2.8.0
|
||||
# 1. 使用docker-compose 宿主机不需要配置host来发现
|
||||
# 2. 无需修改源码,根目录 docker-compose up 即可
|
||||
# 3. 静静等待服务启动
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-auth</artifactId>
|
||||
|
||||
@@ -111,6 +111,9 @@ public class PigxTokenEndpoint {
|
||||
@Inner
|
||||
@DeleteMapping("/{token}")
|
||||
public R<Boolean> delToken(@PathVariable("token") String token) {
|
||||
if (token != null) {
|
||||
throw new RuntimeException("lalalala");
|
||||
}
|
||||
OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
|
||||
tokenStore.removeAccessToken(oAuth2AccessToken);
|
||||
return new R<>();
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
<description>pigx 公共版本控制</description>
|
||||
|
||||
<properties>
|
||||
<pigx.version>2.7.0</pigx.version>
|
||||
<pigx.version>2.8.0</pigx.version>
|
||||
<mybatis-plus.version>3.1.0</mybatis-plus.version>
|
||||
<mysql.connector.version>8.0.13</mysql.connector.version>
|
||||
<mysql.connector.version>8.0.15</mysql.connector.version>
|
||||
<swagger.core.version>1.5.22</swagger.core.version>
|
||||
<mp.weixin.version>3.3.0</mp.weixin.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -104,6 +105,17 @@
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>${swagger.core.version}</version>
|
||||
</dependency>
|
||||
<!--微信依赖-->
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
<version>${mp.weixin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-common</artifactId>
|
||||
<version>${mp.weixin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
|
||||
+4
@@ -155,4 +155,8 @@ public interface SecurityConstants {
|
||||
*/
|
||||
String DETAILS_LICENSE = "license";
|
||||
|
||||
/**
|
||||
* AES 加密
|
||||
*/
|
||||
String AES = "aes";
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
|
||||
+11
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-job</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-minio</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
|
||||
+2
-3
@@ -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<T> 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
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-transaction</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-config</artifactId>
|
||||
|
||||
@@ -12,6 +12,12 @@ 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/
|
||||
|
||||
pigx:
|
||||
tenant:
|
||||
column: tenant_id
|
||||
tables:
|
||||
- sys_datasource_conf
|
||||
@@ -0,0 +1,33 @@
|
||||
## 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
|
||||
hikari:
|
||||
connection-init-sql: SET NAMES utf8mb4
|
||||
resources:
|
||||
static-locations: classpath:/static/,classpath:/views/
|
||||
|
||||
|
||||
# 租户表维护
|
||||
pigx:
|
||||
tenant:
|
||||
column: tenant_id
|
||||
tables:
|
||||
- t_wx_account
|
||||
- t_wx_account_fans
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-eureka</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-gateway</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms-api</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms-biz</artifactId>
|
||||
|
||||
-10
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
|
||||
-8
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 部门管理 Mapper 接口
|
||||
@@ -34,10 +32,4 @@ import java.util.List;
|
||||
*/
|
||||
public interface SysDeptMapper extends BaseMapper<SysDept> {
|
||||
|
||||
/**
|
||||
* 关联dept——relation
|
||||
*
|
||||
* @return 数据列表
|
||||
*/
|
||||
List<SysDept> listDepts();
|
||||
}
|
||||
-7
@@ -42,13 +42,6 @@ public interface SysDeptService extends IService<SysDept> {
|
||||
*/
|
||||
List<DeptTree> selectTree();
|
||||
|
||||
/**
|
||||
* 查询用户部门树
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DeptTree> getUserTree();
|
||||
|
||||
/**
|
||||
* 添加信息部门
|
||||
*
|
||||
|
||||
+13
-31
@@ -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<SysDeptMapper, SysDept> impl
|
||||
public Boolean removeDeptById(Integer id) {
|
||||
//级联删除部门
|
||||
List<Integer> idList = sysDeptRelationService
|
||||
.list(Wrappers.<SysDeptRelation>query().lambda()
|
||||
.eq(SysDeptRelation::getAncestor, id))
|
||||
.stream()
|
||||
.map(SysDeptRelation::getDescendant)
|
||||
.collect(Collectors.toList());
|
||||
.list(Wrappers.<SysDeptRelation>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<SysDeptMapper, SysDept> impl
|
||||
return getDeptTree(this.list(Wrappers.emptyWrapper()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户部门树
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<DeptTree> getUserTree() {
|
||||
Integer deptId = SecurityUtils.getUser().getDeptId();
|
||||
List<Integer> descendantIdList = sysDeptRelationService
|
||||
.list(Wrappers.<SysDeptRelation>query().lambda()
|
||||
.eq(SysDeptRelation::getAncestor, deptId))
|
||||
.stream().map(SysDeptRelation::getDescendant)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<SysDept> deptList = baseMapper.selectBatchIds(descendantIdList);
|
||||
return getDeptTree(deptList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建部门树
|
||||
@@ -149,14 +131,14 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> impl
|
||||
*/
|
||||
private List<DeptTree> getDeptTree(List<SysDept> depts) {
|
||||
List<DeptTree> 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);
|
||||
}
|
||||
}
|
||||
@@ -21,28 +21,4 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.pig4cloud.pigx.admin.mapper.SysDeptMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.pig4cloud.pigx.admin.api.entity.SysDept">
|
||||
<id column="dept_id" property="deptId"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="sort" property="sort"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
<result column="del_flag" property="delFlag"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
dept_id AS deptId, parent_id AS parentId, name, sort, create_time AS createTime, update_time AS updateTime, del_flag AS delFlag
|
||||
</sql>
|
||||
|
||||
<!--关联查询部门列表-->
|
||||
<select id="listDepts" resultType="com.pig4cloud.pigx.admin.api.entity.SysDept">
|
||||
SELECT
|
||||
t.*
|
||||
FROM
|
||||
sys_dept t
|
||||
LEFT JOIN sys_dept_relation dr ON t.dept_id = dr.descendant
|
||||
WHERE dr.ancestor = 0
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-activiti</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-codegen</artifactId>
|
||||
@@ -49,6 +49,10 @@
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
</dependency>
|
||||
<!--代码生成模板引擎-->
|
||||
<dependency>
|
||||
<artifactId>velocity</artifactId>
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+25
@@ -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
|
||||
* <p>
|
||||
* 动态数据源类
|
||||
*/
|
||||
@Slf4j
|
||||
public class DynamicDataSource extends AbstractRoutingDataSource {
|
||||
|
||||
/**
|
||||
* 指定路由Key
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey() {
|
||||
return DynamicDataSourceContextHolder.getDataSourceType();
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
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;
|
||||
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
|
||||
* <p>
|
||||
* 动态数据源切换配置
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
public class DynamicDataSourceConfig implements TransactionManagementConfigurer {
|
||||
private final Map<Object, Object> dataSourceMap = new HashMap<>(8);
|
||||
private final DataSourceProperties dataSourceProperties;
|
||||
private final StringEncryptor stringEncryptor;
|
||||
|
||||
@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());
|
||||
|
||||
List<Map<String, Object>> dbList = new JdbcTemplate(dds).queryForList(DataSourceConstant.QUERY_DS_SQL);
|
||||
log.info("开始 -> 初始化动态数据源");
|
||||
Optional.of(dbList).ifPresent(list -> list.forEach(db -> {
|
||||
log.info("数据源:{}", db.get(DataSourceConstant.DS_NAME));
|
||||
HikariDataSource ds = new HikariDataSource();
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载数据源配置
|
||||
*/
|
||||
public Boolean reload() {
|
||||
init();
|
||||
DynamicDataSource dataSource = dataSource();
|
||||
dataSource.setTargetDataSources(dataSourceMap);
|
||||
dataSource.afterPropertiesSet();
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager txManager() {
|
||||
return new DataSourceTransactionManager(dataSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformTransactionManager annotationDrivenTransactionManager() {
|
||||
return txManager();
|
||||
}
|
||||
|
||||
}
|
||||
+111
@@ -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.codegen.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
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 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) {
|
||||
return new R<>(sysDatasourceConfService.saveDsByEnc(sysDatasourceConf));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改数据源表
|
||||
*
|
||||
* @param sysDatasourceConf 数据源表
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("修改数据源表")
|
||||
@PutMapping
|
||||
public R updateById(@RequestBody SysDatasourceConf sysDatasourceConf) {
|
||||
return new R<>(sysDatasourceConfService.updateDsByEnc(sysDatasourceConf));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除数据源表
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("删除数据源表")
|
||||
@DeleteMapping("/{id}")
|
||||
public R removeById(@PathVariable Integer id) {
|
||||
return new R<>(sysDatasourceConfService.removeById(id));
|
||||
}
|
||||
|
||||
}
|
||||
+3
-4
@@ -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));
|
||||
|
||||
+4
@@ -26,6 +26,10 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
public class GenConfig {
|
||||
/**
|
||||
* 数据源ID
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 包名
|
||||
*/
|
||||
|
||||
Executable
+79
@@ -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<SysDatasourceConf> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Integer id;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* jdbcurl
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createDate;
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
private LocalDateTime updateDate;
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private Integer tenantId;
|
||||
|
||||
}
|
||||
+30
@@ -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<SysDatasourceConf> {
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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<SysDatasourceConf> {
|
||||
/**
|
||||
* 保存数据源并且加密
|
||||
*
|
||||
* @param sysDatasourceConf
|
||||
* @return
|
||||
*/
|
||||
Boolean saveDsByEnc(SysDatasourceConf sysDatasourceConf);
|
||||
|
||||
/**
|
||||
* 更新数据源
|
||||
*
|
||||
* @param sysDatasourceConf
|
||||
* @return
|
||||
*/
|
||||
Boolean updateDsByEnc(SysDatasourceConf sysDatasourceConf);
|
||||
}
|
||||
+3
-1
@@ -39,8 +39,10 @@ public interface SysGeneratorService {
|
||||
|
||||
/**
|
||||
* 分页查询表
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param id 数据源ID
|
||||
* @return
|
||||
*/
|
||||
IPage<List<Map<String, Object>>> getPage(Page page, String tableName);
|
||||
IPage<List<Map<String, Object>>> getPage(Page page, String tableName, Integer id);
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 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;
|
||||
|
||||
/**
|
||||
* 数据源表
|
||||
*
|
||||
* @author pigx code generator
|
||||
* @date 2019-03-31 16:00:20
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysDatasourceConfServiceImpl extends ServiceImpl<SysDatasourceConfMapper, SysDatasourceConf> 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();
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -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<List<Map<String, Object>>> getPage(Page page, String tableName) {
|
||||
return sysGeneratorMapper.queryList(page,tableName);
|
||||
public IPage<List<Map<String, Object>>> 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);
|
||||
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.pig4cloud.pigx.codegen.util;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-04-01
|
||||
* <p>
|
||||
* 数据源相关常量
|
||||
*/
|
||||
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";
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.pig4cloud.pigx.codegen.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-03-31
|
||||
* <p>
|
||||
* 保存上线文中数据库路由
|
||||
*/
|
||||
@UtilityClass
|
||||
public class DynamicDataSourceContextHolder {
|
||||
private final ThreadLocal<Integer> 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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-daemon-elastic-job</artifactId>
|
||||
|
||||
+1
-1
@@ -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<ExecutionLog> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
+1
-1
@@ -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<StatusTraceLog> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-monitor</artifactId>
|
||||
@@ -36,7 +36,7 @@
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -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
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-mp-manager</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<description>微信公众号管理模块</description>
|
||||
|
||||
<dependencies>
|
||||
<!--配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-config</artifactId>
|
||||
</dependency>
|
||||
<!--数据操作-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<!--common-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
</dependency>
|
||||
<!--swagger-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<!--安全模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
</dependency>
|
||||
<!--微信依赖-->
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
Executable
+40
@@ -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);
|
||||
}
|
||||
}
|
||||
Executable
+21
@@ -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);
|
||||
}
|
||||
Executable
+24
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+149
@@ -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
|
||||
* <p>
|
||||
* 微信公众号基础配置,初始化配置
|
||||
*/
|
||||
@Configuration
|
||||
public class WxMpConfiguration {
|
||||
public static Map<String, WxMpMessageRouter> getRouters() {
|
||||
return routers;
|
||||
}
|
||||
|
||||
public static Map<String, WxMpService> 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<String, WxMpMessageRouter> routers = Maps.newHashMap();
|
||||
private static Map<String, WxMpService> 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;
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -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<String> 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();
|
||||
}
|
||||
}
|
||||
+120
@@ -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
|
||||
* <p>
|
||||
* 微信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<String, String> 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());
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R list() {
|
||||
return new R<>(wxAccountService.list());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号接口数据
|
||||
*
|
||||
* @param appId 公众号
|
||||
* @param interval 时间间隔
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/statistics")
|
||||
public R statistics(String appId, String interval) {
|
||||
return wxAccountService.statistics(appId, interval);
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步粉丝
|
||||
*
|
||||
* @param appId
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/sync/{appId}")
|
||||
public R sync(@PathVariable String appId) {
|
||||
return new R(wxAccountFansService.syncAccountFans(appId));
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+106
@@ -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 消息
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxFansMsgPage(Page page, WxFansMsg wxFansMsg) {
|
||||
return new R<>(wxFansMsgService.page(page, Wrappers.query(wxFansMsg)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询消息
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R getById(@PathVariable("id") Integer id) {
|
||||
return new R<>(wxFansMsgService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增消息
|
||||
*
|
||||
* @param wxFansMsg 消息
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("新增消息")
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsg_add')")
|
||||
public R save(@RequestBody WxFansMsg wxFansMsg) {
|
||||
return new R<>(wxFansMsgService.save(wxFansMsg));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改消息
|
||||
*
|
||||
* @param wxFansMsg 消息
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("修改消息")
|
||||
@PutMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsg_edit')")
|
||||
public R updateById(@RequestBody WxFansMsg wxFansMsg) {
|
||||
return new R<>(wxFansMsgService.updateById(wxFansMsg));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除消息
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("删除消息")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsg_del')")
|
||||
public R removeById(@PathVariable Integer id) {
|
||||
return new R<>(wxFansMsgService.removeById(id));
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -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 回复
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxFansMsgResPage(Page page, WxFansMsgRes wxFansMsgRes) {
|
||||
return new R<>(wxFansMsgResService.page(page, Wrappers.query(wxFansMsgRes)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询回复
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R getById(@PathVariable("id") Integer id) {
|
||||
return new R<>(wxFansMsgResService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增回复
|
||||
*
|
||||
* @param wxFansMsgRes 回复
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("新增回复")
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_add')")
|
||||
public R save(@RequestBody WxFansMsgRes wxFansMsgRes) {
|
||||
return wxFansMsgResService.saveAndSend(wxFansMsgRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改回复
|
||||
*
|
||||
* @param wxFansMsgRes 回复
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("修改回复")
|
||||
@PutMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_edit')")
|
||||
public R updateById(@RequestBody WxFansMsgRes wxFansMsgRes) {
|
||||
return new R<>(wxFansMsgResService.updateById(wxFansMsgRes));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除回复
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("删除回复")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_del')")
|
||||
public R removeById(@PathVariable Integer id) {
|
||||
return new R<>(wxFansMsgResService.removeById(id));
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 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.WxMpMenu;
|
||||
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 WxMpMenu lengleng
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxMpMenuPage(Page page, WxMpMenu WxMpMenu) {
|
||||
return new R<>(wxMenuService.page(page, Wrappers.query(WxMpMenu)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过appid查询微信菜单
|
||||
*
|
||||
* @param appId 公众号
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/{appId}")
|
||||
public R getById(@PathVariable("appId") String appId) {
|
||||
return wxMenuService.getByAppId(appId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增微信菜单
|
||||
*
|
||||
* @param WxMpMenus 微信菜单列表
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("新增微信菜单")
|
||||
@PostMapping("/{appId}")
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxmenu_add')")
|
||||
public R save(@RequestBody JSONObject WxMpMenus, @PathVariable String appId) {
|
||||
return new R(wxMenuService.save(WxMpMenus, appId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布微信菜单
|
||||
*
|
||||
* @param appId 公众号
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("发布微信菜单")
|
||||
@PutMapping("/{appId}")
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxmenu_push')")
|
||||
public R updateById(@PathVariable String appId) {
|
||||
return wxMenuService.push(appId);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
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;
|
||||
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
|
||||
* <p>
|
||||
* 微信接入入口
|
||||
*/
|
||||
@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) {
|
||||
|
||||
WxMpContextHolder.setAppId(appId);
|
||||
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);
|
||||
WxMpContextHolder.clear();
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/controller/WxRedirectController.java
Executable
+37
@@ -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";
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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<WxAccount> {
|
||||
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;
|
||||
|
||||
/**
|
||||
* 租户
|
||||
*/
|
||||
private Integer tenantId;
|
||||
}
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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<WxAccountFans> {
|
||||
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 Integer wxAccountId;
|
||||
/**
|
||||
* 微信公众号appid
|
||||
*/
|
||||
private String wxAccountAppid;
|
||||
|
||||
/**
|
||||
* 微信公众号名
|
||||
*/
|
||||
private String wxAccountName;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
/**
|
||||
* 是否删除 -1:已删除 0:正常
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
}
|
||||
+125
@@ -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<WxFansMsg> {
|
||||
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;
|
||||
|
||||
}
|
||||
+69
@@ -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<WxFansMsgRes> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Integer id;
|
||||
/**
|
||||
* 粉丝消息ID
|
||||
*/
|
||||
private Integer fansMsgId;
|
||||
/**
|
||||
* 回复内容
|
||||
*/
|
||||
private String resContent;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Integer userId;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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:18
|
||||
*/
|
||||
@Data
|
||||
@TableName("t_wx_menu")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class WxMpMenu extends Model<WxMpMenu> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
private String menu;
|
||||
|
||||
/**
|
||||
* 微信公众号ID
|
||||
*/
|
||||
private Integer wxAccountId;
|
||||
/**
|
||||
* 微信公众号appid
|
||||
*/
|
||||
private String wxAccountAppid;
|
||||
|
||||
/**
|
||||
* 微信公众号名
|
||||
*/
|
||||
private String wxAccountName;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 是否删除 -1:已删除 0:正常
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 是否发布 0 未发布 1 已发布
|
||||
*/
|
||||
private String pubFlag;
|
||||
|
||||
}
|
||||
Executable
+9
@@ -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 {
|
||||
}
|
||||
Executable
+24
@@ -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<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+34
@@ -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<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
//上报地理位置事件
|
||||
log.info("上报地理位置,纬度 : {},经度 : {},精度 : {}",
|
||||
wxMessage.getLatitude(), wxMessage.getLongitude(), wxMessage.getPrecision());
|
||||
|
||||
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用
|
||||
|
||||
String content = "感谢反馈,您的的地理位置已收到!";
|
||||
return new TextBuilder().build(content, wxMessage, null);
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +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 lengleng
|
||||
* <p>
|
||||
* 保存微信消息
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class LogHandler extends AbstractHandler {
|
||||
private final WxFansMsgService wxFansMsgService;
|
||||
private final WxAccountService wxAccountService;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
log.debug("接收到请求消息,内容:{}", wxMessage.getContent());
|
||||
|
||||
WxAccount wxAccount = wxAccountService.getOne(Wrappers.<WxAccount>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;
|
||||
}
|
||||
}
|
||||
+36
@@ -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<String, Object> 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();
|
||||
}
|
||||
|
||||
}
|
||||
+49
@@ -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<String, Object> 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -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<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -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<String, Object> map,
|
||||
WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException {
|
||||
// 扫码事件处理
|
||||
return null;
|
||||
}
|
||||
}
|
||||
pigx-visual/pigx-mp-manager/src/main/java/com/pig4cloud/pigx/mp/handler/StoreCheckNotifyHandler.java
Executable
+27
@@ -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<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
// TODO 处理门店审核事件
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+72
@@ -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<String, Object> 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;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+29
@@ -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<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
String openId = wxMessage.getFromUser();
|
||||
log.info("取消关注用户 OPENID: " + openId);
|
||||
// TODO 可以更新本地数据库为取消关注状态
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+30
@@ -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<WxAccountFans> {
|
||||
|
||||
}
|
||||
Executable
+30
@@ -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<WxAccount> {
|
||||
|
||||
}
|
||||
Executable
+30
@@ -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<WxFansMsg> {
|
||||
|
||||
}
|
||||
Executable
+30
@@ -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<WxFansMsgRes> {
|
||||
|
||||
}
|
||||
+30
@@ -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.WxMpMenu;
|
||||
|
||||
/**
|
||||
* lengleng
|
||||
*
|
||||
* @author pigx code generator
|
||||
* @date 2019-03-27 20:45:18
|
||||
*/
|
||||
public interface WxMenuMapper extends BaseMapper<WxMpMenu> {
|
||||
|
||||
}
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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<WxAccountFans> {
|
||||
|
||||
/**
|
||||
* 同步指定公众号粉丝
|
||||
*
|
||||
* @param appId
|
||||
* @return
|
||||
*/
|
||||
Boolean syncAccountFans(String appId);
|
||||
}
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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<WxAccount> {
|
||||
|
||||
/**
|
||||
* 生成公众号二维码
|
||||
*
|
||||
* @param appId
|
||||
* @return
|
||||
*/
|
||||
R generateQr(String appId);
|
||||
|
||||
/**
|
||||
* 获取公众号统计数据
|
||||
*
|
||||
* @param appId
|
||||
* @param interval
|
||||
* @return
|
||||
*/
|
||||
R statistics(String appId, String interval);
|
||||
}
|
||||
Executable
+38
@@ -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.WxFansMsgRes;
|
||||
|
||||
/**
|
||||
* 微信消息回复业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:48
|
||||
*/
|
||||
public interface WxFansMsgResService extends IService<WxFansMsgRes> {
|
||||
|
||||
/**
|
||||
* 保存并发送回复
|
||||
*
|
||||
* @param wxFansMsgRes
|
||||
* @return
|
||||
*/
|
||||
R saveAndSend(WxFansMsgRes wxFansMsgRes);
|
||||
}
|
||||
Executable
+30
@@ -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<WxFansMsg> {
|
||||
|
||||
}
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMpMenu;
|
||||
|
||||
/**
|
||||
* 微信菜单业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:18
|
||||
*/
|
||||
public interface WxMenuService extends IService<WxMpMenu> {
|
||||
|
||||
/**
|
||||
* 新增微信公众号按钮
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 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
|
||||
* <p>
|
||||
* 微信公众号粉丝
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class WxAccountFansServiceImpl extends ServiceImpl<WxAccountFansMapper, WxAccountFans> 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.<WxAccount>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<WxAccountFans> wxAccountFansList = new ArrayList<>();
|
||||
try {
|
||||
wxMpUserService.userInfoList(openIdList).forEach(wxMpUser -> {
|
||||
WxAccountFans wxAccountFans = baseMapper
|
||||
.selectOne(Wrappers.<WxAccountFans>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(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("批量同步微信用户信息完成");
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 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;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* 公众号账户
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-26 22:07:53
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class WxAccountServiceImpl extends ServiceImpl<WxAccountMapper, WxAccount> 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.<WxAccount>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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号统计数据
|
||||
*
|
||||
* @param appId 公众号信息
|
||||
* @param interval 时间间隔
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R statistics(String appId, String interval) {
|
||||
String[] split = interval.split(StrUtil.DASHED);
|
||||
Date start = new Date(Long.parseLong(split[0]));
|
||||
Date end = new Date(Long.parseLong(split[1]));
|
||||
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpDataCubeService cubeService = wxMpService.getDataCubeService();
|
||||
|
||||
List<List<Object>> result = new ArrayList<>();
|
||||
try {
|
||||
// 获取累计用户数据
|
||||
List<Object> cumulateList = cubeService.getUserCumulate(start, end).stream()
|
||||
.map(WxDataCubeUserCumulate::getCumulateUser)
|
||||
.collect(Collectors.toList());
|
||||
result.add(cumulateList);
|
||||
|
||||
// 获取用户分享数据
|
||||
List<Object> shareList = cubeService.getUserShare(start, end).stream()
|
||||
.map(WxDataCubeArticleResult::getShareCount)
|
||||
.collect(Collectors.toList());
|
||||
result.add(shareList);
|
||||
|
||||
// 获取消息发送概况数据
|
||||
List<Object> upstreamList = cubeService.getUpstreamMsg(start, end).stream()
|
||||
.map(WxDataCubeMsgResult::getMsgCount)
|
||||
.collect(Collectors.toList());
|
||||
result.add(upstreamList);
|
||||
|
||||
// 获取接口调用概况数据
|
||||
List<WxDataCubeInterfaceResult> interfaceSummaryList = cubeService.getInterfaceSummary(start, end);
|
||||
List<Object> interfaceList = interfaceSummaryList.stream()
|
||||
.map(WxDataCubeInterfaceResult::getCallbackCount)
|
||||
.collect(Collectors.toList());
|
||||
result.add(interfaceList);
|
||||
|
||||
// 接口日期保存
|
||||
List<Object> 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();
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.service.PigxUser;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpConfiguration;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsgRes;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxFansMsgMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxFansMsgResMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxFansMsgResService;
|
||||
import lombok.AllArgsConstructor;
|
||||
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.kefu.WxMpKefuMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 微信消息回复业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:48
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class WxFansMsgResServiceImpl extends ServiceImpl<WxFansMsgResMapper, WxFansMsgRes> implements WxFansMsgResService {
|
||||
private final WxFansMsgMapper wxFansMsgMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 保存并发送回复
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user