Commit 91401ea615b3950d33148642655348596478e5c7
1 parent
62dd484b
feat:定时任务项目
Showing
57 changed files
with
4804 additions
and
0 deletions
Too many changes to show.
To preserve performance only 57 of 59 files are displayed.
job/Dockerfile
0 → 100644
job/docker-compose.yml
0 → 100644
job/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <parent> | ||
6 | + <artifactId>canrd-services</artifactId> | ||
7 | + <groupId>com.canrd.shop</groupId> | ||
8 | + <version>1.0-SNAPSHOT</version> | ||
9 | + </parent> | ||
10 | + <modelVersion>4.0.0</modelVersion> | ||
11 | + | ||
12 | + <artifactId>job</artifactId> | ||
13 | + | ||
14 | + <dependencies> | ||
15 | + <dependency> | ||
16 | + <groupId>org.springframework.boot</groupId> | ||
17 | + <artifactId>spring-boot-starter-web</artifactId> | ||
18 | + <!-- <version>2.2.5.RELEASE</version>--> | ||
19 | + <exclusions> | ||
20 | + <exclusion> | ||
21 | + <groupId>org.springframework.boot</groupId> | ||
22 | + <artifactId>spring-boot-starter-logging</artifactId> | ||
23 | + </exclusion> | ||
24 | + </exclusions> | ||
25 | + </dependency> | ||
26 | + | ||
27 | + <!-- Lombok 依赖--> | ||
28 | + <dependency> | ||
29 | + <groupId>org.projectlombok</groupId> | ||
30 | + <artifactId>lombok</artifactId> | ||
31 | + <version>1.18.12</version> | ||
32 | + <optional>true</optional> | ||
33 | + </dependency> | ||
34 | + <dependency> | ||
35 | + <groupId>org.springframework.boot</groupId> | ||
36 | + <artifactId>spring-boot-starter-aop</artifactId> | ||
37 | + </dependency> | ||
38 | + <dependency> | ||
39 | + <groupId>org.springframework.boot</groupId> | ||
40 | + <artifactId>spring-boot-starter-test</artifactId> | ||
41 | + <scope>test</scope> | ||
42 | + </dependency> | ||
43 | + | ||
44 | + <dependency> | ||
45 | + <groupId>com.baomidou</groupId> | ||
46 | + <artifactId>mybatis-plus-boot-starter</artifactId> | ||
47 | + </dependency> | ||
48 | + <!-- <dependency>--> | ||
49 | + <!-- <groupId>com.baomidou</groupId>--> | ||
50 | + <!-- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>--> | ||
51 | + <!-- </dependency>--> | ||
52 | + <dependency> | ||
53 | + <groupId>mysql</groupId> | ||
54 | + <artifactId>mysql-connector-java</artifactId> | ||
55 | + </dependency> | ||
56 | + <dependency> | ||
57 | + <groupId>com.alibaba</groupId> | ||
58 | + <artifactId>druid-spring-boot-starter</artifactId> | ||
59 | + </dependency> | ||
60 | + | ||
61 | + <dependency> | ||
62 | + <groupId>org.springframework.boot</groupId> | ||
63 | + <artifactId>spring-boot-starter-log4j2</artifactId> | ||
64 | + </dependency> | ||
65 | + | ||
66 | + | ||
67 | + <dependency> | ||
68 | + <groupId>com.alibaba</groupId> | ||
69 | + <artifactId>fastjson</artifactId> | ||
70 | + </dependency> | ||
71 | + | ||
72 | + <dependency> | ||
73 | + <groupId>cn.hutool</groupId> | ||
74 | + <artifactId>hutool-crypto</artifactId> | ||
75 | + </dependency> | ||
76 | + | ||
77 | + <dependency> | ||
78 | + <groupId>org.apache.commons</groupId> | ||
79 | + <artifactId>commons-pool2</artifactId> | ||
80 | + </dependency> | ||
81 | + <dependency> | ||
82 | + <groupId>org.apache.commons</groupId> | ||
83 | + <artifactId>commons-lang3</artifactId> | ||
84 | + </dependency> | ||
85 | + | ||
86 | + | ||
87 | + <!--工具包--> | ||
88 | + <dependency> | ||
89 | + <groupId>cn.hutool</groupId> | ||
90 | + <artifactId>hutool-all</artifactId> | ||
91 | + </dependency> | ||
92 | + | ||
93 | + <dependency> | ||
94 | + <groupId>joda-time</groupId> | ||
95 | + <artifactId>joda-time</artifactId> | ||
96 | + </dependency> | ||
97 | + <dependency> | ||
98 | + <groupId>com.google.guava</groupId> | ||
99 | + <artifactId>guava</artifactId> | ||
100 | + </dependency> | ||
101 | + </dependencies> | ||
102 | + <build> | ||
103 | + <finalName>job.services-1.0-SNAPSHOT</finalName> | ||
104 | + <plugins> | ||
105 | + <plugin> | ||
106 | + <groupId>org.apache.maven.plugins</groupId> | ||
107 | + <artifactId>maven-source-plugin</artifactId> | ||
108 | + </plugin> | ||
109 | + | ||
110 | + <plugin> | ||
111 | + <groupId>org.springframework.boot</groupId> | ||
112 | + <artifactId>spring-boot-maven-plugin</artifactId> | ||
113 | + <configuration> | ||
114 | + <executable>true</executable> | ||
115 | + </configuration> | ||
116 | + </plugin> | ||
117 | + | ||
118 | + </plugins> | ||
119 | + </build> | ||
120 | +</project> | ||
0 | \ No newline at end of file | 121 | \ No newline at end of file |
job/src/main/java/com/canrd/shop/JobApplication.java
0 → 100644
1 | +package com.canrd.shop; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.annotation.DbType; | ||
4 | +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; | ||
5 | +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; | ||
6 | +import com.canrd.shop.common.Path; | ||
7 | +import org.mybatis.spring.annotation.MapperScan; | ||
8 | +import org.springframework.boot.SpringApplication; | ||
9 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
10 | +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; | ||
11 | +import org.springframework.context.annotation.Bean; | ||
12 | +import org.springframework.scheduling.annotation.EnableScheduling; | ||
13 | +import org.springframework.transaction.annotation.EnableTransactionManagement; | ||
14 | + | ||
15 | +/** | ||
16 | + * @author: xms | ||
17 | + * @description: 管理后台启动 | ||
18 | + * @date: 2023/3/29 18:00 | ||
19 | + * @version: 1.0 | ||
20 | + */ | ||
21 | +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, scanBasePackages = {"com.canrd.shop"}) | ||
22 | +@MapperScan("com.canrd.shop.**.mapper") | ||
23 | +@EnableScheduling | ||
24 | +@EnableTransactionManagement | ||
25 | +public class JobApplication { | ||
26 | + | ||
27 | + private static void setLogPath() { | ||
28 | + String appPath = Path.getAppPath(JobApplication.class); | ||
29 | + System.setProperty("logging.path", appPath); | ||
30 | + } | ||
31 | + | ||
32 | + public static void main(String[] args) { | ||
33 | + setLogPath(); | ||
34 | + SpringApplication.run(JobApplication.class, args); | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * 分页插件 | ||
39 | + * | ||
40 | + * @return | ||
41 | + */ | ||
42 | + @Bean | ||
43 | + public MybatisPlusInterceptor mybatisPlusInterceptor() { | ||
44 | + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); | ||
45 | + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); | ||
46 | + return interceptor; | ||
47 | + } | ||
48 | +} |
job/src/main/java/com/canrd/shop/common/Path.java
0 → 100644
1 | +package com.canrd.shop.common; | ||
2 | + | ||
3 | + | ||
4 | +import com.canrd.shop.common.constant.Constant; | ||
5 | + | ||
6 | +/** | ||
7 | + * @author xms | ||
8 | + */ | ||
9 | +public class Path { | ||
10 | + /** | ||
11 | + * 获取程序启动路径 | ||
12 | + * | ||
13 | + * @param cls,建议直接传 ServiceApplication.class | ||
14 | + * @return 应用启动路径 | ||
15 | + */ | ||
16 | + public static String getAppPath(Class cls) { | ||
17 | + String path = cls.getResource(Constant.SLASH_MARK_CHARACTER).getPath(); | ||
18 | + String os = System.getProperty("os.name").toLowerCase(); | ||
19 | + final String OSWINDOW = "windows"; | ||
20 | + if (os.indexOf(OSWINDOW) != -1 && path.length() > 1) { | ||
21 | + //windows路径样例: /D:/work/code/shop-services/online-shop-oss/target/classes/ | ||
22 | + return path.substring(1); | ||
23 | + } | ||
24 | + | ||
25 | + //linux 路径样例 file:/opt/target/online-shop-oss-SNAPSHOT.jar!/BOOT-INF/classes!/"; | ||
26 | + final String FILE = "file:"; | ||
27 | + if (path.indexOf(FILE) != -1) { | ||
28 | + path = path.substring(FILE.length()); | ||
29 | + } | ||
30 | + | ||
31 | + int pos = -1; | ||
32 | + if ((pos = path.indexOf(Constant.EXCLAMATION_MARK_CHARACTER)) != -1) { | ||
33 | + if (-1 != (pos = path.lastIndexOf(Constant.SLASH_MARK_CHARACTER, pos))) { | ||
34 | + path = path.substring(0, pos + 1); | ||
35 | + } | ||
36 | + } | ||
37 | + | ||
38 | + return path; | ||
39 | + } | ||
40 | +} |
job/src/main/java/com/canrd/shop/common/constant/Constant.java
0 → 100644
1 | +package com.canrd.shop.common.constant; | ||
2 | + | ||
3 | +import java.util.Arrays; | ||
4 | +import java.util.List; | ||
5 | + | ||
6 | +public class Constant { | ||
7 | + /** | ||
8 | + * 分隔符英文的横杠 | ||
9 | + */ | ||
10 | + public static final String CROSS_BAR_CHARACTER = "-"; | ||
11 | + /** | ||
12 | + * 英文的 . | ||
13 | + */ | ||
14 | + public static final String POINT_BAR_CHARACTER = "."; | ||
15 | + /** | ||
16 | + * 英文的 ! | ||
17 | + */ | ||
18 | + public static final String EXCLAMATION_MARK_CHARACTER = "!"; | ||
19 | + /** | ||
20 | + * 英文的 / | ||
21 | + */ | ||
22 | + public static final String SLASH_MARK_CHARACTER = "/"; | ||
23 | + /** | ||
24 | + * 英文的 : | ||
25 | + */ | ||
26 | + public static final String COLON_CHARACTER = ":"; | ||
27 | + | ||
28 | + /** | ||
29 | + * 英文的 ; | ||
30 | + */ | ||
31 | + public static final String SEMICOLON_CHARACTER = ";"; | ||
32 | + | ||
33 | + /** | ||
34 | + * 英文的逗号 | ||
35 | + */ | ||
36 | + public static final String COMMA_CHARACTER = ","; | ||
37 | + /** | ||
38 | + * 英文的*号 | ||
39 | + */ | ||
40 | + public static final String START_CHARACTER = "*"; | ||
41 | + /** | ||
42 | + * 分隔符 | ||
43 | + */ | ||
44 | + public static final String SPLIT_SYMBOL = ",|,"; | ||
45 | + | ||
46 | + /** | ||
47 | + * 特殊分隔符 _ | ||
48 | + */ | ||
49 | + public static final String SPECIAL_KEY = "_"; | ||
50 | + | ||
51 | + | ||
52 | + /** | ||
53 | + * 括号 | ||
54 | + */ | ||
55 | + public static final String BRACKETS_RIGHT = "]"; | ||
56 | + /** | ||
57 | + * 括号 | ||
58 | + */ | ||
59 | + public static final String BRACKETS_LEFT = "["; | ||
60 | + | ||
61 | + /** | ||
62 | + * 手机号码正则校验 | ||
63 | + */ | ||
64 | + public static final String PHONE_REGEXP = "^[1][3,4,5,6,7,8,9][0-9]{9}$"; | ||
65 | + | ||
66 | + /** | ||
67 | + * 脱敏手机号 | ||
68 | + */ | ||
69 | + public static final String PHONE_DESENSITIZATION_REGEXP = "^[1][3,4,5,6,7,8,9][0-9][*]{4}[0-9]{4}$"; | ||
70 | + | ||
71 | + /** | ||
72 | + * 邮箱 | ||
73 | + */ | ||
74 | + public static final String EMAIL_REGEXP = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$"; | ||
75 | + | ||
76 | + /** | ||
77 | + * 三位数字 | ||
78 | + */ | ||
79 | + public static final String THREE_DIGITS_REGEXP = "\\d{3}"; | ||
80 | + | ||
81 | + /** | ||
82 | + * 中文 英文 数字 | ||
83 | + */ | ||
84 | + public static final String CHI_EN_NUM_REGEXP = "^[A-z0-9\\u4e00-\\u9fa5]*$"; | ||
85 | + | ||
86 | + | ||
87 | + /** | ||
88 | + * 仅包含英文和数字 | ||
89 | + */ | ||
90 | + public static final String EN_REGEXP = "^[a-zA-Z]+$"; | ||
91 | + | ||
92 | + public static final String EN_NUM_REGEXP = "^[a-z0-9A-Z]+$"; | ||
93 | + | ||
94 | + public static final String LINE_EN_NUM_REGEXP = "^[a-z0-9A-Z\\-]+$"; | ||
95 | + | ||
96 | + /** | ||
97 | + * 仅包含英文和中文 | ||
98 | + */ | ||
99 | + public static final String CHI_EN_REGEXP = "^[A-z\\u4e00-\\u9fa5]*$"; | ||
100 | + | ||
101 | + /** | ||
102 | + * 纯数字 | ||
103 | + */ | ||
104 | + public static final String NUMERIC_REGEXP = "^\\d+$"; | ||
105 | + /** | ||
106 | + * 纯中文 | ||
107 | + */ | ||
108 | + public static final String CHI_REGEXP = "^[\u4e00-\u9fa5]+$"; | ||
109 | + /** | ||
110 | + * 不超过两位小数 | ||
111 | + */ | ||
112 | + public static final String DICMAL_REGEXP = "^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,3})?$"; | ||
113 | + | ||
114 | + /** | ||
115 | + * 默认空字符串 | ||
116 | + */ | ||
117 | + public static final String EMPTY_STRING = ""; | ||
118 | + | ||
119 | + /** | ||
120 | + * 统一返回data的key | ||
121 | + */ | ||
122 | + public static final String RESULT_CHARACTER = "result"; | ||
123 | + | ||
124 | + /** | ||
125 | + * 统一返回data的key | ||
126 | + */ | ||
127 | + public static final String SUCCESS_RESULT_CHARACTER = "success"; | ||
128 | + | ||
129 | + /** | ||
130 | + * 返回的默认结果集 | ||
131 | + */ | ||
132 | + public static final String RESULT_FAIL = null; | ||
133 | + | ||
134 | + /** | ||
135 | + * ENABLE_FLAG | ||
136 | + */ | ||
137 | + public static final String ENABLE_FLAG = "enable_flag"; | ||
138 | + | ||
139 | + /** | ||
140 | + * 是否可用 10-可用 20-删除 | ||
141 | + */ | ||
142 | + public static final int ENABLE_TEN = 10; | ||
143 | + /** | ||
144 | + * 是否可用 10-可用 20-删除 | ||
145 | + */ | ||
146 | + public static final int UNABLE_TWENTY = 20; | ||
147 | + | ||
148 | + public static final int ONE = 1; | ||
149 | + | ||
150 | + public static final Integer INTEGER_ONE = 1; | ||
151 | + | ||
152 | + public static final int TWO = 2; | ||
153 | + | ||
154 | + public static final int THREE = 3; | ||
155 | + | ||
156 | + public static final int FOUR = 4; | ||
157 | + | ||
158 | + public static final int FIVE = 5; | ||
159 | + | ||
160 | + public static final int SIX = 6; | ||
161 | + | ||
162 | + public static final int SEVEN = 7; | ||
163 | + | ||
164 | + public static final int THIRTY = 30; | ||
165 | + | ||
166 | + public static final int NINETEEN = 19; | ||
167 | + | ||
168 | + public static final int THOUSAND = 1000; | ||
169 | + | ||
170 | + public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss"; | ||
171 | + | ||
172 | + public static final int ZERO = 0; | ||
173 | + | ||
174 | + public static final String STRING_ZERO = "0"; | ||
175 | + | ||
176 | + public static final String ZERO_STRING = "0"; | ||
177 | + | ||
178 | + public static final String THOUSAND_STRING = "1000"; | ||
179 | + | ||
180 | + public static final String SYSTEM_USER = "System"; | ||
181 | + | ||
182 | + public static final String percent50 = "0.5"; | ||
183 | + | ||
184 | + public static final String DELETE_SUCCESS_RESULT_CHARACTER = "删除成功"; | ||
185 | + | ||
186 | + | ||
187 | + /** | ||
188 | + * token rediskey | ||
189 | + */ | ||
190 | + public static final String TOKEN_FLAG = "token:"; | ||
191 | + /** | ||
192 | + * token 限制api请求 | ||
193 | + */ | ||
194 | + public static final String PERMISSION_API_LIMIT = "token_api_limit:"; | ||
195 | + | ||
196 | + /** | ||
197 | + * token过期时间 | ||
198 | + */ | ||
199 | + public static final Integer TOKEN_EXPIRE_HOURS = 1; | ||
200 | + /** | ||
201 | + * 密码3次错误锁定 | ||
202 | + */ | ||
203 | + public static final int LOCK_ERROR_TIMES = 3; | ||
204 | + | ||
205 | + /** | ||
206 | + * session字段 | ||
207 | + */ | ||
208 | + public static final String HEAD_TOKEN = "Authorization"; | ||
209 | + public static final String ACCESS_TOKEN = "token"; | ||
210 | + public static final String REQUEST_ORIGIN = "source"; | ||
211 | + public static final String REQUEST_IP = "ip"; | ||
212 | + public static final String USER_INFO = "userInfo"; | ||
213 | + public static final String FILED_ID = "id"; | ||
214 | + public static final String FILED_USER_NAME = "username"; | ||
215 | + public static final String FILED_DEVICE_NUM = "deviceNum"; | ||
216 | + | ||
217 | + /** | ||
218 | + * 请求来源 | ||
219 | + */ | ||
220 | + public static final String ORIGIN_WEB = "WEB"; | ||
221 | + public static final String ORIGIN_PDA = "PDA"; | ||
222 | + | ||
223 | + /** | ||
224 | + * 1001 参数校验不通过 | ||
225 | + * 1002 签名验证不通过 | ||
226 | + */ | ||
227 | + public static final List<String> ERROR_CODE_LIST = Arrays.asList("1001", "1002"); | ||
228 | + | ||
229 | + /** | ||
230 | + * 分布式锁超时时间 | ||
231 | + */ | ||
232 | + public static final long REDIS_LOCK_DEFAULT_TIME_OUT_MILLIS = 3000; | ||
233 | + public static final long REDIS_LOCK_FIVE_SECONDS_TIME_OUT_MILLIS = 5000; | ||
234 | + | ||
235 | + /** | ||
236 | + * 系统来源WMS | ||
237 | + */ | ||
238 | + public static final String SYS_ORIGIN_WMS = "WMS"; | ||
239 | + | ||
240 | + public static final String STRING_ONE = "1"; | ||
241 | + | ||
242 | + | ||
243 | + public static final String STRING_TWO = "2"; | ||
244 | + | ||
245 | + public static final String STRING_THREE = "3"; | ||
246 | + | ||
247 | + public static final String STRING_FOUR = "4"; | ||
248 | + | ||
249 | + public static final String STRING_FIVE = "5"; | ||
250 | + | ||
251 | + public static final String STRING_SIX = "6"; | ||
252 | + | ||
253 | + public static final String STRING_SEVEN = "7"; | ||
254 | + | ||
255 | + public static final String STRING_EIGHT = "8"; | ||
256 | + | ||
257 | + public static final String STRING_NINE = "9"; | ||
258 | + | ||
259 | + public static final String STRING_TEN = "10"; | ||
260 | + | ||
261 | + public static final String STRING_ELEVEN = "11"; | ||
262 | + | ||
263 | + public static final String STRING_TWELVE = "12"; | ||
264 | + | ||
265 | + /** | ||
266 | + * 异常延时队列后缀 | ||
267 | + */ | ||
268 | + public static final String ERROR_DELAY_QUEUE_SUFFIX = "error"; | ||
269 | + | ||
270 | + /** | ||
271 | + * 推送出库数据延时队列 redis key prefix | ||
272 | + */ | ||
273 | + public static final String OUTBOUND_NOTIFY_DELAY_QUEUE_PREFIX = "outbound:notify:"; | ||
274 | + | ||
275 | + /** | ||
276 | + * 同步MES库存队列 redis key prefix | ||
277 | + */ | ||
278 | + public static final String MES_STOCK_SYNC_QUEUE_PREFIX = "mes:stock_sync:"; | ||
279 | + | ||
280 | + /** | ||
281 | + * 分拣详情 错误码: 157205 返回值段 | ||
282 | + */ | ||
283 | + public static final String SEPARATE_PICK_QUERY_RETURN_FIELD = "separatePickQuery"; | ||
284 | + /** | ||
285 | + * 限制上限值 | ||
286 | + */ | ||
287 | + public static final Integer LIMIT_999 = 999; | ||
288 | + | ||
289 | + /** | ||
290 | + * 东八区 | ||
291 | + */ | ||
292 | + public static final String GMT_8 = "GMT+8"; | ||
293 | + | ||
294 | + /** | ||
295 | + * 英文的 " | ||
296 | + */ | ||
297 | + public static final String QUOTATION_MARK_CHARACTER = "\""; | ||
298 | + | ||
299 | + | ||
300 | + /** | ||
301 | + * 英文的 \" | ||
302 | + */ | ||
303 | + public static final String QUOTATION_SLASH_MARK_CHARACTER = "\\\""; | ||
304 | + | ||
305 | + public static final String SUCCESS_VALUE = "success"; | ||
306 | + | ||
307 | + | ||
308 | + public static final String TRUE = "true"; | ||
309 | + | ||
310 | + public static final String ROOT_PARENT_ID = "0"; | ||
311 | + | ||
312 | + public static final Long ROOT_PARENT_ID_LONG = 0L; | ||
313 | + | ||
314 | + | ||
315 | + /** | ||
316 | + * 短信验证码 redis key | ||
317 | + */ | ||
318 | + public static final String SMS_AUTH_CODE_PREFIX = "sms:auth:code:"; | ||
319 | + | ||
320 | + public static final String DEFAULT_PASSWORD = "JBXT123456"; | ||
321 | + | ||
322 | + /** | ||
323 | + * 账号在线队列 redis key | ||
324 | + */ | ||
325 | + public static final String ACCOUNT_ONLINE_LIST = "account:online:"; | ||
326 | + | ||
327 | + /** | ||
328 | + * 缓存导入excel错误信息 redis key | ||
329 | + */ | ||
330 | + public static final String EXCEL_IMPORT_ERROR_PREFIX = "excel:import:error:"; | ||
331 | + | ||
332 | +} |
job/src/main/java/com/canrd/shop/common/constant/ServerResult.java
0 → 100644
1 | +package com.canrd.shop.common.constant; | ||
2 | + | ||
3 | + | ||
4 | +import java.io.Serializable; | ||
5 | +import java.util.HashMap; | ||
6 | +import java.util.Map; | ||
7 | + | ||
8 | +/** | ||
9 | + * @author : dengbin | ||
10 | + * @Date: 2020/9/5 | ||
11 | + * 统一的返回结果实体 | ||
12 | + */ | ||
13 | +public class ServerResult<T> implements Serializable { | ||
14 | + /** | ||
15 | + * 序列化ID | ||
16 | + */ | ||
17 | + private static final long serialVersionUID = -5809782578272943999L; | ||
18 | + /** | ||
19 | + * 返回的状态码 | ||
20 | + */ | ||
21 | + private int result = ServerResultCode.SUCCESS.getErrorCode(); | ||
22 | + /** | ||
23 | + * 返回的消息 | ||
24 | + */ | ||
25 | + private String message = ServerResultCode.SUCCESS.getErrorDesc(); | ||
26 | + /** | ||
27 | + * 返回的数据实体 | ||
28 | + */ | ||
29 | + private T data = null; | ||
30 | + /** | ||
31 | + * | ||
32 | + */ | ||
33 | + final int INIT_SIZE = 128; | ||
34 | + | ||
35 | + /** | ||
36 | + * | ||
37 | + */ | ||
38 | + public ServerResult() { | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public String toString() { | ||
43 | + StringBuilder buffer = new StringBuilder(INIT_SIZE); | ||
44 | + buffer.append("{\"result\":").append(this.result); | ||
45 | + buffer.append(",\"message\":\"").append(this.message != null ? message : "").append("\""); | ||
46 | + buffer.append(",\"data\":").append(data).append("}"); | ||
47 | + return buffer.toString(); | ||
48 | + } | ||
49 | + | ||
50 | + public int getResult() { | ||
51 | + return result; | ||
52 | + } | ||
53 | + | ||
54 | + public ServerResult setResult(int result) { | ||
55 | + this.result = result; | ||
56 | + return this; | ||
57 | + } | ||
58 | + | ||
59 | + public ServerResult setResult(ServerResultCode serverResultCode) { | ||
60 | + this.result = serverResultCode.getErrorCode(); | ||
61 | + this.message = serverResultCode.getErrorDesc(); | ||
62 | + return this; | ||
63 | + } | ||
64 | + | ||
65 | + public ServerResult setResult(int errorCode, String errorDesc) { | ||
66 | + this.result = errorCode; | ||
67 | + this.message = errorDesc; | ||
68 | + return this; | ||
69 | + } | ||
70 | + | ||
71 | + public String getMessage() { | ||
72 | + return message; | ||
73 | + } | ||
74 | + | ||
75 | + public ServerResult<T> setMessage(String message) { | ||
76 | + this.message = message; | ||
77 | + return this; | ||
78 | + } | ||
79 | + | ||
80 | + public T getData() { | ||
81 | + return data; | ||
82 | + } | ||
83 | + | ||
84 | + public ServerResult setData(T data) { | ||
85 | + this.data = data; | ||
86 | + return this; | ||
87 | + } | ||
88 | + | ||
89 | + public static <T> ServerResult<T> success() { | ||
90 | + return new ServerResult() | ||
91 | + .setResult(ServerResultCode.SUCCESS) | ||
92 | + .setMessage(ServerResultCode.SUCCESS.getErrorDesc()) | ||
93 | + .setData(defaultResult(ServerResultCode.SUCCESS)); | ||
94 | + } | ||
95 | + | ||
96 | + public static <T> ServerResult<T> success(T data) { | ||
97 | + return new ServerResult() | ||
98 | + .setResult(ServerResultCode.SUCCESS) | ||
99 | + .setMessage(ServerResultCode.SUCCESS.getErrorDesc()) | ||
100 | + .setData(data); | ||
101 | + } | ||
102 | + | ||
103 | + public static <T> ServerResult<T> success(T data, String message) { | ||
104 | + return new ServerResult() | ||
105 | + .setResult(ServerResultCode.SUCCESS) | ||
106 | + .setMessage(message) | ||
107 | + .setData(data); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * @description 错误码使用系统错误 1000 错误类型自定义 | ||
112 | + * @author dengbin | ||
113 | + * @date 2020/9/12 | ||
114 | + */ | ||
115 | + public static <T> ServerResult<T> fail(String message) { | ||
116 | + return new ServerResult() | ||
117 | + .setResult(ServerResultCode.FAIL) | ||
118 | + .setMessage(message) | ||
119 | + .setData(defaultResult(Constant.RESULT_FAIL)); | ||
120 | + } | ||
121 | + | ||
122 | + /** | ||
123 | + * 错误时需要返回相关数据时使用 | ||
124 | + * | ||
125 | + * @param data | ||
126 | + * @param <T> | ||
127 | + * @return | ||
128 | + */ | ||
129 | + public static <T> ServerResult<T> fail(T data, ServerResultCode serverResultCode) { | ||
130 | + return new ServerResult() | ||
131 | + .setData(data) | ||
132 | + .setResult(serverResultCode) | ||
133 | + .setMessage(serverResultCode.getErrorDesc()); | ||
134 | + } | ||
135 | + | ||
136 | + /** | ||
137 | + * 错误时需要返回相关数据时使用(不设值 data) | ||
138 | + * | ||
139 | + * @param sr | ||
140 | + * @param | ||
141 | + * @return | ||
142 | + */ | ||
143 | + public static <T> ServerResult<T> fail(ServerResult<?> sr) { | ||
144 | + return new ServerResult<>() | ||
145 | + .setMessage(sr.getMessage()) | ||
146 | + .setResult(sr.getResult()); | ||
147 | + | ||
148 | + } | ||
149 | + | ||
150 | + /** | ||
151 | + * @description 错误码使用上面的枚举定义的,错误信息重新定义 | ||
152 | + * @author dengbin | ||
153 | + * @date 2020/9/12 | ||
154 | + */ | ||
155 | + public static <T> ServerResult<T> fail(ServerResultCode serverResultCode, String msg) { | ||
156 | + return new ServerResult() | ||
157 | + .setResult(serverResultCode) | ||
158 | + .setMessage(msg) | ||
159 | + .setData(defaultResult(Constant.RESULT_FAIL)); | ||
160 | + } | ||
161 | + | ||
162 | + /** | ||
163 | + * @return | ||
164 | + * @description 直接选用上面的枚举错误码,输出定义的错误信息 | ||
165 | + * @author dengbin | ||
166 | + * @date 2020/9/12 | ||
167 | + */ | ||
168 | + public static <T> ServerResult<T> fail(ServerResultCode serverResultCode) { | ||
169 | + return new ServerResult() | ||
170 | + .setResult(serverResultCode) | ||
171 | + .setMessage(serverResultCode.getErrorDesc()) | ||
172 | + .setData(defaultResult(Constant.RESULT_FAIL)); | ||
173 | + } | ||
174 | + | ||
175 | + /** | ||
176 | + * 错误时需要返回相关数据时使用 | ||
177 | + * | ||
178 | + * @param data | ||
179 | + * @param <T> | ||
180 | + * @return | ||
181 | + */ | ||
182 | + public static <T> ServerResult<T> fail(T data, int errorCode, String errorDesc) { | ||
183 | + return new ServerResult() | ||
184 | + .setData(data) | ||
185 | + .setResult(errorCode, errorDesc); | ||
186 | + } | ||
187 | + | ||
188 | + | ||
189 | + public static <T> ServerResult<T> fail() { | ||
190 | + return new ServerResult() | ||
191 | + .setResult(ServerResultCode.FAIL.getErrorCode()) | ||
192 | + .setMessage(ServerResultCode.FAIL.getErrorDesc()) | ||
193 | + .setData(defaultResult(Constant.RESULT_FAIL)); | ||
194 | + } | ||
195 | + | ||
196 | + | ||
197 | + /** | ||
198 | + * @description 直接选用上面的枚举错误码,输出定义的错误信息 | ||
199 | + * @author dengbin | ||
200 | + * @date 2020/9/12 | ||
201 | + */ | ||
202 | + public ServerResult failEnum(ServerResultCode serverResultCode) { | ||
203 | + setResult(serverResultCode); | ||
204 | + setMessage(serverResultCode.getErrorDesc()); | ||
205 | + return this; | ||
206 | + } | ||
207 | + | ||
208 | + public static <T> ServerResult<T> fail(int errorCode, String errorDesc) { | ||
209 | + return new ServerResult() | ||
210 | + .setResult(errorCode, errorDesc) | ||
211 | + .setData(defaultResult(Constant.RESULT_FAIL)); | ||
212 | + | ||
213 | + } | ||
214 | + | ||
215 | + /** | ||
216 | + * 判断当前的状态码是否是SUCCESS | ||
217 | + * | ||
218 | + * @return 结果 ture or false | ||
219 | + */ | ||
220 | + public boolean checkSuccess() { | ||
221 | + return result == ServerResultCode.SUCCESS.getErrorCode(); | ||
222 | + } | ||
223 | + | ||
224 | + public boolean checkNotSuccess() { | ||
225 | + return !checkSuccess(); | ||
226 | + } | ||
227 | + | ||
228 | + private static Map<String, Object> defaultResult(Object object) { | ||
229 | + Map<String, Object> map = new HashMap<>(Constant.ONE); | ||
230 | + map.put(Constant.RESULT_CHARACTER, null); | ||
231 | + return map; | ||
232 | + } | ||
233 | +} |
job/src/main/java/com/canrd/shop/common/constant/ServerResultCode.java
0 → 100644
1 | +package com.canrd.shop.common.constant; | ||
2 | + | ||
3 | + | ||
4 | +import com.canrd.shop.common.exception.ErrorInfo; | ||
5 | +import lombok.Setter; | ||
6 | + | ||
7 | + | ||
8 | +/** | ||
9 | + * 请求成功 返回 0 | ||
10 | + */ | ||
11 | +public enum ServerResultCode implements ErrorInfo { | ||
12 | + //成功 "0" | ||
13 | + SUCCESS(0, "成功"), | ||
14 | + FAIL(1000, "系统内部错误,请联系业务系统运维管理员"), | ||
15 | + FIlE_UPLOAD_TOO_LARGE(1051, "上传文件太大,图片文件一般小于2兆"), | ||
16 | + | ||
17 | + //空指针异常 | ||
18 | + NULL_POINT(1001, "空指针异常"), | ||
19 | + | ||
20 | + //校验异常 | ||
21 | + RUN_ERROR(1002, "程序运行报错"), | ||
22 | + ILLEGAL_ARGUMENT(1003, "参数非法"), | ||
23 | + FILED_ERROR(1004, "传入参数错误"), | ||
24 | + PARAM_ERROR(1005, "入参为空"), | ||
25 | + EMPTY_RESULT(1006, "数据不存在"), | ||
26 | + EMPTY_LIST(1007, "查询结果为空"), | ||
27 | + | ||
28 | + //认证授权异常 | ||
29 | + UNAUTHENTICATION(401, "未登录"), | ||
30 | + | ||
31 | + | ||
32 | + //用户 | ||
33 | + USER_NOT_EXIT(20001, "用户不存在"), | ||
34 | + | ||
35 | + | ||
36 | + // 公司 | ||
37 | + COMPANY_NOT_EXIT(30001, "公司不存在"), | ||
38 | + ; | ||
39 | + | ||
40 | + | ||
41 | + ServerResultCode(Integer errorCode, String errorDesc) { | ||
42 | + this.errorCode = errorCode; | ||
43 | + this.errorDesc = errorDesc; | ||
44 | + } | ||
45 | + | ||
46 | + @Setter | ||
47 | + private Integer errorCode; | ||
48 | + @Setter | ||
49 | + private String errorDesc; | ||
50 | + | ||
51 | + @Override | ||
52 | + public Integer getErrorCode() { | ||
53 | + return this.errorCode; | ||
54 | + } | ||
55 | + | ||
56 | + @Override | ||
57 | + public String getErrorDesc() { | ||
58 | + return this.errorDesc; | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * 根据errorCode获得枚举 | ||
63 | + * | ||
64 | + * @param errorCode | ||
65 | + * @return | ||
66 | + */ | ||
67 | + public static String getDescByCode(Integer errorCode) { | ||
68 | + if (errorCode == null) { | ||
69 | + return null; | ||
70 | + } | ||
71 | + ServerResultCode[] serverResults = values(); | ||
72 | + for (ServerResultCode serverResult : serverResults) { | ||
73 | + if (serverResult.getErrorCode().equals(errorCode)) { | ||
74 | + return serverResult.getErrorDesc(); | ||
75 | + } | ||
76 | + } | ||
77 | + return null; | ||
78 | + } | ||
79 | + | ||
80 | +} | ||
0 | \ No newline at end of file | 81 | \ No newline at end of file |
job/src/main/java/com/canrd/shop/common/exception/BadRequestException.java
0 → 100644
1 | +package com.canrd.shop.common.exception; | ||
2 | + | ||
3 | +import lombok.Getter; | ||
4 | +import org.springframework.http.HttpStatus; | ||
5 | + | ||
6 | +import static org.springframework.http.HttpStatus.BAD_REQUEST; | ||
7 | + | ||
8 | +/** | ||
9 | + * | ||
10 | + * @date 2018-11-23 | ||
11 | + * 统一异常处理 | ||
12 | + */ | ||
13 | +@Getter | ||
14 | +public class BadRequestException extends RuntimeException { | ||
15 | + | ||
16 | + private Integer status = BAD_REQUEST.value(); | ||
17 | + | ||
18 | + public BadRequestException(String msg) { | ||
19 | + super(msg); | ||
20 | + } | ||
21 | + | ||
22 | + public BadRequestException(HttpStatus status, String msg) { | ||
23 | + super(msg); | ||
24 | + this.status = status.value(); | ||
25 | + } | ||
26 | +} |
job/src/main/java/com/canrd/shop/common/exception/BusinessException.java
0 → 100644
1 | +package com.canrd.shop.common.exception; | ||
2 | + | ||
3 | +import com.canrd.shop.common.constant.ServerResult; | ||
4 | +import com.canrd.shop.common.constant.ServerResultCode; | ||
5 | +import lombok.Getter; | ||
6 | +import lombok.Setter; | ||
7 | +import lombok.extern.slf4j.Slf4j; | ||
8 | + | ||
9 | +/** | ||
10 | + * <p>基础异常类,所有自定义异常类都需要继承本类</p> | ||
11 | + * | ||
12 | + * @author A80076 | ||
13 | + * @date 2021/1/11 | ||
14 | + */ | ||
15 | +@Slf4j | ||
16 | +public class BusinessException extends RuntimeException { | ||
17 | + | ||
18 | + private static final long serialVersionUID = 3152549963899218489L; | ||
19 | + @Setter | ||
20 | + @Getter | ||
21 | + private String errorDesc; | ||
22 | + @Setter | ||
23 | + @Getter | ||
24 | + private Integer errorCode; | ||
25 | + @Setter | ||
26 | + @Getter | ||
27 | + private Object data; | ||
28 | + | ||
29 | + public BusinessException() { | ||
30 | + super(ServerResultCode.FAIL.getErrorDesc()); | ||
31 | + this.errorCode = ServerResultCode.FAIL.getErrorCode(); | ||
32 | + this.errorDesc = ServerResultCode.FAIL.getErrorDesc(); | ||
33 | + } | ||
34 | + | ||
35 | + public BusinessException(int errorCode, String errorDesc) { | ||
36 | + super(errorDesc); | ||
37 | + this.errorCode = errorCode; | ||
38 | + this.errorDesc = errorDesc; | ||
39 | + } | ||
40 | + | ||
41 | + public BusinessException(ServerResultCode serverResultCode) { | ||
42 | + super(serverResultCode.getErrorDesc()); | ||
43 | + this.errorCode = serverResultCode.getErrorCode(); | ||
44 | + this.errorDesc = serverResultCode.getErrorDesc(); | ||
45 | + log.error("业务异常: ", this); | ||
46 | + } | ||
47 | + | ||
48 | + public BusinessException(ErrorInfo errorInfo) { | ||
49 | + super(errorInfo.getErrorDesc()); | ||
50 | + this.errorCode = errorInfo.getErrorCode(); | ||
51 | + this.errorDesc = errorInfo.getErrorDesc(); | ||
52 | + log.error("业务异常: ", this); | ||
53 | + } | ||
54 | + | ||
55 | + public BusinessException(ServerResult<?> serverResult) { | ||
56 | + super(serverResult == null ? ServerResultCode.FAIL.getErrorDesc() : serverResult.getMessage()); | ||
57 | + if (serverResult == null) { | ||
58 | + this.errorCode = ServerResultCode.FAIL.getErrorCode(); | ||
59 | + this.errorDesc = ServerResultCode.FAIL.getErrorDesc(); | ||
60 | + } else { | ||
61 | + this.errorCode = serverResult.getResult(); | ||
62 | + this.errorDesc = serverResult.getMessage(); | ||
63 | + this.data = serverResult.getData(); | ||
64 | + } | ||
65 | + log.error("业务异常: ", this); | ||
66 | + } | ||
67 | + | ||
68 | + public BusinessException(String message) { | ||
69 | + super(message); | ||
70 | + } | ||
71 | + | ||
72 | + public BusinessException(Throwable cause) { | ||
73 | + super(cause); | ||
74 | + log.error("业务异常: ", this); | ||
75 | + } | ||
76 | + | ||
77 | + public BusinessException(String message, Throwable cause) { | ||
78 | + super(message, cause); | ||
79 | + log.error("业务异常: ", this); | ||
80 | + } | ||
81 | +} |
job/src/main/java/com/canrd/shop/common/exception/BusinessExceptionHandlerAdvice.java
0 → 100644
1 | +package com.canrd.shop.common.exception; | ||
2 | + | ||
3 | +import com.canrd.shop.common.constant.ServerResult; | ||
4 | +import com.canrd.shop.common.constant.ServerResultCode; | ||
5 | +import org.springframework.core.annotation.Order; | ||
6 | +import org.springframework.http.HttpStatus; | ||
7 | +import org.springframework.http.ResponseEntity; | ||
8 | +import org.springframework.web.bind.annotation.ControllerAdvice; | ||
9 | +import org.springframework.web.bind.annotation.ExceptionHandler; | ||
10 | +import org.springframework.web.bind.annotation.ResponseStatus; | ||
11 | + | ||
12 | +import java.util.Optional; | ||
13 | + | ||
14 | +/** | ||
15 | + * 业务异常统一处理类 | ||
16 | + * | ||
17 | + * @author A80076 | ||
18 | + * @date 2021/1/11 | ||
19 | + */ | ||
20 | +@ControllerAdvice | ||
21 | +@Order(5) | ||
22 | +public class BusinessExceptionHandlerAdvice { | ||
23 | + | ||
24 | + | ||
25 | + @ExceptionHandler(value = {BusinessException.class}) | ||
26 | + @ResponseStatus(value = HttpStatus.OK) | ||
27 | + public ResponseEntity<Object> handleException(BusinessException exception) throws Exception { | ||
28 | + return new ResponseEntity<Object>(handleBusinessException(exception), HttpStatus.OK); | ||
29 | + } | ||
30 | + | ||
31 | + private ServerResult handleBusinessException(BusinessException exception) { | ||
32 | + Integer code = Optional.ofNullable(exception.getErrorCode()).orElse(ServerResultCode.FAIL.getErrorCode()); | ||
33 | + String msg = Optional.ofNullable(exception.getMessage()).orElse(ServerResultCode.FAIL.getErrorDesc()); | ||
34 | + Object data = Optional.ofNullable(exception.getData()).orElse(null); | ||
35 | + return ServerResult.fail(data, code, msg); | ||
36 | + } | ||
37 | +} |
job/src/main/java/com/canrd/shop/common/exception/EntityExistException.java
0 → 100644
1 | +package com.canrd.shop.common.exception; | ||
2 | + | ||
3 | +import org.springframework.util.StringUtils; | ||
4 | + | ||
5 | +/** | ||
6 | + * | ||
7 | + * @date 2018-11-23 | ||
8 | + */ | ||
9 | +public class EntityExistException extends RuntimeException { | ||
10 | + | ||
11 | + public EntityExistException(Class clazz, String field, String val) { | ||
12 | + super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val)); | ||
13 | + } | ||
14 | + | ||
15 | + private static String generateMessage(String entity, String field, String val) { | ||
16 | + return StringUtils.capitalize(entity) | ||
17 | + + " with " + field + " " + val + " existed"; | ||
18 | + } | ||
19 | +} | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
job/src/main/java/com/canrd/shop/common/exception/EntityNotFoundException.java
0 → 100644
1 | +package com.canrd.shop.common.exception; | ||
2 | + | ||
3 | +import org.springframework.util.StringUtils; | ||
4 | + | ||
5 | +/** | ||
6 | + * | ||
7 | + * @date 2018-11-23 | ||
8 | + */ | ||
9 | +public class EntityNotFoundException extends RuntimeException { | ||
10 | + | ||
11 | + public EntityNotFoundException(Class clazz, String field, String val) { | ||
12 | + super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val)); | ||
13 | + } | ||
14 | + | ||
15 | + private static String generateMessage(String entity, String field, String val) { | ||
16 | + return StringUtils.capitalize(entity) | ||
17 | + + " with " + field + " " + val + " does not exist"; | ||
18 | + } | ||
19 | +} | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
job/src/main/java/com/canrd/shop/common/exception/ErrorInfo.java
0 → 100644
job/src/main/java/com/canrd/shop/common/exception/handler/ApiError.java
0 → 100644
1 | +package com.canrd.shop.common.exception.handler; | ||
2 | + | ||
3 | +import com.fasterxml.jackson.annotation.JsonFormat; | ||
4 | +import lombok.Data; | ||
5 | + | ||
6 | +import java.time.LocalDateTime; | ||
7 | + | ||
8 | +/** | ||
9 | + * | ||
10 | + * @date 2018-11-23 | ||
11 | + */ | ||
12 | +@Data | ||
13 | +class ApiError { | ||
14 | + | ||
15 | + private Integer status = 200; | ||
16 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
17 | + private LocalDateTime timestamp; | ||
18 | + private String message; | ||
19 | + private String errorCode; | ||
20 | + | ||
21 | + private ApiError() { | ||
22 | + timestamp = LocalDateTime.now(); | ||
23 | + } | ||
24 | + | ||
25 | + public static ApiError error(String message){ | ||
26 | + ApiError apiError = new ApiError(); | ||
27 | + apiError.setMessage(message); | ||
28 | + return apiError; | ||
29 | + } | ||
30 | + | ||
31 | + public static ApiError error(Integer status, String message){ | ||
32 | + ApiError apiError = new ApiError(); | ||
33 | + apiError.setStatus(status); | ||
34 | + apiError.setMessage(message); | ||
35 | + return apiError; | ||
36 | + } | ||
37 | +} | ||
38 | + | ||
39 | + |
job/src/main/java/com/canrd/shop/common/exception/handler/GlobalExceptionHandler.java
0 → 100644
1 | +package com.canrd.shop.common.exception.handler; | ||
2 | + | ||
3 | + | ||
4 | +import com.canrd.shop.common.constant.ServerResult; | ||
5 | +import com.canrd.shop.common.constant.ServerResultCode; | ||
6 | +import com.canrd.shop.common.exception.BadRequestException; | ||
7 | +import com.canrd.shop.common.exception.BusinessException; | ||
8 | +import com.canrd.shop.common.exception.EntityExistException; | ||
9 | +import com.canrd.shop.common.exception.EntityNotFoundException; | ||
10 | +import com.canrd.shop.common.utils.ThrowableUtil; | ||
11 | +import lombok.extern.slf4j.Slf4j; | ||
12 | +import org.springframework.http.HttpStatus; | ||
13 | +import org.springframework.http.ResponseEntity; | ||
14 | +import org.springframework.web.bind.MethodArgumentNotValidException; | ||
15 | +import org.springframework.web.bind.annotation.ExceptionHandler; | ||
16 | +import org.springframework.web.bind.annotation.ResponseStatus; | ||
17 | +import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
18 | +import org.springframework.web.multipart.MaxUploadSizeExceededException; | ||
19 | + | ||
20 | +import java.util.Objects; | ||
21 | + | ||
22 | +/** | ||
23 | + * @date 2018-11-23 | ||
24 | + */ | ||
25 | +@Slf4j | ||
26 | +@RestControllerAdvice | ||
27 | +public class GlobalExceptionHandler { | ||
28 | + /** | ||
29 | + * @param exception | ||
30 | + * @return | ||
31 | + * @throws Exception | ||
32 | + */ | ||
33 | + @ExceptionHandler(value = RuntimeException.class) | ||
34 | + public ResponseEntity<Object> handleServiceException(Exception exception) throws Exception { | ||
35 | + return new ResponseEntity(translateException(exception), HttpStatus.OK); | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * @param exception | ||
40 | + * @return | ||
41 | + * @throws Exception | ||
42 | + */ | ||
43 | + @ExceptionHandler(value = Exception.class) | ||
44 | + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) | ||
45 | + public ResponseEntity<Object> handleException(Exception exception) throws Exception { | ||
46 | + return new ResponseEntity<Object>(translateException(exception), HttpStatus.OK); | ||
47 | + } | ||
48 | + | ||
49 | + | ||
50 | + /** | ||
51 | + * 处理所有接口数据验证异常 | ||
52 | + * | ||
53 | + * @param e | ||
54 | + * @return | ||
55 | + */ | ||
56 | + @ExceptionHandler(MethodArgumentNotValidException.class) | ||
57 | + public ResponseEntity<ServerResult> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { | ||
58 | + // 打印堆栈信息 | ||
59 | + log.error(ThrowableUtil.getStackTrace(e)); | ||
60 | + String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\."); | ||
61 | + String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage(); | ||
62 | + String msg = "不能为空"; | ||
63 | + if (msg.equals(message)) { | ||
64 | + message = str[1] + ":" + message; | ||
65 | + } | ||
66 | + return buildResponseEntity(ServerResult.fail(message)); | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * 处理自定义异常 | ||
71 | + * | ||
72 | + * @param e | ||
73 | + * @return | ||
74 | + */ | ||
75 | + @ExceptionHandler(value = BadRequestException.class) | ||
76 | + public ResponseEntity<ServerResult> badRequestException(BadRequestException e) { | ||
77 | + // 打印堆栈信息 | ||
78 | + log.error(ThrowableUtil.getStackTrace(e)); | ||
79 | + return buildResponseEntity(ServerResult.fail(e.getStatus(), e.getMessage())); | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * 处理 EntityExist | ||
84 | + */ | ||
85 | + @ExceptionHandler(value = EntityExistException.class) | ||
86 | + public ResponseEntity<ServerResult> entityExistException(EntityExistException e) { | ||
87 | + // 打印堆栈信息 | ||
88 | + log.error(ThrowableUtil.getStackTrace(e)); | ||
89 | + return buildResponseEntity(ServerResult.fail(e.getMessage())); | ||
90 | + } | ||
91 | + | ||
92 | + /** | ||
93 | + * 处理 EntityNotFound | ||
94 | + * | ||
95 | + * @param e | ||
96 | + * @return | ||
97 | + */ | ||
98 | + @ExceptionHandler(value = EntityNotFoundException.class) | ||
99 | + public ResponseEntity<ServerResult> entityNotFoundException(EntityNotFoundException e) { | ||
100 | + // 打印堆栈信息 | ||
101 | + log.error(ThrowableUtil.getStackTrace(e)); | ||
102 | + return buildResponseEntity(ServerResult.fail(HttpStatus.NOT_FOUND.value(), e.getMessage())); | ||
103 | + } | ||
104 | + | ||
105 | + /** | ||
106 | + * @param serverResult | ||
107 | + * @return | ||
108 | + */ | ||
109 | + private ResponseEntity<ServerResult> buildResponseEntity(ServerResult serverResult) { | ||
110 | + return new ResponseEntity<>(serverResult, HttpStatus.valueOf(200)); | ||
111 | + } | ||
112 | + | ||
113 | + /** | ||
114 | + * @param e | ||
115 | + * @return | ||
116 | + * @throws Exception | ||
117 | + */ | ||
118 | + private Object translateException(Exception e) throws Exception { | ||
119 | + ServerResult serverResult = null; | ||
120 | + if (e instanceof NullPointerException) { | ||
121 | + serverResult = ServerResult.fail(ServerResultCode.NULL_POINT); | ||
122 | + } else if (e instanceof IllegalArgumentException) { | ||
123 | + serverResult = ServerResult.fail(ServerResultCode.FAIL); | ||
124 | + } else if (e instanceof MaxUploadSizeExceededException) { | ||
125 | + serverResult = ServerResult.fail(ServerResultCode.FIlE_UPLOAD_TOO_LARGE); | ||
126 | + } else if (e instanceof BusinessException) { | ||
127 | + serverResult = ServerResult.fail(((BusinessException) e).getErrorCode(), ((BusinessException) e).getErrorDesc()); | ||
128 | + } else { | ||
129 | + serverResult = ServerResult.fail(ServerResultCode.FAIL); | ||
130 | + serverResult.setMessage(serverResult.getMessage() + "|,业务异常:" + e.getMessage()); | ||
131 | + } | ||
132 | + | ||
133 | + log.error("业务异常", e); | ||
134 | + return serverResult; | ||
135 | + } | ||
136 | +} |
job/src/main/java/com/canrd/shop/common/jsr303/ListValueConstraintValidator.java
0 → 100644
1 | +package com.canrd.shop.common.jsr303; | ||
2 | + | ||
3 | + | ||
4 | +import com.canrd.shop.common.jsr303.annotation.ListIntValue; | ||
5 | + | ||
6 | +import javax.validation.ConstraintValidator; | ||
7 | +import javax.validation.ConstraintValidatorContext; | ||
8 | +import java.util.HashSet; | ||
9 | +import java.util.Set; | ||
10 | + | ||
11 | +/** | ||
12 | + * 自定义校验注解 -枚举值校验 | ||
13 | + * | ||
14 | + * @author fanzhenyu | ||
15 | + * @date 2023-01-15 | ||
16 | + */ | ||
17 | +public class ListValueConstraintValidator implements ConstraintValidator<ListIntValue, Integer> { | ||
18 | + private Set<Integer> set = new HashSet<>(); | ||
19 | + // 是否必填 | ||
20 | + private boolean require; | ||
21 | + | ||
22 | + @Override | ||
23 | + public void initialize(ListIntValue constraintAnnotation) { | ||
24 | + for (int i : constraintAnnotation.enumValue()) { | ||
25 | + set.add(i); | ||
26 | + } | ||
27 | + require = constraintAnnotation.require(); | ||
28 | + } | ||
29 | + | ||
30 | + /** | ||
31 | + * 判断是否通过校验 | ||
32 | + * | ||
33 | + * @param value 传入的值 | ||
34 | + * @param context | ||
35 | + * @return | ||
36 | + */ | ||
37 | + @Override | ||
38 | + public boolean isValid(Integer value, ConstraintValidatorContext context) { | ||
39 | + if (!require && value == null) { | ||
40 | + return true; | ||
41 | + } | ||
42 | + return set.contains(value); | ||
43 | + } | ||
44 | + | ||
45 | +} |
job/src/main/java/com/canrd/shop/common/jsr303/OperateGroup.java
0 → 100644
1 | +package com.canrd.shop.common.jsr303; | ||
2 | + | ||
3 | + | ||
4 | +public class OperateGroup { | ||
5 | + /** | ||
6 | + * 新增校验 | ||
7 | + */ | ||
8 | + public interface Save { | ||
9 | + } | ||
10 | + | ||
11 | + /** | ||
12 | + * 删除校验 | ||
13 | + */ | ||
14 | + public interface Delete { | ||
15 | + } | ||
16 | + | ||
17 | + /** | ||
18 | + * 修改校验 | ||
19 | + */ | ||
20 | + public interface Update { | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * 查询列表 | ||
25 | + */ | ||
26 | + public interface List { | ||
27 | + } | ||
28 | + | ||
29 | + /** | ||
30 | + * 分页查询 | ||
31 | + */ | ||
32 | + public interface Page { | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * 长度校验 | ||
37 | + */ | ||
38 | + public interface Length { | ||
39 | + } | ||
40 | + | ||
41 | + /** | ||
42 | + * 格式校验 | ||
43 | + */ | ||
44 | + public interface Format { | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * 详情 | ||
49 | + */ | ||
50 | + public interface Detail { | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * 单条 | ||
55 | + */ | ||
56 | + public interface One { | ||
57 | + } | ||
58 | + | ||
59 | + | ||
60 | + public interface Trace { | ||
61 | + | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 批量查询 | ||
66 | + */ | ||
67 | + public interface BatchQuery { | ||
68 | + } | ||
69 | + | ||
70 | + | ||
71 | + /** | ||
72 | + * 导出 | ||
73 | + */ | ||
74 | + public interface Export { | ||
75 | + } | ||
76 | + | ||
77 | +} |
job/src/main/java/com/canrd/shop/common/jsr303/annotation/ListIntValue.java
0 → 100644
1 | +package com.canrd.shop.common.jsr303.annotation; | ||
2 | + | ||
3 | + | ||
4 | +import com.canrd.shop.common.jsr303.ListValueConstraintValidator; | ||
5 | + | ||
6 | +import javax.validation.Constraint; | ||
7 | +import javax.validation.Payload; | ||
8 | +import java.lang.annotation.*; | ||
9 | + | ||
10 | +/** | ||
11 | + * @author fanzhenyu | ||
12 | + * @date 2023-01-15 | ||
13 | + */ | ||
14 | +@Constraint(validatedBy = {ListValueConstraintValidator.class}) | ||
15 | +@Documented | ||
16 | +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) | ||
17 | +@Retention(RetentionPolicy.RUNTIME) | ||
18 | +public @interface ListIntValue { | ||
19 | + | ||
20 | + | ||
21 | + // 配置文件中错误提示信息的名称 | ||
22 | + String message() default "非法的类型"; | ||
23 | + | ||
24 | + Class<?>[] groups() default {}; | ||
25 | + | ||
26 | + Class<? extends Payload>[] payload() default {}; | ||
27 | + | ||
28 | + // 自定义值的类型 | ||
29 | + int[] enumValue() default {}; | ||
30 | + | ||
31 | + // 是否必填,默认允许为空 | ||
32 | + boolean require() default false; | ||
33 | +} |
job/src/main/java/com/canrd/shop/common/utils/EncryptUtils.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import javax.crypto.Cipher; | ||
4 | +import javax.crypto.SecretKey; | ||
5 | +import javax.crypto.SecretKeyFactory; | ||
6 | +import javax.crypto.spec.DESKeySpec; | ||
7 | +import javax.crypto.spec.IvParameterSpec; | ||
8 | +import java.nio.charset.StandardCharsets; | ||
9 | + | ||
10 | +/** | ||
11 | + * 加密 | ||
12 | + * | ||
13 | + * @date 2018-11-23 | ||
14 | + */ | ||
15 | +public class EncryptUtils { | ||
16 | + | ||
17 | + private static String strParam = "Passw0rd"; | ||
18 | + | ||
19 | + private static Cipher cipher; | ||
20 | + | ||
21 | + private static IvParameterSpec iv = new IvParameterSpec(strParam.getBytes(StandardCharsets.UTF_8)); | ||
22 | + | ||
23 | + private static DESKeySpec getDesKeySpec(String source) throws Exception { | ||
24 | + if (source == null || source.length() == 0) { | ||
25 | + return null; | ||
26 | + } | ||
27 | + cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); | ||
28 | + String strKey = "Passw0rd"; | ||
29 | + return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8)); | ||
30 | + } | ||
31 | + | ||
32 | + /** | ||
33 | + * 对称加密 | ||
34 | + */ | ||
35 | + public static String desEncrypt(String source) throws Exception { | ||
36 | + DESKeySpec desKeySpec = getDesKeySpec(source); | ||
37 | + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); | ||
38 | + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); | ||
39 | + cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); | ||
40 | + return byte2hex( | ||
41 | + cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase(); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 对称解密 | ||
46 | + */ | ||
47 | + public static String desDecrypt(String source) throws Exception { | ||
48 | + byte[] src = hex2byte(source.getBytes()); | ||
49 | + DESKeySpec desKeySpec = getDesKeySpec(source); | ||
50 | + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); | ||
51 | + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); | ||
52 | + cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); | ||
53 | + byte[] retByte = cipher.doFinal(src); | ||
54 | + return new String(retByte); | ||
55 | + } | ||
56 | + | ||
57 | + private static String byte2hex(byte[] inStr) { | ||
58 | + String stmp; | ||
59 | + StringBuilder out = new StringBuilder(inStr.length * 2); | ||
60 | + for (byte b : inStr) { | ||
61 | + stmp = Integer.toHexString(b & 0xFF); | ||
62 | + if (stmp.length() == 1) { | ||
63 | + // 如果是0至F的单位字符串,则添加0 | ||
64 | + out.append("0").append(stmp); | ||
65 | + } else { | ||
66 | + out.append(stmp); | ||
67 | + } | ||
68 | + } | ||
69 | + return out.toString(); | ||
70 | + } | ||
71 | + | ||
72 | + private static byte[] hex2byte(byte[] b) { | ||
73 | + int size = 2; | ||
74 | + if ((b.length % size) != 0) { | ||
75 | + throw new IllegalArgumentException("长度不是偶数"); | ||
76 | + } | ||
77 | + byte[] b2 = new byte[b.length / 2]; | ||
78 | + for (int n = 0; n < b.length; n += size) { | ||
79 | + String item = new String(b, n, 2); | ||
80 | + b2[n / 2] = (byte) Integer.parseInt(item, 16); | ||
81 | + } | ||
82 | + return b2; | ||
83 | + } | ||
84 | +} |
job/src/main/java/com/canrd/shop/common/utils/JsonUtil.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | + | ||
4 | +import com.alibaba.fastjson.JSONException; | ||
5 | +import com.alibaba.fastjson.JSONObject; | ||
6 | +import com.fasterxml.jackson.annotation.JsonInclude; | ||
7 | +import com.fasterxml.jackson.core.JsonGenerator; | ||
8 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
9 | +import com.fasterxml.jackson.core.type.TypeReference; | ||
10 | +import com.fasterxml.jackson.databind.*; | ||
11 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
12 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
13 | +import lombok.extern.slf4j.Slf4j; | ||
14 | + | ||
15 | +import java.io.IOException; | ||
16 | + | ||
17 | +/** | ||
18 | + * | ||
19 | + * @author achims | ||
20 | + * @date 2019/11/4 | ||
21 | + * 用于转换成json字符串以及解析成对象 | ||
22 | + */ | ||
23 | +@Slf4j | ||
24 | +public class JsonUtil { | ||
25 | + | ||
26 | + private static ObjectMapper mapper = new ObjectMapper(); | ||
27 | + | ||
28 | + static { | ||
29 | + log.info("注册jackson-datatype-jsr310的java8时间处理模块"); | ||
30 | + mapper.findAndRegisterModules(); | ||
31 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | ||
32 | + mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { | ||
33 | + @Override | ||
34 | + public void serialize(Object paramT, JsonGenerator paramJsonGenerator, | ||
35 | + SerializerProvider paramSerializerProvider) throws IOException { | ||
36 | + //设置返回null转为 空字符串"" | ||
37 | + paramJsonGenerator.writeString(""); | ||
38 | + } | ||
39 | + }); | ||
40 | + } | ||
41 | + | ||
42 | + | ||
43 | + | ||
44 | + | ||
45 | + /** | ||
46 | + * Create empty json node | ||
47 | + * | ||
48 | + * @return | ||
49 | + */ | ||
50 | + public static ObjectNode createJsonNode() { | ||
51 | + return mapper.createObjectNode(); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * Create empty json Array | ||
56 | + * | ||
57 | + * @return | ||
58 | + */ | ||
59 | + public static ArrayNode createJsonArray() { | ||
60 | + return mapper.createArrayNode(); | ||
61 | + | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Convert the object to corresponding json string | ||
66 | + * | ||
67 | + * @param obj | ||
68 | + * @return | ||
69 | + */ | ||
70 | + public static String toJsonString(Object obj) { | ||
71 | + try { | ||
72 | + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | ||
73 | + return mapper.writeValueAsString(obj); | ||
74 | + } catch (JsonProcessingException e) { | ||
75 | + return null; | ||
76 | + } | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
80 | + * 转成格式化后的json,便于调试排错 | ||
81 | + * @param obj | ||
82 | + * @return | ||
83 | + */ | ||
84 | + public static String toJsonStringWithDefaultPretty(Object obj) { | ||
85 | + try { | ||
86 | + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | ||
87 | + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); | ||
88 | + } catch (JsonProcessingException e) { | ||
89 | + | ||
90 | + return null; | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + public static <T> T jsonToEntity(String json, Class<T> clazz) { | ||
95 | + if (StringUtils.isEmpty(json)) return null; | ||
96 | + try { | ||
97 | + return mapper.readValue(json, clazz); | ||
98 | + } catch (IOException e) { | ||
99 | + e.printStackTrace(); | ||
100 | + } | ||
101 | + return null; | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * 借助json做中转,实体类转实体类 | ||
106 | + * @param obj 实体 | ||
107 | + * @param clazz 目标类型 | ||
108 | + * @param <T> 目标泛型 | ||
109 | + * @return 结果 | ||
110 | + */ | ||
111 | + public static <T> T entityConvert(Object obj, Class<T> clazz) { | ||
112 | + return jsonToEntity(toJsonString(obj), clazz); | ||
113 | + } | ||
114 | + | ||
115 | + /** | ||
116 | + * 带泛型返回不告警 | ||
117 | + * @param json json字符 | ||
118 | + * @param typeReference TypeReference | ||
119 | + * @param <R> 返回类型 | ||
120 | + * @param <T> 转换的类型 | ||
121 | + * @return 转换结果 | ||
122 | + * @author 刘迪榕 | ||
123 | + * @version Date 2022-08-26 | ||
124 | + */ | ||
125 | + public static <R, T extends R> R jsonToEntity(String json, TypeReference<T> typeReference) { | ||
126 | + if (StringUtils.isEmpty(json)) return null; | ||
127 | + try { | ||
128 | + return mapper.readValue(json, typeReference); | ||
129 | + } catch (IOException e) { | ||
130 | + e.printStackTrace(); | ||
131 | + } | ||
132 | + return null; | ||
133 | + } | ||
134 | + | ||
135 | + public static JsonNode readStringAsJsonNode(String json) { | ||
136 | + try { | ||
137 | + return mapper.readValue(json, JsonNode.class); | ||
138 | + } catch (IOException e) { | ||
139 | + e.printStackTrace(); | ||
140 | + } | ||
141 | + return null; | ||
142 | + } | ||
143 | + | ||
144 | + public static JsonNode valueToTree(Object value) { | ||
145 | + return mapper.valueToTree(value); | ||
146 | + } | ||
147 | + | ||
148 | + public static <T> T treeToValue(JsonNode jsonNode, Class<T> clazz) { | ||
149 | + try { | ||
150 | + return mapper.treeToValue(jsonNode, clazz); | ||
151 | + } catch (IOException e) { | ||
152 | + e.printStackTrace(); | ||
153 | + } | ||
154 | + return null; | ||
155 | + } | ||
156 | + | ||
157 | + /** | ||
158 | + * 是否爲json格式的數據 | ||
159 | + * | ||
160 | + * @param test | ||
161 | + * @return | ||
162 | + */ | ||
163 | + public final static boolean isJSONValid(String test) { | ||
164 | + try { | ||
165 | + JSONObject.parseObject(test); | ||
166 | + } catch (JSONException ex) { | ||
167 | + try { | ||
168 | + JSONObject.parseArray(test); | ||
169 | + } catch (JSONException ex1) { | ||
170 | + return false; | ||
171 | + } | ||
172 | + } | ||
173 | + return true; | ||
174 | + } | ||
175 | + | ||
176 | + public <T> T paraseJsonTOClass(String json, Class<T> cla) { | ||
177 | + try { | ||
178 | + return JSONObject.parseObject(json, cla); | ||
179 | + } catch (JSONException ex) { | ||
180 | + return null; | ||
181 | + } | ||
182 | + } | ||
183 | +} |
job/src/main/java/com/canrd/shop/common/utils/LocalDateTimeUtil.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import org.joda.time.DateTime; | ||
4 | + | ||
5 | +import java.time.LocalDateTime; | ||
6 | + | ||
7 | +/** | ||
8 | + * @author: xms | ||
9 | + * @description: TODO | ||
10 | + * @date: 2023/1/16 16:35 | ||
11 | + * @version: 1.0 | ||
12 | + */ | ||
13 | +public class LocalDateTimeUtil { | ||
14 | + | ||
15 | + /** | ||
16 | + * @param dateTime | ||
17 | + * @return | ||
18 | + */ | ||
19 | + public static LocalDateTime toLocalDateTime(DateTime dateTime) { | ||
20 | + return LocalDateTime.of(dateTime.getYear(), dateTime.getMonthOfYear(), | ||
21 | + dateTime.getDayOfMonth(), dateTime.getHourOfDay(), | ||
22 | + dateTime.getMinuteOfHour(), dateTime.getSecondOfMinute()); | ||
23 | + } | ||
24 | + | ||
25 | + /** | ||
26 | + * | ||
27 | + * @param localDateTime | ||
28 | + * @return | ||
29 | + */ | ||
30 | + public static DateTime toDateTime(LocalDateTime localDateTime) { | ||
31 | + return new DateTime().withYear(localDateTime.getYear()).withMonthOfYear(localDateTime.getMonthValue()) | ||
32 | + .withDayOfMonth(localDateTime.getDayOfMonth()).withHourOfDay(localDateTime.getHour()) | ||
33 | + .withMinuteOfHour(localDateTime.getMinute()).withSecondOfMinute(localDateTime.getSecond()); | ||
34 | + } | ||
35 | +} |
job/src/main/java/com/canrd/shop/common/utils/PageUtils.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.core.metadata.IPage; | ||
4 | +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||
5 | +import com.canrd.shop.module.vo.BasePageVO; | ||
6 | +import org.springframework.util.CollectionUtils; | ||
7 | + | ||
8 | +import java.io.Serializable; | ||
9 | +import java.util.*; | ||
10 | + | ||
11 | +/** | ||
12 | + * @Author: dengbin | ||
13 | + * @Date: 2020/9/11 | ||
14 | + * 分页工具类 | ||
15 | + */ | ||
16 | + | ||
17 | +public class PageUtils implements Serializable { | ||
18 | + private static final long serialVersionUID = 4359709211352400087L; | ||
19 | + private static final String PAGE_INDEX = "pageNo"; | ||
20 | + private static final String PAGE_SIZE = "pageSize"; | ||
21 | + private static final String TOTAL_ROWS = "total"; | ||
22 | + private static final String TOTAL_PAGES = "pages"; | ||
23 | + private static final String RECORDS = "records"; | ||
24 | + | ||
25 | + private static final int DEFAULT_PAGE_INDEX = 1; | ||
26 | + private static final int DEFAULT_PAGE_SIZE = 10; | ||
27 | + private static final int DEFAULT_MAP_CAPACITY = 5; | ||
28 | + | ||
29 | + /** | ||
30 | + * 统一分页返回对象 | ||
31 | + * | ||
32 | + * @param list | ||
33 | + * @return | ||
34 | + */ | ||
35 | + public static Map<String, Object> getUnifiedPageReturn(IPage list) { | ||
36 | + if (list == null) { | ||
37 | + return getUnifiedEmptyPage(DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE); | ||
38 | + } | ||
39 | + | ||
40 | + Map<String, Object> resultMap = new HashMap<>(DEFAULT_MAP_CAPACITY); | ||
41 | + resultMap.put(PAGE_INDEX, list.getCurrent()); | ||
42 | + resultMap.put(PAGE_SIZE, list.getSize()); | ||
43 | + resultMap.put(RECORDS, list.getRecords()); | ||
44 | + resultMap.put(TOTAL_PAGES, list.getPages()); | ||
45 | + resultMap.put(TOTAL_ROWS, list.getTotal()); | ||
46 | + | ||
47 | + return resultMap; | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * 返回空分页信息给前端 | ||
52 | + * 返回空或其他字段不满足前端要求,会报错 | ||
53 | + * | ||
54 | + * @return | ||
55 | + */ | ||
56 | + public static Map<String, Object> getUnifiedEmptyPage(int pageIndex, int pageSize) { | ||
57 | + Map<String, Object> resultMap = new HashMap<>(DEFAULT_MAP_CAPACITY); | ||
58 | + resultMap.put(PAGE_INDEX, pageIndex); | ||
59 | + resultMap.put(PAGE_SIZE, pageSize); | ||
60 | + resultMap.put(RECORDS, new ArrayList<>()); | ||
61 | + resultMap.put(TOTAL_PAGES, 0); | ||
62 | + resultMap.put(TOTAL_ROWS, 0); | ||
63 | + return resultMap; | ||
64 | + } | ||
65 | + | ||
66 | + public static Map<String, Object> getUnifiedEmptyPage(BasePageVO pageVO) { | ||
67 | + return getUnifiedEmptyPage(pageVO.getPageNo(), pageVO.getPageSize()); | ||
68 | + } | ||
69 | + | ||
70 | + | ||
71 | + /** | ||
72 | + * 将旧的分页转换成新的分页对象 | ||
73 | + * | ||
74 | + * @param oldPage 旧的分页对象,例如:xxDo的分页对象 | ||
75 | + * @param records 新的分页对象,例如:xxVo的分页对象 | ||
76 | + * @param <T> 新的分页对象的类型 | ||
77 | + * @return 统一的返回的分页对象 | ||
78 | + */ | ||
79 | + public static <T> Map<String, Object> transferPage(IPage<?> oldPage, List<T> records) { | ||
80 | + Page<T> newPage = new Page<>(); | ||
81 | + newPage.setCurrent(oldPage.getCurrent()); | ||
82 | + newPage.setSize(oldPage.getSize()); | ||
83 | + newPage.setRecords(records); | ||
84 | + newPage.setPages(oldPage.getPages()); | ||
85 | + newPage.setTotal(oldPage.getTotal()); | ||
86 | + return getUnifiedPageReturn(newPage); | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * 统一分页返回对象 | ||
91 | + * | ||
92 | + * @param records 分页数据 | ||
93 | + * @param pageVO 分页参数 | ||
94 | + * @return | ||
95 | + */ | ||
96 | + public static Map<String, Object> getPageReturn(List records, BasePageVO pageVO) { | ||
97 | + if (records == null) { | ||
98 | + return getUnifiedEmptyPage(DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE); | ||
99 | + } | ||
100 | + if (CollectionUtils.isEmpty(records)) { | ||
101 | + return getUnifiedEmptyPage(Math.toIntExact(pageVO.getPageNo()), Math.toIntExact(pageVO.getPageSize())); | ||
102 | + } | ||
103 | + Map<String, Object> resultMap = new HashMap<>(DEFAULT_MAP_CAPACITY); | ||
104 | + resultMap.put(PAGE_INDEX, pageVO.getPageNo()); | ||
105 | + resultMap.put(PAGE_SIZE, pageVO.getPageSize()); | ||
106 | + resultMap.put(RECORDS, records); | ||
107 | + resultMap.put(TOTAL_PAGES, (pageVO.getTotal() + pageVO.getPageSize() - 1) / pageVO.getPageSize()); | ||
108 | + resultMap.put(TOTAL_ROWS, pageVO.getTotal()); | ||
109 | + | ||
110 | + return resultMap; | ||
111 | + } | ||
112 | + | ||
113 | + public static <T> Page<T> getRAMPageReturn(Integer current, Integer size, List<T> records) { | ||
114 | + if (Objects.isNull(current)) { | ||
115 | + current = 1; | ||
116 | + } | ||
117 | + if (Objects.isNull(size)) { | ||
118 | + size = 10; | ||
119 | + } | ||
120 | + int startIndex = (current - 1) * size; | ||
121 | + int endIndex = Math.min(current * size, records.size()); | ||
122 | + if (startIndex > endIndex) { | ||
123 | + startIndex = endIndex; | ||
124 | + } | ||
125 | + Page<T> page = new Page<>(); | ||
126 | + page.setCurrent(current); | ||
127 | + page.setSize(size); | ||
128 | + page.setRecords(records.subList(startIndex, endIndex)); | ||
129 | + int totalPages = size == 0 ? 0 : records.size() % size == 0 ? (records.size() / size) : (records.size() / size + 1); | ||
130 | + page.setPages(totalPages); | ||
131 | + page.setTotal(records.size()); | ||
132 | + return page; | ||
133 | + } | ||
134 | + | ||
135 | + | ||
136 | +} |
job/src/main/java/com/canrd/shop/common/utils/RequestContextUtil.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import org.springframework.web.context.ContextLoader; | ||
4 | +import org.springframework.web.context.request.RequestContextHolder; | ||
5 | +import org.springframework.web.context.request.ServletRequestAttributes; | ||
6 | + | ||
7 | +import javax.servlet.ServletContext; | ||
8 | +import javax.servlet.http.HttpServletRequest; | ||
9 | +import javax.servlet.http.HttpServletResponse; | ||
10 | +import javax.servlet.http.HttpSession; | ||
11 | + | ||
12 | + | ||
13 | +public class RequestContextUtil { | ||
14 | + | ||
15 | + public static HttpServletRequest getRequest() { | ||
16 | + return getRequestAttributes().getRequest(); | ||
17 | + } | ||
18 | + | ||
19 | + public static HttpServletResponse getResponse() { | ||
20 | + return getRequestAttributes().getResponse(); | ||
21 | + } | ||
22 | + | ||
23 | + public static HttpSession getSession() { | ||
24 | + return getRequest().getSession(); | ||
25 | + } | ||
26 | + | ||
27 | + public static ServletRequestAttributes getRequestAttributes() { | ||
28 | + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()); | ||
29 | + } | ||
30 | + | ||
31 | + public static ServletContext getServletContext() { | ||
32 | + return ContextLoader.getCurrentWebApplicationContext().getServletContext(); | ||
33 | + } | ||
34 | + | ||
35 | +} |
job/src/main/java/com/canrd/shop/common/utils/ServletUtils.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import com.canrd.shop.common.constant.ServerResult; | ||
4 | +import lombok.extern.slf4j.Slf4j; | ||
5 | +import org.springframework.http.HttpStatus; | ||
6 | + | ||
7 | +import javax.servlet.http.HttpServletResponse; | ||
8 | +import java.io.IOException; | ||
9 | + | ||
10 | +/** | ||
11 | + * @date 2023-02-02 | ||
12 | + */ | ||
13 | +@Slf4j | ||
14 | +public class ServletUtils { | ||
15 | + | ||
16 | + | ||
17 | + public static void renderServerResult(HttpServletResponse response, ServerResult serverResult, HttpStatus httpStatus) | ||
18 | + { | ||
19 | + try | ||
20 | + { | ||
21 | + response.setStatus(httpStatus.value()); | ||
22 | + response.setContentType("application/json"); | ||
23 | + response.setCharacterEncoding("utf-8"); | ||
24 | + response.getWriter().print(JsonUtil.toJsonString(serverResult)); | ||
25 | + } | ||
26 | + catch (IOException e) | ||
27 | + { | ||
28 | + log.error("ServletUtils#renderServerResult:",e); | ||
29 | + } | ||
30 | + } | ||
31 | + | ||
32 | + | ||
33 | + public static void renderExcelFileNotFound(HttpServletResponse response){ | ||
34 | + try { | ||
35 | + response.setStatus(404); | ||
36 | + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); | ||
37 | + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 | ||
38 | + response.setHeader("Content-Disposition", "attachment;filename=file.xlsx"); | ||
39 | + response.sendError(HttpStatus.NOT_FOUND.value(),"下载失败,资源不存在"); | ||
40 | + }catch (IOException e){ | ||
41 | + log.error("ServletUtils#renderWithResourceNotFound:",e); | ||
42 | + } | ||
43 | + } | ||
44 | +} |
job/src/main/java/com/canrd/shop/common/utils/SpringContextHolder.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import lombok.extern.slf4j.Slf4j; | ||
4 | +import org.springframework.beans.BeansException; | ||
5 | +import org.springframework.beans.factory.DisposableBean; | ||
6 | +import org.springframework.context.ApplicationContext; | ||
7 | +import org.springframework.context.ApplicationContextAware; | ||
8 | + | ||
9 | +/** | ||
10 | + * @author Jie | ||
11 | + * @date 2019-01-07 | ||
12 | + */ | ||
13 | +@Slf4j | ||
14 | +public class SpringContextHolder implements ApplicationContextAware, DisposableBean { | ||
15 | + | ||
16 | + private static ApplicationContext applicationContext = null; | ||
17 | + | ||
18 | + /** | ||
19 | + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. | ||
20 | + */ | ||
21 | + @SuppressWarnings("unchecked") | ||
22 | + public static <T> T getBean(String name) { | ||
23 | + assertContextInjected(); | ||
24 | + return (T) applicationContext.getBean(name); | ||
25 | + } | ||
26 | + | ||
27 | + /** | ||
28 | + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. | ||
29 | + */ | ||
30 | + public static <T> T getBean(Class<T> requiredType) { | ||
31 | + assertContextInjected(); | ||
32 | + return applicationContext.getBean(requiredType); | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * 检查ApplicationContext不为空. | ||
37 | + */ | ||
38 | + private static void assertContextInjected() { | ||
39 | + if (applicationContext == null) { | ||
40 | + throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" + | ||
41 | + ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder."); | ||
42 | + } | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * 清除SpringContextHolder中的ApplicationContext为Null. | ||
47 | + */ | ||
48 | + private static void clearHolder() { | ||
49 | + log.debug("清除SpringContextHolder中的ApplicationContext:" | ||
50 | + + applicationContext); | ||
51 | + applicationContext = null; | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public void destroy() { | ||
56 | + SpringContextHolder.clearHolder(); | ||
57 | + } | ||
58 | + | ||
59 | + @Override | ||
60 | + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { | ||
61 | + if (SpringContextHolder.applicationContext != null) { | ||
62 | + log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); | ||
63 | + } | ||
64 | + SpringContextHolder.applicationContext = applicationContext; | ||
65 | + } | ||
66 | +} |
job/src/main/java/com/canrd/shop/common/utils/StringUtils.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import com.canrd.shop.common.constant.Constant; | ||
4 | +import lombok.extern.slf4j.Slf4j; | ||
5 | +import org.springframework.util.CollectionUtils; | ||
6 | + | ||
7 | +import java.io.ByteArrayInputStream; | ||
8 | +import java.io.ByteArrayOutputStream; | ||
9 | +import java.io.IOException; | ||
10 | +import java.math.BigDecimal; | ||
11 | +import java.nio.charset.StandardCharsets; | ||
12 | +import java.util.*; | ||
13 | +import java.util.regex.Matcher; | ||
14 | +import java.util.regex.Pattern; | ||
15 | +import java.util.regex.PatternSyntaxException; | ||
16 | +import java.util.stream.Collectors; | ||
17 | +import java.util.stream.Stream; | ||
18 | +import java.util.zip.GZIPInputStream; | ||
19 | +import java.util.zip.GZIPOutputStream; | ||
20 | + | ||
21 | +/** | ||
22 | + * @param | ||
23 | + * @author 邓彬 | ||
24 | + * @version 0.1.0 | ||
25 | + * @Description | ||
26 | + * @return | ||
27 | + * @date 2021/4/16 17:44 | ||
28 | + * @since 0.1.0 | ||
29 | + */ | ||
30 | +@Slf4j | ||
31 | +public class StringUtils { | ||
32 | + /** | ||
33 | + * 首字母变小写 | ||
34 | + * | ||
35 | + * @param str | ||
36 | + * @return | ||
37 | + */ | ||
38 | + public static String firstCharToLowerCase(String str) { | ||
39 | + char firstChar = str.charAt(0); | ||
40 | + if (firstChar >= 'A' && firstChar <= 'Z') { | ||
41 | + char[] arr = str.toCharArray(); | ||
42 | + arr[0] += ('a' - 'A'); | ||
43 | + return new String(arr); | ||
44 | + } | ||
45 | + return str; | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * 首字母变大写 | ||
50 | + * | ||
51 | + * @param str | ||
52 | + * @return | ||
53 | + */ | ||
54 | + public static String firstCharToUpperCase(String str) { | ||
55 | + char firstChar = str.charAt(0); | ||
56 | + if (firstChar >= 'a' && firstChar <= 'z') { | ||
57 | + char[] arr = str.toCharArray(); | ||
58 | + arr[0] -= ('a' - 'A'); | ||
59 | + return new String(arr); | ||
60 | + } | ||
61 | + return str; | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 判断是否为空 | ||
66 | + * | ||
67 | + * @param str | ||
68 | + * @return | ||
69 | + */ | ||
70 | + public static boolean isEmpty(final String str) { | ||
71 | + return (str == null) || (str.length() == 0); | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * 判断是否不为空 | ||
76 | + * | ||
77 | + * @param str | ||
78 | + * @return | ||
79 | + */ | ||
80 | + public static boolean isNotEmpty(final String str) { | ||
81 | + return !isEmpty(str); | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * 判断是否空白 | ||
86 | + * | ||
87 | + * @param str | ||
88 | + * @return | ||
89 | + */ | ||
90 | + public static boolean isBlank(final String str) { | ||
91 | + int strLen; | ||
92 | + if ((str == null) || ((strLen = str.length()) == 0)) { | ||
93 | + return true; | ||
94 | + } | ||
95 | + for (int i = 0; i < strLen; i++) { | ||
96 | + if (!Character.isWhitespace(str.charAt(i))) { | ||
97 | + return false; | ||
98 | + } | ||
99 | + } | ||
100 | + return true; | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * 判断是否不是空白 | ||
105 | + * | ||
106 | + * @param str | ||
107 | + * @return | ||
108 | + */ | ||
109 | + public static boolean isNotBlank(final String str) { | ||
110 | + return !isBlank(str); | ||
111 | + } | ||
112 | + | ||
113 | + /** | ||
114 | + * 判断多个字符串全部是否为空 | ||
115 | + * | ||
116 | + * @param strings | ||
117 | + * @return | ||
118 | + */ | ||
119 | + public static boolean isAllEmpty(String... strings) { | ||
120 | + if (strings == null) { | ||
121 | + return true; | ||
122 | + } | ||
123 | + for (String str : strings) { | ||
124 | + if (isNotEmpty(str)) { | ||
125 | + return false; | ||
126 | + } | ||
127 | + } | ||
128 | + return true; | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * 判断多个字符串其中任意一个是否为空 | ||
133 | + * | ||
134 | + * @param strings | ||
135 | + * @return | ||
136 | + */ | ||
137 | + public static boolean isHasEmpty(String... strings) { | ||
138 | + if (strings == null) { | ||
139 | + return true; | ||
140 | + } | ||
141 | + for (String str : strings) { | ||
142 | + if (isEmpty(str)) { | ||
143 | + return true; | ||
144 | + } | ||
145 | + } | ||
146 | + return false; | ||
147 | + } | ||
148 | + | ||
149 | + /** | ||
150 | + * 判断多个字符串是否都为blank | ||
151 | + * | ||
152 | + * @param strings | ||
153 | + * @return | ||
154 | + */ | ||
155 | + public static boolean isAllBlank(String... strings) { | ||
156 | + if (strings == null) { | ||
157 | + return true; | ||
158 | + } | ||
159 | + for (String str : strings) { | ||
160 | + if (isNotBlank(str)) { | ||
161 | + return false; | ||
162 | + } | ||
163 | + } | ||
164 | + return true; | ||
165 | + } | ||
166 | + | ||
167 | + /** | ||
168 | + * checkValue为 null 或者为 "" 时返回 defaultValue | ||
169 | + * | ||
170 | + * @param checkValue | ||
171 | + * @param defaultValue | ||
172 | + * @return | ||
173 | + */ | ||
174 | + public static String isEmpty(String checkValue, String defaultValue) { | ||
175 | + return isEmpty(checkValue) ? defaultValue : checkValue; | ||
176 | + } | ||
177 | + | ||
178 | + /** | ||
179 | + * 字符串不为 null 而且不为 "" 并且等于other | ||
180 | + * | ||
181 | + * @param str | ||
182 | + * @param other | ||
183 | + * @return | ||
184 | + */ | ||
185 | + public static boolean isNotEmptyAndEqualsOther(String str, String other) { | ||
186 | + return !isEmpty(str) && str.equals(other); | ||
187 | + } | ||
188 | + | ||
189 | + /** | ||
190 | + * 字符串不为 null 而且不为 "" 并且不等于other | ||
191 | + * | ||
192 | + * @param str | ||
193 | + * @param other | ||
194 | + * @return | ||
195 | + */ | ||
196 | + public static boolean isNotEmptyAndNotEqualsOther(String str, String... other) { | ||
197 | + if (isEmpty(str)) { | ||
198 | + return false; | ||
199 | + } | ||
200 | + for (String s : other) { | ||
201 | + if (str.equals(s)) { | ||
202 | + return false; | ||
203 | + } | ||
204 | + } | ||
205 | + return true; | ||
206 | + } | ||
207 | + | ||
208 | + /** | ||
209 | + * 字符串不等于other | ||
210 | + * | ||
211 | + * @param str | ||
212 | + * @param other | ||
213 | + * @return | ||
214 | + */ | ||
215 | + public static boolean isNotEqualsOther(String str, String... other) { | ||
216 | + for (String s : other) { | ||
217 | + if (s.equals(str)) { | ||
218 | + return false; | ||
219 | + } | ||
220 | + } | ||
221 | + return true; | ||
222 | + } | ||
223 | + | ||
224 | + /** | ||
225 | + * 判断字符串不为空 | ||
226 | + * | ||
227 | + * @param strings | ||
228 | + * @return | ||
229 | + */ | ||
230 | + public static boolean isNotEmpty(String... strings) { | ||
231 | + if (strings == null || strings.length == 0) { | ||
232 | + return false; | ||
233 | + } | ||
234 | + for (String str : strings) { | ||
235 | + if (str == null || "".equals(str.trim())) { | ||
236 | + return false; | ||
237 | + } | ||
238 | + } | ||
239 | + return true; | ||
240 | + } | ||
241 | + | ||
242 | + /** | ||
243 | + * 比较字符相等 | ||
244 | + * | ||
245 | + * @param value | ||
246 | + * @param equals | ||
247 | + * @return | ||
248 | + */ | ||
249 | + public static boolean equals(String value, String equals) { | ||
250 | + if (isAllEmpty(value, equals)) { | ||
251 | + return true; | ||
252 | + } | ||
253 | + //进一步判断value是不是空,如果是空,要直接equals会报NPE异常 | ||
254 | + if (value == null) { | ||
255 | + return false; | ||
256 | + } | ||
257 | + return value.equals(equals); | ||
258 | + } | ||
259 | + | ||
260 | + /** | ||
261 | + * @description 将字符串转换为数字数组 | ||
262 | + * @author 黄楷涵 | ||
263 | + * @date 2020/9/15 | ||
264 | + */ | ||
265 | + public static int[] stringParseToInt(String str, String regex) { | ||
266 | + return stringParseToInt(str.split(regex)); | ||
267 | + } | ||
268 | + | ||
269 | + /** | ||
270 | + * @description 将字符串数组转换为数字数组 | ||
271 | + * @author dengbin | ||
272 | + * @date 2020/9/15 | ||
273 | + */ | ||
274 | + public static int[] stringParseToInt(String[] str) { | ||
275 | + int[] num = new int[str.length]; | ||
276 | + for (int i = 0; i < str.length; i++) { | ||
277 | + num[i] = Integer.parseInt(str[i]); | ||
278 | + } | ||
279 | + return num; | ||
280 | + } | ||
281 | + | ||
282 | + /** | ||
283 | + * 比较字符串不相等 | ||
284 | + * | ||
285 | + * @param value | ||
286 | + * @param equals | ||
287 | + * @return | ||
288 | + */ | ||
289 | + public static boolean isNotEquals(String value, String equals) { | ||
290 | + return !equals(value, equals); | ||
291 | + } | ||
292 | + | ||
293 | + public static String[] split(String content, String separatorChars) { | ||
294 | + return splitWorker(content, separatorChars, -1, false); | ||
295 | + } | ||
296 | + | ||
297 | + public static String[] split(String str, String separatorChars, int max) { | ||
298 | + return splitWorker(str, separatorChars, max, false); | ||
299 | + } | ||
300 | + | ||
301 | + public static final String[] EMPTY_STRING_ARRAY = new String[0]; | ||
302 | + | ||
303 | + private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) { | ||
304 | + if (str == null) { | ||
305 | + return null; | ||
306 | + } | ||
307 | + int len = str.length(); | ||
308 | + if (len == 0) { | ||
309 | + return EMPTY_STRING_ARRAY; | ||
310 | + } | ||
311 | + List<String> list = new ArrayList<String>(); | ||
312 | + int sizePlus1 = 1; | ||
313 | + int i = 0, start = 0; | ||
314 | + boolean match = false; | ||
315 | + boolean lastMatch = false; | ||
316 | + if (separatorChars == null) { | ||
317 | + while (i < len) { | ||
318 | + if (Character.isWhitespace(str.charAt(i))) { | ||
319 | + if (match || preserveAllTokens) { | ||
320 | + lastMatch = true; | ||
321 | + if (sizePlus1++ == max) { | ||
322 | + i = len; | ||
323 | + lastMatch = false; | ||
324 | + } | ||
325 | + list.add(str.substring(start, i)); | ||
326 | + match = false; | ||
327 | + } | ||
328 | + start = ++i; | ||
329 | + continue; | ||
330 | + } | ||
331 | + lastMatch = false; | ||
332 | + match = true; | ||
333 | + i++; | ||
334 | + } | ||
335 | + } else if (separatorChars.length() == 1) { | ||
336 | + char sep = separatorChars.charAt(0); | ||
337 | + while (i < len) { | ||
338 | + if (str.charAt(i) == sep) { | ||
339 | + if (match || preserveAllTokens) { | ||
340 | + lastMatch = true; | ||
341 | + if (sizePlus1++ == max) { | ||
342 | + i = len; | ||
343 | + lastMatch = false; | ||
344 | + } | ||
345 | + list.add(str.substring(start, i)); | ||
346 | + match = false; | ||
347 | + } | ||
348 | + start = ++i; | ||
349 | + continue; | ||
350 | + } | ||
351 | + lastMatch = false; | ||
352 | + match = true; | ||
353 | + i++; | ||
354 | + } | ||
355 | + } else { | ||
356 | + while (i < len) { | ||
357 | + if (separatorChars.indexOf(str.charAt(i)) >= 0) { | ||
358 | + if (match || preserveAllTokens) { | ||
359 | + lastMatch = true; | ||
360 | + if (sizePlus1++ == max) { | ||
361 | + i = len; | ||
362 | + lastMatch = false; | ||
363 | + } | ||
364 | + list.add(str.substring(start, i)); | ||
365 | + match = false; | ||
366 | + } | ||
367 | + start = ++i; | ||
368 | + continue; | ||
369 | + } | ||
370 | + lastMatch = false; | ||
371 | + match = true; | ||
372 | + i++; | ||
373 | + } | ||
374 | + } | ||
375 | + if (match || (preserveAllTokens && lastMatch)) { | ||
376 | + list.add(str.substring(start, i)); | ||
377 | + } | ||
378 | + return list.toArray(EMPTY_STRING_ARRAY); | ||
379 | + } | ||
380 | + | ||
381 | + /** | ||
382 | + * 消除转义字符 | ||
383 | + * | ||
384 | + * @param str | ||
385 | + * @return | ||
386 | + */ | ||
387 | + public static String escapeXml(String str) { | ||
388 | + if (str == null) { | ||
389 | + return ""; | ||
390 | + } | ||
391 | + StringBuilder sb = new StringBuilder(); | ||
392 | + for (int i = 0; i < str.length(); ++i) { | ||
393 | + char c = str.charAt(i); | ||
394 | + switch (c) { | ||
395 | + case '\u00FF': | ||
396 | + case '\u0024': | ||
397 | + break; | ||
398 | + case '&': | ||
399 | + sb.append("&"); | ||
400 | + break; | ||
401 | + case '<': | ||
402 | + sb.append("<"); | ||
403 | + break; | ||
404 | + case '>': | ||
405 | + sb.append(">"); | ||
406 | + break; | ||
407 | + case '\"': | ||
408 | + sb.append("""); | ||
409 | + break; | ||
410 | + case '\'': | ||
411 | + sb.append("'"); | ||
412 | + break; | ||
413 | + default: | ||
414 | + if (c <= '\u001F') { | ||
415 | + break; | ||
416 | + } | ||
417 | + if (c >= '\uE000' && c <= '\uF8FF') { | ||
418 | + break; | ||
419 | + } | ||
420 | + if (c >= '\uFFF0') { | ||
421 | + break; | ||
422 | + } | ||
423 | + sb.append(c); | ||
424 | + break; | ||
425 | + } | ||
426 | + } | ||
427 | + return sb.toString(); | ||
428 | + } | ||
429 | + | ||
430 | + /** | ||
431 | + * 将字符串中特定模式的字符转换成map中对应的值 | ||
432 | + * | ||
433 | + * @param s 需要转换的字符串 | ||
434 | + * @param map 转换所需的键值对集合 | ||
435 | + * @return 转换后的字符串 | ||
436 | + */ | ||
437 | + public static String replace(String s, Map<String, Object> map) { | ||
438 | + StringBuilder ret = new StringBuilder((int) (s.length() * 1.5)); | ||
439 | + int cursor = 0; | ||
440 | + for (int start, end; (start = s.indexOf("${", cursor)) != -1 && (end = s.indexOf("}", start)) != -1; ) { | ||
441 | + ret.append(s.substring(cursor, start)).append(map.get(s.substring(start + 2, end))); | ||
442 | + cursor = end + 1; | ||
443 | + } | ||
444 | + ret.append(s.substring(cursor, s.length())); | ||
445 | + return ret.toString(); | ||
446 | + } | ||
447 | + | ||
448 | + public static String replace(String s, Object... objs) { | ||
449 | + if (objs == null || objs.length == 0) { | ||
450 | + return s; | ||
451 | + } | ||
452 | + if (!s.contains("{}")) { | ||
453 | + return s; | ||
454 | + } | ||
455 | + StringBuilder ret = new StringBuilder((int) (s.length() * 1.5)); | ||
456 | + int cursor = 0; | ||
457 | + int index = 0; | ||
458 | + for (int start; (start = s.indexOf("{}", cursor)) != -1; ) { | ||
459 | + ret.append(s.substring(cursor, start)); | ||
460 | + if (index < objs.length) { | ||
461 | + ret.append(objs[index]); | ||
462 | + } else { | ||
463 | + ret.append("{}"); | ||
464 | + } | ||
465 | + cursor = start + 2; | ||
466 | + index++; | ||
467 | + } | ||
468 | + ret.append(s.substring(cursor, s.length())); | ||
469 | + return ret.toString(); | ||
470 | + } | ||
471 | + | ||
472 | + | ||
473 | + /** | ||
474 | + * 转换为字节数组 | ||
475 | + * | ||
476 | + * @param bytes | ||
477 | + * @return | ||
478 | + */ | ||
479 | + public static String toString(byte[] bytes) { | ||
480 | + return new String(bytes, StandardCharsets.UTF_8); | ||
481 | + } | ||
482 | + | ||
483 | + /** | ||
484 | + * 转换为字节数组 | ||
485 | + * | ||
486 | + * @param str | ||
487 | + * @return | ||
488 | + */ | ||
489 | + public static byte[] getBytes(String str) { | ||
490 | + return str != null ? str.getBytes(StandardCharsets.UTF_8) : null; | ||
491 | + } | ||
492 | + | ||
493 | + public static boolean isNumeric(String cs) { | ||
494 | + if (isEmpty(cs)) { | ||
495 | + return false; | ||
496 | + } | ||
497 | + for (int i = 0, sz = cs.length(); i < sz; ++i) { | ||
498 | + if (!Character.isDigit(cs.charAt(i))) { | ||
499 | + return false; | ||
500 | + } | ||
501 | + } | ||
502 | + return true; | ||
503 | + | ||
504 | + } | ||
505 | + | ||
506 | + /** | ||
507 | + * 手机号脱敏 | ||
508 | + * | ||
509 | + * @param phoneNumber | ||
510 | + * @return | ||
511 | + */ | ||
512 | + public static String desensitizedPhoneNumber(String phoneNumber) { | ||
513 | + if (StringUtils.isNotEmpty(phoneNumber)) { | ||
514 | + phoneNumber = phoneNumber.replaceAll("(\\w{3})\\w*(\\w{4})", "$1****$2"); | ||
515 | + } | ||
516 | + return phoneNumber; | ||
517 | + } | ||
518 | + | ||
519 | + /** | ||
520 | + * 校验3位小数 | ||
521 | + * | ||
522 | + * @param str | ||
523 | + * @return | ||
524 | + */ | ||
525 | + public static boolean checkDecimal(String str) { | ||
526 | + return Pattern.compile(Constant.DICMAL_REGEXP).matcher(str).find(); | ||
527 | + } | ||
528 | + | ||
529 | + /** | ||
530 | + * 校验11位国内手机号 | ||
531 | + * <p>规则: 11位数,首位必须为1,第二位可以是3-9;其他位数不限制 | ||
532 | + * | ||
533 | + * @param phone 手机号 | ||
534 | + * @return 格式正确则返回false; 反之为true | ||
535 | + * @author A80080 | ||
536 | + * @createDate 2020/12/19 | ||
537 | + */ | ||
538 | + public static boolean checkPhoneNum(String phone) { | ||
539 | + return StringUtils.isEmpty(phone) || !Pattern.compile("^1([3-9])[0-9]{9}$").matcher(phone).find(); | ||
540 | + } | ||
541 | + | ||
542 | + /** | ||
543 | + * @param str | ||
544 | + * @return boolean | ||
545 | + * @Description 判断字符串是否含有空格 | ||
546 | + * @version 0.1.0 | ||
547 | + * @author 邓彬 | ||
548 | + * @date 2021/1/13 18:10 | ||
549 | + * @since 0.1.0 | ||
550 | + */ | ||
551 | + public static boolean checkStringContainEmpty(String str) { | ||
552 | + return !StringUtils.isEmpty(str) && str.contains(" "); | ||
553 | + } | ||
554 | + | ||
555 | + /** | ||
556 | + * 字符串切分 | ||
557 | + * | ||
558 | + * @param splitStr | ||
559 | + * @param splitFlag | ||
560 | + * @return | ||
561 | + */ | ||
562 | + public static List<String> splitTag(String splitStr, String splitFlag) { | ||
563 | + return StringUtils.isBlank(splitStr) || StringUtils.isBlank(splitFlag) ? | ||
564 | + new ArrayList<>() : | ||
565 | + Arrays.stream(splitStr.split(splitFlag)).collect(Collectors.toList()); | ||
566 | + } | ||
567 | + | ||
568 | + /** | ||
569 | + * @param name | ||
570 | + * @return true代表全是汉字 | ||
571 | + * @Description 校验String是否全是中文 | ||
572 | + * @version 0.1.0 | ||
573 | + * @author 邓彬 | ||
574 | + * @date 2021/1/18 19:54 | ||
575 | + * @since 0.1.0 | ||
576 | + */ | ||
577 | + public static boolean checkNameChina(String name) { | ||
578 | + boolean res = true; | ||
579 | + char[] cTemp = name.toCharArray(); | ||
580 | + for (int i = 0; i < name.length(); i++) { | ||
581 | + if (!isChinese(cTemp[i])) { | ||
582 | + res = false; | ||
583 | + break; | ||
584 | + } | ||
585 | + } | ||
586 | + return res; | ||
587 | + } | ||
588 | + | ||
589 | + /** | ||
590 | + * @param c | ||
591 | + * @return true代表是汉字 | ||
592 | + * @Description 判定输入的是否是汉字 | ||
593 | + * @version 0.1.0 | ||
594 | + * @author 邓彬 | ||
595 | + * @date 2021/1/18 19:53 | ||
596 | + * @since 0.1.0 | ||
597 | + */ | ||
598 | + public static boolean isChinese(char c) { | ||
599 | + Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); | ||
600 | + if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS | ||
601 | + || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS | ||
602 | + || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A | ||
603 | + || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION | ||
604 | + || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION | ||
605 | + || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { | ||
606 | + return true; | ||
607 | + } | ||
608 | + return false; | ||
609 | + } | ||
610 | + | ||
611 | + /** | ||
612 | + * @param c | ||
613 | + * @return true代表符合条件 | ||
614 | + * @Description 校验某个字符是否是a-z、A-Z、_、0-9 | ||
615 | + * @version 0.1.0 | ||
616 | + * @author 邓彬 | ||
617 | + * @date 2021/1/18 19:56 | ||
618 | + * @since 0.1.0 | ||
619 | + */ | ||
620 | + public static boolean isWord(char c) { | ||
621 | + return Pattern.compile("[\\w]").matcher("" + c).matches(); | ||
622 | + } | ||
623 | + | ||
624 | + /** | ||
625 | + * @param str | ||
626 | + * @return boolean | ||
627 | + * @Description 字符串是否仅包含数字和字母 | ||
628 | + * @version 0.1.0 | ||
629 | + * @author 邓彬 | ||
630 | + * @date 2021/1/18 20:00 | ||
631 | + * @since 0.1.0 | ||
632 | + */ | ||
633 | + public static boolean isLetterDigit(String str) { | ||
634 | + return str.matches("^[a-z0-9A-Z]+$"); | ||
635 | + } | ||
636 | + | ||
637 | + /** | ||
638 | + * @param str | ||
639 | + * @return boolean | ||
640 | + * @Description 判断是否是纯数字 | ||
641 | + * @version 0.1.0 | ||
642 | + * @author 邓彬 | ||
643 | + * @date 2021/1/23 16:33 | ||
644 | + * @since 0.1.0 | ||
645 | + */ | ||
646 | + public static boolean isDigit(String str) { | ||
647 | + return str.matches("^[0-9]+$"); | ||
648 | + } | ||
649 | + | ||
650 | + /** | ||
651 | + * 是否合法手机号 | ||
652 | + * | ||
653 | + * @param phone | ||
654 | + * @return | ||
655 | + */ | ||
656 | + public static boolean isMobilePhone(String phone) { | ||
657 | + return Pattern.compile(Constant.PHONE_REGEXP).matcher(phone).matches(); | ||
658 | + } | ||
659 | + | ||
660 | + /** | ||
661 | + * 是否脱敏手机号 | ||
662 | + * | ||
663 | + * @param phone | ||
664 | + * @return | ||
665 | + */ | ||
666 | + public static boolean isDesensitizationMobilePhone(String phone) { | ||
667 | + return Pattern.compile(Constant.PHONE_DESENSITIZATION_REGEXP).matcher(phone).matches(); | ||
668 | + } | ||
669 | + | ||
670 | + /** | ||
671 | + * 判断String是否是整数<br> | ||
672 | + * 支持10进制 | ||
673 | + * | ||
674 | + * @param s String | ||
675 | + * @return 是否为整数 | ||
676 | + */ | ||
677 | + public static boolean isInteger(String s) { | ||
678 | + try { | ||
679 | + Integer.parseInt(s); | ||
680 | + } catch (NumberFormatException e) { | ||
681 | + return false; | ||
682 | + } | ||
683 | + return true; | ||
684 | + } | ||
685 | + | ||
686 | + /** | ||
687 | + * 判断对象能否转 | ||
688 | + * | ||
689 | + * @param o Object | ||
690 | + * @return 是否为Integer | ||
691 | + */ | ||
692 | + public static boolean isInteger(Object o) { | ||
693 | + try { | ||
694 | + Integer.parseInt(String.valueOf(o)); | ||
695 | + return true; | ||
696 | + } catch (NumberFormatException e) { | ||
697 | + return false; | ||
698 | + } | ||
699 | + } | ||
700 | + | ||
701 | + public static String escapeCharacter(String str) { | ||
702 | + if (!isEmpty(str)) { | ||
703 | + if (str.contains("\\")) { | ||
704 | + str = str.replaceAll("\\\\", "\\\\\\\\"); | ||
705 | + } | ||
706 | + } | ||
707 | + return str; | ||
708 | + } | ||
709 | + | ||
710 | + /** | ||
711 | + * @param str | ||
712 | + * @return boolean | ||
713 | + * @Description 匹配字符串是,数字、26个英文字母、下划线组成的8-16位的字符串组合 | ||
714 | + * @version 0.1.0 | ||
715 | + * @author A80077-刘始达 | ||
716 | + * @date 2021/04/06 | ||
717 | + * @since 0.1.0 | ||
718 | + */ | ||
719 | + public static boolean checkPWD(String str) { | ||
720 | + return str.matches("^(?=.*([a-zA-Z].*))(?=.*[0-9].*)[a-zA-Z0-9-_]{8,16}+$"); | ||
721 | + } | ||
722 | + | ||
723 | + /** | ||
724 | + * 判断是否包含特殊字符 | ||
725 | + * | ||
726 | + * @param str | ||
727 | + * @return | ||
728 | + */ | ||
729 | + public static boolean checkSpecificSymbol(String str) { | ||
730 | + String regEx = "[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]|\n|\r|\t"; | ||
731 | + Pattern p = Pattern.compile(regEx); | ||
732 | + Matcher m = p.matcher(str); | ||
733 | + return m.find(); | ||
734 | + } | ||
735 | + | ||
736 | + /** | ||
737 | + * 拼接图片标签url | ||
738 | + * | ||
739 | + * @param str | ||
740 | + * @param ossDomain | ||
741 | + * @return | ||
742 | + */ | ||
743 | + public static String replaceHtmlTag(String str, String ossDomain) { | ||
744 | + if (StringUtils.isEmpty(str)) { | ||
745 | + return ""; | ||
746 | + } | ||
747 | + if (StringUtils.isEmpty(ossDomain)) { | ||
748 | + return str; | ||
749 | + } | ||
750 | + return replaceHtmlTag(str, "img", "src", "src=\"" + ossDomain, "\""); | ||
751 | + } | ||
752 | + | ||
753 | + /** | ||
754 | + * html格式处理:替换指定标签的属性和值 | ||
755 | + * | ||
756 | + * @param str 需要处理的字符串 | ||
757 | + * @param tag 标签名称 | ||
758 | + * @param tagAttrib 要替换的标签属性值 | ||
759 | + * @param startTag 新标签开始标记 | ||
760 | + * @param endTag 新标签结束标记 | ||
761 | + * @return | ||
762 | + */ | ||
763 | + public static String replaceHtmlTag(String str, String tag, String tagAttrib, String startTag, String endTag) { | ||
764 | + String regxpForTag = "<\\s*" + tag + "\\s+([^>]*)\\s*"; | ||
765 | + String regxpForTagAttrib = tagAttrib + "=\\s*\"([^\"]+)\""; | ||
766 | + Pattern patternForTag = Pattern.compile(regxpForTag, Pattern.CASE_INSENSITIVE); | ||
767 | + Pattern patternForAttrib = Pattern.compile(regxpForTagAttrib, Pattern.CASE_INSENSITIVE); | ||
768 | + Matcher matcherForTag = patternForTag.matcher(str); | ||
769 | + StringBuffer sb = new StringBuffer(); | ||
770 | + boolean result = matcherForTag.find(); | ||
771 | + while (result) { | ||
772 | + StringBuffer stringBuffer = new StringBuffer("<" + tag + " "); | ||
773 | + Matcher matcherForAttrib = patternForAttrib.matcher(matcherForTag.group(1)); | ||
774 | + if (matcherForAttrib.find()) { | ||
775 | + String attributeStr = matcherForAttrib.group(1); | ||
776 | + if (!attributeStr.contains("https") && !attributeStr.contains("http")) { | ||
777 | + matcherForAttrib.appendReplacement(stringBuffer, startTag + attributeStr + endTag); | ||
778 | + } | ||
779 | + } | ||
780 | + matcherForAttrib.appendTail(stringBuffer); | ||
781 | + matcherForTag.appendReplacement(sb, stringBuffer.toString()); | ||
782 | + result = matcherForTag.find(); | ||
783 | + } | ||
784 | + matcherForTag.appendTail(sb); | ||
785 | + return sb.toString(); | ||
786 | + } | ||
787 | + | ||
788 | + /** | ||
789 | + * @param str | ||
790 | + * @return java.util.Map<String, List < String>> | ||
791 | + * @Description 字符串的连续切割 返回中文词组 数字和字母的集合 | ||
792 | + * @version 0.1.0 | ||
793 | + * @author 邓彬 | ||
794 | + * @date 2021/4/15 13:53 | ||
795 | + * @since 0.1.0 | ||
796 | + */ | ||
797 | + public static Map<String, List<String>> convertStrToChineseList(String str) { | ||
798 | + if (StringUtils.isEmpty(str)) { | ||
799 | + return null; | ||
800 | + } | ||
801 | + Map<String, List<String>> resultMap = new HashMap<>(); | ||
802 | + List<String> chineseList; | ||
803 | + List<String> charList; | ||
804 | + char[] list = str.toCharArray(); | ||
805 | + StringBuilder chineseStr = new StringBuilder(); | ||
806 | + StringBuilder charStr = new StringBuilder(); | ||
807 | + for (char c : list) { | ||
808 | + if (StringUtils.isChinese(c)) { | ||
809 | + chineseStr.append(c); | ||
810 | + charStr.append(Constant.SLASH_MARK_CHARACTER); | ||
811 | + } else if (Character.isLetterOrDigit(c)) { | ||
812 | + charStr.append(c); | ||
813 | + chineseStr.append(Constant.SLASH_MARK_CHARACTER); | ||
814 | + } else { | ||
815 | + charStr.append(Constant.SLASH_MARK_CHARACTER); | ||
816 | + chineseStr.append(Constant.SLASH_MARK_CHARACTER); | ||
817 | + } | ||
818 | + | ||
819 | + } | ||
820 | + chineseList = Arrays.stream(chineseStr.toString() | ||
821 | + .split(Constant.SLASH_MARK_CHARACTER)) | ||
822 | + .filter(StringUtils::isNotEmpty).collect(Collectors.toList()); | ||
823 | + charList = Arrays.stream(charStr.toString() | ||
824 | + .split(Constant.SLASH_MARK_CHARACTER)) | ||
825 | + .filter(StringUtils::isNotEmpty).map(String::toLowerCase).collect(Collectors.toList()); | ||
826 | + | ||
827 | + resultMap.put("chineseKey", chineseList); | ||
828 | + resultMap.put("charKey", charList); | ||
829 | + return resultMap; | ||
830 | + } | ||
831 | + | ||
832 | + /** | ||
833 | + * 单个字符转换为小写 | ||
834 | + * | ||
835 | + * @param c | ||
836 | + * @return | ||
837 | + */ | ||
838 | + public static char singleCharToLowerCase(char c) { | ||
839 | + if (c >= 'A' && c <= 'Z') { | ||
840 | + c += ('a' - 'A'); | ||
841 | + return c; | ||
842 | + } | ||
843 | + return c; | ||
844 | + } | ||
845 | + | ||
846 | + public static boolean isLong(String shopId) { | ||
847 | + try { | ||
848 | + Long.parseLong(shopId); | ||
849 | + } catch (NumberFormatException e) { | ||
850 | + return false; | ||
851 | + } | ||
852 | + return true; | ||
853 | + } | ||
854 | + | ||
855 | + public static String priceFormatting(String price) { | ||
856 | + if (StringUtils.isEmpty(price)) { | ||
857 | + return Constant.EMPTY_STRING; | ||
858 | + } | ||
859 | + | ||
860 | + String newPrice = ""; | ||
861 | + // 价格不存在小数点,则直接返回,无需处理 | ||
862 | + if (!price.contains(Constant.POINT_BAR_CHARACTER)) { | ||
863 | + newPrice = price; | ||
864 | + return newPrice; | ||
865 | + } | ||
866 | + | ||
867 | + // 有小数点,则分割字符串 | ||
868 | + String[] s = price.split("\\."); | ||
869 | + | ||
870 | + // 小数位数大于0 且小于2 且存在非0字符 | ||
871 | + if (s[1].length() > 0 && s[1].length() <= 2 && !judgeIsNumeric(s[1])) { | ||
872 | + BigDecimal bigDecimal = new BigDecimal(price).setScale(2, BigDecimal.ROUND_HALF_UP); | ||
873 | + newPrice = bigDecimal.toPlainString(); | ||
874 | + } | ||
875 | + // 【保留这个else if】小数位数大于0 且大于2 且存在非0字符,理论上不会存在,因为新增商品时已经限定最多输入2个小数点 | ||
876 | + else if (s[1].length() > 0 && s[1].length() > 2 && !judgeIsNumeric(s[1])) { | ||
877 | + BigDecimal bigDecimal = new BigDecimal(price).setScale(2, BigDecimal.ROUND_HALF_UP); | ||
878 | + String[] split = bigDecimal.toPlainString().split("\\."); | ||
879 | + if (split[1].length() > 0 && judgeIsNumeric(split[1])) { | ||
880 | + newPrice = new BigDecimal(bigDecimal.toPlainString()).setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString(); | ||
881 | + } else { | ||
882 | + newPrice = bigDecimal.toPlainString(); | ||
883 | + } | ||
884 | + } else { | ||
885 | + // 小数位数大于0 且小于2 且小数点都是0 | ||
886 | + newPrice = new BigDecimal(price).setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString(); | ||
887 | + } | ||
888 | + return newPrice; | ||
889 | + } | ||
890 | + | ||
891 | + /** | ||
892 | + * 判断字符串是否只包含0 | ||
893 | + * | ||
894 | + * @param str | ||
895 | + * @return | ||
896 | + */ | ||
897 | + private static boolean judgeIsNumeric(String str) { | ||
898 | + return Pattern.compile("[0]*").matcher(str).matches(); | ||
899 | + } | ||
900 | + | ||
901 | + /** | ||
902 | + * 字符串以","分隔后转为String[] | ||
903 | + * | ||
904 | + * @param s | ||
905 | + * @return | ||
906 | + */ | ||
907 | + public static String[] string2ArraySplitByComma(String s) { | ||
908 | + if (s == null || s.length() == 0) { | ||
909 | + return new String[]{}; | ||
910 | + } | ||
911 | + return s.split(Constant.COMMA_CHARACTER); | ||
912 | + } | ||
913 | + | ||
914 | + public static boolean isStringArrayContainsSpecifiedValue(String[] strings, String value) { | ||
915 | + if (null == strings || strings.length <= 0 || value == null || value.length() == 0) { | ||
916 | + return false; | ||
917 | + } | ||
918 | + boolean isContainsSpecifiedValue = false; | ||
919 | + for (String s : strings) { | ||
920 | + if (s.equals(value)) { | ||
921 | + isContainsSpecifiedValue = true; | ||
922 | + break; | ||
923 | + } | ||
924 | + } | ||
925 | + return isContainsSpecifiedValue; | ||
926 | + } | ||
927 | + | ||
928 | + /** | ||
929 | + * 字符串以","分隔后转为list | ||
930 | + * | ||
931 | + * @param s | ||
932 | + * @return | ||
933 | + */ | ||
934 | + public static List<String> string2ListSplitByComma(String s) { | ||
935 | + List<String> stringList = new ArrayList<>(); | ||
936 | + if (s == null || s.length() == 0) { | ||
937 | + return stringList; | ||
938 | + } | ||
939 | + String[] strArray = string2ArraySplitByComma(s); | ||
940 | + | ||
941 | + for (String st : strArray) { | ||
942 | + if (null != st && st.trim() != null || st.trim().length() != 0) { | ||
943 | + stringList.add(st.trim()); | ||
944 | + } | ||
945 | + } | ||
946 | + | ||
947 | + return stringList; | ||
948 | + } | ||
949 | + | ||
950 | + /** | ||
951 | + * 字符串按照特殊符号 | ||
952 | + * ".*[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?\\\\]+.*" | ||
953 | + * 截取转成字符串集合 | ||
954 | + * | ||
955 | + * @param str | ||
956 | + * @return | ||
957 | + */ | ||
958 | + public static List<String> splitStringBySpecificSymbol(String str) throws PatternSyntaxException { | ||
959 | + String regEx = "[`~!@#$%^&*()\\-+=|{}':;,\\[\\].<>/?!¥…()—【】‘;:”“’。,、?\\\\]"; | ||
960 | + Pattern p = Pattern.compile(regEx); | ||
961 | + Matcher m = p.matcher(str); | ||
962 | + return Stream.of(m.replaceAll("_").split("_")).map(String::trim).filter(StringUtils::isNotBlank).collect(Collectors.toList()); | ||
963 | + } | ||
964 | + | ||
965 | + /** | ||
966 | + * 使用gzip压缩字符串 | ||
967 | + * | ||
968 | + * @param str 要压缩的字符串 | ||
969 | + * @return 压缩后的字符串 | ||
970 | + */ | ||
971 | + public static String compressByGZip(String str) { | ||
972 | + if (str == null || str.length() == 0) { | ||
973 | + return str; | ||
974 | + } | ||
975 | + ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
976 | + GZIPOutputStream gzip = null; | ||
977 | + try { | ||
978 | + gzip = new GZIPOutputStream(out); | ||
979 | + gzip.write(str.getBytes(StandardCharsets.UTF_8)); | ||
980 | + } catch (IOException e) { | ||
981 | + log.error("compressByGZip error: {}", e); | ||
982 | + } finally { | ||
983 | + if (gzip != null) { | ||
984 | + try { | ||
985 | + gzip.close(); | ||
986 | + } catch (IOException e) { | ||
987 | + log.error("compressByGZip gzip close error: {}", e); | ||
988 | + } | ||
989 | + } | ||
990 | + } | ||
991 | + // 必须在关闭gzip流之后再读取 | ||
992 | + try { | ||
993 | + return new sun.misc.BASE64Encoder().encode(out.toByteArray()); | ||
994 | + } catch (Exception e) { | ||
995 | + log.error("compressByGZip BASE64Encoder error:{}", e); | ||
996 | + } | ||
997 | + return str; | ||
998 | + } | ||
999 | + | ||
1000 | + /** | ||
1001 | + * 使用gzip解压缩 | ||
1002 | + * | ||
1003 | + * @param compressedStr 已压缩的字符串 | ||
1004 | + * @return 解压之后的字符串 | ||
1005 | + */ | ||
1006 | + public static String uncompressByGZip(String compressedStr) { | ||
1007 | + if (compressedStr == null || compressedStr.length() == 0) { | ||
1008 | + return compressedStr; | ||
1009 | + } | ||
1010 | + | ||
1011 | + String decompressed; | ||
1012 | + try ( | ||
1013 | + ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
1014 | + ByteArrayInputStream in = new ByteArrayInputStream(new sun.misc.BASE64Decoder().decodeBuffer(compressedStr)); | ||
1015 | + GZIPInputStream ginzip = new GZIPInputStream(in); | ||
1016 | + ) { | ||
1017 | + byte[] buffer = new byte[1024]; | ||
1018 | + int offset; | ||
1019 | + while ((offset = ginzip.read(buffer)) != -1) { | ||
1020 | + out.write(buffer, 0, offset); | ||
1021 | + } | ||
1022 | + decompressed = out.toString(); | ||
1023 | + } catch (IOException e) { | ||
1024 | + log.error("uncompressByGZip error:{}", e); | ||
1025 | + return compressedStr; | ||
1026 | + } | ||
1027 | + return decompressed; | ||
1028 | + } | ||
1029 | + | ||
1030 | + /** | ||
1031 | + * 将list转为字符串,用逗号隔开 | ||
1032 | + * | ||
1033 | + * @param list | ||
1034 | + * @return | ||
1035 | + */ | ||
1036 | + public static String listTransToStr(List<String> list) { | ||
1037 | + if (CollectionUtils.isEmpty(list)) return null; | ||
1038 | + StringBuilder sb = new StringBuilder(); | ||
1039 | + list.forEach(x -> { | ||
1040 | + sb.append(x); | ||
1041 | + sb.append(","); | ||
1042 | + }); | ||
1043 | + String str = sb.toString(); | ||
1044 | + return str.substring(0, str.length() - 1); | ||
1045 | + } | ||
1046 | + | ||
1047 | + /** | ||
1048 | + * 是否包含中英文 | ||
1049 | + * | ||
1050 | + * @param str | ||
1051 | + * @return | ||
1052 | + */ | ||
1053 | + public static boolean checkCnAndEn(String str) { | ||
1054 | + String regEx = Constant.CHI_EN_REGEXP; | ||
1055 | + Pattern p = Pattern.compile(regEx); | ||
1056 | + Matcher m = p.matcher(str); | ||
1057 | + return m.find(); | ||
1058 | + } | ||
1059 | + | ||
1060 | + | ||
1061 | + /** | ||
1062 | + * @param code 要隐藏显示的字符串 | ||
1063 | + * @param head 前面保留的位数 | ||
1064 | + * @param tail 后面保留的位数 | ||
1065 | + * @return 处理后的字符串 | ||
1066 | + */ | ||
1067 | + public static String getEncryptCode(String code, int head, int tail) { | ||
1068 | + int body = code.length() - head - tail; | ||
1069 | + String regexVar = "(\\w{%d})(\\w{%d})(\\w{%d})"; | ||
1070 | + String regex = String.format(regexVar, head, body, tail); | ||
1071 | + String bodyPart = code.replaceAll(regex, "$2"); | ||
1072 | + String bodyEncrypt = bodyPart.replaceAll("\\w", "*"); | ||
1073 | + String replacement = String.format("$1%s$3", bodyEncrypt); | ||
1074 | + return code.replaceAll(regex, replacement); | ||
1075 | + } | ||
1076 | +} |
job/src/main/java/com/canrd/shop/common/utils/TemplateFormatUtils.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import java.util.Map; | ||
4 | +import java.util.regex.Matcher; | ||
5 | +import java.util.regex.Pattern; | ||
6 | + | ||
7 | +/** | ||
8 | + * | ||
9 | + * 消息模板占位符替换工具 | ||
10 | + * | ||
11 | + * @author fanzhenyu | ||
12 | + * @date 2022-04-20 | ||
13 | + */ | ||
14 | +public class TemplateFormatUtils { | ||
15 | + | ||
16 | + | ||
17 | + /** | ||
18 | + * 正则 匹配 { + "多个任意字符" + } | ||
19 | + */ | ||
20 | + private static final String DEFAULT_REG = "\\{[\\w]+\\}"; | ||
21 | + | ||
22 | + /** | ||
23 | + * | ||
24 | + * @param text 原模板 占位符格式必须为:{fieldName} | ||
25 | + * @param map 模板参数 | ||
26 | + * @return | ||
27 | + */ | ||
28 | + public static String replaceTemplateContent(String text, Map<String, String> map){ | ||
29 | + return replaceTemplateContent(text,map,DEFAULT_REG); | ||
30 | + } | ||
31 | + | ||
32 | + /** | ||
33 | + * | ||
34 | + * @param text 原模板 占位符格式必须为:{fieldName} | ||
35 | + * @param map 模板参数 | ||
36 | + * @param reg 自定义占位符样式 - 正则匹配 | ||
37 | + * @return | ||
38 | + */ | ||
39 | + public static String replaceTemplateContent(String text,Map<String,String> map,String reg){ | ||
40 | + | ||
41 | + if(StringUtils.isBlank(reg)){ | ||
42 | + reg = DEFAULT_REG; | ||
43 | + } | ||
44 | + | ||
45 | + Pattern pattern = Pattern.compile(reg); | ||
46 | + Matcher m = pattern.matcher(text); | ||
47 | + while(m.find()){ | ||
48 | + String currentGroup = m.group(); | ||
49 | + String currentPattern = currentGroup.replaceAll("^\\{", "").replaceAll("\\}$", "").trim(); | ||
50 | + String mapValue = map.get(currentPattern); | ||
51 | + if (mapValue != null){ | ||
52 | + text = text.replace(currentGroup, mapValue); | ||
53 | + } | ||
54 | + } | ||
55 | + return text; | ||
56 | + } | ||
57 | +} |
job/src/main/java/com/canrd/shop/common/utils/ThrowableUtil.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | + | ||
4 | +import com.canrd.shop.common.exception.BadRequestException; | ||
5 | + | ||
6 | +import javax.validation.ConstraintViolationException; | ||
7 | +import java.io.PrintWriter; | ||
8 | +import java.io.StringWriter; | ||
9 | + | ||
10 | +/** | ||
11 | + * 异常工具 2019-01-06 | ||
12 | + */ | ||
13 | +public class ThrowableUtil { | ||
14 | + | ||
15 | + /** | ||
16 | + * 获取堆栈信息 | ||
17 | + */ | ||
18 | + public static String getStackTrace(Throwable throwable) { | ||
19 | + StringWriter sw = new StringWriter(); | ||
20 | + try (PrintWriter pw = new PrintWriter(sw)) { | ||
21 | + throwable.printStackTrace(pw); | ||
22 | + return sw.toString(); | ||
23 | + } | ||
24 | + } | ||
25 | + | ||
26 | + public static void throwForeignKeyException(Throwable e, String msg) { | ||
27 | + Throwable t = e.getCause(); | ||
28 | + while ((t != null) && !(t instanceof ConstraintViolationException)) { | ||
29 | + t = t.getCause(); | ||
30 | + } | ||
31 | + if (t != null) { | ||
32 | + throw new BadRequestException(msg); | ||
33 | + } | ||
34 | + assert false; | ||
35 | + throw new BadRequestException("删除失败:" + t.getMessage()); | ||
36 | + } | ||
37 | +} |
job/src/main/java/com/canrd/shop/common/utils/TransactionHelper.java
0 → 100644
1 | +package com.canrd.shop.common.utils; | ||
2 | + | ||
3 | +import org.springframework.stereotype.Component; | ||
4 | +import org.springframework.transaction.annotation.Propagation; | ||
5 | +import org.springframework.transaction.annotation.Transactional; | ||
6 | + | ||
7 | +import java.util.function.Supplier; | ||
8 | + | ||
9 | +/** | ||
10 | + * @author: | ||
11 | + * @date: 2021/12/21 | ||
12 | + */ | ||
13 | +@Component | ||
14 | +public class TransactionHelper { | ||
15 | + | ||
16 | + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) | ||
17 | + public <T> T run(Supplier<T> command) { | ||
18 | + return command.get(); | ||
19 | + } | ||
20 | + | ||
21 | + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) | ||
22 | + public void run(Runnable command) { | ||
23 | + command.run(); | ||
24 | + } | ||
25 | + | ||
26 | + | ||
27 | +} |
job/src/main/java/com/canrd/shop/config/MybatisPlusConfig.java
0 → 100644
job/src/main/java/com/canrd/shop/config/RestTemplateConfig.java
0 → 100644
1 | +package com.canrd.shop.config; | ||
2 | + | ||
3 | +import org.springframework.context.annotation.Bean; | ||
4 | +import org.springframework.context.annotation.Configuration; | ||
5 | +import org.springframework.http.client.ClientHttpRequestFactory; | ||
6 | +import org.springframework.http.client.SimpleClientHttpRequestFactory; | ||
7 | +import org.springframework.web.client.RestTemplate; | ||
8 | + | ||
9 | + | ||
10 | +@Configuration | ||
11 | +public class RestTemplateConfig { | ||
12 | + | ||
13 | + @Bean | ||
14 | + public RestTemplate restTemplate(ClientHttpRequestFactory factory) { | ||
15 | + return new RestTemplate(factory); | ||
16 | + } | ||
17 | + | ||
18 | + @Bean | ||
19 | + public ClientHttpRequestFactory simpleClientHttpRequestFactory() { | ||
20 | + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); | ||
21 | + factory.setReadTimeout(3000); | ||
22 | + factory.setConnectTimeout(5000); | ||
23 | + return factory; | ||
24 | + } | ||
25 | + | ||
26 | +} |
job/src/main/java/com/canrd/shop/config/WebConfig.java
0 → 100644
1 | +package com.canrd.shop.config; | ||
2 | + | ||
3 | +import com.alibaba.fastjson.support.config.FastJsonConfig; | ||
4 | +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; | ||
5 | +import lombok.extern.slf4j.Slf4j; | ||
6 | +import org.springframework.context.annotation.Configuration; | ||
7 | +import org.springframework.http.MediaType; | ||
8 | +import org.springframework.http.converter.HttpMessageConverter; | ||
9 | +import org.springframework.http.converter.StringHttpMessageConverter; | ||
10 | +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
11 | + | ||
12 | +import java.nio.charset.StandardCharsets; | ||
13 | +import java.util.ArrayList; | ||
14 | +import java.util.Collections; | ||
15 | +import java.util.List; | ||
16 | +import java.util.stream.Collectors; | ||
17 | + | ||
18 | + | ||
19 | +@Slf4j | ||
20 | +@Configuration | ||
21 | +public class WebConfig implements WebMvcConfigurer { | ||
22 | + | ||
23 | + | ||
24 | + @Override | ||
25 | + public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { | ||
26 | + FastJsonHttpMessageConverter fastConverter = getFastJsonHttpMessageConverter(); | ||
27 | + | ||
28 | + StringHttpMessageConverter stringHttpMessageConverter = getStringHttpMessageConverter(); | ||
29 | + | ||
30 | + /** | ||
31 | + * 添加StringHttpMessageConverter ,让其转化String。注意顺序,StringHttpMessageConverter 要在FastJsonHttpMessageConverter 之前。 | ||
32 | + * | ||
33 | + * https://www.cnblogs.com/slankka/p/11437034.html | ||
34 | + */ | ||
35 | + converters.add(0, fastConverter); | ||
36 | + converters.add(0, stringHttpMessageConverter); | ||
37 | + log.info("HttpMessageConverter顺序\n{}", converters.stream().map(c -> c.getClass().getName()).collect(Collectors.joining("\n"))); | ||
38 | + } | ||
39 | + | ||
40 | + private static StringHttpMessageConverter getStringHttpMessageConverter() { | ||
41 | + StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); | ||
42 | + stringHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN)); | ||
43 | + return stringHttpMessageConverter; | ||
44 | + } | ||
45 | + | ||
46 | + private static FastJsonHttpMessageConverter getFastJsonHttpMessageConverter() { | ||
47 | + FastJsonConfig fastJsonConfig = new FastJsonConfig(); | ||
48 | + //解决空值序列化的问题,改为不序列化 | ||
49 | + /*fastJsonConfig.setSerializeFilters(new PropertyFilter() { | ||
50 | + @Override | ||
51 | + public boolean apply(Object source,String name, Object value) { | ||
52 | + //if(value.getClass().isPrimitive() == null){ | ||
53 | + if(value == null){ | ||
54 | + return false; | ||
55 | + } | ||
56 | + return true; | ||
57 | + } | ||
58 | + });*/ | ||
59 | + fastJsonConfig.setCharset(StandardCharsets.UTF_8); | ||
60 | + FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); | ||
61 | + List<MediaType> supportedMediaTypes = new ArrayList<>(); | ||
62 | + supportedMediaTypes.add(MediaType.APPLICATION_JSON); | ||
63 | + supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); | ||
64 | + supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); | ||
65 | +// supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); | ||
66 | + supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); | ||
67 | + supportedMediaTypes.add(MediaType.APPLICATION_PDF); | ||
68 | + supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); | ||
69 | + supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); | ||
70 | +// supportedMediaTypes.add(MediaType.APPLICATION_XML); | ||
71 | + supportedMediaTypes.add(MediaType.IMAGE_GIF); | ||
72 | + supportedMediaTypes.add(MediaType.IMAGE_JPEG); | ||
73 | + supportedMediaTypes.add(MediaType.IMAGE_PNG); | ||
74 | + supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); | ||
75 | + supportedMediaTypes.add(MediaType.TEXT_HTML); | ||
76 | + supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); | ||
77 | + supportedMediaTypes.add(MediaType.TEXT_PLAIN); | ||
78 | +// supportedMediaTypes.add(MediaType.TEXT_XML); | ||
79 | + fastConverter.setSupportedMediaTypes(supportedMediaTypes); | ||
80 | + fastConverter.setFastJsonConfig(fastJsonConfig); | ||
81 | + fastConverter.setDefaultCharset(StandardCharsets.UTF_8); | ||
82 | + return fastConverter; | ||
83 | + } | ||
84 | +} |
job/src/main/java/com/canrd/shop/controller/HelloController.java
0 → 100644
1 | +package com.canrd.shop.controller; | ||
2 | + | ||
3 | +import com.canrd.shop.common.constant.ServerResult; | ||
4 | +import com.canrd.shop.common.jsr303.OperateGroup; | ||
5 | +import com.canrd.shop.module.vo.ProductQueryVO; | ||
6 | +import org.springframework.validation.annotation.Validated; | ||
7 | +import org.springframework.web.bind.annotation.PostMapping; | ||
8 | +import org.springframework.web.bind.annotation.RequestBody; | ||
9 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
10 | +import org.springframework.web.bind.annotation.RestController; | ||
11 | + | ||
12 | +/** | ||
13 | + * (Product)表控制层 | ||
14 | + * | ||
15 | + * @author makejava | ||
16 | + * @since 2023-05-29 11:43:33 | ||
17 | + */ | ||
18 | +@RestController | ||
19 | +@RequestMapping("/canrd/job") | ||
20 | +public class HelloController { | ||
21 | + | ||
22 | + /** | ||
23 | + * 分页查询 | ||
24 | + * | ||
25 | + * @param productQueryVO 查询条件 | ||
26 | + * @return 查询结果 | ||
27 | + */ | ||
28 | + @PostMapping("/list") | ||
29 | + public ServerResult hello(@RequestBody @Validated({OperateGroup.List.class}) ProductQueryVO productQueryVO) { | ||
30 | + return ServerResult.success("hello world!"); | ||
31 | + } | ||
32 | + | ||
33 | +} | ||
34 | + |
job/src/main/java/com/canrd/shop/job/OrderOverTimeJob.java
0 → 100644
1 | +package com.canrd.shop.job; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
4 | +import com.canrd.shop.common.constant.Constant; | ||
5 | +import com.canrd.shop.module.dto.OrdersDO; | ||
6 | +import com.canrd.shop.service.OrdersService; | ||
7 | +import lombok.extern.slf4j.Slf4j; | ||
8 | +import org.joda.time.DateTime; | ||
9 | +import org.springframework.scheduling.annotation.Scheduled; | ||
10 | +import org.springframework.stereotype.Component; | ||
11 | +import org.springframework.util.CollectionUtils; | ||
12 | + | ||
13 | +import javax.annotation.Resource; | ||
14 | +import java.util.ArrayList; | ||
15 | +import java.util.Arrays; | ||
16 | +import java.util.List; | ||
17 | + | ||
18 | +/** | ||
19 | + * @author: xms | ||
20 | + * @description: TODO | ||
21 | + * @date: 2023/6/25 10:35 | ||
22 | + * @version: 1.0 | ||
23 | + */ | ||
24 | +@Slf4j | ||
25 | +@Component | ||
26 | +public class OrderOverTimeJob { | ||
27 | + | ||
28 | + @Resource | ||
29 | + private OrdersService ordersService; | ||
30 | + | ||
31 | + /** | ||
32 | + * 每隔5分执行一次 | ||
33 | + */ | ||
34 | + @Scheduled(cron = "0 */5 * * * ?") | ||
35 | +// @Scheduled(cron = "*/5 * * * * ?") | ||
36 | + public void payOverTimeExecute() { | ||
37 | + log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss")); | ||
38 | + LambdaQueryWrapper<OrdersDO> queryWrapper = new LambdaQueryWrapper<OrdersDO>() | ||
39 | + .in(OrdersDO::getPaymentstatus, Arrays.asList(0, 1)); | ||
40 | + List<OrdersDO> ordersDOS = ordersService.list(queryWrapper); | ||
41 | + | ||
42 | + if (!CollectionUtils.isEmpty(ordersDOS)) { | ||
43 | + List<OrdersDO> updateOrdersList = new ArrayList<>(); | ||
44 | + ordersDOS.forEach(ordersDO -> { | ||
45 | + DateTime createTime = new DateTime(ordersDO.getCreatedate()); | ||
46 | + if (DateTime.now().isAfter(createTime.plusDays(Constant.ONE))) { | ||
47 | + ordersDO.setOrderstatus(-1); | ||
48 | + ordersDO.setPaymentstatus(-1); | ||
49 | + ordersDO.setModifydate(DateTime.now().toDate()); | ||
50 | + updateOrdersList.add(ordersDO); | ||
51 | + } | ||
52 | + | ||
53 | + }); | ||
54 | + if (!CollectionUtils.isEmpty(updateOrdersList)) { | ||
55 | + ordersService.updateBatchById(ordersDOS); | ||
56 | + } | ||
57 | + | ||
58 | + } | ||
59 | + log.info("执行结束时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss")); | ||
60 | + } | ||
61 | + | ||
62 | +} |
job/src/main/java/com/canrd/shop/mapper/OrdersMapper.java
0 → 100644
1 | +package com.canrd.shop.mapper; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
4 | +import com.canrd.shop.module.dto.OrdersDO; | ||
5 | + | ||
6 | +/** | ||
7 | + * (Orders)表数据库访问层 | ||
8 | + * | ||
9 | + * @author makejava | ||
10 | + * @since 2023-06-25 10:43:07 | ||
11 | + */ | ||
12 | +public interface OrdersMapper extends BaseMapper<OrdersDO> { | ||
13 | + | ||
14 | + | ||
15 | +} | ||
16 | + |
job/src/main/java/com/canrd/shop/mapper/ProductMapper.java
0 → 100644
1 | +package com.canrd.shop.mapper; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
4 | +import com.canrd.shop.module.dto.ProductDO; | ||
5 | +import org.apache.ibatis.annotations.Mapper; | ||
6 | + | ||
7 | +/** | ||
8 | + * (Product)表数据库访问层 | ||
9 | + * | ||
10 | + * @author makejava | ||
11 | + * @since 2023-05-29 11:43:34 | ||
12 | + */ | ||
13 | +@Mapper | ||
14 | +public interface ProductMapper extends BaseMapper<ProductDO> { | ||
15 | + | ||
16 | + | ||
17 | +} | ||
18 | + |
job/src/main/java/com/canrd/shop/module/dto/OrdersDO.java
0 → 100644
1 | +package com.canrd.shop.module.dto; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
4 | +import lombok.*; | ||
5 | +import lombok.experimental.SuperBuilder; | ||
6 | + | ||
7 | +import java.io.Serializable; | ||
8 | +import java.util.Date; | ||
9 | + | ||
10 | +/** | ||
11 | + * (Orders)实体类 | ||
12 | + * | ||
13 | + * @author makejava | ||
14 | + * @since 2023-06-25 10:42:58 | ||
15 | + */ | ||
16 | +@TableName("orders") | ||
17 | +@Data | ||
18 | +@AllArgsConstructor | ||
19 | +@ToString | ||
20 | +@NoArgsConstructor | ||
21 | +@EqualsAndHashCode(callSuper = false) | ||
22 | +@SuperBuilder | ||
23 | +public class OrdersDO implements Serializable { | ||
24 | + private static final long serialVersionUID = -34170173982796273L; | ||
25 | + | ||
26 | + private String id; | ||
27 | + | ||
28 | + private Date createdate; | ||
29 | + | ||
30 | + private Date modifydate; | ||
31 | + | ||
32 | + private Double deliveryfee; | ||
33 | + | ||
34 | + private String deliverytypename; | ||
35 | + | ||
36 | + private String memo; | ||
37 | + | ||
38 | + private String ordersn; | ||
39 | + | ||
40 | + private Integer orderstatus; | ||
41 | + | ||
42 | + private Double paidamount; | ||
43 | + | ||
44 | + private String paymentconfigname; | ||
45 | + | ||
46 | + private Double paymentfee; | ||
47 | + | ||
48 | + private Integer paymentstatus; | ||
49 | + | ||
50 | + private Double producttotalprice; | ||
51 | + | ||
52 | + private Integer producttotalquantity; | ||
53 | + | ||
54 | + private Double productweight; | ||
55 | + | ||
56 | + private Integer productweightunit; | ||
57 | + | ||
58 | + private String shipaddress; | ||
59 | + | ||
60 | + private String shiparea; | ||
61 | + | ||
62 | + private String shipareapath; | ||
63 | + | ||
64 | + private String shipmobile; | ||
65 | + | ||
66 | + private String shipname; | ||
67 | + | ||
68 | + private String shipphone; | ||
69 | + | ||
70 | + private String shipzipcode; | ||
71 | + | ||
72 | + private String invoice; | ||
73 | + | ||
74 | + private String tax; | ||
75 | + | ||
76 | + private String invoiceId; | ||
77 | + | ||
78 | + private String invoiceType; | ||
79 | + | ||
80 | + private Integer shippingstatus; | ||
81 | + | ||
82 | + private Double totalamount; | ||
83 | + | ||
84 | + private String memberId; | ||
85 | + | ||
86 | + private String deliverytypeId; | ||
87 | + | ||
88 | + private String paymentconfigId; | ||
89 | + | ||
90 | + private String school; | ||
91 | + | ||
92 | + private String college; | ||
93 | + | ||
94 | + private String teacher; | ||
95 | + | ||
96 | + private String teacherphone; | ||
97 | + | ||
98 | +} |
job/src/main/java/com/canrd/shop/module/dto/ProductDO.java
0 → 100644
1 | +package com.canrd.shop.module.dto; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
4 | +import lombok.*; | ||
5 | +import lombok.experimental.SuperBuilder; | ||
6 | + | ||
7 | +import java.io.Serializable; | ||
8 | +import java.util.Date; | ||
9 | + | ||
10 | +/** | ||
11 | + * (Product)实体类 | ||
12 | + * | ||
13 | + * @author makejava | ||
14 | + * @since 2023-05-29 11:43:32 | ||
15 | + */ | ||
16 | +@TableName("product") | ||
17 | +@Data | ||
18 | +@AllArgsConstructor | ||
19 | +@ToString | ||
20 | +@NoArgsConstructor | ||
21 | +@EqualsAndHashCode(callSuper = false) | ||
22 | +@SuperBuilder | ||
23 | +public class ProductDO implements Serializable { | ||
24 | + | ||
25 | + private String id; | ||
26 | + | ||
27 | + private Date createdate; | ||
28 | + | ||
29 | + private Date modifydate; | ||
30 | + | ||
31 | + private String description; | ||
32 | + | ||
33 | + private Integer freezestore; | ||
34 | + | ||
35 | + private String htmlfilepath; | ||
36 | + | ||
37 | + private Byte isbest; | ||
38 | + | ||
39 | + private Byte ishot; | ||
40 | + /** | ||
41 | + * 是否上架 | ||
42 | + */ | ||
43 | + private Byte ismarketable; | ||
44 | + | ||
45 | + private Byte isnew; | ||
46 | + | ||
47 | + private Double marketprice; | ||
48 | + | ||
49 | + private String metadescription; | ||
50 | + | ||
51 | + private String metakeywords; | ||
52 | + | ||
53 | + private String name; | ||
54 | + | ||
55 | + private String englishname; | ||
56 | + | ||
57 | + private String model; | ||
58 | + | ||
59 | + private String exterior; | ||
60 | + | ||
61 | + private String basecore1; | ||
62 | + | ||
63 | + private String basename2; | ||
64 | + | ||
65 | + private String basecore2; | ||
66 | + | ||
67 | + private String basename3; | ||
68 | + | ||
69 | + private String basecore3; | ||
70 | + | ||
71 | + private String basename4; | ||
72 | + | ||
73 | + private String basecore4; | ||
74 | + | ||
75 | + private String basename5; | ||
76 | + | ||
77 | + private String basecore5; | ||
78 | + | ||
79 | + private String basename6; | ||
80 | + | ||
81 | + private String basecore6; | ||
82 | + | ||
83 | + private String basename7; | ||
84 | + | ||
85 | + private String basecore7; | ||
86 | + | ||
87 | + private String basename8; | ||
88 | + | ||
89 | + private String basecore8; | ||
90 | + | ||
91 | + private String basename1; | ||
92 | + | ||
93 | + private Integer point; | ||
94 | + | ||
95 | + private Double price; | ||
96 | + | ||
97 | + private String productimageliststore; | ||
98 | + | ||
99 | + private String productsn; | ||
100 | + | ||
101 | + private Integer store; | ||
102 | + | ||
103 | + private Double weight; | ||
104 | + | ||
105 | + private Integer weightunit; | ||
106 | + | ||
107 | + private String brandId; | ||
108 | + | ||
109 | + private String productcategoryId; | ||
110 | + | ||
111 | + private String productcategoryName; | ||
112 | + | ||
113 | + private String producttypeId; | ||
114 | + | ||
115 | + private String producttypeName; | ||
116 | + | ||
117 | + private String introduction; | ||
118 | + | ||
119 | + private String storage; | ||
120 | + | ||
121 | + private String physicalproperty; | ||
122 | + | ||
123 | + private String advantage; | ||
124 | + | ||
125 | + private String wiki; | ||
126 | + | ||
127 | +} |
job/src/main/java/com/canrd/shop/module/vo/BasePageVO.java
0 → 100644
1 | +package com.canrd.shop.module.vo; | ||
2 | + | ||
3 | +import com.canrd.shop.common.constant.Constant; | ||
4 | +import com.canrd.shop.common.jsr303.OperateGroup; | ||
5 | +import com.fasterxml.jackson.annotation.JsonInclude; | ||
6 | +import lombok.AllArgsConstructor; | ||
7 | +import lombok.Data; | ||
8 | +import lombok.NoArgsConstructor; | ||
9 | +import lombok.experimental.SuperBuilder; | ||
10 | + | ||
11 | +import javax.validation.constraints.Max; | ||
12 | +import javax.validation.constraints.Min; | ||
13 | +import javax.validation.constraints.NotNull; | ||
14 | + | ||
15 | + | ||
16 | +@SuperBuilder(toBuilder = true) | ||
17 | +@Data | ||
18 | +@NoArgsConstructor | ||
19 | +@AllArgsConstructor | ||
20 | +public class BasePageVO { | ||
21 | + | ||
22 | + /** | ||
23 | + * 页码 | ||
24 | + */ | ||
25 | + @JsonInclude(JsonInclude.Include.NON_NULL) | ||
26 | + @NotNull(message = "页码不能为空", groups = {OperateGroup.List.class}) | ||
27 | + @Min(value = Constant.ONE, message = "页码不能小于1", groups = {OperateGroup.List.class}) | ||
28 | + private Integer pageNo = 1; | ||
29 | + /** | ||
30 | + * 页 | ||
31 | + */ | ||
32 | + @JsonInclude(JsonInclude.Include.NON_NULL) | ||
33 | + @NotNull(message = "每页大小不能为空", groups = {OperateGroup.List.class}) | ||
34 | + @Min(value = 1, message = "每页大小不能小于1", groups = {OperateGroup.List.class}) | ||
35 | + @Max(value = 5000, message = "每页大小不能大于5000", groups = {OperateGroup.List.class}) | ||
36 | + private Integer pageSize = 10; | ||
37 | + | ||
38 | + /** | ||
39 | + * 总数 | ||
40 | + */ | ||
41 | + @JsonInclude(JsonInclude.Include.NON_NULL) | ||
42 | + private Integer total; | ||
43 | +} |
job/src/main/java/com/canrd/shop/module/vo/OrdersQueryVO.java
0 → 100644
1 | +package com.canrd.shop.module.vo; | ||
2 | + | ||
3 | +import lombok.*; | ||
4 | +import lombok.experimental.SuperBuilder; | ||
5 | + | ||
6 | +import java.io.Serializable; | ||
7 | +import java.util.Date; | ||
8 | +import java.util.List; | ||
9 | + | ||
10 | +/** | ||
11 | + * (Orders)实体类 | ||
12 | + * | ||
13 | + * @author makejava | ||
14 | + * @since 2023-06-25 10:43:07 | ||
15 | + */ | ||
16 | +@Data | ||
17 | +@AllArgsConstructor | ||
18 | +@ToString | ||
19 | +@NoArgsConstructor | ||
20 | +@EqualsAndHashCode(callSuper = false) | ||
21 | +@SuperBuilder | ||
22 | +public class OrdersQueryVO extends BasePageVO implements Serializable { | ||
23 | + | ||
24 | + private List<Long> ids; | ||
25 | + | ||
26 | + | ||
27 | + private String id; | ||
28 | + | ||
29 | + private Date createdate; | ||
30 | + | ||
31 | + private Date modifydate; | ||
32 | + | ||
33 | + private Double deliveryfee; | ||
34 | + | ||
35 | + private String deliverytypename; | ||
36 | + | ||
37 | + private String memo; | ||
38 | + | ||
39 | + private String ordersn; | ||
40 | + | ||
41 | + private Integer orderstatus; | ||
42 | + | ||
43 | + private Double paidamount; | ||
44 | + | ||
45 | + private String paymentconfigname; | ||
46 | + | ||
47 | + private Double paymentfee; | ||
48 | + | ||
49 | + private Integer paymentstatus; | ||
50 | + | ||
51 | + private Double producttotalprice; | ||
52 | + | ||
53 | + private Integer producttotalquantity; | ||
54 | + | ||
55 | + private Double productweight; | ||
56 | + | ||
57 | + private Integer productweightunit; | ||
58 | + | ||
59 | + private String shipaddress; | ||
60 | + | ||
61 | + private String shiparea; | ||
62 | + | ||
63 | + private String shipareapath; | ||
64 | + | ||
65 | + private String shipmobile; | ||
66 | + | ||
67 | + private String shipname; | ||
68 | + | ||
69 | + private String shipphone; | ||
70 | + | ||
71 | + private String shipzipcode; | ||
72 | + | ||
73 | + private String invoice; | ||
74 | + | ||
75 | + private String tax; | ||
76 | + | ||
77 | + private String invoiceId; | ||
78 | + | ||
79 | + private String invoiceType; | ||
80 | + | ||
81 | + private Integer shippingstatus; | ||
82 | + | ||
83 | + private Double totalamount; | ||
84 | + | ||
85 | + private String memberId; | ||
86 | + | ||
87 | + private String deliverytypeId; | ||
88 | + | ||
89 | + private String paymentconfigId; | ||
90 | + | ||
91 | + private String school; | ||
92 | + | ||
93 | + private String college; | ||
94 | + | ||
95 | + private String teacher; | ||
96 | + | ||
97 | + private String teacherphone; | ||
98 | + | ||
99 | + | ||
100 | +} | ||
101 | + |
job/src/main/java/com/canrd/shop/module/vo/OrdersVO.java
0 → 100644
1 | +package com.canrd.shop.module.vo; | ||
2 | + | ||
3 | +import lombok.*; | ||
4 | +import lombok.experimental.SuperBuilder; | ||
5 | + | ||
6 | +import java.io.Serializable; | ||
7 | +import java.util.Date; | ||
8 | + | ||
9 | +/** | ||
10 | + * (Orders)实体类 | ||
11 | + * | ||
12 | + * @author makejava | ||
13 | + * @since 2023-06-25 10:43:04 | ||
14 | + */ | ||
15 | +@Data | ||
16 | +@AllArgsConstructor | ||
17 | +@ToString | ||
18 | +@NoArgsConstructor | ||
19 | +@EqualsAndHashCode(callSuper = false) | ||
20 | +@SuperBuilder | ||
21 | +public class OrdersVO implements Serializable { | ||
22 | + private static final long serialVersionUID = -82673229208636654L; | ||
23 | + | ||
24 | + private String id; | ||
25 | + | ||
26 | + private Date createdate; | ||
27 | + | ||
28 | + private Date modifydate; | ||
29 | + | ||
30 | + private Double deliveryfee; | ||
31 | + | ||
32 | + private String deliverytypename; | ||
33 | + | ||
34 | + private String memo; | ||
35 | + | ||
36 | + private String ordersn; | ||
37 | + | ||
38 | + private Integer orderstatus; | ||
39 | + | ||
40 | + private Double paidamount; | ||
41 | + | ||
42 | + private String paymentconfigname; | ||
43 | + | ||
44 | + private Double paymentfee; | ||
45 | + | ||
46 | + private Integer paymentstatus; | ||
47 | + | ||
48 | + private Double producttotalprice; | ||
49 | + | ||
50 | + private Integer producttotalquantity; | ||
51 | + | ||
52 | + private Double productweight; | ||
53 | + | ||
54 | + private Integer productweightunit; | ||
55 | + | ||
56 | + private String shipaddress; | ||
57 | + | ||
58 | + private String shiparea; | ||
59 | + | ||
60 | + private String shipareapath; | ||
61 | + | ||
62 | + private String shipmobile; | ||
63 | + | ||
64 | + private String shipname; | ||
65 | + | ||
66 | + private String shipphone; | ||
67 | + | ||
68 | + private String shipzipcode; | ||
69 | + | ||
70 | + private String invoice; | ||
71 | + | ||
72 | + private String tax; | ||
73 | + | ||
74 | + private String invoiceId; | ||
75 | + | ||
76 | + private String invoiceType; | ||
77 | + | ||
78 | + private Integer shippingstatus; | ||
79 | + | ||
80 | + private Double totalamount; | ||
81 | + | ||
82 | + private String memberId; | ||
83 | + | ||
84 | + private String deliverytypeId; | ||
85 | + | ||
86 | + private String paymentconfigId; | ||
87 | + | ||
88 | + private String school; | ||
89 | + | ||
90 | + private String college; | ||
91 | + | ||
92 | + private String teacher; | ||
93 | + | ||
94 | + private String teacherphone; | ||
95 | + | ||
96 | + | ||
97 | +} |
job/src/main/java/com/canrd/shop/module/vo/ProductQueryVO.java
0 → 100644
1 | +package com.canrd.shop.module.vo; | ||
2 | + | ||
3 | +import lombok.*; | ||
4 | +import lombok.experimental.SuperBuilder; | ||
5 | + | ||
6 | +import java.io.Serializable; | ||
7 | +import java.util.List; | ||
8 | + | ||
9 | +/** | ||
10 | + * (Product)实体类 | ||
11 | + * | ||
12 | + * @author makejava | ||
13 | + * @since 2023-05-29 11:43:33 | ||
14 | + */ | ||
15 | +@Data | ||
16 | +@AllArgsConstructor | ||
17 | +@ToString | ||
18 | +@NoArgsConstructor | ||
19 | +@EqualsAndHashCode(callSuper = false) | ||
20 | +@SuperBuilder | ||
21 | +public class ProductQueryVO extends BasePageVO implements Serializable { | ||
22 | + private static final long serialVersionUID = 108846000631816096L; | ||
23 | + | ||
24 | + private List<Long> ids; | ||
25 | + | ||
26 | + | ||
27 | + private String id; | ||
28 | + | ||
29 | + | ||
30 | +} | ||
31 | + |
job/src/main/java/com/canrd/shop/module/vo/ProductVO.java
0 → 100644
1 | +package com.canrd.shop.module.vo; | ||
2 | + | ||
3 | +import lombok.*; | ||
4 | +import lombok.experimental.SuperBuilder; | ||
5 | + | ||
6 | +import java.io.Serializable; | ||
7 | +import java.util.Date; | ||
8 | + | ||
9 | +/** | ||
10 | + * (Product)实体类 | ||
11 | + * | ||
12 | + * @author makejava | ||
13 | + * @since 2023-05-29 11:43:33 | ||
14 | + */ | ||
15 | +@Data | ||
16 | +@AllArgsConstructor | ||
17 | +@ToString | ||
18 | +@NoArgsConstructor | ||
19 | +@EqualsAndHashCode(callSuper = false) | ||
20 | +@SuperBuilder | ||
21 | +public class ProductVO implements Serializable { | ||
22 | + private static final long serialVersionUID = -82998374747158271L; | ||
23 | + | ||
24 | + private String id; | ||
25 | + | ||
26 | + private Date createdate; | ||
27 | + | ||
28 | + private Date modifydate; | ||
29 | + | ||
30 | + private String description; | ||
31 | + | ||
32 | + private Integer freezestore; | ||
33 | + | ||
34 | + private String htmlfilepath; | ||
35 | + | ||
36 | + private Byte isbest; | ||
37 | + | ||
38 | + private Byte ishot; | ||
39 | + /** | ||
40 | + * 是否上架 | ||
41 | + */ | ||
42 | + private Byte ismarketable; | ||
43 | + | ||
44 | + private Byte isnew; | ||
45 | + | ||
46 | + private Double marketprice; | ||
47 | + | ||
48 | + private String metadescription; | ||
49 | + | ||
50 | + private String metakeywords; | ||
51 | + | ||
52 | + private String name; | ||
53 | + | ||
54 | + private String englishname; | ||
55 | + | ||
56 | + private String model; | ||
57 | + | ||
58 | + private String exterior; | ||
59 | + | ||
60 | + private String basecore1; | ||
61 | + | ||
62 | + private String basename2; | ||
63 | + | ||
64 | + private String basecore2; | ||
65 | + | ||
66 | + private String basename3; | ||
67 | + | ||
68 | + private String basecore3; | ||
69 | + | ||
70 | + private String basename4; | ||
71 | + | ||
72 | + private String basecore4; | ||
73 | + | ||
74 | + private String basename5; | ||
75 | + | ||
76 | + private String basecore5; | ||
77 | + | ||
78 | + private String basename6; | ||
79 | + | ||
80 | + private String basecore6; | ||
81 | + | ||
82 | + private String basename7; | ||
83 | + | ||
84 | + private String basecore7; | ||
85 | + | ||
86 | + private String basename8; | ||
87 | + | ||
88 | + private String basecore8; | ||
89 | + | ||
90 | + private String basename1; | ||
91 | + | ||
92 | + private Integer point; | ||
93 | + | ||
94 | + private Double price; | ||
95 | + | ||
96 | + private String productimageliststore; | ||
97 | + | ||
98 | + private String productsn; | ||
99 | + | ||
100 | + private Integer store; | ||
101 | + | ||
102 | + private Double weight; | ||
103 | + | ||
104 | + private Integer weightunit; | ||
105 | + | ||
106 | + private String brandId; | ||
107 | + | ||
108 | + private String productcategoryId; | ||
109 | + | ||
110 | + private String productcategoryName; | ||
111 | + | ||
112 | + private String producttypeId; | ||
113 | + | ||
114 | + private String producttypeName; | ||
115 | + | ||
116 | + private String introduction; | ||
117 | + | ||
118 | + private String storage; | ||
119 | + | ||
120 | + private String physicalproperty; | ||
121 | + | ||
122 | + private String advantage; | ||
123 | + | ||
124 | + private String wiki; | ||
125 | + | ||
126 | + | ||
127 | +} |
job/src/main/java/com/canrd/shop/service/OrdersService.java
0 → 100644
1 | +package com.canrd.shop.service; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.extension.service.IService; | ||
4 | +import com.canrd.shop.common.constant.ServerResult; | ||
5 | +import com.canrd.shop.module.dto.OrdersDO; | ||
6 | +import com.canrd.shop.module.vo.OrdersQueryVO; | ||
7 | +import com.canrd.shop.module.vo.OrdersVO; | ||
8 | + | ||
9 | +/** | ||
10 | + * (Orders)表服务接口 | ||
11 | + * | ||
12 | + * @author makejava | ||
13 | + * @since 2023-06-25 10:43:08 | ||
14 | + */ | ||
15 | +public interface OrdersService extends IService<OrdersDO> { | ||
16 | + | ||
17 | + /** | ||
18 | + * 通过ID查询单条数据 | ||
19 | + * | ||
20 | + * @param ordersQueryVO 主键 | ||
21 | + * @return 实例对象 | ||
22 | + */ | ||
23 | + ServerResult queryById(OrdersQueryVO ordersQueryVO); | ||
24 | + | ||
25 | + /** | ||
26 | + * 分页查询 | ||
27 | + * | ||
28 | + * @param ordersQueryVO 筛选条件 | ||
29 | + * @return 查询结果 | ||
30 | + */ | ||
31 | + ServerResult list(OrdersQueryVO ordersQueryVO); | ||
32 | + | ||
33 | + /** | ||
34 | + * 新增数据 | ||
35 | + * | ||
36 | + * @param ordersVO 数据VO | ||
37 | + * @return 新增结果 | ||
38 | + */ | ||
39 | + ServerResult add(OrdersVO ordersVO); | ||
40 | + | ||
41 | + /** | ||
42 | + * 修改数据 | ||
43 | + * | ||
44 | + * @param ordersVO 数据VO | ||
45 | + * @return 编辑结果 | ||
46 | + */ | ||
47 | + ServerResult edit(OrdersVO ordersVO); | ||
48 | + | ||
49 | + /** | ||
50 | + * 通过主键删除数据 | ||
51 | + * | ||
52 | + * @param ordersQueryVO 筛选条件 | ||
53 | + * @return 是否成功 | ||
54 | + */ | ||
55 | + ServerResult deleteById(OrdersQueryVO ordersQueryVO); | ||
56 | + | ||
57 | +} |
job/src/main/java/com/canrd/shop/service/ProductService.java
0 → 100644
1 | +package com.canrd.shop.service; | ||
2 | + | ||
3 | +import com.baomidou.mybatisplus.extension.service.IService; | ||
4 | +import com.canrd.shop.common.constant.ServerResult; | ||
5 | +import com.canrd.shop.module.dto.ProductDO; | ||
6 | +import com.canrd.shop.module.vo.ProductQueryVO; | ||
7 | +import com.canrd.shop.module.vo.ProductVO; | ||
8 | + | ||
9 | +/** | ||
10 | + * (Product)表服务接口 | ||
11 | + * | ||
12 | + * @author makejava | ||
13 | + * @since 2023-05-29 11:43:34 | ||
14 | + */ | ||
15 | +public interface ProductService extends IService<ProductDO> { | ||
16 | + | ||
17 | + /** | ||
18 | + * 通过ID查询单条数据 | ||
19 | + * | ||
20 | + * @param productQueryVO 主键 | ||
21 | + * @return 实例对象 | ||
22 | + */ | ||
23 | + ServerResult queryById(ProductQueryVO productQueryVO); | ||
24 | + | ||
25 | + /** | ||
26 | + * 分页查询 | ||
27 | + * | ||
28 | + * @param productQueryVO 筛选条件 | ||
29 | + * @return 查询结果 | ||
30 | + */ | ||
31 | + ServerResult list(ProductQueryVO productQueryVO); | ||
32 | + | ||
33 | + /** | ||
34 | + * 新增数据 | ||
35 | + * | ||
36 | + * @param productVO 数据VO | ||
37 | + * @return 新增结果 | ||
38 | + */ | ||
39 | + ServerResult add(ProductVO productVO); | ||
40 | + | ||
41 | + /** | ||
42 | + * 修改数据 | ||
43 | + * | ||
44 | + * @param productVO 数据VO | ||
45 | + * @return 编辑结果 | ||
46 | + */ | ||
47 | + ServerResult edit(ProductVO productVO); | ||
48 | + | ||
49 | + /** | ||
50 | + * 通过主键删除数据 | ||
51 | + * | ||
52 | + * @param productQueryVO 筛选条件 | ||
53 | + * @return 是否成功 | ||
54 | + */ | ||
55 | + ServerResult deleteById(ProductQueryVO productQueryVO); | ||
56 | + | ||
57 | +} |
job/src/main/java/com/canrd/shop/service/impl/OrdersServiceImpl.java
0 → 100644
1 | +package com.canrd.shop.service.impl; | ||
2 | + | ||
3 | +import cn.hutool.core.bean.BeanUtil; | ||
4 | +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||
5 | +import com.canrd.shop.common.constant.ServerResult; | ||
6 | +import com.canrd.shop.mapper.OrdersMapper; | ||
7 | +import com.canrd.shop.module.dto.OrdersDO; | ||
8 | +import com.canrd.shop.module.vo.OrdersQueryVO; | ||
9 | +import com.canrd.shop.module.vo.OrdersVO; | ||
10 | +import com.canrd.shop.service.OrdersService; | ||
11 | +import lombok.extern.slf4j.Slf4j; | ||
12 | +import org.springframework.stereotype.Service; | ||
13 | + | ||
14 | +import java.util.Objects; | ||
15 | + | ||
16 | +/** | ||
17 | + * (Orders)表服务实现类 | ||
18 | + * | ||
19 | + * @author makejava | ||
20 | + * @since 2023-06-25 10:43:09 | ||
21 | + */ | ||
22 | +@Slf4j | ||
23 | +@Service | ||
24 | +public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> implements OrdersService { | ||
25 | + | ||
26 | + | ||
27 | + /** | ||
28 | + * 通过ID查询单条数据 | ||
29 | + * <p> | ||
30 | + * ordersQueryVO 主键 | ||
31 | + * | ||
32 | + * @return 实例对象 | ||
33 | + */ | ||
34 | + @Override | ||
35 | + public ServerResult queryById(OrdersQueryVO ordersQueryVO) { | ||
36 | + if (Objects.isNull(ordersQueryVO.getId())) { | ||
37 | + return ServerResult.fail("id 不能为空"); | ||
38 | + } | ||
39 | + OrdersDO OrdersDo = getById(ordersQueryVO.getId()); | ||
40 | + if (Objects.isNull(OrdersDo)) { | ||
41 | + return ServerResult.success(null); | ||
42 | + } | ||
43 | + return ServerResult.success(BeanUtil.copyProperties(OrdersDo, OrdersVO.class)); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * 分页查询 | ||
48 | + * | ||
49 | + * @param ordersQueryVO 筛选条件 | ||
50 | + * @return 查询结果 | ||
51 | + */ | ||
52 | + @Override | ||
53 | + public ServerResult list(OrdersQueryVO ordersQueryVO) { | ||
54 | + | ||
55 | + return ServerResult.success(); | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * 新增数据 | ||
60 | + * | ||
61 | + * @param ordersVO 实例对象 | ||
62 | + * @return 实例对象 | ||
63 | + */ | ||
64 | + @Override | ||
65 | + public ServerResult add(OrdersVO ordersVO) { | ||
66 | + //todo 校验 | ||
67 | + if (Objects.nonNull(ordersVO.getId())) { | ||
68 | + ordersVO.setId(null); | ||
69 | + } | ||
70 | + OrdersDO ordersDo = BeanUtil.copyProperties(ordersVO, OrdersDO.class); | ||
71 | + | ||
72 | + save(ordersDo); | ||
73 | + | ||
74 | + return ServerResult.success(); | ||
75 | + } | ||
76 | + | ||
77 | + /** | ||
78 | + * 修改数据 | ||
79 | + * | ||
80 | + * @param ordersVO 实例对象 | ||
81 | + * @return 实例对象 | ||
82 | + */ | ||
83 | + @Override | ||
84 | + public ServerResult edit(OrdersVO ordersVO) { | ||
85 | + //todo 校验 | ||
86 | + if (Objects.isNull(ordersVO.getId())) { | ||
87 | + return ServerResult.fail("id 不能为空"); | ||
88 | + } | ||
89 | + OrdersDO ordersDo = BeanUtil.copyProperties(ordersVO, OrdersDO.class); | ||
90 | + | ||
91 | + updateById(ordersDo); | ||
92 | + | ||
93 | + return ServerResult.success(); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * 通过主键删除数据 | ||
98 | + * | ||
99 | + * @param ordersQueryVO 筛选条件 | ||
100 | + * @return 是否成功 | ||
101 | + */ | ||
102 | + @Override | ||
103 | + public ServerResult deleteById(OrdersQueryVO ordersQueryVO) { | ||
104 | + return ServerResult.success(); | ||
105 | + } | ||
106 | +} |
job/src/main/java/com/canrd/shop/service/impl/ProductServiceImpl.java
0 → 100644
1 | +package com.canrd.shop.service.impl; | ||
2 | + | ||
3 | +import cn.hutool.core.bean.BeanUtil; | ||
4 | +import cn.hutool.core.collection.CollUtil; | ||
5 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
6 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
7 | +import com.baomidou.mybatisplus.core.metadata.IPage; | ||
8 | +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||
9 | +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||
10 | +import com.canrd.shop.common.constant.ServerResult; | ||
11 | +import com.canrd.shop.common.utils.PageUtils; | ||
12 | +import com.canrd.shop.mapper.ProductMapper; | ||
13 | +import com.canrd.shop.module.dto.ProductDO; | ||
14 | +import com.canrd.shop.module.vo.ProductQueryVO; | ||
15 | +import com.canrd.shop.module.vo.ProductVO; | ||
16 | +import com.canrd.shop.service.ProductService; | ||
17 | +import lombok.extern.slf4j.Slf4j; | ||
18 | +import org.springframework.stereotype.Service; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | +import java.util.Objects; | ||
22 | + | ||
23 | +/** | ||
24 | + * (Product)表服务实现类 | ||
25 | + * | ||
26 | + * @author makejava | ||
27 | + * @since 2023-05-29 11:43:35 | ||
28 | + */ | ||
29 | +@Slf4j | ||
30 | +@Service | ||
31 | +public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> implements ProductService { | ||
32 | + | ||
33 | + | ||
34 | + /** | ||
35 | + * 通过ID查询单条数据 | ||
36 | + * <p> | ||
37 | + * productQueryVO 主键 | ||
38 | + * | ||
39 | + * @return 实例对象 | ||
40 | + */ | ||
41 | + @Override | ||
42 | + public ServerResult queryById(ProductQueryVO productQueryVO) { | ||
43 | + if (Objects.isNull(productQueryVO.getId())) { | ||
44 | + return ServerResult.fail("id 不能为空"); | ||
45 | + } | ||
46 | + ProductDO ProductDo = getById(productQueryVO.getId()); | ||
47 | + if (Objects.isNull(ProductDo)) { | ||
48 | + return ServerResult.success(null); | ||
49 | + } | ||
50 | + return ServerResult.success(BeanUtil.copyProperties(ProductDo, ProductVO.class)); | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * 分页查询 | ||
55 | + * | ||
56 | + * @param productQueryVO 筛选条件 | ||
57 | + * @return 查询结果 | ||
58 | + */ | ||
59 | + @Override | ||
60 | + public ServerResult list(ProductQueryVO productQueryVO) { | ||
61 | + | ||
62 | + LambdaQueryWrapper<ProductDO> queryWapper = new LambdaQueryWrapper<ProductDO>() | ||
63 | + .orderByDesc(ProductDO::getId); | ||
64 | + Page page = new Page<>(productQueryVO.getPageNo(), productQueryVO.getPageSize()); | ||
65 | + IPage<ProductDO> iPage = page(page, queryWapper); | ||
66 | + productQueryVO.setTotal(Long.valueOf(iPage.getTotal()).intValue()); | ||
67 | + | ||
68 | + return ServerResult.success(PageUtils.getPageReturn(iPage.getRecords(), productQueryVO)); | ||
69 | + } | ||
70 | + | ||
71 | + /** | ||
72 | + * 新增数据 | ||
73 | + * | ||
74 | + * @param productVO 实例对象 | ||
75 | + * @return 实例对象 | ||
76 | + */ | ||
77 | + @Override | ||
78 | + public ServerResult add(ProductVO productVO) { | ||
79 | + //todo 校验 | ||
80 | + if (Objects.nonNull(productVO.getId())) { | ||
81 | + productVO.setId(null); | ||
82 | + } | ||
83 | + ProductDO productDo = BeanUtil.copyProperties(productVO, ProductDO.class); | ||
84 | + | ||
85 | + save(productDo); | ||
86 | + | ||
87 | + return ServerResult.success(); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * 修改数据 | ||
92 | + * | ||
93 | + * @param productVO 实例对象 | ||
94 | + * @return 实例对象 | ||
95 | + */ | ||
96 | + @Override | ||
97 | + public ServerResult edit(ProductVO productVO) { | ||
98 | + //todo 校验 | ||
99 | + if (Objects.isNull(productVO.getId())) { | ||
100 | + return ServerResult.fail("id 不能为空"); | ||
101 | + } | ||
102 | + ProductDO productDo = BeanUtil.copyProperties(productVO, ProductDO.class); | ||
103 | + | ||
104 | + updateById(productDo); | ||
105 | + | ||
106 | + return ServerResult.success(); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * 通过主键删除数据 | ||
111 | + * | ||
112 | + * @param productQueryVO 筛选条件 | ||
113 | + * @return 是否成功 | ||
114 | + */ | ||
115 | + @Override | ||
116 | + public ServerResult deleteById(ProductQueryVO productQueryVO) { | ||
117 | + List<Long> ids = productQueryVO.getIds(); | ||
118 | + if (CollUtil.isEmpty(ids)) { | ||
119 | + return ServerResult.fail("ids 参数不能为空"); | ||
120 | + } | ||
121 | + List<ProductDO> productList = listByIds(ids); | ||
122 | + if (CollUtil.isEmpty(productList)) { | ||
123 | + return ServerResult.success(); | ||
124 | + } | ||
125 | + //todo 校验是否可以逻辑删除 | ||
126 | + LambdaUpdateWrapper<ProductDO> updateWrapper = new LambdaUpdateWrapper<ProductDO>() | ||
127 | + .in(ProductDO::getId, ids); | ||
128 | + update(updateWrapper); | ||
129 | + return ServerResult.success(); | ||
130 | + } | ||
131 | +} |
job/src/main/resources/application-local.yml
0 → 100644
1 | +mybatis-plus: | ||
2 | + configuration: | ||
3 | + cache-enabled: false | ||
4 | + call-setters-on-nulls: true | ||
5 | + jdbc-type-for-null: 'null' | ||
6 | + map-underscore-to-camel-case: true | ||
7 | + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | ||
8 | + global-config: | ||
9 | + db-config: | ||
10 | + capital-mode: false | ||
11 | + field-strategy: NOT_NULL | ||
12 | + id-type: AUTO | ||
13 | + logic-delete-field: enable_flag | ||
14 | + logic-delete-value: 20 | ||
15 | + logic-not-delete-value: 10 | ||
16 | + mapper-locations: classpath:/mapper/**.xml | ||
17 | + type-aliases-package: com.canrd.shop.**.dto | ||
18 | +#spring: | ||
19 | +# datasource: | ||
20 | +# dynamic: | ||
21 | +# primary: overtime #设置默认的数据源或者数据源组,默认值即为master | ||
22 | +# strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源. | ||
23 | +# datasource: | ||
24 | +# wms_warehouse: | ||
25 | +# url: jdbc:mysql://127.0.0.1:3306/overtime?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true&rewriteBatchedStatements=true | ||
26 | +# username: root | ||
27 | +# password: root | ||
28 | +# driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 | ||
29 | +# druid: | ||
30 | +# initial-size: 5 | ||
31 | +# max-active: 20 | ||
32 | +# max-evictable-idle-time-millis: 300000 | ||
33 | +# max-wait: 60000 | ||
34 | +# min-evictable-idle-time-millis: 300000 | ||
35 | +# min-idle: 5 | ||
36 | +# time-between-eviction-runs-millis: 60000 | ||
37 | +# type: com.alibaba.druid.pool.DruidDataSource | ||
38 | +spring: | ||
39 | + servlet: | ||
40 | + multipart: | ||
41 | + enabled: true | ||
42 | + max-file-size: 100MB | ||
43 | + max-request-size: 20MB | ||
44 | + file-size-threshold: 20MB | ||
45 | + datasource: | ||
46 | + db-type: com.alibaba.druid.pool.DruidDataSource | ||
47 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
48 | + initial-size: 5 | ||
49 | + max-active: 30 | ||
50 | + max-wait: 30000 | ||
51 | + min-idle: 5 | ||
52 | + #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | ||
53 | + timeBetweenEvictionRunsMillis: 30000 | ||
54 | + #配置一个连接在池中最小生存的时间,单位是毫秒,30000=30s | ||
55 | + minEvictableIdleTimeMillis: 30000 | ||
56 | + validationQuery: SELECT 'x' | ||
57 | + testWhileIdle: true | ||
58 | + testOnBorrow: true | ||
59 | + testOnReturn: true | ||
60 | + password: 123456 | ||
61 | + time-between-eviction-runs-millis: 1000 | ||
62 | + url: jdbc:mysql://39.108.227.113:3306/jfinalshop?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true | ||
63 | + username: root | ||
64 | + | ||
65 | + | ||
66 | +logging: | ||
67 | + config: classpath:log4j2-dev.xml | ||
0 | \ No newline at end of file | 68 | \ No newline at end of file |
job/src/main/resources/application-prod.yml
0 → 100644
1 | +mybatis-plus: | ||
2 | + configuration: | ||
3 | + cache-enabled: false | ||
4 | + call-setters-on-nulls: true | ||
5 | + jdbc-type-for-null: 'null' | ||
6 | + map-underscore-to-camel-case: true | ||
7 | + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl | ||
8 | + global-config: | ||
9 | + db-config: | ||
10 | + capital-mode: false | ||
11 | + field-strategy: NOT_NULL | ||
12 | + id-type: AUTO | ||
13 | + logic-delete-field: enable_flag | ||
14 | + logic-delete-value: 20 | ||
15 | + logic-not-delete-value: 10 | ||
16 | + mapper-locations: classpath:/mapper/**.xml | ||
17 | + type-aliases-package: com.canrd.shop.**.dto | ||
18 | +#spring: | ||
19 | +# datasource: | ||
20 | +# dynamic: | ||
21 | +# primary: overtime #设置默认的数据源或者数据源组,默认值即为master | ||
22 | +# strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源. | ||
23 | +# datasource: | ||
24 | +# wms_warehouse: | ||
25 | +# url: jdbc:mysql://127.0.0.1:3306/overtime?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true&rewriteBatchedStatements=true | ||
26 | +# username: root | ||
27 | +# password: root | ||
28 | +# driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 | ||
29 | +# druid: | ||
30 | +# initial-size: 5 | ||
31 | +# max-active: 20 | ||
32 | +# max-evictable-idle-time-millis: 300000 | ||
33 | +# max-wait: 60000 | ||
34 | +# min-evictable-idle-time-millis: 300000 | ||
35 | +# min-idle: 5 | ||
36 | +# time-between-eviction-runs-millis: 60000 | ||
37 | +# type: com.alibaba.druid.pool.DruidDataSource | ||
38 | +spring: | ||
39 | + servlet: | ||
40 | + multipart: | ||
41 | + enabled: true | ||
42 | + max-file-size: 100MB | ||
43 | + max-request-size: 20MB | ||
44 | + file-size-threshold: 20MB | ||
45 | + datasource: | ||
46 | + db-type: com.alibaba.druid.pool.DruidDataSource | ||
47 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
48 | + initial-size: 5 | ||
49 | + max-active: 30 | ||
50 | + max-wait: 30000 | ||
51 | + min-idle: 5 | ||
52 | + #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | ||
53 | + timeBetweenEvictionRunsMillis: 30000 | ||
54 | + #配置一个连接在池中最小生存的时间,单位是毫秒,30000=30s | ||
55 | + minEvictableIdleTimeMillis: 30000 | ||
56 | + validationQuery: SELECT 'x' | ||
57 | + testWhileIdle: true | ||
58 | + testOnBorrow: true | ||
59 | + testOnReturn: true | ||
60 | + password: 123456 | ||
61 | + time-between-eviction-runs-millis: 1000 | ||
62 | + url: jdbc:mysql://39.108.227.113:3306/jfinalshop?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true | ||
63 | + username: root | ||
64 | + | ||
65 | + | ||
66 | +logging: | ||
67 | + config: classpath:log4j2-prod.xml |
job/src/main/resources/application-test.yml
0 → 100644
1 | +mybatis-plus: | ||
2 | + configuration: | ||
3 | + cache-enabled: false | ||
4 | + call-setters-on-nulls: true | ||
5 | + jdbc-type-for-null: 'null' | ||
6 | + map-underscore-to-camel-case: true | ||
7 | + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl | ||
8 | + global-config: | ||
9 | + db-config: | ||
10 | + capital-mode: false | ||
11 | + field-strategy: NOT_NULL | ||
12 | + id-type: AUTO | ||
13 | + logic-delete-field: enable_flag | ||
14 | + logic-delete-value: 20 | ||
15 | + logic-not-delete-value: 10 | ||
16 | + mapper-locations: classpath:/mapper/**.xml | ||
17 | + type-aliases-package: com.canrd.shop.**.dto | ||
18 | +#spring: | ||
19 | +# datasource: | ||
20 | +# dynamic: | ||
21 | +# primary: overtime #设置默认的数据源或者数据源组,默认值即为master | ||
22 | +# strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源. | ||
23 | +# datasource: | ||
24 | +# wms_warehouse: | ||
25 | +# url: jdbc:mysql://127.0.0.1:3306/overtime?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true&rewriteBatchedStatements=true | ||
26 | +# username: root | ||
27 | +# password: root | ||
28 | +# driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 | ||
29 | +# druid: | ||
30 | +# initial-size: 5 | ||
31 | +# max-active: 20 | ||
32 | +# max-evictable-idle-time-millis: 300000 | ||
33 | +# max-wait: 60000 | ||
34 | +# min-evictable-idle-time-millis: 300000 | ||
35 | +# min-idle: 5 | ||
36 | +# time-between-eviction-runs-millis: 60000 | ||
37 | +# type: com.alibaba.druid.pool.DruidDataSource | ||
38 | +spring: | ||
39 | + servlet: | ||
40 | + multipart: | ||
41 | + enabled: true | ||
42 | + max-file-size: 100MB | ||
43 | + max-request-size: 20MB | ||
44 | + file-size-threshold: 20MB | ||
45 | + datasource: | ||
46 | + db-type: com.alibaba.druid.pool.DruidDataSource | ||
47 | + driverClassName: com.mysql.cj.jdbc.Driver | ||
48 | + initial-size: 5 | ||
49 | + max-active: 30 | ||
50 | + max-wait: 30000 | ||
51 | + min-idle: 5 | ||
52 | + #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | ||
53 | + timeBetweenEvictionRunsMillis: 30000 | ||
54 | + #配置一个连接在池中最小生存的时间,单位是毫秒,30000=30s | ||
55 | + minEvictableIdleTimeMillis: 30000 | ||
56 | + validationQuery: SELECT 'x' | ||
57 | + testWhileIdle: true | ||
58 | + testOnBorrow: true | ||
59 | + testOnReturn: true | ||
60 | + password: 123456 | ||
61 | + time-between-eviction-runs-millis: 1000 | ||
62 | + url: jdbc:mysql://39.108.227.113:3306/jfinalshop?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true | ||
63 | + username: root | ||
64 | + | ||
65 | + | ||
66 | +logging: | ||
67 | + config: classpath:log4j2-dev.xml | ||
0 | \ No newline at end of file | 68 | \ No newline at end of file |
job/src/main/resources/application.yml
0 → 100644
job/src/main/resources/log4j2-dev.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> | ||
3 | +<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出 --> | ||
4 | +<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数 --> | ||
5 | +<configuration status="debug" monitorInterval="30"> | ||
6 | + <!--<contextName>log4j2</contextName>--> | ||
7 | + <properties> | ||
8 | + <!--${sys:catalina.home}表示linux中环境变量中的tomcat根目录 用户主目录--> | ||
9 | + <!--原来用logback时候在统一配置中心也配置一个logging.path=/opt/tomcat-log/${spring.application.name} LOG_PATH是内置变量--> | ||
10 | + <!--${sys:user.home} 用户主目录--> | ||
11 | + <!-- <Property name="log_path">${sys:user.home}/logs</Property>--> | ||
12 | +<!-- <Property name="log_path" value="./logs/" />--> | ||
13 | + <property name="console_log_pattern">%d|%t|%traceId|%-5level|%F:%L|%M|%m%n</property> | ||
14 | + <!-- 保留日志天数 D H M S 分别对应天 小时 分钟 秒 --> | ||
15 | + <property name="KEEP_LOG_DAY">60D</property> | ||
16 | + <!-- 日志切割的最小单位 --> | ||
17 | + <property name="EVERY_FILE_SIZE">100M</property> | ||
18 | + </properties> | ||
19 | + <!--先定义所有的appender --> | ||
20 | + <appenders> | ||
21 | + <console name="Console" target="SYSTEM_OUT"> | ||
22 | + <!--输出日志的格式 --> | ||
23 | + <PatternLayout charset="UTF-8" pattern="${console_log_pattern}"/> | ||
24 | + <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> | ||
25 | + </console> | ||
26 | + <!--这个输出控制台的配置 --> | ||
27 | + <!--<console name="Console" target="SYSTEM_OUT" follow="false">--> | ||
28 | + <!--<!–输出日志的格式 –>--> | ||
29 | + <!--<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />--> | ||
30 | + <!--</console>--> | ||
31 | + | ||
32 | + <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 --> | ||
33 | + <RollingFile name="RollingFileInfo" fileName="${sys:logging.path}/logs/overtime.log" filePattern="${sys:logging.path}/logs/$${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log"> | ||
34 | + <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --> | ||
35 | + <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" /> | ||
36 | + <!--<Filters>--> | ||
37 | + <!--<ThresholdFilter level="INFO"/>--> | ||
38 | + <!--<ThresholdFilter level="WARN" onMatch="DENY"--> | ||
39 | + <!--onMismatch="NEUTRAL"/>--> | ||
40 | + <!--</Filters>--> | ||
41 | + <PatternLayout charset="UTF-8" pattern="${console_log_pattern}"/> | ||
42 | + <Policies> | ||
43 | + <!-- 归档每天的文件 --> | ||
44 | + <!--<TimeBasedTriggeringPolicy interval="1" modulate="true"/>--> | ||
45 | + <TimeBasedTriggeringPolicy /> | ||
46 | + <!-- 限制单个文件大小 --> | ||
47 | + <SizeBasedTriggeringPolicy size="${EVERY_FILE_SIZE}"/> | ||
48 | + </Policies> | ||
49 | + <!-- 限制每天文件个数 --> <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了100 --> | ||
50 | + <DefaultRolloverStrategy max="256"> | ||
51 | + <Delete basePath="${sys:logging.path}/logs/" maxDepth="3"> | ||
52 | + <IfFileName glob="*/*info*.log"/> | ||
53 | + <IfLastModified age="${KEEP_LOG_DAY}"/> | ||
54 | + </Delete> | ||
55 | + </DefaultRolloverStrategy> | ||
56 | + </RollingFile> | ||
57 | + </appenders> | ||
58 | + <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 --> | ||
59 | + <loggers> | ||
60 | + <!--过滤掉spring和mybatis的一些无用的DEBUG信息 --> | ||
61 | + <logger name="org.springframework" level="debug" > | ||
62 | + <ThresholdFilter level="debug"/> | ||
63 | + <appender-ref ref="RollingFileInfo" /> | ||
64 | + </logger> | ||
65 | + <logger name="org.mybatis" level="DEBUG" > | ||
66 | + <ThresholdFilter level="debug"/> | ||
67 | + <appender-ref ref="RollingFileInfo" /> | ||
68 | + </logger> | ||
69 | + <logger name="com.canrd.shop" level="DEBUG" > | ||
70 | + <ThresholdFilter level="debug"/> | ||
71 | + <appender-ref ref="RollingFileInfo" /> | ||
72 | + </logger> | ||
73 | + <!--<root level="all">--> | ||
74 | + <root level="debug"> | ||
75 | + <appender-ref ref="Console" /> | ||
76 | + </root> | ||
77 | + </loggers> | ||
78 | +</configuration> |
job/src/main/resources/log4j2-prod.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> | ||
3 | +<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出 --> | ||
4 | +<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数 --> | ||
5 | +<configuration status="INFO" monitorInterval="30"> | ||
6 | + <!--<contextName>log4j2</contextName>--> | ||
7 | + <properties> | ||
8 | + <!--${sys:catalina.home}表示linux中环境变量中的tomcat根目录 用户主目录--> | ||
9 | + <!--原来用logback时候在统一配置中心也配置一个logging.path=/opt/tomcat-log/${spring.application.name} LOG_PATH是内置变量--> | ||
10 | + <!--${sys:user.home} 用户主目录--> | ||
11 | + <!-- <Property name="log_path">${sys:user.home}/logs</Property>--> | ||
12 | +<!-- <Property name="log_path" value="./logs/" />--> | ||
13 | + <property name="console_log_pattern">%d|%t|%traceId|%-5level|%F:%L|%M|%m%n</property> | ||
14 | + <!-- 保留日志天数 D H M S 分别对应天 小时 分钟 秒 --> | ||
15 | + <property name="KEEP_LOG_DAY">60D</property> | ||
16 | + <!-- 日志切割的最小单位 --> | ||
17 | + <property name="EVERY_FILE_SIZE">100M</property> | ||
18 | + </properties> | ||
19 | + <!--先定义所有的appender --> | ||
20 | + <appenders> | ||
21 | + <console name="Console" target="SYSTEM_OUT"> | ||
22 | + <!--输出日志的格式 --> | ||
23 | + <PatternLayout charset="UTF-8" pattern="${console_log_pattern}"/> | ||
24 | + <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> | ||
25 | + </console> | ||
26 | + <!--这个输出控制台的配置 --> | ||
27 | + <!--<console name="Console" target="SYSTEM_OUT" follow="false">--> | ||
28 | + <!--<!–输出日志的格式 –>--> | ||
29 | + <!--<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />--> | ||
30 | + <!--</console>--> | ||
31 | + | ||
32 | + <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 --> | ||
33 | + <RollingFile name="RollingFileInfo" fileName="${sys:logging.path}/logs/overtime.log" filePattern="${sys:logging.path}/logs/$${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log"> | ||
34 | + <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --> | ||
35 | + <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> | ||
36 | + <!--<Filters>--> | ||
37 | + <!--<ThresholdFilter level="INFO"/>--> | ||
38 | + <!--<ThresholdFilter level="WARN" onMatch="DENY"--> | ||
39 | + <!--onMismatch="NEUTRAL"/>--> | ||
40 | + <!--</Filters>--> | ||
41 | + <PatternLayout charset="UTF-8" pattern="${console_log_pattern}"/> | ||
42 | + <Policies> | ||
43 | + <!-- 归档每天的文件 --> | ||
44 | + <!--<TimeBasedTriggeringPolicy interval="1" modulate="true"/>--> | ||
45 | + <TimeBasedTriggeringPolicy /> | ||
46 | + <!-- 限制单个文件大小 --> | ||
47 | + <SizeBasedTriggeringPolicy size="${EVERY_FILE_SIZE}"/> | ||
48 | + </Policies> | ||
49 | + <!-- 限制每天文件个数 --> <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了100 --> | ||
50 | + <DefaultRolloverStrategy max="256"> | ||
51 | + <Delete basePath="${sys:logging.path}/logs/" maxDepth="3"> | ||
52 | + <IfFileName glob="*/*info*.log"/> | ||
53 | + <IfLastModified age="${KEEP_LOG_DAY}"/> | ||
54 | + </Delete> | ||
55 | + </DefaultRolloverStrategy> | ||
56 | + </RollingFile> | ||
57 | + </appenders> | ||
58 | + <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 --> | ||
59 | + <loggers> | ||
60 | + <logger name="org.springframework" level="info" > | ||
61 | + <ThresholdFilter level="info"/> | ||
62 | + <appender-ref ref="RollingFileInfo" /> | ||
63 | + </logger> | ||
64 | + <logger name="org.mybatis" level="info" > | ||
65 | + <ThresholdFilter level="info"/> | ||
66 | + <appender-ref ref="RollingFileInfo" /> | ||
67 | + </logger> | ||
68 | + <logger name="com.canrd.shop" level="info" > | ||
69 | + <ThresholdFilter level="info"/> | ||
70 | + <appender-ref ref="RollingFileInfo" /> | ||
71 | + </logger> | ||
72 | + </loggers> | ||
73 | +</configuration> |
job/src/test/java/com/canrd/shop/BaseTest.java
0 → 100644
1 | +package com.canrd.shop; | ||
2 | + | ||
3 | +import org.junit.runner.RunWith; | ||
4 | +import org.springframework.boot.test.context.SpringBootTest; | ||
5 | +import org.springframework.test.context.junit4.SpringRunner; | ||
6 | +import org.springframework.transaction.annotation.Transactional; | ||
7 | + | ||
8 | +/** | ||
9 | + * @author fanzhenyu | ||
10 | + * @date 2023-01-15 | ||
11 | + */ | ||
12 | +@RunWith(SpringRunner.class) | ||
13 | +@SpringBootTest(classes = JobApplication.class) | ||
14 | +//主动回滚测试产生的数据 | ||
15 | +@Transactional | ||
16 | +public class BaseTest { | ||
17 | + | ||
18 | + | ||
19 | +} |
job/src/test/java/com/canrd/shop/test/DateTimeUtilTest.java
0 → 100644
1 | +package com.canrd.shop.test; | ||
2 | + | ||
3 | +import org.joda.time.format.DateTimeFormat; | ||
4 | +import org.joda.time.format.DateTimeFormatter; | ||
5 | +import org.junit.Test; | ||
6 | + | ||
7 | +/** | ||
8 | + * @author: xms | ||
9 | + * @description: TODO | ||
10 | + * @date: 2023/2/10 14:09 | ||
11 | + * @version: 1.0 | ||
12 | + */ | ||
13 | +public class DateTimeUtilTest { | ||
14 | + | ||
15 | + @Test | ||
16 | + public void test() { | ||
17 | + DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"); | ||
18 | + System.out.println(fmt.parseDateTime("2023-02-10 12:00").isBefore(fmt.parseDateTime("2023-02-10 13:30"))); | ||
19 | + System.out.println(fmt.parseDateTime("2023-02-10 12:00").isBeforeNow()); | ||
20 | + } | ||
21 | +} |