upd: 编码规范
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
<h1 style="text-align: center">ELADMIN 后台管理系统</h1>
|
<h1 style="text-align: center">CuteJava 后台管理系统</h1>
|
||||||
|
|
||||||
#### 项目简介
|
#### 项目简介
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.annotation.rest;
|
package cn.odboy.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.annotation.rest;
|
package cn.odboy.annotation;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.annotation.rest;
|
package cn.odboy.annotation;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.annotation.rest;
|
package cn.odboy.annotation;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.annotation.rest;
|
package cn.odboy.annotation;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.annotation.rest;
|
package cn.odboy.annotation;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AliasFor;
|
import org.springframework.core.annotation.AliasFor;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
+5
-1
@@ -18,7 +18,7 @@ import java.sql.Timestamp;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class BaseEntity extends MyObject {
|
public class MyEntity extends MyObject {
|
||||||
|
|
||||||
@CreatedBy
|
@CreatedBy
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
@@ -33,11 +33,15 @@ public class BaseEntity extends MyObject {
|
|||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
||||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
// @JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Timestamp createTime;
|
private Timestamp createTime;
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
@ApiModelProperty(value = "更新时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
@ApiModelProperty(value = "更新时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
||||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
// @JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Timestamp updateTime;
|
private Timestamp updateTime;
|
||||||
|
|
||||||
/* 分组校验 */
|
/* 分组校验 */
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package cn.odboy.base;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.springframework.data.annotation.CreatedBy;
|
||||||
|
import org.springframework.data.annotation.LastModifiedBy;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逻辑删除通用模型
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-12
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class MyLogicEntity extends MyObject {
|
||||||
|
@CreatedBy
|
||||||
|
@TableField(value = "create_by", fill = FieldFill.INSERT)
|
||||||
|
@ApiModelProperty(value = "创建人", hidden = true)
|
||||||
|
private String createBy;
|
||||||
|
@LastModifiedBy
|
||||||
|
@TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
|
||||||
|
@ApiModelProperty(value = "更新人", hidden = true)
|
||||||
|
private String updateBy;
|
||||||
|
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||||
|
@ApiModelProperty(value = "创建时间", hidden = true)
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Timestamp createTime;
|
||||||
|
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
|
||||||
|
@ApiModelProperty(value = "更新时间", hidden = true)
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Timestamp updateTime;
|
||||||
|
@ApiModelProperty(value = "数据有效性", hidden = true)
|
||||||
|
@TableLogic
|
||||||
|
@TableField("available")
|
||||||
|
private Integer available;
|
||||||
|
|
||||||
|
/* 分组校验 */
|
||||||
|
public @interface Create {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分组校验 */
|
||||||
|
public @interface Update {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
ToStringBuilder builder = new ToStringBuilder(this);
|
||||||
|
Field[] fields = this.getClass().getDeclaredFields();
|
||||||
|
try {
|
||||||
|
for (Field f : fields) {
|
||||||
|
f.setAccessible(true);
|
||||||
|
builder.append(f.getName(), f.get(this)).append("\n");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
builder.append("toString builder encounter an error");
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.base;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 元数据选项
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-13
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MyMetaOption extends MyObject {
|
||||||
|
private String label;
|
||||||
|
private String value;
|
||||||
|
private Map<String, Object> ext;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package cn.odboy.base;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据分页参数
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-20
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PageArgs<T> implements Serializable {
|
||||||
|
@NotNull(message = "参数page不能为空")
|
||||||
|
@Min(value = 1, message = "参数page最小值为1")
|
||||||
|
@ApiModelProperty(value = "页码", example = "1")
|
||||||
|
private Integer page;
|
||||||
|
@NotNull(message = "参数size不能为空")
|
||||||
|
@Min(value = 1, message = "参数size最小值为1")
|
||||||
|
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||||
|
private Integer size;
|
||||||
|
private T args;
|
||||||
|
}
|
||||||
+1
-4
@@ -1,6 +1,5 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.base;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -16,8 +15,6 @@ import java.util.List;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class PageResult<T> extends MyObject {
|
public class PageResult<T> extends MyObject {
|
||||||
|
|
||||||
private List<T> content;
|
private List<T> content;
|
||||||
|
|
||||||
private long totalElements;
|
private long totalElements;
|
||||||
}
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package cn.odboy.config.webConfig;
|
|
||||||
|
|
||||||
import org.apache.catalina.connector.Connector;
|
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 允许在查询字符串中使用特定的特殊字符
|
|
||||||
*/
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
public class QueryCustomizer implements TomcatConnectorCustomizer {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void customize(Connector connector) {
|
|
||||||
connector.setProperty("relaxedQueryChars", "[]{}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config;
|
package cn.odboy.context;
|
||||||
|
|
||||||
import cn.odboy.util.SecurityUtil;
|
import cn.odboy.util.SecurityUtil;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.context;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean加载完毕 监听
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-16
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class BeanLoadFinishListener implements ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||||
|
log.info("所有的Bean都加载完毕了");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.context;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主要目的是输出应用的服务地址
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2024-04-20
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class BootApplication {
|
||||||
|
@Bean
|
||||||
|
public SpringBeanHolder springContextHolder() {
|
||||||
|
return new SpringBeanHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void inited(ConfigurableApplicationContext application) throws UnknownHostException {
|
||||||
|
Environment env = application.getEnvironment();
|
||||||
|
String ip = InetAddress.getLocalHost().getHostAddress();
|
||||||
|
String port = env.getProperty("server.port");
|
||||||
|
String path = StrUtil.isEmpty(env.getProperty("config.servlet.context-path")) ? "" : env.getProperty("config.servlet.context-path");
|
||||||
|
log.info(
|
||||||
|
"\n----------------------------------------------------------\n\t"
|
||||||
|
+ "Application is running! Access URLs:\n\t"
|
||||||
|
+ "Local: \t\thttp://localhost:" + port + path + "/\n\t"
|
||||||
|
+ "External: \thttp://" + ip + ":" + port + path + "/\n\t"
|
||||||
|
+ "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n"
|
||||||
|
+ "----------------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.context;
|
||||||
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.context;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
+1
-1
@@ -3,7 +3,7 @@ package cn.odboy.exception.handler;
|
|||||||
import cn.odboy.exception.BadRequestException;
|
import cn.odboy.exception.BadRequestException;
|
||||||
import cn.odboy.exception.EntityExistException;
|
import cn.odboy.exception.EntityExistException;
|
||||||
import cn.odboy.exception.EntityNotFoundException;
|
import cn.odboy.exception.EntityNotFoundException;
|
||||||
import cn.odboy.util.ThrowableUtil;
|
import cn.odboy.exception.util.ThrowableUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.exception.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 适配 logger 占位符
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-13
|
||||||
|
*/
|
||||||
|
public class LogFmtUtil {
|
||||||
|
/**
|
||||||
|
* 替换字符串中的占位符 {} 为传入的参数
|
||||||
|
*
|
||||||
|
* @param message 消息模板
|
||||||
|
* @param args 替换占位符的参数
|
||||||
|
* @return 替换后的消息
|
||||||
|
*/
|
||||||
|
public static String format(String message, Object... args) {
|
||||||
|
if (message == null || args == null || args.length == 0) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
// 使用 String.format 替换占位符
|
||||||
|
return String.format(message.replace("{}", "%s"), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 示例用法
|
||||||
|
String messageTemplate = "获取dingtalk accessToken失败, code={}, message={}";
|
||||||
|
String formattedMessage = format(messageTemplate, 400, "Bad Request");
|
||||||
|
// 输出: 获取dingtalk accessToken失败, code=400, message=Bad Request
|
||||||
|
System.out.println(formattedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.exception.util;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.monitor;
|
||||||
|
|
||||||
|
import cn.odboy.annotation.AnonymousGetMapping;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 健康检查接口
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2022-01-06
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/health")
|
||||||
|
@Api(tags = "系统:健康检查接口")
|
||||||
|
public class HealthCheckController {
|
||||||
|
/**
|
||||||
|
* 健康检查
|
||||||
|
*/
|
||||||
|
@AnonymousGetMapping(value = "/check")
|
||||||
|
public ResponseEntity<?> doCheck() {
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问首页提示
|
||||||
|
*/
|
||||||
|
@AnonymousGetMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "success";
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
-7
@@ -1,7 +1,10 @@
|
|||||||
package cn.odboy.config.mybatis;
|
package cn.odboy.mybatis.config;
|
||||||
|
|
||||||
|
import cn.odboy.mybatis.context.InsertBatchSqlInjector;
|
||||||
import com.baomidou.mybatisplus.annotation.DbType;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -10,18 +13,28 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
public class MybatisPlusConfig {
|
public class MybatisPlusConfig {
|
||||||
/**
|
|
||||||
* MyBatisPlus拦截器(用于分页)
|
|
||||||
*/
|
|
||||||
@Bean
|
@Bean
|
||||||
public MybatisPlusInterceptor paginationInterceptor() {
|
public MybatisPlusInterceptor paginationInterceptor() {
|
||||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||||
// 添加MySQL的分页拦截器
|
// MySQL的分页拦截器
|
||||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
|
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
|
||||||
paginationInnerInterceptor.setOptimizeJoin(true);
|
|
||||||
paginationInnerInterceptor.setMaxLimit(500L);
|
paginationInnerInterceptor.setMaxLimit(500L);
|
||||||
paginationInnerInterceptor.setOverflow(false);
|
/// 这个配置会导致:当分页没数据时,游标从0开始,会导致无论page为什么值,就算分页超出最大页数,依然能够查询到
|
||||||
|
/// paginationInnerInterceptor.setOverflow(true);
|
||||||
|
paginationInnerInterceptor.setOptimizeJoin(true);
|
||||||
interceptor.addInnerInterceptor(paginationInnerInterceptor);
|
interceptor.addInnerInterceptor(paginationInnerInterceptor);
|
||||||
|
// 乐观锁
|
||||||
|
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
|
||||||
|
// 防全表更新与删除
|
||||||
|
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapper支持批量插入
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public InsertBatchSqlInjector insertBatchSqlInjector() {
|
||||||
|
return new InsertBatchSqlInjector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config;
|
package cn.odboy.mybatis.config;
|
||||||
|
|
||||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
||||||
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
|
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* <<
|
||||||
|
* Davinci
|
||||||
|
* ==
|
||||||
|
* Copyright (C) 2016 - 2019 EDP
|
||||||
|
* ==
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* >>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package cn.odboy.mybatis.constant;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author /
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@SuppressWarnings({"unchecked", "all"})
|
||||||
|
public enum DataTypeEnum {
|
||||||
|
/**
|
||||||
|
* mysql
|
||||||
|
*/
|
||||||
|
MYSQL("mysql", "mysql", "com.mysql.jdbc.Driver", "`", "`", "'", "'"),
|
||||||
|
/**
|
||||||
|
* oracle
|
||||||
|
*/
|
||||||
|
ORACLE("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* sql config
|
||||||
|
*/
|
||||||
|
SQLSERVER("sqlserver", "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "\"", "\"", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* h2
|
||||||
|
*/
|
||||||
|
H2("h2", "h2", "org.h2.Driver", "`", "`", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* phoenix
|
||||||
|
*/
|
||||||
|
PHOENIX("phoenix", "hbase phoenix", "org.apache.phoenix.jdbc.PhoenixDriver", "", "", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* mongo
|
||||||
|
*/
|
||||||
|
MONGODB("mongo", "mongodb", "mongodb.jdbc.MongoDriver", "`", "`", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* sql4es
|
||||||
|
*/
|
||||||
|
ELASTICSEARCH("sql4es", "elasticsearch", "nl.anchormen.sql4es.jdbc.ESDriver", "", "", "'", "'"),
|
||||||
|
/**
|
||||||
|
* presto
|
||||||
|
*/
|
||||||
|
PRESTO("presto", "presto", "com.facebook.presto.jdbc.PrestoDriver", "", "", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* moonbox
|
||||||
|
*/
|
||||||
|
MOONBOX("moonbox", "moonbox", "moonbox.jdbc.MbDriver", "`", "`", "`", "`"),
|
||||||
|
/**
|
||||||
|
* cassandra
|
||||||
|
*/
|
||||||
|
CASSANDRA("cassandra", "cassandra", "com.github.adejanovski.cassandra.jdbc.CassandraDriver", "", "", "'", "'"),
|
||||||
|
/**
|
||||||
|
* click house
|
||||||
|
*/
|
||||||
|
CLICKHOUSE("clickhouse", "clickhouse", "ru.yandex.clickhouse.ClickHouseDriver", "", "", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* kylin
|
||||||
|
*/
|
||||||
|
KYLIN("kylin", "kylin", "org.apache.kylin.jdbc.Driver", "\"", "\"", "\"", "\""),
|
||||||
|
/**
|
||||||
|
* vertica
|
||||||
|
*/
|
||||||
|
VERTICA("vertica", "vertica", "com.vertica.jdbc.Driver", "", "", "'", "'"),
|
||||||
|
/**
|
||||||
|
* sap
|
||||||
|
*/
|
||||||
|
HANA("sap", "sap hana", "com.sap.db.jdbc.Driver", "", "", "'", "'"),
|
||||||
|
/**
|
||||||
|
* impala
|
||||||
|
*/
|
||||||
|
IMPALA("impala", "impala", "com.cloudera.impala.jdbc41.Driver", "", "", "'", "'");
|
||||||
|
private String feature;
|
||||||
|
private String desc;
|
||||||
|
private String driver;
|
||||||
|
private String keywordPrefix;
|
||||||
|
private String keywordSuffix;
|
||||||
|
private String aliasPrefix;
|
||||||
|
private String aliasSuffix;
|
||||||
|
private static final String JDBC_URL_PREFIX = "jdbc:";
|
||||||
|
|
||||||
|
DataTypeEnum(String feature, String desc, String driver, String keywordPrefix, String keywordSuffix, String aliasPrefix, String aliasSuffix) {
|
||||||
|
this.feature = feature;
|
||||||
|
this.desc = desc;
|
||||||
|
this.driver = driver;
|
||||||
|
this.keywordPrefix = keywordPrefix;
|
||||||
|
this.keywordSuffix = keywordSuffix;
|
||||||
|
this.aliasPrefix = aliasPrefix;
|
||||||
|
this.aliasSuffix = aliasSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataTypeEnum urlOf(String jdbcUrl) {
|
||||||
|
String url = jdbcUrl.toLowerCase().trim();
|
||||||
|
for (DataTypeEnum dataTypeEnum : values()) {
|
||||||
|
if (url.startsWith(JDBC_URL_PREFIX + dataTypeEnum.feature)) {
|
||||||
|
try {
|
||||||
|
Class<?> aClass = Class.forName(dataTypeEnum.getDriver());
|
||||||
|
if (null == aClass) {
|
||||||
|
throw new RuntimeException("Unable to get driver instance for jdbcUrl: " + jdbcUrl);
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException("Unable to get driver instance: " + jdbcUrl);
|
||||||
|
}
|
||||||
|
return dataTypeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFeature() {
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriver() {
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeywordPrefix() {
|
||||||
|
return keywordPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeywordSuffix() {
|
||||||
|
return keywordSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAliasPrefix() {
|
||||||
|
return aliasPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAliasSuffix() {
|
||||||
|
return aliasSuffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package cn.odboy.mybatis.constant;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询描述
|
||||||
|
*
|
||||||
|
* @date 2023-11-25
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface MpQuery {
|
||||||
|
/**
|
||||||
|
* 基本对象的属性名
|
||||||
|
*/
|
||||||
|
String propName() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询方式
|
||||||
|
*/
|
||||||
|
QueryTypeEnum type() default QueryTypeEnum.EQUAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接查询的属性名, 如User类中的dept
|
||||||
|
*/
|
||||||
|
String joinName() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认左连接
|
||||||
|
*/
|
||||||
|
Join join() default Join.LEFT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多字段模糊搜索, 仅支持String类型字段, 多个用逗号隔开, 如@MpQuery(blurry = "email,username")
|
||||||
|
*/
|
||||||
|
String blurry() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 适用于简单连接查询, 复杂的请自定义该注解, 或者使用sql查询
|
||||||
|
*/
|
||||||
|
enum Join {
|
||||||
|
/**
|
||||||
|
* 左连接
|
||||||
|
*/
|
||||||
|
LEFT,
|
||||||
|
/**
|
||||||
|
* 右连接
|
||||||
|
*/
|
||||||
|
RIGHT,
|
||||||
|
/**
|
||||||
|
* 内连接
|
||||||
|
*/
|
||||||
|
INNER
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package cn.odboy.mybatis.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态查询 枚举
|
||||||
|
*/
|
||||||
|
public enum QueryTypeEnum {
|
||||||
|
/**
|
||||||
|
* 相等
|
||||||
|
*/
|
||||||
|
EQUAL
|
||||||
|
/**
|
||||||
|
* 大于等于
|
||||||
|
*/
|
||||||
|
, GREATER_THAN
|
||||||
|
/**
|
||||||
|
* 小于等于
|
||||||
|
*/
|
||||||
|
, LESS_THAN
|
||||||
|
/**
|
||||||
|
* 中模糊查询
|
||||||
|
*/
|
||||||
|
, INNER_LIKE
|
||||||
|
/**
|
||||||
|
* 左模糊查询
|
||||||
|
*/
|
||||||
|
, LEFT_LIKE
|
||||||
|
/**
|
||||||
|
* 右模糊查询
|
||||||
|
*/
|
||||||
|
, RIGHT_LIKE
|
||||||
|
/**
|
||||||
|
* 小于
|
||||||
|
*/
|
||||||
|
, LESS_THAN_NQ
|
||||||
|
/**
|
||||||
|
* 包含
|
||||||
|
*/
|
||||||
|
, IN
|
||||||
|
/**
|
||||||
|
* 不包含
|
||||||
|
*/
|
||||||
|
, NOT_IN
|
||||||
|
/**
|
||||||
|
* 不等于
|
||||||
|
*/
|
||||||
|
, NOT_EQUAL
|
||||||
|
/**
|
||||||
|
* between(注:被注解的属性一定得是数组或者集合, 长度大于等于2)
|
||||||
|
*/
|
||||||
|
, BETWEEN
|
||||||
|
/**
|
||||||
|
* 不为空
|
||||||
|
*/
|
||||||
|
, NOT_NULL
|
||||||
|
/**
|
||||||
|
* 为空
|
||||||
|
*/
|
||||||
|
, IS_NULL
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config.mybatis;
|
package cn.odboy.mybatis.context;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
|
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.mybatis.context;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||||
|
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
|
import com.baomidou.mybatisplus.extension.injector.methods.AlwaysUpdateSomeColumnById;
|
||||||
|
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
|
||||||
|
import org.apache.ibatis.session.Configuration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量插入SQL注入器
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-11
|
||||||
|
*/
|
||||||
|
public class InsertBatchSqlInjector extends DefaultSqlInjector {
|
||||||
|
@Override
|
||||||
|
public List<AbstractMethod> getMethodList(Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
|
||||||
|
List<AbstractMethod> methodList = super.getMethodList(configuration, mapperClass, tableInfo);
|
||||||
|
// 新增自定义方法, InsertBatchSomeColumn这个方法Mp没有开放出来
|
||||||
|
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
|
||||||
|
// 全量更新, 包括null字段
|
||||||
|
methodList.add(new AlwaysUpdateSomeColumnById(i -> i.getFieldFill() != FieldFill.INSERT));
|
||||||
|
return methodList;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config.mybatis;
|
package cn.odboy.mybatis.context;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.odboy.util.SecurityUtil;
|
import cn.odboy.util.SecurityUtil;
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.mybatis.interfaces;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.odboy.base.PageResult;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共抽象Mapper接口类
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2022-04-03
|
||||||
|
*/
|
||||||
|
public interface EasyMapper<E> extends BaseMapper<E> {
|
||||||
|
/**
|
||||||
|
* 批量插入
|
||||||
|
*
|
||||||
|
* @param entityList List<E>
|
||||||
|
* @return 影响的行数
|
||||||
|
*/
|
||||||
|
int insertBatchSomeColumn(List<E> entityList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id全量更新
|
||||||
|
*
|
||||||
|
* @param entity E
|
||||||
|
* @return 影响的行数
|
||||||
|
*/
|
||||||
|
int alwaysUpdateSomeColumnById(@Param("et") E entity);
|
||||||
|
|
||||||
|
default QueryChainWrapper<E> select() {
|
||||||
|
return ChainWrappers.queryChain(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
default UpdateChainWrapper<E> update() {
|
||||||
|
return ChainWrappers.updateChain(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
default LambdaQueryChainWrapper<E> lambdaSelect() {
|
||||||
|
return ChainWrappers.lambdaQueryChain(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
default LambdaUpdateChainWrapper<E> lambdaUpdate() {
|
||||||
|
return ChainWrappers.lambdaUpdateChain(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字典
|
||||||
|
*
|
||||||
|
* @param wrapper LambdaQueryWrapper<E>
|
||||||
|
* @param keyName 键对应的列名称
|
||||||
|
* @param valueName 值对应的列名称
|
||||||
|
* @return Map<String, Object>
|
||||||
|
*/
|
||||||
|
default Map<String, Object> selectMap(LambdaQueryWrapper<E> wrapper, String keyName, String valueName) {
|
||||||
|
Map<String, Object> result = new ConcurrentHashMap<>(1);
|
||||||
|
List<E> list = this.selectList(wrapper);
|
||||||
|
if (CollUtil.isEmpty(list)) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
E tempObj = list.stream().findFirst().orElse(null);
|
||||||
|
if (tempObj == null) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
Field[] fields = ReflectUtil.getFields(tempObj.getClass());
|
||||||
|
for (E e : list) {
|
||||||
|
Field keyField = null;
|
||||||
|
Field valueField = null;
|
||||||
|
for (Field field : fields) {
|
||||||
|
String fieldName = field.getName();
|
||||||
|
if (fieldName.equals(keyName)) {
|
||||||
|
keyField = field;
|
||||||
|
} else if (fieldName.equals(valueName)) {
|
||||||
|
valueField = field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String fieldKey = String.valueOf(ReflectUtil.getFieldValue(e, keyField));
|
||||||
|
Object fieldValue = ReflectUtil.getFieldValue(e, valueField);
|
||||||
|
if (fieldKey != null) {
|
||||||
|
result.put(fieldKey, fieldValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件查询列表, 并返回期望的对象
|
||||||
|
*
|
||||||
|
* @param wrapper LambdaQueryWrapper<E>
|
||||||
|
* @param clazz 期望的对象类型
|
||||||
|
* @return List<T>
|
||||||
|
*/
|
||||||
|
default <T> List<T> selectList(LambdaQueryWrapper<E> wrapper, Class<T> clazz) {
|
||||||
|
List<E> list = this.selectList(wrapper);
|
||||||
|
if (CollUtil.isEmpty(list)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return BeanUtil.copyToList(list, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件查询列表, 并返回期望的对象
|
||||||
|
*
|
||||||
|
* @param wrapper LambdaQueryWrapper<E>
|
||||||
|
* @param clazz 期望的对象类型
|
||||||
|
* @return List<T>
|
||||||
|
*/
|
||||||
|
default <T> List<T> selectList(LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||||
|
List<E> list = wrapper.list();
|
||||||
|
if (CollUtil.isEmpty(list)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return BeanUtil.copyToList(list, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件查询分页列表, 并返回期望的对象
|
||||||
|
*
|
||||||
|
* @param pageable 分页参数
|
||||||
|
* @param wrapper LambdaQueryWrapper<E> wrapper
|
||||||
|
* @param clazz 期望的对象类型
|
||||||
|
* @return IPage<T>
|
||||||
|
*/
|
||||||
|
default <T> PageResult<T> selectPage(Pageable pageable, LambdaQueryWrapper<E> wrapper, Class<T> clazz) {
|
||||||
|
int pageNumber = pageable.getPageNumber();
|
||||||
|
int pageSize = pageable.getPageSize();
|
||||||
|
pageNumber = pageNumber <= 0 ? 1 : pageNumber;
|
||||||
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||||||
|
IPage<E> pageInfo = this.selectPage(new Page<>(pageNumber, pageSize), wrapper);
|
||||||
|
if (CollUtil.isEmpty(pageInfo.getRecords())) {
|
||||||
|
return new PageResult<>(new ArrayList<>(), pageInfo.getTotal());
|
||||||
|
}
|
||||||
|
return new PageResult<>(BeanUtil.copyToList(pageInfo.getRecords(), clazz), pageInfo.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件查询分页列表, 并返回期望的对象
|
||||||
|
*
|
||||||
|
* @param pageable 分页参数
|
||||||
|
* @param wrapper LambdaQueryWrapper<E> wrapper
|
||||||
|
* @param clazz 期望的对象类型
|
||||||
|
* @return IPage<T>
|
||||||
|
*/
|
||||||
|
default <T> PageResult<T> selectPage(Pageable pageable, LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||||
|
int pageNumber = pageable.getPageNumber();
|
||||||
|
int pageSize = pageable.getPageSize();
|
||||||
|
pageNumber = pageNumber <= 0 ? 1 : pageNumber;
|
||||||
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||||||
|
IPage<E> pageInfo = wrapper.page(new Page<>(pageNumber, pageSize));
|
||||||
|
if (CollUtil.isEmpty(pageInfo.getRecords())) {
|
||||||
|
return new PageResult<>(new ArrayList<>(), pageInfo.getTotal());
|
||||||
|
}
|
||||||
|
return new PageResult<>(BeanUtil.copyToList(pageInfo.getRecords(), clazz), pageInfo.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取目标类
|
||||||
|
*
|
||||||
|
* @param wrapper LambdaQueryChainWrapper<E> wrapper
|
||||||
|
* @param clazz 期望的对象类型
|
||||||
|
* @return T
|
||||||
|
*/
|
||||||
|
default <T> T selectOne(LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||||
|
E e = this.selectOne(wrapper);
|
||||||
|
if (e == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return BeanUtil.copyProperties(e, clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.mybatis.interfaces;
|
||||||
|
|
||||||
|
import cn.odboy.base.PageResult;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共抽象Mapper接口类
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2022-04-03
|
||||||
|
*/
|
||||||
|
public interface EasyService<T> extends IService<T> {
|
||||||
|
LambdaQueryWrapper<T> quick();
|
||||||
|
|
||||||
|
<G> int quickSave(G resources);
|
||||||
|
|
||||||
|
<G> int quickSaveBatch(List<G> resources);
|
||||||
|
|
||||||
|
<G> int quickModifyById(G resources);
|
||||||
|
|
||||||
|
<G> boolean quickModifyBatchById(Collection<G> resources, int batchSize);
|
||||||
|
|
||||||
|
<G> G quickGetOneById(Serializable id, Class<G> targetClazz);
|
||||||
|
|
||||||
|
T quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn);
|
||||||
|
|
||||||
|
<G> G quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn, Class<G> clazz);
|
||||||
|
|
||||||
|
<G> List<G> quickListByIds(List<Serializable> ids, Class<G> targetClazz);
|
||||||
|
|
||||||
|
<Q> List<T> quickList(Q criteria);
|
||||||
|
|
||||||
|
List<T> quickList(LambdaQueryWrapper<T> wrapper);
|
||||||
|
|
||||||
|
<G, Q> List<G> quickList(Q criteria, Class<G> targetClazz);
|
||||||
|
|
||||||
|
<G> List<G> quickList(LambdaQueryWrapper<T> wrapper, Class<G> targetClazz);
|
||||||
|
|
||||||
|
PageResult<T> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable);
|
||||||
|
|
||||||
|
<G> PageResult<G> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable, Class<G> targetClazz);
|
||||||
|
|
||||||
|
<G, Q> PageResult<G> quickPage(Q criteria, IPage<T> pageable, Class<G> targetClazz);
|
||||||
|
|
||||||
|
<Q> PageResult<T> quickPage(Q criteria, IPage<T> pageable);
|
||||||
|
|
||||||
|
int quickUpdate(LambdaQueryWrapper<T> wrapper, T entity);
|
||||||
|
|
||||||
|
int quickDelete(LambdaQueryWrapper<T> wrapper);
|
||||||
|
}
|
||||||
+260
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.mybatis.interfaces.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.odboy.base.PageResult;
|
||||||
|
import cn.odboy.exception.BadRequestException;
|
||||||
|
import cn.odboy.mybatis.interfaces.EasyMapper;
|
||||||
|
import cn.odboy.mybatis.util.MybatisHelper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.apache.ibatis.binding.MapperMethod;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共抽象Mapper接口类
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2022-04-03
|
||||||
|
*/
|
||||||
|
public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M, T> {
|
||||||
|
public LambdaQueryWrapper<T> quick() {
|
||||||
|
return new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速插入
|
||||||
|
*
|
||||||
|
* @param resources /
|
||||||
|
*/
|
||||||
|
public <G> int quickSave(G resources) {
|
||||||
|
return this.getBaseMapper().insert(BeanUtil.copyProperties(resources, this.getEntityClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速批量插入
|
||||||
|
*
|
||||||
|
* @param resources /
|
||||||
|
*/
|
||||||
|
public <G> int quickSaveBatch(List<G> resources) {
|
||||||
|
return this.getBaseMapper().insertBatchSomeColumn(BeanUtil.copyToList(resources, this.getEntityClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速更新
|
||||||
|
*
|
||||||
|
* @param resources /
|
||||||
|
*/
|
||||||
|
public <G> int quickModifyById(G resources) {
|
||||||
|
return this.getBaseMapper().updateById(BeanUtil.copyProperties(resources, this.getEntityClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速批量更新
|
||||||
|
*
|
||||||
|
* @param resources /
|
||||||
|
* @param batchSize 每批数量
|
||||||
|
*/
|
||||||
|
public <G> boolean quickModifyBatchById(Collection<G> resources, int batchSize) {
|
||||||
|
String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE_BY_ID);
|
||||||
|
return this.executeBatch(resources, batchSize, (sqlSession, entity) -> {
|
||||||
|
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||||
|
param.put("et", BeanUtil.copyProperties(entity, this.getEntityClass()));
|
||||||
|
sqlSession.update(sqlStatement, param);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
*
|
||||||
|
* @param id /
|
||||||
|
* @param targetClazz 目标类型
|
||||||
|
*/
|
||||||
|
public <G> G quickGetOneById(Serializable id, Class<G> targetClazz) {
|
||||||
|
T entity = this.getById(id);
|
||||||
|
return entity == null ? null : BeanUtil.copyProperties(entity, targetClazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查一条数据
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
*/
|
||||||
|
public T quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn) {
|
||||||
|
if (orderColumn == null) {
|
||||||
|
throw new BadRequestException("参数orderColumn(排序的列)必填");
|
||||||
|
}
|
||||||
|
if (wrapper == null) {
|
||||||
|
wrapper = new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
wrapper.orderByDesc(orderColumn);
|
||||||
|
List<T> ts = baseMapper.selectList(wrapper);
|
||||||
|
if (ts.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ts.stream().findFirst().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <G> G quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn, Class<G> clazz) {
|
||||||
|
if (orderColumn == null) {
|
||||||
|
throw new BadRequestException("参数orderColumn(排序的列)必填");
|
||||||
|
}
|
||||||
|
if (wrapper == null) {
|
||||||
|
wrapper = new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
wrapper.orderByDesc(orderColumn);
|
||||||
|
List<T> ts = baseMapper.selectList(wrapper);
|
||||||
|
if (ts.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return BeanUtil.copyProperties(ts.stream().findFirst().get(), clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id集合查询
|
||||||
|
*
|
||||||
|
* @param ids /
|
||||||
|
* @param targetClazz 目标类型
|
||||||
|
*/
|
||||||
|
public <G> List<G> quickListByIds(List<Serializable> ids, Class<G> targetClazz) {
|
||||||
|
List<T> entitys = this.listByIds(ids);
|
||||||
|
return entitys == null || entitys.isEmpty() ? CollUtil.newArrayList() : BeanUtil.copyToList(entitys, targetClazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查有关的数据
|
||||||
|
*
|
||||||
|
* @param criteria 动态条件
|
||||||
|
*/
|
||||||
|
public <Q> List<T> quickList(Q criteria) {
|
||||||
|
QueryWrapper<T> predicate = MybatisHelper.build(criteria);
|
||||||
|
return baseMapper.selectList(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查有关的数据
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
*/
|
||||||
|
public List<T> quickList(LambdaQueryWrapper<T> wrapper) {
|
||||||
|
if (wrapper == null) {
|
||||||
|
wrapper = new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
return baseMapper.selectList(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查有关的数据并转成目标类型的数据
|
||||||
|
*
|
||||||
|
* @param criteria 动态条件
|
||||||
|
* @param targetClazz 目标类型
|
||||||
|
*/
|
||||||
|
public <G, Q> List<G> quickList(Q criteria, Class<G> targetClazz) {
|
||||||
|
QueryWrapper<T> predicate = MybatisHelper.build(criteria);
|
||||||
|
List<T> data = baseMapper.selectList(predicate);
|
||||||
|
return BeanUtil.copyToList(data, targetClazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查有关的数据并转换为目标类型
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
* @param targetClazz 目标类型
|
||||||
|
*/
|
||||||
|
public <G> List<G> quickList(LambdaQueryWrapper<T> wrapper, Class<G> targetClazz) {
|
||||||
|
if (wrapper == null) {
|
||||||
|
wrapper = new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
return BeanUtil.copyToList(baseMapper.selectList(wrapper), targetClazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查有关的分页数据
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
* @param pageable 分页参数
|
||||||
|
*/
|
||||||
|
public PageResult<T> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable) {
|
||||||
|
if (wrapper == null) {
|
||||||
|
wrapper = new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
IPage<T> originPageData = baseMapper.selectPage(pageable, wrapper);
|
||||||
|
return new PageResult<>(originPageData.getRecords(), originPageData.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查有关的分页数据
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
* @param pageable 分页参数
|
||||||
|
* @param targetClazz 目标类型
|
||||||
|
*/
|
||||||
|
public <G> PageResult<G> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable, Class<G> targetClazz) {
|
||||||
|
if (wrapper == null) {
|
||||||
|
wrapper = new LambdaQueryWrapper<>();
|
||||||
|
}
|
||||||
|
IPage<T> originPageData = baseMapper.selectPage(pageable, wrapper);
|
||||||
|
return new PageResult<>(BeanUtil.copyToList(originPageData.getRecords(), targetClazz), originPageData.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <G, Q> PageResult<G> quickPage(Q criteria, IPage<T> pageable, Class<G> targetClazz) {
|
||||||
|
QueryWrapper<T> wrapper = MybatisHelper.build(criteria);
|
||||||
|
IPage<T> originPageData = baseMapper.selectPage(pageable, wrapper);
|
||||||
|
return new PageResult<>(BeanUtil.copyToList(originPageData.getRecords(), targetClazz), originPageData.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <Q> PageResult<T> quickPage(Q criteria, IPage<T> pageable) {
|
||||||
|
QueryWrapper<T> wrapper = MybatisHelper.build(criteria);
|
||||||
|
IPage<T> originPageData = baseMapper.selectPage(pageable, wrapper);
|
||||||
|
return new PageResult<>(originPageData.getRecords(), originPageData.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件更新
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
* @param entity 更新内容
|
||||||
|
*/
|
||||||
|
public int quickUpdate(LambdaQueryWrapper<T> wrapper, T entity) {
|
||||||
|
if (wrapper == null) {
|
||||||
|
throw new BadRequestException("参数wrapper必填");
|
||||||
|
}
|
||||||
|
return baseMapper.update(entity, wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件删除
|
||||||
|
*
|
||||||
|
* @param wrapper 制造条件
|
||||||
|
*/
|
||||||
|
public int quickDelete(LambdaQueryWrapper<T> wrapper) {
|
||||||
|
if (wrapper == null) {
|
||||||
|
throw new BadRequestException("参数wrapper必填");
|
||||||
|
}
|
||||||
|
return baseMapper.delete(wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.mybatis.util;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.*;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.rules.DateType;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||||
|
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
|
||||||
|
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||||
|
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成器入口
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CmdGenHelper {
|
||||||
|
/**
|
||||||
|
* 数据库类型 MySQL
|
||||||
|
*/
|
||||||
|
private static final IDbQuery DB_QUERY = new MySqlQuery();
|
||||||
|
/**
|
||||||
|
* 类型转换
|
||||||
|
*/
|
||||||
|
private static final String TYPE_TINY_INT = "tinyint";
|
||||||
|
private static final String TYPE_DATETIME = "datetime";
|
||||||
|
private static final String TYPE_DATE = "date";
|
||||||
|
private String databaseUrl;
|
||||||
|
private String databaseUsername;
|
||||||
|
private String databasePassword;
|
||||||
|
private String driverClassName;
|
||||||
|
private String parentPackageName;
|
||||||
|
private String parentPackageModuleName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成函数
|
||||||
|
*
|
||||||
|
* @param tablePrefix 表前缀(可空)
|
||||||
|
* @param tableNames 表名称, 多个用逗号分隔
|
||||||
|
*/
|
||||||
|
public void gen(String tablePrefix, List<String> tableNames) {
|
||||||
|
// 1.数据库配置
|
||||||
|
DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig
|
||||||
|
.Builder(this.databaseUrl, this.databaseUsername, this.databasePassword)
|
||||||
|
.driverClassName(this.driverClassName);
|
||||||
|
dataSourceConfigBuilder.dbQuery(DB_QUERY);
|
||||||
|
dataSourceConfigBuilder.keyWordsHandler(new MySqlKeyWordsHandler());
|
||||||
|
// 1.1.快速生成器
|
||||||
|
FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(dataSourceConfigBuilder);
|
||||||
|
// 2.全局配置
|
||||||
|
// 自定义类型转换
|
||||||
|
fastAutoGenerator.dataSourceConfig(getDataSourceConfigConsumer());
|
||||||
|
// 覆盖已生成文件
|
||||||
|
// 添加swagger注解
|
||||||
|
// 设置注释的作者
|
||||||
|
// 设置注释的日期格式
|
||||||
|
// 使用java8新的时间类型
|
||||||
|
fastAutoGenerator.globalConfig(getGlobalConfigConsumer());
|
||||||
|
// 3.包配置
|
||||||
|
// 设置父包名
|
||||||
|
// 设置父包模块名
|
||||||
|
// 设置MVC下各个模块的包名
|
||||||
|
// 设置XML资源文件的目录
|
||||||
|
fastAutoGenerator.packageConfig(getPackageConfigConsumer());
|
||||||
|
// 4.模板配置
|
||||||
|
// 使用Freemarker引擎模板, 默认的是Velocity引擎模板
|
||||||
|
AbstractTemplateEngine templateEngine = new FreemarkerTemplateEngine();
|
||||||
|
fastAutoGenerator.templateEngine(templateEngine);
|
||||||
|
// 5.策略配置
|
||||||
|
// 设置需要生成的表名
|
||||||
|
// 设置过滤表前缀
|
||||||
|
fastAutoGenerator.strategyConfig(getStrategyConfigConsumer(tableNames)
|
||||||
|
);
|
||||||
|
if (tablePrefix != null) {
|
||||||
|
// 表前缀, 可多个
|
||||||
|
fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.addTablePrefix(tablePrefix));
|
||||||
|
}
|
||||||
|
// 5.1.Entity策略配置
|
||||||
|
// 生成实体时生成字段的注解, 包括@TableId注解等
|
||||||
|
// 数据库表和字段映射到实体的命名策略, 为下划线转驼峰
|
||||||
|
// 全局主键类型为None
|
||||||
|
// 实体名称格式化为XXXEntity
|
||||||
|
fastAutoGenerator.strategyConfig(getEntityConfigConsumer());
|
||||||
|
// 5.2.Controller策略配置
|
||||||
|
// 开启生成@RestController控制器
|
||||||
|
fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.controllerBuilder().enableRestStyle());
|
||||||
|
// 如果不需要生成Controller
|
||||||
|
// fastAutoGenerator.templateConfig(templateConfig -> templateConfig.controller(""));
|
||||||
|
// 5.3.Service策略配置
|
||||||
|
// 格式化service接口和实现类的文件名称, 去掉默认的ServiceName前面的I
|
||||||
|
fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder
|
||||||
|
.serviceBuilder()
|
||||||
|
.formatServiceFileName("%sService")
|
||||||
|
.formatServiceImplFileName("%sServiceImpl"));
|
||||||
|
// 5.4.Mapper策略配置
|
||||||
|
// 格式化 mapper文件名,格式化xml实现类文件名称
|
||||||
|
fastAutoGenerator.strategyConfig(getStrategyConfigConsumer());
|
||||||
|
// 6.生成代码
|
||||||
|
fastAutoGenerator.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Consumer<StrategyConfig.Builder> getEntityConfigConsumer() {
|
||||||
|
return strategyConfigBuilder -> strategyConfigBuilder
|
||||||
|
.entityBuilder()
|
||||||
|
.enableLombok()
|
||||||
|
// 如果不需要生成注解, 去掉.enableTableFieldAnnotation()
|
||||||
|
.enableTableFieldAnnotation()
|
||||||
|
.enableFileOverride()
|
||||||
|
.naming(NamingStrategy.underline_to_camel)
|
||||||
|
.columnNaming(NamingStrategy.underline_to_camel)
|
||||||
|
.idType(IdType.AUTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Consumer<StrategyConfig.Builder> getStrategyConfigConsumer(List<String> tableNames) {
|
||||||
|
return strategyConfigBuilder -> strategyConfigBuilder
|
||||||
|
.enableCapitalMode()
|
||||||
|
.enableSkipView()
|
||||||
|
.disableSqlFilter()
|
||||||
|
.addInclude(tableNames)
|
||||||
|
.mapperBuilder()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Consumer<PackageConfig.Builder> getPackageConfigConsumer() {
|
||||||
|
return packageConfigBuilder -> packageConfigBuilder
|
||||||
|
.parent(this.parentPackageName == null ? "cn.codegen" : this.parentPackageName)
|
||||||
|
.moduleName(this.parentPackageModuleName == null ? "moduleName" : this.parentPackageModuleName)
|
||||||
|
.entity("domain")
|
||||||
|
.service("service")
|
||||||
|
.mapper("mapper")
|
||||||
|
.serviceImpl("service.service")
|
||||||
|
.controller("rest")
|
||||||
|
.pathInfo(Collections.singletonMap(OutputFile.xml, (System.getProperty("os.name").toLowerCase().contains("win") ? "C:\\CodeGen\\resources\\mapper" : "/tmp/CodeGen/resources/mapper")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Consumer<GlobalConfig.Builder> getGlobalConfigConsumer() {
|
||||||
|
return globalConfigBuilder -> globalConfigBuilder
|
||||||
|
.enableSwagger()
|
||||||
|
.outputDir((System.getProperty("os.name").toLowerCase().contains("win") ? "C:\\CodeGen" : "/tmp/CodeGen"))
|
||||||
|
.author("codegen")
|
||||||
|
.commentDate("yyyy-MM-dd")
|
||||||
|
.dateType(DateType.TIME_PACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Consumer<StrategyConfig.Builder> getStrategyConfigConsumer() {
|
||||||
|
return strategyConfigBuilder -> strategyConfigBuilder
|
||||||
|
.mapperBuilder()
|
||||||
|
.formatMapperFileName("%sMapper")
|
||||||
|
.formatXmlFileName("%sMapper");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Consumer<DataSourceConfig.Builder> getDataSourceConfigConsumer() {
|
||||||
|
return builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
|
||||||
|
int typeCode = metaInfo.getJdbcType().TYPE_CODE;
|
||||||
|
if (typeCode == Types.SMALLINT) {
|
||||||
|
return DbColumnType.INTEGER;
|
||||||
|
}
|
||||||
|
if (typeCode == Types.DATE) {
|
||||||
|
return DbColumnType.DATE;
|
||||||
|
}
|
||||||
|
if (typeCode == Types.TIME) {
|
||||||
|
return DbColumnType.DATE;
|
||||||
|
}
|
||||||
|
if (typeCode == Types.TIMESTAMP) {
|
||||||
|
return DbColumnType.DATE;
|
||||||
|
}
|
||||||
|
return typeRegistry.getColumnType(metaInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
package cn.odboy.mybatis.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.odboy.base.MyEntity;
|
||||||
|
import cn.odboy.exception.BadRequestException;
|
||||||
|
import cn.odboy.mybatis.constant.MpQuery;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询条件创建工具
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class MybatisHelper {
|
||||||
|
public static <R, Q> QueryWrapper<R> build(Q query) {
|
||||||
|
QueryWrapper<R> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (query == null) {
|
||||||
|
return queryWrapper;
|
||||||
|
}
|
||||||
|
Class<?> clazz = query.getClass();
|
||||||
|
try {
|
||||||
|
List<Field> fields = getAllFields(clazz, new ArrayList<>());
|
||||||
|
for (Field field : fields) {
|
||||||
|
if (!field.canAccess(clazz)) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
MpQuery q = field.getAnnotation(MpQuery.class);
|
||||||
|
if (q != null) {
|
||||||
|
String propName = q.propName();
|
||||||
|
String blurry = q.blurry();
|
||||||
|
String attributeName = StrUtil.isBlank(propName) ? field.getName() : propName;
|
||||||
|
attributeName = humpToUnderline(attributeName);
|
||||||
|
Object fieldVal = field.get(query);
|
||||||
|
if (ObjectUtil.isNull(fieldVal) || "".equals(fieldVal)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isNotEmpty(blurry)) {
|
||||||
|
handleBlurryQuery(queryWrapper, blurry, fieldVal);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
handleWrapper(q, queryWrapper, attributeName, fieldVal);
|
||||||
|
}
|
||||||
|
field.setAccessible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("组装SQL失败", e);
|
||||||
|
}
|
||||||
|
return queryWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <R> void handleWrapper(MpQuery q, QueryWrapper<R> queryWrapper, String attributeName, Object fieldVal) {
|
||||||
|
switch (q.type()) {
|
||||||
|
case EQUAL:
|
||||||
|
queryWrapper.eq(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case GREATER_THAN:
|
||||||
|
queryWrapper.ge(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case LESS_THAN:
|
||||||
|
queryWrapper.le(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case LESS_THAN_NQ:
|
||||||
|
queryWrapper.lt(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case INNER_LIKE:
|
||||||
|
queryWrapper.like(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case LEFT_LIKE:
|
||||||
|
queryWrapper.likeLeft(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case RIGHT_LIKE:
|
||||||
|
queryWrapper.likeRight(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case IN:
|
||||||
|
handleInQuery(queryWrapper, attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case NOT_IN:
|
||||||
|
handleNotInQuery(queryWrapper, attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case NOT_EQUAL:
|
||||||
|
queryWrapper.ne(attributeName, fieldVal);
|
||||||
|
break;
|
||||||
|
case NOT_NULL:
|
||||||
|
queryWrapper.isNotNull(attributeName);
|
||||||
|
break;
|
||||||
|
case IS_NULL:
|
||||||
|
queryWrapper.isNull(attributeName);
|
||||||
|
break;
|
||||||
|
case BETWEEN:
|
||||||
|
handleBetweenQuery(queryWrapper, fieldVal, attributeName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <R> void handleBetweenQuery(QueryWrapper<R> queryWrapper, Object fieldVal, String finalAttributeName) {
|
||||||
|
if (fieldVal instanceof List) {
|
||||||
|
List<Object> between = new ArrayList<>((List<?>) fieldVal);
|
||||||
|
if (CollectionUtil.isNotEmpty(between)) {
|
||||||
|
if (between.size() >= 2) {
|
||||||
|
queryWrapper.between(finalAttributeName, between.get(0), between.get(1));
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException("BETWEEN类型的对象列表长度必须 >= 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException("BETWEEN类型的对象必须是一个List子集合");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <R> void handleNotInQuery(QueryWrapper<R> queryWrapper, String finalAttributeName, Object fieldVal) {
|
||||||
|
Collection<?> wrapNotInVal = (Collection<?>) fieldVal;
|
||||||
|
if (CollectionUtil.isNotEmpty(wrapNotInVal)) {
|
||||||
|
Optional<?> anyValOptional = wrapNotInVal.stream().findAny();
|
||||||
|
if (anyValOptional.isPresent()) {
|
||||||
|
Object o = anyValOptional.get();
|
||||||
|
if (o instanceof Long) {
|
||||||
|
queryWrapper.notIn(finalAttributeName, fieldVal);
|
||||||
|
} else if (o instanceof Integer) {
|
||||||
|
queryWrapper.notIn(finalAttributeName, fieldVal);
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException("NOT_IN类型的对象属性值必须是Long/Integer类型集合");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IN查询
|
||||||
|
*
|
||||||
|
* @param queryWrapper /
|
||||||
|
* @param fieldVal /
|
||||||
|
* @param finalAttributeName /
|
||||||
|
* @param <R> /
|
||||||
|
*/
|
||||||
|
private static <R> void handleInQuery(QueryWrapper<R> queryWrapper, String finalAttributeName, Object fieldVal) {
|
||||||
|
Collection<?> wrapInVal = (Collection<?>) fieldVal;
|
||||||
|
if (CollectionUtil.isNotEmpty(wrapInVal)) {
|
||||||
|
Optional<?> anyValOptional = wrapInVal.stream().findAny();
|
||||||
|
if (anyValOptional.isPresent()) {
|
||||||
|
Object o = anyValOptional.get();
|
||||||
|
if (o instanceof Long) {
|
||||||
|
queryWrapper.in(finalAttributeName, fieldVal);
|
||||||
|
} else if (o instanceof Integer) {
|
||||||
|
queryWrapper.in(finalAttributeName, fieldVal);
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException("IN类型的对象属性值必须是Long/Integer类型集合");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊多字段
|
||||||
|
*
|
||||||
|
* @param queryWrapper /
|
||||||
|
* @param blurry /
|
||||||
|
* @param fieldVal /
|
||||||
|
* @param <R> /
|
||||||
|
*/
|
||||||
|
private static <R> void handleBlurryQuery(QueryWrapper<R> queryWrapper, String blurry, Object fieldVal) {
|
||||||
|
List<String> blurryList = Arrays.stream(blurry.split(",")).filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
|
||||||
|
queryWrapper.and(wrapper -> {
|
||||||
|
for (String blurryItem : blurryList) {
|
||||||
|
String column = humpToUnderline(blurryItem);
|
||||||
|
wrapper.or();
|
||||||
|
wrapper.like(column, fieldVal.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Field> getAllFields(Class<?> clazz, List<Field> fields) {
|
||||||
|
if (clazz != null) {
|
||||||
|
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||||
|
getAllFields(clazz.getSuperclass(), fields);
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 驼峰命名转为下划线命名
|
||||||
|
*
|
||||||
|
* @param para
|
||||||
|
* 驼峰命名的字符串
|
||||||
|
*/
|
||||||
|
private static String humpToUnderline(String para) {
|
||||||
|
return StrUtil.toUnderlineCase(para);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TableName("test_domain")
|
||||||
|
private static class TestDomain {
|
||||||
|
@NotNull(groups = MyEntity.Update.class)
|
||||||
|
@TableId(value = "user_id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
@TableField(value = "dept_id")
|
||||||
|
private Long deptId;
|
||||||
|
@NotBlank
|
||||||
|
private String username;
|
||||||
|
@NotBlank
|
||||||
|
private String nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
QueryWrapper<TestDomain> query = new QueryWrapper<TestDomain>();
|
||||||
|
//query.or();
|
||||||
|
query.or(wrapper -> wrapper.eq("username", 1).or().eq("nickname", 2));
|
||||||
|
//query.like("a",1);
|
||||||
|
//query.or();
|
||||||
|
//query.like("b",2);
|
||||||
|
//query.and(wrapper->wrapper.eq("c",1));
|
||||||
|
query.eq("id", 1);
|
||||||
|
query.orderByDesc("id");
|
||||||
|
// query.apply("left join student t1 on t1.id = t1.id");
|
||||||
|
// query.last("left join student t1 on t1.id = t1.id");
|
||||||
|
System.err.println("getSqlSelect=================================");
|
||||||
|
System.err.println(query.getSqlSelect());
|
||||||
|
System.err.println("getSqlSegment=================================");
|
||||||
|
System.err.println(query.getSqlSegment());
|
||||||
|
System.err.println("getSqlComment=================================");
|
||||||
|
System.err.println(query.getSqlComment());
|
||||||
|
System.err.println("getSqlSet=================================");
|
||||||
|
System.err.println(query.getSqlSet());
|
||||||
|
System.err.println("getTargetSql=================================");
|
||||||
|
System.err.println(query.getTargetSql());
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config.properties;
|
package cn.odboy.properties;
|
||||||
|
|
||||||
import cn.odboy.constant.SystemConstant;
|
import cn.odboy.constant.SystemConstant;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config.properties;
|
package cn.odboy.properties;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
+11
-2
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config;
|
package cn.odboy.redis;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONFactory;
|
import com.alibaba.fastjson2.JSONFactory;
|
||||||
@@ -39,7 +39,10 @@ public class RedisConfiguration extends CachingConfigurerSupport {
|
|||||||
/**
|
/**
|
||||||
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
||||||
*/
|
*/
|
||||||
private static final String[] WHITELIST_STR = {"cn.odboy"};
|
private static final String[] WHITELIST_STR = {
|
||||||
|
"org.springframework",
|
||||||
|
"cn.odboy.model",
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 redis 数据默认过期时间,默认2小时
|
* 设置 redis 数据默认过期时间,默认2小时
|
||||||
@@ -158,6 +161,9 @@ public class RedisConfiguration extends CachingConfigurerSupport {
|
|||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列化
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] serialize(T t) throws SerializationException {
|
public byte[] serialize(T t) throws SerializationException {
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
@@ -166,6 +172,9 @@ public class RedisConfiguration extends CachingConfigurerSupport {
|
|||||||
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(StandardCharsets.UTF_8);
|
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反序列化
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T deserialize(byte[] bytes) throws SerializationException {
|
public T deserialize(byte[] bytes) throws SerializationException {
|
||||||
if (bytes == null || bytes.length == 0) {
|
if (bytes == null || bytes.length == 0) {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config;
|
package cn.odboy.redis;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+13
-2
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.config.webConfig;
|
package cn.odboy.server;
|
||||||
|
|
||||||
import cn.odboy.config.properties.FileProperties;
|
import cn.odboy.properties.FileProperties;
|
||||||
import com.alibaba.fastjson2.JSONWriter;
|
import com.alibaba.fastjson2.JSONWriter;
|
||||||
import com.alibaba.fastjson2.support.config.FastJsonConfig;
|
import com.alibaba.fastjson2.support.config.FastJsonConfig;
|
||||||
import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter;
|
import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter;
|
||||||
@@ -67,7 +67,18 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
|
|||||||
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
|
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
// 开启引用检测,枚举支持
|
// 开启引用检测,枚举支持
|
||||||
config.setWriterFeatures(
|
config.setWriterFeatures(
|
||||||
|
// 是否输出值为null的字段
|
||||||
|
// SerializerFeature.WriteMapNullValue,
|
||||||
|
// 字段如果为null,输出为false,而非null
|
||||||
|
// JSONWriter.Feature.WriteNullBooleanAsFalse,
|
||||||
|
// 字段如果为null,输出为[],而非null
|
||||||
|
// JSONWriter.Feature.WriteNullListAsEmpty,
|
||||||
|
// 字符类型字段如果为null,输出为"",而非null
|
||||||
|
// JSONWriter.Feature.WriteNullStringAsEmpty,
|
||||||
|
// 太具体的数值会直接影响逻辑本身,所以不要这个
|
||||||
|
// SerializerFeature.WriteNullNumberAsZero,
|
||||||
JSONWriter.Feature.WriteEnumUsingToString,
|
JSONWriter.Feature.WriteEnumUsingToString,
|
||||||
|
// SerializerFeature.DisableCircularReferenceDetect
|
||||||
JSONWriter.Feature.ReferenceDetection
|
JSONWriter.Feature.ReferenceDetection
|
||||||
);
|
);
|
||||||
fastJsonConverter.setFastJsonConfig(config);
|
fastJsonConverter.setFastJsonConfig(config);
|
||||||
+9
-4
@@ -1,5 +1,7 @@
|
|||||||
package cn.odboy.config.webConfig;
|
package cn.odboy.server;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.web.servlet.MultipartConfigFactory;
|
import org.springframework.boot.web.servlet.MultipartConfigFactory;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -8,20 +10,23 @@ import javax.servlet.MultipartConfigElement;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class MultipartConfig {
|
public class MultipartConfig {
|
||||||
|
@Value("${spring.application.name}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传临时路径
|
* 文件上传临时路径
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
MultipartConfigElement multipartConfigElement() {
|
public MultipartConfigElement multipartConfigElement() {
|
||||||
MultipartConfigFactory factory = new MultipartConfigFactory();
|
MultipartConfigFactory factory = new MultipartConfigFactory();
|
||||||
String location = System.getProperty("user.home") + "/.eladmin/file/tmp";
|
String location = System.getProperty("user.home") + "/." + name + "/tmp";
|
||||||
File tmpFile = new File(location);
|
File tmpFile = new File(location);
|
||||||
if (!tmpFile.exists()) {
|
if (!tmpFile.exists()) {
|
||||||
if (!tmpFile.mkdirs()) {
|
if (!tmpFile.mkdirs()) {
|
||||||
System.out.println("create was not successful.");
|
log.error("创建临时文件失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
factory.setLocation(location);
|
factory.setLocation(location);
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config.webConfig;
|
package cn.odboy.server;
|
||||||
|
|
||||||
import cn.odboy.util.AnonTagUtil;
|
import cn.odboy.util.AnonTagUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -64,8 +64,8 @@ public class SwaggerConfig {
|
|||||||
private ApiInfo apiInfo() {
|
private ApiInfo apiInfo() {
|
||||||
return new ApiInfoBuilder()
|
return new ApiInfoBuilder()
|
||||||
.description("一个简单且易上手的 Spring boot 后台管理框架")
|
.description("一个简单且易上手的 Spring boot 后台管理框架")
|
||||||
.title("ELADMIN 接口文档")
|
.title("CuteJava 接口文档")
|
||||||
.version("1.6")
|
.version("1.3.0")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
+16
-10
@@ -1,5 +1,6 @@
|
|||||||
package cn.odboy.config;
|
package cn.odboy.thread;
|
||||||
|
|
||||||
|
import com.alibaba.ttl.TtlRunnable;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -53,7 +54,7 @@ public class AsyncExecutor implements AsyncConfigurer {
|
|||||||
@Override
|
@Override
|
||||||
public Executor getAsyncExecutor() {
|
public Executor getAsyncExecutor() {
|
||||||
// 自定义工厂
|
// 自定义工厂
|
||||||
ThreadFactory factory = r -> new Thread(r, "el-async-" + new AtomicInteger(1).getAndIncrement());
|
ThreadFactory factory = r -> new Thread(r, "default-async-" + new AtomicInteger(1).getAndIncrement());
|
||||||
// 自定义线程池
|
// 自定义线程池
|
||||||
return new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveSeconds,
|
return new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveSeconds,
|
||||||
TimeUnit.SECONDS, new ArrayBlockingQueue<>(queueCapacity), factory,
|
TimeUnit.SECONDS, new ArrayBlockingQueue<>(queueCapacity), factory,
|
||||||
@@ -63,18 +64,23 @@ public class AsyncExecutor implements AsyncConfigurer {
|
|||||||
/**
|
/**
|
||||||
* 自定义线程池,用法,注入到类中使用
|
* 自定义线程池,用法,注入到类中使用
|
||||||
* private ThreadPoolTaskExecutor taskExecutor;
|
* private ThreadPoolTaskExecutor taskExecutor;
|
||||||
*
|
|
||||||
* @return ThreadPoolTaskExecutor
|
|
||||||
*/
|
*/
|
||||||
@Bean("taskAsync")
|
@Bean("taskAsync")
|
||||||
public ThreadPoolTaskExecutor taskAsync() {
|
public ThreadPoolTaskExecutor taskAsync() {
|
||||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||||
executor.setCorePoolSize(2);
|
executor.setCorePoolSize(AsyncExecutor.corePoolSize);
|
||||||
executor.setMaxPoolSize(4);
|
executor.setMaxPoolSize(AsyncExecutor.maxPoolSize);
|
||||||
executor.setQueueCapacity(20);
|
executor.setQueueCapacity(AsyncExecutor.queueCapacity);
|
||||||
executor.setKeepAliveSeconds(60);
|
executor.setThreadNamePrefix("task-async-");
|
||||||
executor.setThreadNamePrefix("el-task-");
|
executor.setKeepAliveSeconds(AsyncExecutor.keepAliveSeconds);
|
||||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
// DiscardOldestPolicy,抛弃最早的任务,将新任务加入队列。
|
||||||
|
// AbortPolicy,拒绝执行新任务,并抛出异常。
|
||||||
|
// CallerRunsPolicy,交由调用者线程执行新任务,如果调用者线程已关闭,则抛弃任务。
|
||||||
|
// DiscardPolicy,直接抛弃新任务。
|
||||||
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
|
||||||
|
// 设置包装器
|
||||||
|
executor.setTaskDecorator(TtlRunnable::get);
|
||||||
|
executor.initialize();
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.util;
|
||||||
|
|
||||||
import cn.odboy.annotation.rest.AnonymousAccess;
|
import cn.odboy.annotation.AnonymousAccess;
|
||||||
import cn.odboy.constant.RequestMethodEnum;
|
import cn.odboy.constant.RequestMethodEnum;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.codec.Base64Encoder;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密令牌生成工具
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2022-11-16
|
||||||
|
*/
|
||||||
|
public class Base64SecretUtil {
|
||||||
|
private Base64SecretUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String build() {
|
||||||
|
// 128位uuid
|
||||||
|
return Base64Encoder.encode(getLongUuid(4).getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLongUuid(int bit) {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
for (int i = 0; i < bit; i++) {
|
||||||
|
result.append(IdUtil.simpleUUID());
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(build());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import cn.odboy.base.MyMetaOption;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 集合工具
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2022-11-09
|
||||||
|
*/
|
||||||
|
public class CollUtil extends cn.hutool.core.collection.CollUtil {
|
||||||
|
/**
|
||||||
|
* 连接器
|
||||||
|
*/
|
||||||
|
private static final Joiner JOINER = Joiner.on(",").skipNulls();
|
||||||
|
/**
|
||||||
|
* 分割器
|
||||||
|
*/
|
||||||
|
private static final Splitter SPLITTER = Splitter.on(",").trimResults().omitEmptyStrings();
|
||||||
|
|
||||||
|
public static String join(Object[] parts) {
|
||||||
|
return JOINER.join(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String join(Iterable<?> parts) {
|
||||||
|
return JOINER.join(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String join(Iterator<?> parts) {
|
||||||
|
return JOINER.join(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> splitToList(String parts) {
|
||||||
|
return SPLITTER.splitToList(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分几份
|
||||||
|
*
|
||||||
|
* @param parts /
|
||||||
|
* @param size /
|
||||||
|
* @param <T> /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T> List<List<T>> splitToSize(List<T> parts, int size) {
|
||||||
|
return Lists.partition(parts, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一份几个
|
||||||
|
*
|
||||||
|
* @param parts /
|
||||||
|
* @param groupNum /
|
||||||
|
* @param <T> /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T> List<List<T>> splitToSegment(List<T> parts, int groupNum) {
|
||||||
|
List<List<T>> result = new ArrayList<>(1);
|
||||||
|
int i = 0;
|
||||||
|
for (; i < parts.size() / groupNum; i++) {
|
||||||
|
result.add(parts.subList(i * groupNum, (i + 1) * groupNum));
|
||||||
|
}
|
||||||
|
if (parts.size() % groupNum != 0) {
|
||||||
|
result.add(parts.subList(i * groupNum, i * groupNum + parts.size() % groupNum));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T, K> Predicate<T> distinctPredicate(Function<? super T, ? extends K> keyMapper) {
|
||||||
|
Map<Object, Boolean> map = new HashMap<>();
|
||||||
|
return (t) -> null == map.putIfAbsent(keyMapper.apply(t), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流根据对象属性去重
|
||||||
|
* <p>
|
||||||
|
* 使用方式: list = CollUtil.streamDistinct(list, Object::getXXX)
|
||||||
|
*/
|
||||||
|
public static <T, K> List<T> streamDistinct(List<T> data, Function<? super T, ? extends K> keyMapper) {
|
||||||
|
return data.stream().filter(distinctPredicate(keyMapper)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流根据对象属性自然排序
|
||||||
|
* <p>
|
||||||
|
* 使用方式: list = CollUtil.streamAscSort(list, Object::getXXX)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @param keyExtractor /
|
||||||
|
* @param <T> /
|
||||||
|
* @param <U> /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T, U extends Comparable<? super U>> List<T> streamAscSort(List<T> data, Function<? super T, ? extends U> keyExtractor) {
|
||||||
|
return data.stream().sorted(Comparator.comparing(keyExtractor)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流根据对象属性倒转排序
|
||||||
|
* <p>
|
||||||
|
* 使用方式: list = CollUtil.streamDescSort(list, Object::getXXX)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @param keyExtractor /
|
||||||
|
* @param <T> /
|
||||||
|
* @param <U> /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T, U extends Comparable<? super U>> List<T> streamDescSort(List<T> data, Function<? super T, ? extends U> keyExtractor) {
|
||||||
|
return data.stream().sorted(Comparator.comparing(keyExtractor).reversed()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流拆分对象为键值对
|
||||||
|
* <p>
|
||||||
|
* 使用方式: map = CollUtil.streamToMap(list, Object::getXXKey, Object::getXXValue)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @param keyMapper /
|
||||||
|
* @param valueMapper /
|
||||||
|
* @param <T> /
|
||||||
|
* @param <K> /
|
||||||
|
* @param <U> /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T, K, U> Map<K, U> streamToMap(List<T> data, Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) {
|
||||||
|
// 根据key去重再并流
|
||||||
|
return streamDistinct(data, keyMapper).stream().collect(Collectors.toMap(keyMapper, valueMapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流对List<Double>求和
|
||||||
|
* <p>
|
||||||
|
* 使用方式: total = CollUtil.streamDoubleAdd(doubleList)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static Double streamDoubleAdd(List<Double> data) {
|
||||||
|
if (CollUtil.isNotEmpty(data)) {
|
||||||
|
return data.stream().filter(Objects::nonNull).reduce(Double::sum).orElse(0.0);
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流对List<BigDecimal>求和
|
||||||
|
* <p>
|
||||||
|
* 使用方式: total = CollUtil.streamBigDecimalAdd(doubleList)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static BigDecimal streamBigDecimalAdd(List<BigDecimal> data) {
|
||||||
|
if (CollUtil.isNotEmpty(data)) {
|
||||||
|
return data.stream().filter(Objects::nonNull).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流对List<Object>中的某一BigDecimal属性求和
|
||||||
|
* <p>
|
||||||
|
* 使用方式: total = CollUtil.streamBigDecimalAdd(list, XXX)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T> BigDecimal streamBigDecimalAdd(List<T> data, String elementName) {
|
||||||
|
return data.stream().filter(Objects::nonNull).map(m -> {
|
||||||
|
// 反射, 取集合中各元素的某属性
|
||||||
|
BigDecimal that;
|
||||||
|
try {
|
||||||
|
Field field = m.getClass().getDeclaredField(elementName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
that = (BigDecimal) field.get(m);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 忽略异常
|
||||||
|
that = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流对List<BigDecimal>取最大值
|
||||||
|
* <p>
|
||||||
|
* 使用方式: max = CollUtil.streamBigDecimalMax(list)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static BigDecimal streamBigDecimalMax(List<BigDecimal> data) {
|
||||||
|
return data.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.reduce(BigDecimal::max)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流对List<BigDecimal>取最小值
|
||||||
|
* <p>
|
||||||
|
* 使用方式: max = CollUtil.streamBigDecimalMin(list)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static BigDecimal streamBigDecimalMin(List<BigDecimal> data) {
|
||||||
|
return data.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.reduce(BigDecimal::min)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流对List<BigDecimal>取平均值
|
||||||
|
* <p>
|
||||||
|
* 使用方式: avg = CollUtil.streamBigDecimalAvg(list)
|
||||||
|
*
|
||||||
|
* @param data /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static BigDecimal streamBigDecimalAvg(List<BigDecimal> data) {
|
||||||
|
return data.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
||||||
|
.divide(BigDecimal.valueOf(data.size()), 6, RoundingMode.FLOOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<MyMetaOption> testData = new ArrayList<>();
|
||||||
|
MyMetaOption selectOption1 = MyMetaOption.builder().label("苹果").value("apple").build();
|
||||||
|
MyMetaOption selectOption2 = MyMetaOption.builder().label("苹果").value("apple").build();
|
||||||
|
MyMetaOption selectOption3 = MyMetaOption.builder().label("香蕉").value("banana").build();
|
||||||
|
MyMetaOption selectOption4 = MyMetaOption.builder().label("猫").value("cat").build();
|
||||||
|
testData.add(selectOption1);
|
||||||
|
testData.add(selectOption2);
|
||||||
|
testData.add(selectOption3);
|
||||||
|
testData.add(selectOption4);
|
||||||
|
List<MyMetaOption> selectOptions1 = CollUtil.streamAscSort(testData, MyMetaOption::getValue);
|
||||||
|
System.out.println(JSON.toJSONString(selectOptions1));
|
||||||
|
List<MyMetaOption> selectOptions2 = CollUtil.streamDescSort(testData, MyMetaOption::getValue);
|
||||||
|
System.out.println(JSON.toJSONString(selectOptions2));
|
||||||
|
List<MyMetaOption> selectOptions3 = CollUtil.streamDistinct(testData, MyMetaOption::getValue);
|
||||||
|
System.out.println(JSON.toJSONString(selectOptions3));
|
||||||
|
Map<String, String> selectMap1 = CollUtil.streamToMap(testData, MyMetaOption::getValue, MyMetaOption::getLabel);
|
||||||
|
System.out.println(JSON.toJSONString(selectMap1));
|
||||||
|
// 这只是一个示范
|
||||||
|
BigDecimal total1 = CollUtil.streamBigDecimalAdd(testData, "value");
|
||||||
|
System.out.println(total1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Json工具
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2024-10-01
|
||||||
|
*/
|
||||||
|
public class JsonUtil {
|
||||||
|
public static <K, V> Map<K, V> toMap(String jsonStr, Class<K> kClass, Class<V> vClass) {
|
||||||
|
return JSON.parseObject(jsonStr, new TypeReference<Map<K, V>>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <V> List<V> toList(String jsonStr, Class<V> vClass) {
|
||||||
|
return JSON.parseObject(jsonStr, new TypeReference<List<V>>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String mapStr = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
|
||||||
|
System.err.println(JsonUtil.toMap(mapStr, String.class, String.class));
|
||||||
|
String listStr = "[\"value1\", \"value2\"]";
|
||||||
|
System.err.println(JsonUtil.toList(listStr, String.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.odboy.base.MyEntity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List 工具
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2024-10-01
|
||||||
|
*/
|
||||||
|
public class ListUtil {
|
||||||
|
/**
|
||||||
|
* 根据对象T的属性去重
|
||||||
|
*
|
||||||
|
* @param items 对象T集合
|
||||||
|
* @param classifier 对象T属性表达式, 比如: User::getName
|
||||||
|
*/
|
||||||
|
public static <T, K> List<T> distinctByArgs(List<T> items, Function<? super T, ? extends K> classifier) {
|
||||||
|
return items.stream()
|
||||||
|
.collect(Collectors.groupingBy(classifier))
|
||||||
|
.values().stream()
|
||||||
|
.map(monitorItem -> monitorItem.iterator().next())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list转map,保留新值 -> Map<String, User> userMap = items.stream().collect(Collectors.toMap(User::getName, user -> user)) <br>
|
||||||
|
* list转map,保留旧值 -> Map<String, User> userMap = users.stream().collect(Collectors.toMap(User::getName, user -> user, (existing, replacement) -> existing));
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<MyEntity> entities = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 50; i++) {
|
||||||
|
MyEntity entity = new MyEntity();
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
entity.setCreateBy("odboy");
|
||||||
|
} else {
|
||||||
|
entity.setCreateBy("admin");
|
||||||
|
}
|
||||||
|
entity.setUpdateBy("admin");
|
||||||
|
entity.setCreateTime(DateTime.now().toTimestamp());
|
||||||
|
entity.setUpdateTime(DateTime.now().toTimestamp());
|
||||||
|
entities.add(entity);
|
||||||
|
}
|
||||||
|
List<MyEntity> entities1 = ListUtil.distinctByArgs(entities, MyEntity::getCreateBy);
|
||||||
|
System.err.println(entities1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import cn.odboy.base.PageResult;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.hutool.script.ScriptRuntimeException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.script.*;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脚本工具
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2023-12-05
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ScriptUtil {
|
||||||
|
private static final String FUNCTION_TAG = "function";
|
||||||
|
private final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param script 函数表达式
|
||||||
|
* @return 返回值
|
||||||
|
*/
|
||||||
|
public Object evalObj(String script, Object compareObj) {
|
||||||
|
try {
|
||||||
|
if (script.contains(FUNCTION_TAG)) {
|
||||||
|
throw new RuntimeException("script格式异常");
|
||||||
|
}
|
||||||
|
// 构建一个不同的脚本上下文
|
||||||
|
ScriptContext newContext = new SimpleScriptContext();
|
||||||
|
if (compareObj != null) {
|
||||||
|
Field[] fields = ReflectUtil.getFields(compareObj.getClass());
|
||||||
|
Map<String, Object> filedNameValueMap = new HashMap<>();
|
||||||
|
Arrays.stream(fields).parallel().forEach(f -> filedNameValueMap.put(f.getName(), ReflectUtil.getFieldValue(compareObj, f)));
|
||||||
|
Set<Map.Entry<String, Object>> entries = filedNameValueMap.entrySet();
|
||||||
|
long count = entries.stream().filter(f -> f.getValue() != null).count();
|
||||||
|
if (count == 0) {
|
||||||
|
throw new RuntimeException("比较对象中没有有效值");
|
||||||
|
}
|
||||||
|
Bindings engineScope = engine.createBindings();
|
||||||
|
entries.forEach(f -> {
|
||||||
|
// 在新的执行引擎作用域中添加与上面相同名称的变量
|
||||||
|
engineScope.put(f.getKey(), f.getValue());
|
||||||
|
});
|
||||||
|
newContext.setBindings(engineScope, ScriptContext.ENGINE_SCOPE);
|
||||||
|
}
|
||||||
|
if (script.contains(FUNCTION_TAG)) {
|
||||||
|
// 由ScriptEngines实现的接口, 其方法允许调用以前已执行的脚本中的过程
|
||||||
|
Invocable inv = (Invocable) engine;
|
||||||
|
// 调用全局函数, 并传入参数
|
||||||
|
inv.invokeFunction("hello", "测试");
|
||||||
|
}
|
||||||
|
// 执行脚本, 注意这里指定新的执行作用域上下文
|
||||||
|
return engine.eval(script, newContext);
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
throw new ScriptRuntimeException(e);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new ScriptRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param script 函数表达式, 例如: function hello(name) { print('Hello, ' + name); }
|
||||||
|
* @param functionName 函数名称, 例如: "hello"
|
||||||
|
* @param args 函数参数, 例如: "小明"
|
||||||
|
* @return 返回值
|
||||||
|
*/
|
||||||
|
public Object evalFunction(String script, String functionName, Object... args) {
|
||||||
|
if (!script.contains(FUNCTION_TAG)) {
|
||||||
|
throw new RuntimeException("script格式异常");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 执行脚本
|
||||||
|
engine.eval(script);
|
||||||
|
// 由ScriptEngines实现的接口,其方法允许调用以前已执行的脚本中的过程。
|
||||||
|
Invocable inv = (Invocable) engine;
|
||||||
|
// 调用全局函数,并传入参数
|
||||||
|
return inv.invokeFunction(functionName, args);
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
throw new ScriptRuntimeException(e);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new ScriptRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.jwt.JWT;
|
import cn.hutool.jwt.JWT;
|
||||||
import cn.hutool.jwt.JWTUtil;
|
import cn.hutool.jwt.JWTUtil;
|
||||||
import cn.odboy.constant.DataScopeEnum;
|
import cn.odboy.constant.DataScopeEnum;
|
||||||
|
import cn.odboy.context.SpringBeanHolder;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
|||||||
@@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import cn.odboy.mybatis.constant.DataTypeEnum;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author /
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SqlUtil {
|
||||||
|
/**
|
||||||
|
* 获取数据源
|
||||||
|
*
|
||||||
|
* @param jdbcUrl /
|
||||||
|
* @param userName /
|
||||||
|
* @param password /
|
||||||
|
* @return DataSource
|
||||||
|
*/
|
||||||
|
private static DataSource getDataSource(String jdbcUrl, String userName, String password) {
|
||||||
|
HikariDataSource druidDataSource = new HikariDataSource();
|
||||||
|
String className;
|
||||||
|
try {
|
||||||
|
className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("Get class name error: =" + jdbcUrl);
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(className)) {
|
||||||
|
DataTypeEnum dataTypeEnum = DataTypeEnum.urlOf(jdbcUrl);
|
||||||
|
if (null == dataTypeEnum) {
|
||||||
|
throw new RuntimeException("Not supported data type: jdbcUrl=" + jdbcUrl);
|
||||||
|
}
|
||||||
|
druidDataSource.setDriverClassName(dataTypeEnum.getDriver());
|
||||||
|
} else {
|
||||||
|
druidDataSource.setDriverClassName(className);
|
||||||
|
}
|
||||||
|
druidDataSource.setJdbcUrl(jdbcUrl);
|
||||||
|
druidDataSource.setUsername(userName);
|
||||||
|
druidDataSource.setPassword(password);
|
||||||
|
druidDataSource.setConnectionTimeout(3000);
|
||||||
|
return druidDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Connection getConnection(String jdbcUrl, String userName, String password) {
|
||||||
|
DataSource dataSource = getDataSource(jdbcUrl, userName, password);
|
||||||
|
Connection connection = null;
|
||||||
|
try {
|
||||||
|
connection = dataSource.getConnection();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int timeOut = 5;
|
||||||
|
if (null == connection || connection.isClosed() || !connection.isValid(timeOut)) {
|
||||||
|
log.info("connection is closed or invalid, retry get connection!");
|
||||||
|
connection = dataSource.getConnection();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("create connection error, jdbcUrl: {}", jdbcUrl);
|
||||||
|
throw new RuntimeException("create connection error, jdbcUrl: " + jdbcUrl);
|
||||||
|
} finally {
|
||||||
|
CloseUtil.close(connection);
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void releaseConnection(Connection connection) {
|
||||||
|
if (null != connection) {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
log.error("connection close error:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean testConnection(String jdbcUrl, String userName, String password) {
|
||||||
|
Connection connection = null;
|
||||||
|
try {
|
||||||
|
connection = getConnection(jdbcUrl, userName, password);
|
||||||
|
if (null != connection) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("Get connection failed:" + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
releaseConnection(connection);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String executeFile(String jdbcUrl, String userName, String password, File sqlFile) {
|
||||||
|
Connection connection = getConnection(jdbcUrl, userName, password);
|
||||||
|
try {
|
||||||
|
batchExecute(connection, readSqlList(sqlFile));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("sql脚本执行发生异常:{}", e.getMessage());
|
||||||
|
return e.getMessage();
|
||||||
|
} finally {
|
||||||
|
releaseConnection(connection);
|
||||||
|
}
|
||||||
|
return "success";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量执行sql
|
||||||
|
*
|
||||||
|
* @param connection /
|
||||||
|
* @param sqlList /
|
||||||
|
*/
|
||||||
|
public static void batchExecute(Connection connection, List<String> sqlList) {
|
||||||
|
Statement st = null;
|
||||||
|
try {
|
||||||
|
st = connection.createStatement();
|
||||||
|
for (String sql : sqlList) {
|
||||||
|
if (sql.endsWith(";")) {
|
||||||
|
sql = sql.substring(0, sql.length() - 1);
|
||||||
|
}
|
||||||
|
st.addBatch(sql);
|
||||||
|
}
|
||||||
|
st.executeBatch();
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
CloseUtil.close(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将文件中的sql语句以;为单位读取到列表中
|
||||||
|
*
|
||||||
|
* @param sqlFile /
|
||||||
|
* @return /
|
||||||
|
* @throws Exception e
|
||||||
|
*/
|
||||||
|
private static List<String> readSqlList(File sqlFile) throws Exception {
|
||||||
|
List<String> sqlList = Lists.newArrayList();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||||
|
Files.newInputStream(sqlFile.toPath()), StandardCharsets.UTF_8))) {
|
||||||
|
String tmp;
|
||||||
|
while ((tmp = reader.readLine()) != null) {
|
||||||
|
log.info("line:{}", tmp);
|
||||||
|
if (tmp.endsWith(";")) {
|
||||||
|
sb.append(tmp);
|
||||||
|
sqlList.add(sb.toString());
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
} else {
|
||||||
|
sb.append(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!"".endsWith(sb.toString().trim())) {
|
||||||
|
sqlList.add(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sqlList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package cn.odboy.util;
|
|||||||
|
|
||||||
import cn.hutool.http.useragent.UserAgent;
|
import cn.hutool.http.useragent.UserAgent;
|
||||||
import cn.hutool.http.useragent.UserAgentUtil;
|
import cn.hutool.http.useragent.UserAgentUtil;
|
||||||
|
import cn.odboy.context.SpringBeanHolder;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
|
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
|
||||||
import net.dreamlu.mica.ip2region.core.IpInfo;
|
import net.dreamlu.mica.ip2region.core.IpInfo;
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021-2025 Tian Jun
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.util;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import javax.validation.groups.Default;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean验证工具
|
||||||
|
*
|
||||||
|
* @author odboy
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
public class ValidationUtil {
|
||||||
|
private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();
|
||||||
|
|
||||||
|
public static <T> void validate(T object) {
|
||||||
|
Set<ConstraintViolation<T>> violations = VALIDATOR.validate(object, Default.class);
|
||||||
|
if (!violations.isEmpty()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (ConstraintViolation<T> violation : violations) {
|
||||||
|
sb.append(violation.getMessage()).append(", ");
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.config.webConfig;
|
package cn.odboy.websocket;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.websocket;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ZhangHouYing
|
||||||
|
* @date 2019-08-10 9:55
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WebSocketMsg {
|
||||||
|
private String msg;
|
||||||
|
private WebSocketMsgTypeEnum msgType;
|
||||||
|
|
||||||
|
public WebSocketMsg(String msg, WebSocketMsgTypeEnum msgType) {
|
||||||
|
this.msg = msg;
|
||||||
|
this.msgType = msgType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.websocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ZhangHouYing
|
||||||
|
* @date 2019-08-10 9:56
|
||||||
|
*/
|
||||||
|
public enum WebSocketMsgTypeEnum {
|
||||||
|
/**
|
||||||
|
* 连接
|
||||||
|
*/
|
||||||
|
CONNECT,
|
||||||
|
/**
|
||||||
|
* 关闭
|
||||||
|
*/
|
||||||
|
CLOSE,
|
||||||
|
/**
|
||||||
|
* 信息
|
||||||
|
*/
|
||||||
|
INFO,
|
||||||
|
/**
|
||||||
|
* 错误
|
||||||
|
*/
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.odboy.websocket;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.websocket.*;
|
||||||
|
import javax.websocket.server.PathParam;
|
||||||
|
import javax.websocket.server.ServerEndpoint;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ZhangHouYing
|
||||||
|
* @date 2019-08-10 15:46
|
||||||
|
*/
|
||||||
|
@ServerEndpoint("/webSocket/{sid}")
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class WebSocketServer {
|
||||||
|
/**
|
||||||
|
* concurrent包的线程安全Map,用来存放每个客户端对应的MyWebSocket对象。(分布式必出问题)
|
||||||
|
*/
|
||||||
|
private static final Map<String, WebSocketServer> CLIENT = new ConcurrentHashMap<>();
|
||||||
|
/**
|
||||||
|
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
|
||||||
|
*/
|
||||||
|
private Session session;
|
||||||
|
/**
|
||||||
|
* 接收sid
|
||||||
|
*/
|
||||||
|
private String sid = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接建立成功调用的方法
|
||||||
|
*/
|
||||||
|
@OnOpen
|
||||||
|
public void onOpen(Session session, @PathParam("sid") String sid) {
|
||||||
|
this.session = session;
|
||||||
|
// 如果存在就先删除一个,防止重复推送消息
|
||||||
|
CLIENT.remove(sid);
|
||||||
|
CLIENT.put(sid, this);
|
||||||
|
this.sid = sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接关闭调用的方法
|
||||||
|
*/
|
||||||
|
@OnClose
|
||||||
|
public void onClose() {
|
||||||
|
CLIENT.remove(this.sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到客户端消息后调用的方法
|
||||||
|
*
|
||||||
|
* @param message 客户端发送过来的消息
|
||||||
|
*/
|
||||||
|
@OnMessage
|
||||||
|
public void onMessage(String message, Session session) {
|
||||||
|
log.info("收到来{}的信息:{}", sid, message);
|
||||||
|
sendToAll(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发消息
|
||||||
|
*
|
||||||
|
* @param message /
|
||||||
|
*/
|
||||||
|
private static void sendToAll(String message) {
|
||||||
|
//
|
||||||
|
for (WebSocketServer item : CLIENT.values()) {
|
||||||
|
try {
|
||||||
|
item.sendMessage(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("发送消息给{}失败", item.sid, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnError
|
||||||
|
public void onError(Session session, Throwable error) {
|
||||||
|
log.error("发生错误");
|
||||||
|
error.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现服务器主动推送
|
||||||
|
*/
|
||||||
|
private void sendMessage(String message) throws IOException {
|
||||||
|
this.session.getBasicRemote().sendText(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发自定义消息
|
||||||
|
*/
|
||||||
|
public static void sendInfo(WebSocketMsg webSocketMsg, @PathParam("sid") String sid) throws IOException {
|
||||||
|
String message = JSON.toJSONString(webSocketMsg);
|
||||||
|
log.info("推送消息到{},推送内容:{}", sid, message);
|
||||||
|
try {
|
||||||
|
if (sid == null) {
|
||||||
|
sendToAll(message);
|
||||||
|
} else {
|
||||||
|
CLIENT.get(sid).sendMessage(message);
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
WebSocketServer that = (WebSocketServer) o;
|
||||||
|
return Objects.equals(session, that.session) &&
|
||||||
|
Objects.equals(sid, that.sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(session, sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package cn.odboy.websocket;
|
||||||
|
|
||||||
|
import io.undertow.server.DefaultByteBufferPool;
|
||||||
|
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
||||||
|
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||||
|
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解决启动io.undertow.websockets.jsr UT026010: Buffer pool was not
|
||||||
|
* set on WebSocketDeploymentInfo, the default pool will be used的警告
|
||||||
|
*
|
||||||
|
* @date 2024-06-07
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class WebSocketServerFactory implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(UndertowServletWebServerFactory factory) {
|
||||||
|
factory.addDeploymentInfoCustomizers(deploymentInfo -> {
|
||||||
|
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
|
||||||
|
webSocketDeploymentInfo.setBuffers(
|
||||||
|
new DefaultByteBufferPool(false, 1024)
|
||||||
|
// new DefaultByteBufferPool(false, 1024,20,4)
|
||||||
|
);
|
||||||
|
deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>cutejava</artifactId>
|
||||||
|
<groupId>cn.odboy</groupId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<properties>
|
||||||
|
<hutool.version>5.8.36</hutool.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<artifactId>cutejava-domain</artifactId>
|
||||||
|
<name>模型模块</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.odboy</groupId>
|
||||||
|
<artifactId>cutejava-common</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.domain;
|
package cn.odboy.model.job.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@@ -16,11 +16,11 @@ import javax.validation.constraints.NotNull;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_quartz_job")
|
@TableName("sys_quartz_job")
|
||||||
public class QuartzJob extends BaseEntity {
|
public class QuartzJob extends MyEntity {
|
||||||
|
|
||||||
public static final String JOB_KEY = "JOB_KEY";
|
public static final String JOB_KEY = "JOB_KEY";
|
||||||
|
|
||||||
@TableId(value = "job_id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
@NotNull(groups = {Update.class})
|
@NotNull(groups = {Update.class})
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain;
|
package cn.odboy.model.job.domain;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
@@ -15,7 +15,7 @@ public class QuartzLog extends MyObject {
|
|||||||
|
|
||||||
@TableId(value = "log_id", type = IdType.AUTO)
|
@TableId(value = "log_id", type = IdType.AUTO)
|
||||||
@ApiModelProperty(value = "ID", hidden = true)
|
@ApiModelProperty(value = "ID", hidden = true)
|
||||||
private Long id;
|
private Long logId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务名称", hidden = true)
|
@ApiModelProperty(value = "任务名称", hidden = true)
|
||||||
private String jobName;
|
private String jobName;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain.dto;
|
package cn.odboy.model.job.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
@@ -19,7 +19,7 @@ import java.util.Set;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_dept")
|
@TableName("sys_dept")
|
||||||
public class Dept extends BaseEntity {
|
public class Dept extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = Update.class)
|
@NotNull(groups = Update.class)
|
||||||
@TableId(value = "dept_id", type = IdType.AUTO)
|
@TableId(value = "dept_id", type = IdType.AUTO)
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@@ -15,7 +15,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_dict")
|
@TableName("sys_dict")
|
||||||
public class Dict extends BaseEntity {
|
public class Dict extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = Update.class)
|
@NotNull(groups = Update.class)
|
||||||
@ApiModelProperty(value = "ID", hidden = true)
|
@ApiModelProperty(value = "ID", hidden = true)
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@@ -14,7 +14,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_dict_detail")
|
@TableName("sys_dict_detail")
|
||||||
public class DictDetail extends BaseEntity {
|
public class DictDetail extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = Update.class)
|
@NotNull(groups = Update.class)
|
||||||
@ApiModelProperty(value = "ID", hidden = true)
|
@ApiModelProperty(value = "ID", hidden = true)
|
||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@@ -16,10 +16,10 @@ import java.util.Objects;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_job")
|
@TableName("sys_job")
|
||||||
public class Job extends BaseEntity {
|
public class Job extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = Update.class)
|
@NotNull(groups = Update.class)
|
||||||
@TableId(value = "job_id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
@ApiModelProperty(value = "ID", hidden = true)
|
@ApiModelProperty(value = "ID", hidden = true)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
@@ -18,7 +18,7 @@ import java.util.Set;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_menu")
|
@TableName("sys_menu")
|
||||||
public class Menu extends BaseEntity {
|
public class Menu extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = {Update.class})
|
@NotNull(groups = {Update.class})
|
||||||
@TableId(value = "menu_id", type = IdType.AUTO)
|
@TableId(value = "menu_id", type = IdType.AUTO)
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import cn.odboy.constant.DataScopeEnum;
|
import cn.odboy.constant.DataScopeEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
@@ -21,7 +21,7 @@ import java.util.Set;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_role")
|
@TableName("sys_role")
|
||||||
public class Role extends BaseEntity {
|
public class Role extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = {Update.class})
|
@NotNull(groups = {Update.class})
|
||||||
@TableId(value = "role_id", type = IdType.AUTO)
|
@TableId(value = "role_id", type = IdType.AUTO)
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.system.domain;
|
package cn.odboy.model.system.domain;
|
||||||
|
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@@ -19,7 +19,7 @@ import java.util.Set;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@TableName("sys_user")
|
@TableName("sys_user")
|
||||||
public class User extends BaseEntity {
|
public class User extends MyEntity {
|
||||||
|
|
||||||
@NotNull(groups = Update.class)
|
@NotNull(groups = Update.class)
|
||||||
@TableId(value = "user_id", type = IdType.AUTO)
|
@TableId(value = "user_id", type = IdType.AUTO)
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.security.service.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.security.service.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.modules.security.service.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import cn.odboy.modules.system.domain.User;
|
import cn.odboy.model.system.domain.User;
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.security.service.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.modules.system.domain.dto;
|
package cn.odboy.model.system.dto;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain;
|
package cn.odboy.model.tools.domain;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
package cn.odboy.domain;
|
package cn.odboy.model.tools.domain;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.bean.copier.CopyOptions;
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
import cn.odboy.base.BaseEntity;
|
import cn.odboy.base.MyEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@@ -15,7 +15,7 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@TableName("tool_local_storage")
|
@TableName("tool_local_storage")
|
||||||
public class LocalStorage extends BaseEntity {
|
public class LocalStorage extends MyEntity {
|
||||||
|
|
||||||
@TableId(value = "storage_id", type = IdType.AUTO)
|
@TableId(value = "storage_id", type = IdType.AUTO)
|
||||||
@ApiModelProperty(value = "ID", hidden = true)
|
@ApiModelProperty(value = "ID", hidden = true)
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain;
|
package cn.odboy.model.tools.domain;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain;
|
package cn.odboy.model.tools.domain;
|
||||||
|
|
||||||
import cn.odboy.base.MyObject;
|
import cn.odboy.base.MyObject;
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain.dto;
|
package cn.odboy.model.tools.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain.dto;
|
package cn.odboy.model.tools.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package cn.odboy.domain.dto;
|
package cn.odboy.model.tools.dto;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package cn.odboy.config;
|
package cn.odboy.config;
|
||||||
|
|
||||||
import cn.odboy.mapper.QuartzJobMapper;
|
import cn.odboy.mapper.QuartzJobMapper;
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
import cn.odboy.util.QuartzManage;
|
import cn.odboy.util.QuartzManage;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package cn.odboy.mapper;
|
package cn.odboy.mapper;
|
||||||
|
|
||||||
import cn.odboy.domain.dto.QuartzJobQueryCriteria;
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.model.job.dto.QuartzJobQueryCriteria;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package cn.odboy.mapper;
|
package cn.odboy.mapper;
|
||||||
|
|
||||||
import cn.odboy.domain.dto.QuartzJobQueryCriteria;
|
import cn.odboy.model.job.domain.QuartzLog;
|
||||||
import cn.odboy.domain.QuartzLog;
|
import cn.odboy.model.job.dto.QuartzJobQueryCriteria;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package cn.odboy.rest;
|
package cn.odboy.rest;
|
||||||
|
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.base.PageResult;
|
||||||
import cn.odboy.domain.QuartzLog;
|
|
||||||
import cn.odboy.domain.dto.QuartzJobQueryCriteria;
|
|
||||||
import cn.odboy.exception.BadRequestException;
|
import cn.odboy.exception.BadRequestException;
|
||||||
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
|
import cn.odboy.model.job.domain.QuartzLog;
|
||||||
|
import cn.odboy.model.job.dto.QuartzJobQueryCriteria;
|
||||||
import cn.odboy.service.QuartzJobService;
|
import cn.odboy.service.QuartzJobService;
|
||||||
import cn.odboy.util.PageResult;
|
import cn.odboy.context.SpringBeanHolder;
|
||||||
import cn.odboy.util.SpringBeanHolder;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package cn.odboy.service;
|
package cn.odboy.service;
|
||||||
|
|
||||||
import cn.odboy.domain.dto.QuartzJobQueryCriteria;
|
import cn.odboy.base.PageResult;
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
import cn.odboy.domain.QuartzLog;
|
import cn.odboy.model.job.domain.QuartzLog;
|
||||||
import cn.odboy.util.PageResult;
|
import cn.odboy.model.job.dto.QuartzJobQueryCriteria;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ package cn.odboy.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.odboy.domain.dto.QuartzJobQueryCriteria;
|
import cn.odboy.base.PageResult;
|
||||||
import cn.odboy.exception.BadRequestException;
|
import cn.odboy.exception.BadRequestException;
|
||||||
import cn.odboy.mapper.QuartzJobMapper;
|
import cn.odboy.mapper.QuartzJobMapper;
|
||||||
import cn.odboy.mapper.QuartzLogMapper;
|
import cn.odboy.mapper.QuartzLogMapper;
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
import cn.odboy.domain.QuartzLog;
|
import cn.odboy.model.job.domain.QuartzLog;
|
||||||
|
import cn.odboy.model.job.dto.QuartzJobQueryCriteria;
|
||||||
import cn.odboy.service.QuartzJobService;
|
import cn.odboy.service.QuartzJobService;
|
||||||
import cn.odboy.util.*;
|
import cn.odboy.util.*;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|||||||
@@ -4,16 +4,14 @@ import cn.hutool.extra.template.Template;
|
|||||||
import cn.hutool.extra.template.TemplateConfig;
|
import cn.hutool.extra.template.TemplateConfig;
|
||||||
import cn.hutool.extra.template.TemplateEngine;
|
import cn.hutool.extra.template.TemplateEngine;
|
||||||
import cn.hutool.extra.template.TemplateUtil;
|
import cn.hutool.extra.template.TemplateUtil;
|
||||||
import cn.odboy.domain.dto.EmailDto;
|
import cn.odboy.context.SpringBeanHolder;
|
||||||
|
import cn.odboy.exception.util.ThrowableUtil;
|
||||||
import cn.odboy.mapper.QuartzLogMapper;
|
import cn.odboy.mapper.QuartzLogMapper;
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
import cn.odboy.domain.QuartzLog;
|
import cn.odboy.model.job.domain.QuartzLog;
|
||||||
import cn.odboy.service.QuartzJobService;
|
import cn.odboy.model.tools.dto.EmailDto;
|
||||||
import cn.odboy.service.EmailService;
|
import cn.odboy.service.EmailService;
|
||||||
import cn.odboy.util.RedisUtil;
|
import cn.odboy.service.QuartzJobService;
|
||||||
import cn.odboy.util.SpringBeanHolder;
|
|
||||||
import cn.odboy.util.StringUtil;
|
|
||||||
import cn.odboy.util.ThrowableUtil;
|
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -27,9 +25,7 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class ExecutionJob extends QuartzJobBean {
|
public class ExecutionJob extends QuartzJobBean {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
// 此处仅供参考,可根据任务执行情况自定义线程池参数
|
// 此处仅供参考,可根据任务执行情况自定义线程池参数
|
||||||
private final ThreadPoolTaskExecutor executor = SpringBeanHolder.getBean("taskAsync");
|
private final ThreadPoolTaskExecutor executor = SpringBeanHolder.getBean("taskAsync");
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.util;
|
||||||
|
|
||||||
import cn.odboy.exception.BadRequestException;
|
import cn.odboy.exception.BadRequestException;
|
||||||
import cn.odboy.domain.QuartzJob;
|
import cn.odboy.model.job.domain.QuartzJob;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
import org.quartz.impl.triggers.CronTriggerImpl;
|
import org.quartz.impl.triggers.CronTriggerImpl;
|
||||||
@@ -10,8 +10,6 @@ import org.springframework.stereotype.Component;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static org.quartz.TriggerBuilder.newTrigger;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class QuartzManage {
|
public class QuartzManage {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package cn.odboy.util;
|
package cn.odboy.util;
|
||||||
|
|
||||||
import cn.odboy.util.SpringBeanHolder;
|
import cn.odboy.context.SpringBeanHolder;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user