commit f1119a54a2580f4b0e7a075bd9f808308e76afdb
Author: zhangsan <646228430@qq.com>
Date: Thu Jul 10 18:30:39 2025 +0800
7.10 DDD工程初始化+微信公众号鉴权
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..613ee2d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,40 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
+/data/
+/.idea/
diff --git a/docs/dev-ops/app/start.sh b/docs/dev-ops/app/start.sh
new file mode 100644
index 0000000..368087e
--- /dev/null
+++ b/docs/dev-ops/app/start.sh
@@ -0,0 +1,20 @@
+CONTAINER_NAME=pay-mall
+IMAGE_NAME=system/pay-mall:1.0-SNAPSHOT
+PORT=8091
+
+echo "容器部署开始 ${CONTAINER_NAME}"
+
+# 停止容器
+docker stop ${CONTAINER_NAME}
+
+# 删除容器
+docker rm ${CONTAINER_NAME}
+
+# 启动容器
+docker run --name ${CONTAINER_NAME} \
+-p ${PORT}:${PORT} \
+-d ${IMAGE_NAME}
+
+echo "容器部署成功 ${CONTAINER_NAME}"
+
+docker logs -f ${CONTAINER_NAME}
\ No newline at end of file
diff --git a/docs/dev-ops/app/stop.sh b/docs/dev-ops/app/stop.sh
new file mode 100644
index 0000000..67c51b4
--- /dev/null
+++ b/docs/dev-ops/app/stop.sh
@@ -0,0 +1 @@
+docker stop pay-mall
\ No newline at end of file
diff --git a/docs/dev-ops/docker-compose-app.yml b/docs/dev-ops/docker-compose-app.yml
new file mode 100644
index 0000000..a0f9f05
--- /dev/null
+++ b/docs/dev-ops/docker-compose-app.yml
@@ -0,0 +1,27 @@
+# /usr/local/bin/docker-compose -f /docs/dev-ops/environment/environment-docker-compose-2.4.yml up -d
+version: '3.8'
+# docker-compose -f docker-compose-app.yml up -d
+# 你需要修改system为你自身系统的仓库名
+services:
+ pay-mall:
+ image: system/pay-mall:1.0-SNAPSHOT
+ container_name: pay-mall
+ restart: on-failure
+ ports:
+ - "8092:8092"
+ environment:
+ - TZ=PRC
+ - SERVER_PORT=8091
+ volumes:
+ - ./log:/data/log
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "10m"
+ max-file: "3"
+ networks:
+ - my-network
+
+networks:
+ my-network:
+ driver: bridge
diff --git a/docs/dev-ops/docker-compose-environment-aliyun.yml b/docs/dev-ops/docker-compose-environment-aliyun.yml
new file mode 100644
index 0000000..87bdbe0
--- /dev/null
+++ b/docs/dev-ops/docker-compose-environment-aliyun.yml
@@ -0,0 +1,87 @@
+# 命令执行 docker-compose -f docker-compose-environment-aliyun.yml up -d
+# docker 代理和使用文档;https://bugstack.cn/md/road-map/docker.html
+version: '3.9'
+services:
+ mysql:
+ image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.0.32
+ container_name: mysql
+ command: --default-authentication-plugin=mysql_native_password
+ restart: always
+ environment:
+ TZ: Asia/Shanghai
+ MYSQL_ROOT_PASSWORD: 123456
+ ports:
+ - "13306:3306"
+ volumes:
+ - ./mysql/sql:/docker-entrypoint-initdb.d
+ healthcheck:
+ test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
+ interval: 5s
+ timeout: 10s
+ retries: 10
+ start_period: 15s
+ networks:
+ - my-network
+
+ # phpmyadmin https://hub.docker.com/_/phpmyadmin
+ phpmyadmin:
+ image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/phpmyadmin:5.2.1
+ container_name: phpmyadmin
+ hostname: phpmyadmin
+ ports:
+ - 8899:80
+ environment:
+ - PMA_HOST=mysql
+ - PMA_PORT=3306
+ - MYSQL_ROOT_PASSWORD=123qwe!@#QWE
+ depends_on:
+ mysql:
+ condition: service_healthy
+ networks:
+ - my-network
+
+ # Redis
+ redis:
+ image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2
+ container_name: redis
+ restart: always
+ hostname: redis
+ privileged: true
+ ports:
+ - 16379:6379
+ volumes:
+ - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
+ command: redis-server /usr/local/etc/redis/redis.conf
+ networks:
+ - my-network
+ healthcheck:
+ test: [ "CMD", "redis-cli", "ping" ]
+ interval: 10s
+ timeout: 5s
+ retries: 3
+
+ # RedisAdmin https://github.com/joeferner/redis-commander
+ # 账密 admin/admin
+ redis-admin:
+ image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis-commander:0.8.0
+ container_name: redis-admin
+ hostname: redis-commander
+ restart: always
+ ports:
+ - 8081:8081
+ environment:
+ - REDIS_HOSTS=local:redis:6379
+ - HTTP_USER=admin
+ - HTTP_PASSWORD=admin
+ - LANG=C.UTF-8
+ - LANGUAGE=C.UTF-8
+ - LC_ALL=C.UTF-8
+ networks:
+ - my-network
+ depends_on:
+ redis:
+ condition: service_healthy
+
+networks:
+ my-network:
+ driver: bridge
\ No newline at end of file
diff --git a/docs/dev-ops/docker-compose-environment.yml b/docs/dev-ops/docker-compose-environment.yml
new file mode 100644
index 0000000..2a270b8
--- /dev/null
+++ b/docs/dev-ops/docker-compose-environment.yml
@@ -0,0 +1,86 @@
+# 命令执行 docker-compose -f docker-compose-environment-aliyun.yml up -d
+# docker 代理和使用文档;https://bugstack.cn/md/road-map/docker.html
+version: '3.9'
+services:
+ mysql:
+ image: mysql:8.0.32
+ container_name: mysql
+ command: --default-authentication-plugin=mysql_native_password
+ restart: always
+ environment:
+ TZ: Asia/Shanghai
+ MYSQL_ROOT_PASSWORD: 123456
+ ports:
+ - "13306:3306"
+ volumes:
+ - ./mysql/sql:/docker-entrypoint-initdb.d
+ healthcheck:
+ test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
+ interval: 5s
+ timeout: 10s
+ retries: 10
+ start_period: 15s
+ networks:
+ - my-network
+
+ # phpmyadmin https://hub.docker.com/_/phpmyadmin
+ phpmyadmin:
+ image: phpmyadmin:5.2.1
+ container_name: phpmyadmin
+ hostname: phpmyadmin
+ ports:
+ - 8899:80
+ environment:
+ - PMA_HOST=mysql
+ - PMA_PORT=3306
+ - MYSQL_ROOT_PASSWORD=123456
+ depends_on:
+ mysql:
+ condition: service_healthy
+ networks:
+ - my-network
+
+ # Redis
+ redis:
+ image: redis:6.2
+ container_name: redis
+ restart: always
+ hostname: redis
+ privileged: true
+ ports:
+ - 16379:6379
+ volumes:
+ - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
+ command: redis-server /usr/local/etc/redis/redis.conf
+ networks:
+ - my-network
+ healthcheck:
+ test: [ "CMD", "redis-cli", "ping" ]
+ interval: 10s
+ timeout: 5s
+ retries: 3
+
+ # RedisAdmin https://github.com/joeferner/redis-commander
+ redis-admin:
+ image: spryker/redis-commander:0.8.0
+ container_name: redis-admin
+ hostname: redis-commander
+ restart: always
+ ports:
+ - 8081:8081
+ environment:
+ - REDIS_HOSTS=local:redis:6379
+ - HTTP_USER=admin
+ - HTTP_PASSWORD=admin
+ - LANG=C.UTF-8
+ - LANGUAGE=C.UTF-8
+ - LC_ALL=C.UTF-8
+ networks:
+ - my-network
+ depends_on:
+ redis:
+ condition: service_healthy
+
+networks:
+ my-network:
+ driver: bridge
\ No newline at end of file
diff --git a/docs/dev-ops/mysql/sql/xfg-frame-archetype.sql b/docs/dev-ops/mysql/sql/xfg-frame-archetype.sql
new file mode 100644
index 0000000..8b598d3
--- /dev/null
+++ b/docs/dev-ops/mysql/sql/xfg-frame-archetype.sql
@@ -0,0 +1,108 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server : 127.0.0.1
+ Source Server Type : MySQL
+ Source Server Version : 50639
+ Source Host : localhost:3306
+ Source Schema : road-map
+
+ Target Server Type : MySQL
+ Target Server Version : 50639
+ File Encoding : 65001
+
+ Date: 15/07/2023 09:26:39
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+CREATE database if NOT EXISTS `xfg_frame_archetype` default character set utf8mb4 collate utf8mb4_0900_ai_ci;
+use `xfg_frame_archetype`;
+
+-- ----------------------------
+-- Table structure for employee
+-- ----------------------------
+DROP TABLE IF EXISTS `employee`;
+CREATE TABLE `employee` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `employee_number` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员ID',
+ `employee_name` varchar(32) NOT NULL DEFAULT '' COMMENT '雇员姓名',
+ `employee_level` varchar(8) NOT NULL DEFAULT '' COMMENT '雇员级别',
+ `employee_title` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员岗位Title',
+ `create_time` datetime NOT NULL COMMENT '创建时间',
+ `update_time` datetime NOT NULL COMMENT '更新时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `idx_employee_number` (`employee_number`)
+) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Records of employee
+-- ----------------------------
+BEGIN;
+INSERT INTO `employee` VALUES (1, '10000001', 'sXvfDpsWnJdLsCVk64tJgw==', 'T-3', '中级工程师', '2023-07-14 15:26:26', '2023-07-14 15:26:26');
+INSERT INTO `employee` VALUES (2, '10000010', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
+INSERT INTO `employee` VALUES (3, '10000011', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
+INSERT INTO `employee` VALUES (4, '10000012', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
+INSERT INTO `employee` VALUES (5, '10000013', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
+INSERT INTO `employee` VALUES (6, '10000014', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
+INSERT INTO `employee` VALUES (9, '10000002', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-15 07:42:52', '2023-07-15 07:42:52');
+INSERT INTO `employee` VALUES (22, '10000015', 'hMCgLG6WV3CsNBQ1UD6PEQ==', 'T2', '见习工程师', '2023-07-15 08:02:31', '2023-07-15 08:02:31');
+INSERT INTO `employee` VALUES (23, '10000016', 'hMCgLG6WV3CsNBQ1UD6PEQ==', 'T2', '见习工程师', '2023-07-15 08:02:31', '2023-07-15 08:02:31');
+INSERT INTO `employee` VALUES (24, '10000017', 'hMCgLG6WV3CsNBQ1UD6PEQ==', 'T2', '见习工程师', '2023-07-15 08:02:31', '2023-07-15 08:02:31');
+INSERT INTO `employee` VALUES (39, '10000022', 'GyG+V0r6mBCNsdusuKl03g==', 'T1', '实习工程师', '2023-07-15 09:17:49', '2023-07-15 09:17:49');
+COMMIT;
+
+-- ----------------------------
+-- Table structure for employee_salary
+-- ----------------------------
+DROP TABLE IF EXISTS `employee_salary`;
+CREATE TABLE `employee_salary` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `employee_number` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员编号',
+ `salary_total_amount` decimal(8,2) NOT NULL COMMENT '薪资总额',
+ `salary_merit_amount` decimal(8,2) NOT NULL COMMENT '绩效工资',
+ `salary_base_amount` decimal(8,2) NOT NULL COMMENT '基础工资',
+ `create_time` datetime NOT NULL COMMENT '创建时间',
+ `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+ PRIMARY KEY (`id`),
+ KEY `idx_employee_number` (`employee_number`)
+) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Records of employee_salary
+-- ----------------------------
+BEGIN;
+INSERT INTO `employee_salary` VALUES (1, '10000001', 5100.00, 1020.00, 4080.00, '2023-07-14 16:09:06', '2023-07-14 16:09:06');
+INSERT INTO `employee_salary` VALUES (2, '10000010', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
+INSERT INTO `employee_salary` VALUES (3, '10000011', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
+INSERT INTO `employee_salary` VALUES (4, '10000012', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
+INSERT INTO `employee_salary` VALUES (5, '10000013', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
+INSERT INTO `employee_salary` VALUES (6, '10000014', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
+INSERT INTO `employee_salary` VALUES (8, '10000022', 100.00, 10.00, 90.00, '2023-07-15 09:17:49', '2023-07-15 09:17:49');
+COMMIT;
+
+-- ----------------------------
+-- Table structure for employee_salary_adjust
+-- ----------------------------
+DROP TABLE IF EXISTS `employee_salary_adjust`;
+CREATE TABLE `employee_salary_adjust` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `employee_number` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员编号',
+ `adjust_order_id` varchar(32) NOT NULL DEFAULT '' COMMENT '调薪单号',
+ `adjust_total_amount` decimal(8,2) NOT NULL COMMENT '总额调薪',
+ `adjust_base_amount` decimal(8,2) NOT NULL COMMENT '基础调薪',
+ `adjust_merit_amount` decimal(8,2) NOT NULL COMMENT '绩效调薪',
+ `create_time` datetime NOT NULL COMMENT '创建时间',
+ `update_time` datetime NOT NULL COMMENT '更新时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `idx_order_id` (`adjust_order_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Records of employee_salary_adjust
+-- ----------------------------
+BEGIN;
+INSERT INTO `employee_salary_adjust` VALUES (1, '10000001', '109089990198888811', 1000.00, 800.00, 200.00, '2023-07-14 16:55:53', '2023-07-14 16:55:53');
+INSERT INTO `employee_salary_adjust` VALUES (2, '10000001', '100908977676001', 100.00, 20.00, 80.00, '2023-07-14 21:57:39', '2023-07-14 21:57:39');
+COMMIT;
\ No newline at end of file
diff --git a/pay-mall-api/pom.xml b/pay-mall-api/pom.xml
new file mode 100644
index 0000000..cb6db6b
--- /dev/null
+++ b/pay-mall-api/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+
+
+ pay-mall-api
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+
+
+ jakarta.validation
+ jakarta.validation-api
+ 3.0.2
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+
+
diff --git a/pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java b/pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java
new file mode 100644
index 0000000..e19888a
--- /dev/null
+++ b/pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 数据传输对象 xxxRequestDTO xxxResponseDTO
+ */
+package edu.whut.api.dto;
\ No newline at end of file
diff --git a/pay-mall-api/src/main/java/edu/whut/api/package-info.java b/pay-mall-api/src/main/java/edu/whut/api/package-info.java
new file mode 100644
index 0000000..d4d52da
--- /dev/null
+++ b/pay-mall-api/src/main/java/edu/whut/api/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 定义api接口
+ */
+package edu.whut.api;
\ No newline at end of file
diff --git a/pay-mall-api/src/main/java/edu/whut/api/response/Response.java b/pay-mall-api/src/main/java/edu/whut/api/response/Response.java
new file mode 100644
index 0000000..5452cd0
--- /dev/null
+++ b/pay-mall-api/src/main/java/edu/whut/api/response/Response.java
@@ -0,0 +1,22 @@
+package edu.whut.api.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Response implements Serializable {
+
+ private static final long serialVersionUID = 7000723935764546321L;
+
+ private String code;
+ private String info;
+ private T data;
+
+}
diff --git a/pay-mall-app/Dockerfile b/pay-mall-app/Dockerfile
new file mode 100644
index 0000000..326c3ab
--- /dev/null
+++ b/pay-mall-app/Dockerfile
@@ -0,0 +1,17 @@
+# 基础镜像
+FROM openjdk:8-jre-slim
+
+# 作者
+MAINTAINER smile
+
+# 配置
+ENV PARAMS=""
+
+# 时区
+ENV TZ=PRC
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+# 添加应用
+ADD target/pay-mall-app.jar /pay-mall-app.jar
+
+ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /pay-mall-app.jar $PARAMS"]
\ No newline at end of file
diff --git a/pay-mall-app/pom.xml b/pay-mall-app/pom.xml
new file mode 100644
index 0000000..e0fa5ad
--- /dev/null
+++ b/pay-mall-app/pom.xml
@@ -0,0 +1,137 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+
+
+ pay-mall-app
+
+ jar
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+
+ mysql
+ mysql-connector-java
+
+
+ com.alibaba
+ fastjson
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ org.projectlombok
+ lombok
+
+
+ com.google.guava
+ guava
+
+
+ junit
+ junit
+ test
+
+
+ io.jsonwebtoken
+ jjwt
+
+
+ com.auth0
+ java-jwt
+
+
+ commons-codec
+ commons-codec
+
+
+ com.squareup.retrofit2
+ converter-gson
+ 2.9.0
+
+
+
+
+ edu.whut
+ pay-mall-trigger
+
+
+ edu.whut
+ pay-mall-infrastructure
+
+
+
+
+ pay-mall-app
+
+
+ src/main/resources
+ true
+
+ **/**
+
+
+
+
+
+ src/test/resources
+ true
+
+ **/**
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.6
+
+ true
+ false
+
+ **/*Test.java
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ edu.whut.Application
+ JAR
+
+
+
+
+
+
diff --git a/pay-mall-app/src/main/java/edu/whut/Application.java b/pay-mall-app/src/main/java/edu/whut/Application.java
new file mode 100644
index 0000000..474acfa
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/Application.java
@@ -0,0 +1,15 @@
+package edu.whut;
+
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@Configurable
+public class Application {
+
+ public static void main(String[] args){
+ SpringApplication.run(Application.class);
+ }
+
+}
diff --git a/pay-mall-app/src/main/java/edu/whut/config/GuavaConfig.java b/pay-mall-app/src/main/java/edu/whut/config/GuavaConfig.java
new file mode 100644
index 0000000..a411e36
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/config/GuavaConfig.java
@@ -0,0 +1,20 @@
+package edu.whut.config;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+public class GuavaConfig {
+
+ @Bean(name = "cache")
+ public Cache cache() {
+ return CacheBuilder.newBuilder()
+ .expireAfterWrite(3, TimeUnit.SECONDS)
+ .build();
+ }
+
+}
diff --git a/pay-mall-app/src/main/java/edu/whut/config/ThreadPoolConfig.java b/pay-mall-app/src/main/java/edu/whut/config/ThreadPoolConfig.java
new file mode 100644
index 0000000..005571a
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/config/ThreadPoolConfig.java
@@ -0,0 +1,50 @@
+package edu.whut.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import java.util.concurrent.*;
+
+@Slf4j
+@EnableAsync
+@Configuration
+@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
+public class ThreadPoolConfig {
+
+ @Bean
+ @ConditionalOnMissingBean(ThreadPoolExecutor.class)
+ public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties properties) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ // 实例化策略
+ RejectedExecutionHandler handler;
+ switch (properties.getPolicy()){
+ case "AbortPolicy":
+ handler = new ThreadPoolExecutor.AbortPolicy();
+ break;
+ case "DiscardPolicy":
+ handler = new ThreadPoolExecutor.DiscardPolicy();
+ break;
+ case "DiscardOldestPolicy":
+ handler = new ThreadPoolExecutor.DiscardOldestPolicy();
+ break;
+ case "CallerRunsPolicy":
+ handler = new ThreadPoolExecutor.CallerRunsPolicy();
+ break;
+ default:
+ handler = new ThreadPoolExecutor.AbortPolicy();
+ break;
+ }
+ // 创建线程池
+ return new ThreadPoolExecutor(properties.getCorePoolSize(),
+ properties.getMaxPoolSize(),
+ properties.getKeepAliveTime(),
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(properties.getBlockQueueSize()),
+ Executors.defaultThreadFactory(),
+ handler);
+ }
+
+}
diff --git a/pay-mall-app/src/main/java/edu/whut/config/ThreadPoolConfigProperties.java b/pay-mall-app/src/main/java/edu/whut/config/ThreadPoolConfigProperties.java
new file mode 100644
index 0000000..db297b7
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/config/ThreadPoolConfigProperties.java
@@ -0,0 +1,26 @@
+package edu.whut.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@ConfigurationProperties(prefix = "thread.pool.executor.config", ignoreInvalidFields = true)
+public class ThreadPoolConfigProperties {
+
+ /** 核心线程数 */
+ private Integer corePoolSize = 20;
+ /** 最大线程数 */
+ private Integer maxPoolSize = 200;
+ /** 最大等待时间 */
+ private Long keepAliveTime = 10L;
+ /** 最大队列数 */
+ private Integer blockQueueSize = 5000;
+ /*
+ * AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
+ * DiscardPolicy:直接丢弃任务,但是不会抛出异常
+ * DiscardOldestPolicy:将最早进入队列的任务删除,之后再尝试加入队列的任务被拒绝
+ * CallerRunsPolicy:如果任务添加线程池失败,那么主线程自己执行该任务
+ * */
+ private String policy = "AbortPolicy";
+
+}
diff --git a/pay-mall-app/src/main/java/edu/whut/config/package-info.java b/pay-mall-app/src/main/java/edu/whut/config/package-info.java
new file mode 100644
index 0000000..727ed2e
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/config/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 1. 用于管理引入的Jar所需的资源启动或者初始化处理
+ * 2. 如果有AOP切面,可以再建一个aop包,来写切面逻辑
+ */
+package edu.whut.config;
+
diff --git a/pay-mall-app/src/main/java/edu/whut/package-info.java b/pay-mall-app/src/main/java/edu/whut/package-info.java
new file mode 100644
index 0000000..2c94a72
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 应用启动层,注意Application所在的包路径,是在上一层。这样才能扫描到其他 module
+ * */
+package edu.whut;
\ No newline at end of file
diff --git a/pay-mall-app/src/main/resources/application-dev.yml b/pay-mall-app/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..9eebd99
--- /dev/null
+++ b/pay-mall-app/src/main/resources/application-dev.yml
@@ -0,0 +1,48 @@
+server:
+ port: 8092
+
+# 线程池配置
+thread:
+ pool:
+ executor:
+ config:
+ core-pool-size: 20
+ max-pool-size: 50
+ keep-alive-time: 5000
+ block-queue-size: 5000
+ policy: CallerRunsPolicy
+
+# 数据库配置;启动时配置数据库资源信息
+spring:
+ datasource:
+ username: root
+ password: 123456
+ url: jdbc:mysql://127.0.0.1:13306/pay-mall?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ hikari:
+ pool-name: Retail_HikariCP
+ minimum-idle: 15 #最小空闲连接数量
+ idle-timeout: 180000 #空闲连接存活最大时间,默认600000(10分钟)
+ maximum-pool-size: 25 #连接池最大连接数,默认是10
+ auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
+ max-lifetime: 1800000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+ connection-timeout: 30000 #数据库连接超时时间,默认30秒,即30000
+ connection-test-query: SELECT 1
+ type: com.zaxxer.hikari.HikariDataSource
+
+# MyBatis 配置【如需使用记得打开】
+#mybatis:
+# mapper-locations: classpath:/mybatis/mapper/*.xml
+# config-location: classpath:/mybatis/config/mybatis-config.xml
+
+# 微信公众号对接
+weixin:
+ config:
+ originalid: gh_b748269e1f4c
+ token: b8b6
+
+# 日志
+logging:
+ level:
+ root: info
+ config: classpath:logback-spring.xml
\ No newline at end of file
diff --git a/pay-mall-app/src/main/resources/application-prod.yml b/pay-mall-app/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..26df58f
--- /dev/null
+++ b/pay-mall-app/src/main/resources/application-prod.yml
@@ -0,0 +1,41 @@
+server:
+ port: 8092
+
+# 线程池配置
+thread:
+ pool:
+ executor:
+ config:
+ core-pool-size: 20
+ max-pool-size: 50
+ keep-alive-time: 5000
+ block-queue-size: 5000
+ policy: CallerRunsPolicy
+
+# 数据库配置
+#spring:
+# datasource:
+# username: root
+# password: 123456
+# url: jdbc:mysql://127.0.0.1:3306/pay-mall?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
+# driver-class-name: com.mysql.cj.jdbc.Driver
+# hikari:
+# pool-name: Retail_HikariCP
+# minimum-idle: 15 #最小空闲连接数量
+# idle-timeout: 180000 #空闲连接存活最大时间,默认600000(10分钟)
+# maximum-pool-size: 25 #连接池最大连接数,默认是10
+# auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
+# max-lifetime: 1800000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+# connection-timeout: 30000 #数据库连接超时时间,默认30秒,即30000
+# connection-test-query: SELECT 1
+# type: com.zaxxer.hikari.HikariDataSource
+
+#mybatis:
+# mapper-locations: classpath:/mybatis/mapper/*.xml
+# config-location: classpath:/mybatis/config/mybatis-config.xml
+
+# 日志
+logging:
+ level:
+ root: info
+ config: classpath:logback-spring.xml
\ No newline at end of file
diff --git a/pay-mall-app/src/main/resources/application-test.yml b/pay-mall-app/src/main/resources/application-test.yml
new file mode 100644
index 0000000..26df58f
--- /dev/null
+++ b/pay-mall-app/src/main/resources/application-test.yml
@@ -0,0 +1,41 @@
+server:
+ port: 8092
+
+# 线程池配置
+thread:
+ pool:
+ executor:
+ config:
+ core-pool-size: 20
+ max-pool-size: 50
+ keep-alive-time: 5000
+ block-queue-size: 5000
+ policy: CallerRunsPolicy
+
+# 数据库配置
+#spring:
+# datasource:
+# username: root
+# password: 123456
+# url: jdbc:mysql://127.0.0.1:3306/pay-mall?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
+# driver-class-name: com.mysql.cj.jdbc.Driver
+# hikari:
+# pool-name: Retail_HikariCP
+# minimum-idle: 15 #最小空闲连接数量
+# idle-timeout: 180000 #空闲连接存活最大时间,默认600000(10分钟)
+# maximum-pool-size: 25 #连接池最大连接数,默认是10
+# auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
+# max-lifetime: 1800000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+# connection-timeout: 30000 #数据库连接超时时间,默认30秒,即30000
+# connection-test-query: SELECT 1
+# type: com.zaxxer.hikari.HikariDataSource
+
+#mybatis:
+# mapper-locations: classpath:/mybatis/mapper/*.xml
+# config-location: classpath:/mybatis/config/mybatis-config.xml
+
+# 日志
+logging:
+ level:
+ root: info
+ config: classpath:logback-spring.xml
\ No newline at end of file
diff --git a/pay-mall-app/src/main/resources/application.yml b/pay-mall-app/src/main/resources/application.yml
new file mode 100644
index 0000000..da00f44
--- /dev/null
+++ b/pay-mall-app/src/main/resources/application.yml
@@ -0,0 +1,5 @@
+spring:
+ config:
+ name: pay-mall-app
+ profiles:
+ active: dev
diff --git a/pay-mall-app/src/main/resources/logback-spring.xml b/pay-mall-app/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..932ad72
--- /dev/null
+++ b/pay-mall-app/src/main/resources/logback-spring.xml
@@ -0,0 +1,113 @@
+
+
+
+
+ logback
+
+
+
+
+
+
+
+
+
+
+
+ info
+
+
+ %d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n
+ UTF-8
+
+
+
+
+
+
+
+ ./data/log/log_info.log
+
+
+ %d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n
+ UTF-8
+
+
+
+
+ ./data/log/log-info-%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 15
+ 10GB
+
+
+
+
+
+
+ ./data/log/log_error.log
+
+
+ %d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n
+ UTF-8
+
+
+
+ ./data/log/log-error-%d{yyyy-MM-dd}.%i.log
+
+ 100MB
+
+
+ 7
+ 5GB
+
+
+
+ WARN
+
+
+
+
+
+
+ 0
+
+ 8192
+
+ true
+
+ false
+
+
+
+
+
+ 0
+
+ 1024
+
+ true
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pay-mall-app/src/main/resources/mybatis/config/mybatis-config.xml b/pay-mall-app/src/main/resources/mybatis/config/mybatis-config.xml
new file mode 100644
index 0000000..ed8ee96
--- /dev/null
+++ b/pay-mall-app/src/main/resources/mybatis/config/mybatis-config.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pay-mall-app/src/main/resources/mybatis/mapper/frame_case_mapper.xml b/pay-mall-app/src/main/resources/mybatis/mapper/frame_case_mapper.xml
new file mode 100644
index 0000000..4e14eaf
--- /dev/null
+++ b/pay-mall-app/src/main/resources/mybatis/mapper/frame_case_mapper.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+ INSERT INTO table(a,b,c) VALUES(#{a}, #{b}, #{c})
+
+
+
+ UPDATE table SET a = #{a} WHERE b = #{b}
+
+
+
+
+
diff --git a/pay-mall-app/src/test/java/edu/whut/test/ApiTest.java b/pay-mall-app/src/test/java/edu/whut/test/ApiTest.java
new file mode 100644
index 0000000..025c536
--- /dev/null
+++ b/pay-mall-app/src/test/java/edu/whut/test/ApiTest.java
@@ -0,0 +1,19 @@
+package edu.whut.test;
+
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ApiTest {
+
+ @Test
+ public void test() {
+ log.info("测试完成");
+ }
+
+}
diff --git a/pay-mall-domain/pom.xml b/pay-mall-domain/pom.xml
new file mode 100644
index 0000000..e321001
--- /dev/null
+++ b/pay-mall-domain/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+
+
+ pay-mall-domain
+
+
+
+ org.projectlombok
+ lombok
+
+
+ com.alibaba
+ fastjson
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ com.google.guava
+ guava
+
+
+ io.jsonwebtoken
+ jjwt
+
+
+ com.auth0
+ java-jwt
+
+
+ commons-codec
+ commons-codec
+
+
+
+ edu.whut
+ pay-mall-types
+
+
+
+
+ pay-mall-domain
+
+
+ org.apache.maven.plugins
+ maven-archetype-plugin
+ 3.2.0
+
+
+
+ create-from-project
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ ${java.version}
+
+
+
+
+
+
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/package-info.java
new file mode 100644
index 0000000..ba422f3
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 外部接口适配器层;当需要调用外部接口时,则创建出这一层,并定义接口,之后由基础设施层的 adapter 层具体实现
+ */
+package edu.whut.domain.xxx.adapter;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/port/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/port/package-info.java
new file mode 100644
index 0000000..8f3e273
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/port/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 外部接口适配器层;当需要调用外部接口时,则创建出这一层,并定义接口,之后由基础设施层的 adapter 层具体实现
+ */
+package edu.whut.domain.xxx.adapter.port;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/repository/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/repository/package-info.java
new file mode 100644
index 0000000..4fc83a4
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/adapter/repository/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * 仓储服务
+ * 1. 定义仓储接口,之后由基础设施层做具体实现
+ */
+package edu.whut.domain.xxx.adapter.repository;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/aggregate/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/aggregate/package-info.java
new file mode 100644
index 0000000..d2ee6fb
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/aggregate/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 聚合对象;
+ * 1. 聚合实体和值对象
+ * 2. 聚合是聚合的对象,和提供基础处理对象的方法。但不建议在聚合中引入仓储和接口来做过大的逻辑。而这些复杂的操作应该放到service中处理
+ * 3. 对象名称 XxxAggregate
+ */
+package edu.whut.domain.xxx.model.aggregate;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/entity/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/entity/package-info.java
new file mode 100644
index 0000000..a7a8ce5
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/entity/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 实体对象;
+ * 1. 一般和数据库持久化对象1v1的关系,但因各自开发系统的不同,也有1vn的可能。
+ * 2. 如果是老系统改造,那么旧的库表冗余了太多的字段,可能会有nv1的情况
+ * 3. 对象名称 XxxEntity
+ */
+package edu.whut.domain.xxx.model.entity;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/valobj/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/valobj/package-info.java
new file mode 100644
index 0000000..f34a181
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/model/valobj/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 值对象;
+ * 1. 用于描述对象属性的值,如一个库表中有json后者一个字段多个属性信息的枚举对象
+ * 2. 对象名称如;XxxVO
+ */
+package edu.whut.domain.xxx.model.valobj;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/xxx/service/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/service/package-info.java
new file mode 100644
index 0000000..a82b91f
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/xxx/service/package-info.java
@@ -0,0 +1 @@
+package edu.whut.domain.xxx.service;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/yyy/adapter/repository/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/adapter/repository/package-info.java
new file mode 100644
index 0000000..e69de29
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/aggregate/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/aggregate/package-info.java
new file mode 100644
index 0000000..a338f2b
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/aggregate/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 聚合对象;
+ * 1. 聚合实体和值对象
+ * 2. 聚合是聚合的对象,和提供基础处理对象的方法。但不建议在聚合中引入仓储和接口来做过大的逻辑。而这些复杂的操作应该放到service中处理
+ * 3. 对象名称 XxxAggregate
+ */
+package edu.whut.domain.yyy.model.aggregate;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/entity/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/entity/package-info.java
new file mode 100644
index 0000000..1d9a9d6
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/entity/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 实体对象;
+ * 1. 一般和数据库持久化对象1v1的关系,但因各自开发系统的不同,也有1vn的可能。
+ * 2. 如果是老系统改造,那么旧的库表冗余了太多的字段,可能会有nv1的情况
+ * 3. 对象名称 XxxEntity
+ */
+package edu.whut.domain.yyy.model.entity;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/valobj/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/valobj/package-info.java
new file mode 100644
index 0000000..ecb5669
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/model/valobj/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 值对象;
+ * 1. 用于描述对象属性的值,如一个库表中有json后者一个字段多个属性信息的枚举对象
+ * 2. 对象名称如;XxxVO
+ */
+package edu.whut.domain.yyy.model.valobj;
\ No newline at end of file
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/yyy/service/package-info.java b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/service/package-info.java
new file mode 100644
index 0000000..ab79c10
--- /dev/null
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/yyy/service/package-info.java
@@ -0,0 +1 @@
+package edu.whut.domain.yyy.service;
\ No newline at end of file
diff --git a/pay-mall-infrastructure/pom.xml b/pay-mall-infrastructure/pom.xml
new file mode 100644
index 0000000..a6cbe6d
--- /dev/null
+++ b/pay-mall-infrastructure/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+
+
+ pay-mall-infrastructure
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+ org.projectlombok
+ lombok
+
+
+
+ edu.whut
+ pay-mall-domain
+
+
+
+
+ pay-mall-infrastructure
+
+
+ org.apache.maven.plugins
+ maven-archetype-plugin
+ 3.2.0
+
+
+
+ create-from-project
+
+
+
+
+
+
+
+
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/port/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/port/package-info.java
new file mode 100644
index 0000000..429f503
--- /dev/null
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/port/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 实现对外部的api调用,类的名称为 XxxPort 接口定义在 domain 中
+ */
+package edu.whut.infrastructure.adapter.port;
\ No newline at end of file
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/package-info.java
new file mode 100644
index 0000000..14b6868
--- /dev/null
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 仓储实现;用于实现 domain 中定义的仓储接口,如;IXxxRepository 在 Repository 中调用服务
+ */
+package edu.whut.infrastructure.adapter.repository;
\ No newline at end of file
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/package-info.java
new file mode 100644
index 0000000..8e44e5b
--- /dev/null
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * DAO 接口;IXxxDao
+ */
+package edu.whut.infrastructure.dao;
\ No newline at end of file
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/package-info.java
new file mode 100644
index 0000000..ddeef77
--- /dev/null
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 持久化对象;XxxPO 最后的 PO 是大写,UserPO
+ */
+package edu.whut.infrastructure.dao.po;
\ No newline at end of file
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/gateway/dto/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/gateway/dto/package-info.java
new file mode 100644
index 0000000..e69de29
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/gateway/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/gateway/package-info.java
new file mode 100644
index 0000000..15d30fd
--- /dev/null
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/gateway/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 定义http、rpc接口,调用外部。在 adapter 中调用这部分内容。
+ */
+package edu.whut.infrastructure.gateway;
\ No newline at end of file
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/redis/package-info.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/redis/package-info.java
new file mode 100644
index 0000000..582d29d
--- /dev/null
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/redis/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 提供redis链接配置
+ */
+package edu.whut.infrastructure.redis;
\ No newline at end of file
diff --git a/pay-mall-trigger/pom.xml b/pay-mall-trigger/pom.xml
new file mode 100644
index 0000000..0862007
--- /dev/null
+++ b/pay-mall-trigger/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+
+
+ pay-mall-trigger
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.alibaba
+ fastjson
+
+
+ org.springframework
+ spring-tx
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+ edu.whut
+ pay-mall-api
+
+
+ edu.whut
+ pay-mall-types
+
+
+ edu.whut
+ pay-mall-domain
+
+
+
+
+ pay-mall-trigger
+
+
+ org.apache.maven.plugins
+ maven-archetype-plugin
+ 3.2.0
+
+
+
+ create-from-project
+
+
+
+
+
+
+
+
diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java
new file mode 100644
index 0000000..e72cc43
--- /dev/null
+++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java
@@ -0,0 +1,76 @@
+package edu.whut.trigger.http;
+import edu.whut.types.weixin.MessageTextEntity;
+import edu.whut.types.weixin.SignatureUtil;
+import edu.whut.types.weixin.XmlUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index 平台地址
+ */
+@Slf4j
+@RestController()
+@CrossOrigin("*")
+@RequestMapping("/api/v1/weixin/portal/")
+public class WeixinPortalController {
+
+ @Value("${weixin.config.originalid}")
+ private String originalid;
+ @Value("${weixin.config.token}")
+ private String token;
+
+ @GetMapping(value = "receive", produces = "text/plain;charset=utf-8")
+ public String validate(@RequestParam(value = "signature", required = false) String signature,
+ @RequestParam(value = "timestamp", required = false) String timestamp,
+ @RequestParam(value = "nonce", required = false) String nonce,
+ @RequestParam(value = "echostr", required = false) String echostr) {
+ try {
+ log.info("微信公众号验签信息开始 [{}, {}, {}, {}]", signature, timestamp, nonce, echostr);
+ if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
+ throw new IllegalArgumentException("请求参数非法,请核实!");
+ }
+ boolean check = SignatureUtil.check(token, signature, timestamp, nonce);
+ log.info("微信公众号验签信息完成 check:{}", check);
+ if (!check) {
+ return null;
+ }
+ return echostr;
+ } catch (Exception e) {
+ log.error("微信公众号验签信息失败 [{}, {}, {}, {}]", signature, timestamp, nonce, echostr, e);
+ return null;
+ }
+ }
+
+ @PostMapping(value = "receive", produces = "application/xml; charset=UTF-8")
+ public String post(@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) {
+ try {
+ log.info("接收微信公众号信息请求{}开始 {}", openid, requestBody);
+ // 消息转换
+ MessageTextEntity message = XmlUtil.xmlToBean(requestBody, MessageTextEntity.class);
+ return buildMessageTextEntity(openid, "你好," + message.getContent());
+ } catch (Exception e) {
+ log.error("接收微信公众号信息请求{}失败 {}", openid, requestBody, e);
+ return "";
+ }
+ }
+
+ private String buildMessageTextEntity(String openid, String content) {
+ MessageTextEntity res = new MessageTextEntity();
+ // 公众号分配的ID
+ res.setFromUserName(originalid);
+ res.setToUserName(openid);
+ res.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000L));
+ res.setMsgType("text");
+ res.setContent(content);
+ return XmlUtil.beanToXml(res);
+ }
+
+}
diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/package-info.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/package-info.java
new file mode 100644
index 0000000..40cb8a7
--- /dev/null
+++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * HTTP 接口服务
+ */
+package edu.whut.trigger.http;
\ No newline at end of file
diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/job/package-info.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/job/package-info.java
new file mode 100644
index 0000000..ac4b97b
--- /dev/null
+++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/job/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 任务服务,可以选择使用 Spring 默认提供的 Schedule https://bugstack.cn/md/road-map/quartz.html
+ */
+package edu.whut.trigger.job;
\ No newline at end of file
diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/listener/package-info.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/listener/package-info.java
new file mode 100644
index 0000000..b23264d
--- /dev/null
+++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/listener/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * 监听服务;在单体服务中,解耦流程。类似MQ的使用,如Spring的Event,Guava的事件总线都可以。如果使用了 Redis 那么也可以有发布/订阅使用。
+ * Guava:https://bugstack.cn/md/road-map/guava.html
+ */
+package edu.whut.trigger.listener;
\ No newline at end of file
diff --git a/pay-mall-types/pom.xml b/pay-mall-types/pom.xml
new file mode 100644
index 0000000..bf1f4d5
--- /dev/null
+++ b/pay-mall-types/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+
+
+ pay-mall-types
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.projectlombok
+ lombok
+
+
+ com.thoughtworks.xstream
+ xstream
+
+
+ dom4j
+ dom4j
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+ pay-mall-types
+
+
+ org.apache.maven.plugins
+ maven-archetype-plugin
+ 3.2.0
+
+
+
+ create-from-project
+
+
+
+
+
+
+
+
diff --git a/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java b/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java
new file mode 100644
index 0000000..381d140
--- /dev/null
+++ b/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java
@@ -0,0 +1,7 @@
+package edu.whut.types.common;
+
+public class Constants {
+
+ public final static String SPLIT = ",";
+
+}
diff --git a/pay-mall-types/src/main/java/edu/whut/types/enums/ResponseCode.java b/pay-mall-types/src/main/java/edu/whut/types/enums/ResponseCode.java
new file mode 100644
index 0000000..8189263
--- /dev/null
+++ b/pay-mall-types/src/main/java/edu/whut/types/enums/ResponseCode.java
@@ -0,0 +1,20 @@
+package edu.whut.types.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+public enum ResponseCode {
+
+ SUCCESS("0000", "成功"),
+ UN_ERROR("0001", "未知失败"),
+ ILLEGAL_PARAMETER("0002", "非法参数"),
+ ;
+
+ private String code;
+ private String info;
+
+}
diff --git a/pay-mall-types/src/main/java/edu/whut/types/exception/AppException.java b/pay-mall-types/src/main/java/edu/whut/types/exception/AppException.java
new file mode 100644
index 0000000..d06854e
--- /dev/null
+++ b/pay-mall-types/src/main/java/edu/whut/types/exception/AppException.java
@@ -0,0 +1,46 @@
+package edu.whut.types.exception;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class AppException extends RuntimeException {
+
+ private static final long serialVersionUID = 5317680961212299217L;
+
+ /** 异常码 */
+ private String code;
+
+ /** 异常信息 */
+ private String info;
+
+ public AppException(String code) {
+ this.code = code;
+ }
+
+ public AppException(String code, Throwable cause) {
+ this.code = code;
+ super.initCause(cause);
+ }
+
+ public AppException(String code, String message) {
+ this.code = code;
+ this.info = message;
+ }
+
+ public AppException(String code, String message, Throwable cause) {
+ this.code = code;
+ this.info = message;
+ super.initCause(cause);
+ }
+
+ @Override
+ public String toString() {
+ return "edu.whut.x.api.types.exception.XApiException{" +
+ "code='" + code + '\'' +
+ ", info='" + info + '\'' +
+ '}';
+ }
+
+}
diff --git a/pay-mall-types/src/main/java/edu/whut/types/weixin/MessageTextEntity.java b/pay-mall-types/src/main/java/edu/whut/types/weixin/MessageTextEntity.java
new file mode 100644
index 0000000..75d9a44
--- /dev/null
+++ b/pay-mall-types/src/main/java/edu/whut/types/weixin/MessageTextEntity.java
@@ -0,0 +1,118 @@
+package edu.whut.types.weixin;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+@XStreamAlias("xml")
+public class MessageTextEntity {
+
+ @XStreamAlias("ToUserName")
+ private String toUserName;
+
+ @XStreamAlias("FromUserName")
+ private String fromUserName;
+
+ @XStreamAlias("CreateTime")
+ private String createTime;
+
+ @XStreamAlias("MsgType")
+ private String msgType;
+
+ @XStreamAlias("Event")
+ private String event;
+
+ @XStreamAlias("EventKey")
+ private String eventKey;
+
+ @XStreamAlias("MsgId")
+ private String msgId;
+
+ @XStreamAlias("Status")
+ private String status;
+
+ @XStreamAlias("Ticket")
+ private String ticket;
+
+ @XStreamAlias("Content")
+ private String content;
+
+ // Getters and Setters
+ public String getToUserName() {
+ return toUserName;
+ }
+
+ public void setToUserName(String toUserName) {
+ this.toUserName = toUserName;
+ }
+
+ public String getFromUserName() {
+ return fromUserName;
+ }
+
+ public void setFromUserName(String fromUserName) {
+ this.fromUserName = fromUserName;
+ }
+
+ public String getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getMsgType() {
+ return msgType;
+ }
+
+ public void setMsgType(String msgType) {
+ this.msgType = msgType;
+ }
+
+ public String getEvent() {
+ return event;
+ }
+
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ public String getMsgId() {
+ return msgId;
+ }
+
+ public void setMsgId(String msgId) {
+ this.msgId = msgId;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getEventKey() {
+ return eventKey;
+ }
+
+ public void setEventKey(String eventKey) {
+ this.eventKey = eventKey;
+ }
+
+ public String getTicket() {
+ return ticket;
+ }
+
+ public void setTicket(String ticket) {
+ this.ticket = ticket;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+}
\ No newline at end of file
diff --git a/pay-mall-types/src/main/java/edu/whut/types/weixin/SignatureUtil.java b/pay-mall-types/src/main/java/edu/whut/types/weixin/SignatureUtil.java
new file mode 100644
index 0000000..5ba7698
--- /dev/null
+++ b/pay-mall-types/src/main/java/edu/whut/types/weixin/SignatureUtil.java
@@ -0,0 +1,68 @@
+package edu.whut.types.weixin;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class SignatureUtil {
+ /**
+ * 验证签名
+ */
+ public static boolean check(String token, String signature, String timestamp, String nonce) {
+ String[] arr = new String[]{token, timestamp, nonce};
+ // 将token、timestamp、nonce三个参数进行字典序排序
+ sort(arr);
+ StringBuilder content = new StringBuilder();
+ for (String s : arr) {
+ content.append(s);
+ }
+ MessageDigest md;
+ String tmpStr = null;
+ try {
+ md = MessageDigest.getInstance("SHA-1");
+ // 将三个参数字符串拼接成一个字符串进行sha1加密
+ byte[] digest = md.digest(content.toString().getBytes());
+ tmpStr = byteToStr(digest);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
+ return tmpStr != null && tmpStr.equals(signature.toUpperCase());
+ }
+
+ /**
+ * 将字节数组转换为十六进制字符串
+ */
+ private static String byteToStr(byte[] byteArray) {
+ StringBuilder strDigest = new StringBuilder();
+ for (byte b : byteArray) {
+ strDigest.append(byteToHexStr(b));
+ }
+ return strDigest.toString();
+ }
+
+ /**
+ * 将字节转换为十六进制字符串
+ */
+ private static String byteToHexStr(byte mByte) {
+ char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ char[] tempArr = new char[2];
+ tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
+ tempArr[1] = Digit[mByte & 0X0F];
+ return new String(tempArr);
+ }
+
+ /**
+ * 进行字典排序
+ */
+ private static void sort(String[] str) {
+ for (int i = 0; i < str.length - 1; i++) {
+ for (int j = i + 1; j < str.length; j++) {
+ if (str[j].compareTo(str[i]) < 0) {
+ String temp = str[i];
+ str[i] = str[j];
+ str[j] = temp;
+ }
+ }
+ }
+ }
+}
diff --git a/pay-mall-types/src/main/java/edu/whut/types/weixin/XmlUtil.java b/pay-mall-types/src/main/java/edu/whut/types/weixin/XmlUtil.java
new file mode 100644
index 0000000..8a405ae
--- /dev/null
+++ b/pay-mall-types/src/main/java/edu/whut/types/weixin/XmlUtil.java
@@ -0,0 +1,151 @@
+package edu.whut.types.weixin;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.core.util.QuickWriter;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
+import com.thoughtworks.xstream.io.xml.XppDriver;
+import com.thoughtworks.xstream.security.AnyTypePermission;
+import org.apache.commons.lang3.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.*;
+
+public class XmlUtil {
+
+ /**
+ * 解析微信发来的请求(xml)
+ */
+ @SuppressWarnings("unchecked")
+ public static Map xmlToMap(HttpServletRequest request) throws Exception {
+ // 从request中取得输入流
+ try (InputStream inputStream = request.getInputStream()) {
+ // 将解析结果存储在HashMap中
+ Map map = new HashMap<>();
+ // 读取输入流
+ SAXReader reader = new SAXReader();
+ // 得到xml文档
+ Document document = reader.read(inputStream);
+ // 得到xml根元素
+ Element root = document.getRootElement();
+ // 得到根元素的所有子节点
+ List elementList = root.elements();
+ // 遍历所有子节点
+ for (Element e : elementList)
+ map.put(e.getName(), e.getText());
+ // 释放资源
+ inputStream.close();
+ return map;
+ }
+ }
+
+ /**
+ * 将map转化成xml响应给微信服务器
+ */
+ static String mapToXML(Map map) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("");
+ mapToXML2(map, sb);
+ sb.append("");
+ try {
+ return sb.toString();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static void mapToXML2(Map map, StringBuffer sb) {
+ Set set = map.keySet();
+ for (Object o : set) {
+ String key = (String) o;
+ Object value = map.get(key);
+ if (null == value)
+ value = "";
+ if (value.getClass().getName().equals("java.util.ArrayList")) {
+ ArrayList list = (ArrayList) map.get(key);
+ sb.append("<").append(key).append(">");
+ for (Object o1 : list) {
+ HashMap hm = (HashMap) o1;
+ mapToXML2(hm, sb);
+ }
+ sb.append("").append(key).append(">");
+
+ } else {
+ if (value instanceof HashMap) {
+ sb.append("<").append(key).append(">");
+ mapToXML2((HashMap) value, sb);
+ sb.append("").append(key).append(">");
+ } else {
+ sb.append("<").append(key).append(">").append(key).append(">");
+ }
+
+ }
+
+ }
+ }
+
+ public static XStream getMyXStream() {
+ return new XStream(new XppDriver() {
+ @Override
+ public HierarchicalStreamWriter createWriter(Writer out) {
+ return new PrettyPrintWriter(out) {
+ // 对所有xml节点都增加CDATA标记
+ boolean cdata = true;
+
+ @Override
+ public void startNode(String name, Class clazz) {
+ super.startNode(name, clazz);
+ }
+
+ @Override
+ protected void writeText(QuickWriter writer, String text) {
+ if (cdata && !StringUtils.isNumeric(text)) {
+ writer.write("");
+ } else {
+ writer.write(text);
+ }
+ }
+ };
+ }
+ });
+ }
+
+ /**
+ * bean转成微信的xml消息格式
+ */
+ public static String beanToXml(Object object) {
+ XStream xStream = getMyXStream();
+ xStream.alias("xml", object.getClass());
+ xStream.processAnnotations(object.getClass());
+ String xml = xStream.toXML(object);
+ if (!StringUtils.isEmpty(xml)) {
+ return xml;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * xml转成bean泛型方法
+ */
+ public static T xmlToBean(String resultXml, Class clazz) {
+ // XStream对象设置默认安全防护,同时设置允许的类
+ XStream stream = new XStream(new DomDriver());
+ stream.addPermission(AnyTypePermission.ANY);
+ XStream.setupDefaultSecurity(stream);
+ stream.allowTypes(new Class[]{clazz});
+ stream.processAnnotations(new Class[]{clazz});
+ stream.setMode(XStream.NO_REFERENCES);
+ stream.alias("xml", clazz);
+ return (T) stream.fromXML(resultXml);
+ }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..93dc316
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,203 @@
+
+
+ 4.0.0
+
+ edu.whut
+ pay-mall
+ 1.0-SNAPSHOT
+ pom
+
+
+ pay-mall-api
+ pay-mall-app
+ pay-mall-domain
+ pay-mall-trigger
+ pay-mall-infrastructure
+ pay-mall-types
+
+
+
+
+ nexus-aliyun
+ nexus-aliyun
+ http://maven.aliyun.com/nexus/content/groups/public/
+
+ true
+
+
+ false
+
+
+
+
+
+ 1.8
+ UTF-8
+ 8
+ 8
+ UTF-8
+
+
+
+
+ xiaofuge
+ 184172133@qq.com
+ fuzhengwei
+ https://github.com/fuzhengwei
+
+
+
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.12
+
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.1.4
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.22
+
+
+ com.alibaba
+ fastjson
+ 2.0.28
+
+
+ org.apache.commons
+ commons-lang3
+ 3.9
+
+
+ com.google.guava
+ guava
+ 32.1.3-jre
+
+
+ dom4j
+ dom4j
+ 1.6.1
+
+
+ com.thoughtworks.xstream
+ xstream
+ 1.4.10
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.9.1
+
+
+ com.auth0
+ java-jwt
+ 4.4.0
+
+
+ commons-codec
+ commons-codec
+ 1.15
+
+
+
+
+ edu.whut
+ pay-mall-api
+ 1.0-SNAPSHOT
+
+
+ edu.whut
+ pay-mall-domain
+ 1.0-SNAPSHOT
+
+
+ edu.whut
+ pay-mall-infrastructure
+ 1.0-SNAPSHOT
+
+
+ edu.whut
+ pay-mall-types
+ 1.0-SNAPSHOT
+
+
+ edu.whut
+ pay-mall-trigger
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.0
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 2.5
+
+ UTF-8
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ 2.7
+
+
+
+
+
+
+ dev
+
+ true
+
+
+ -Xms1G -Xmx1G -server -XX:MaxPermSize=256M -Xss256K -Dspring.profiles.active=test -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/pay-mall-boot -Xloggc:/export/Logs/pay-mall-boot/gc-pay-mall-boot.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
+ dev
+
+
+
+ test
+
+ -Xms1G -Xmx1G -server -XX:MaxPermSize=256M -Xss256K -Dspring.profiles.active=test -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/pay-mall-boot -Xloggc:/export/Logs/pay-mall-boot/gc-pay-mall-boot.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
+ test
+
+
+
+ prod
+
+ -Xms6G -Xmx6G -server -XX:MaxPermSize=256M -Xss256K -Dspring.profiles.active=release -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/fq-mall-activity-app -Xloggc:/export/Logs/pay-mall-boot/gc-pay-mall-boot.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
+ prod
+
+
+
+
+