开始尝试进行业务化模板
This commit is contained in:
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -7,7 +7,7 @@
|
|||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
<outputRelativeToContentRoot value="true" />
|
<outputRelativeToContentRoot value="true" />
|
||||||
<module name="spring-boot-apijson-server" />
|
<module name="spring-boot-server-template" />
|
||||||
</profile>
|
</profile>
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
15
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
15
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="NullableProblems" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
|
||||||
|
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
|
||||||
|
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
|
||||||
|
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
|
||||||
|
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
|
||||||
|
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
|
||||||
|
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
|
||||||
|
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -2,7 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/spring-boot-apijson-server.iml" filepath="$PROJECT_DIR$/spring-boot-apijson-server.iml" />
|
<module fileurl="file://$PROJECT_DIR$/spring-boot-server-template.iml" filepath="$PROJECT_DIR$/spring-boot-server-template.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
<groupId>com.lanyuanxiaoyao</groupId>
|
||||||
<artifactId>spring-boot-apijson-server</artifactId>
|
<artifactId>spring-boot-server-template</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -48,6 +48,10 @@
|
|||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.lanyuanxiaoyao.server.configuration.amis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crud 响应
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @date 2023-07-06
|
||||||
|
*/
|
||||||
|
public class AmisItemResponse extends AmisMapResponse {
|
||||||
|
public void setDetail(Object detail) {
|
||||||
|
getData().put("item", detail);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.lanyuanxiaoyao.server.configuration.amis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crud 响应
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @date 2023-07-06
|
||||||
|
*/
|
||||||
|
public class AmisListResponse extends AmisMapResponse {
|
||||||
|
public void setData(Iterable<?> list) {
|
||||||
|
getData().put("items", list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Long total) {
|
||||||
|
getData().put("total", total);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Integer total) {
|
||||||
|
setTotal(total.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(Iterable<?> list, Long total) {
|
||||||
|
setData(list);
|
||||||
|
setTotal(total);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(Iterable<?> list, Integer total) {
|
||||||
|
setData(list, total.longValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.lanyuanxiaoyao.server.configuration.amis;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map 响应
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @date 2023-07-06
|
||||||
|
*/
|
||||||
|
public class AmisMapResponse extends AmisResponse<Map<String, Object>> {
|
||||||
|
public AmisMapResponse() {
|
||||||
|
setData(new HashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AmisMapResponse setData(String key, Object value) {
|
||||||
|
getData().put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.lanyuanxiaoyao.server.configuration.amis;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import java.util.Map;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amis 组件结构化返回值
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @date 2022-09-21
|
||||||
|
*/
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AmisResponse<T> {
|
||||||
|
private static final int SUCCESS_STATUS = 0;
|
||||||
|
private static final int ERROR_STATUS = 500;
|
||||||
|
private static final String SUCCESS_MESSAGE = "成功";
|
||||||
|
private static final String ERROR_MESSAGE = "错误";
|
||||||
|
private Integer status;
|
||||||
|
@JsonProperty("msg")
|
||||||
|
private String message;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static AmisResponse<Object> responseError() {
|
||||||
|
return responseError(ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisResponse<Object> responseError(String message) {
|
||||||
|
AmisResponse<Object> response = new AmisResponse<>();
|
||||||
|
response.setStatus(ERROR_STATUS);
|
||||||
|
response.setMessage(message);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisResponse<Object> responseSuccess() {
|
||||||
|
return responseSuccess(SUCCESS_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisResponse<Object> responseSuccess(String message) {
|
||||||
|
AmisResponse<Object> response = new AmisResponse<>();
|
||||||
|
response.setStatus(SUCCESS_STATUS);
|
||||||
|
response.setMessage(message);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <E> AmisResponse<E> responseSuccess(String message, E data) {
|
||||||
|
AmisResponse<E> response = new AmisResponse<>();
|
||||||
|
response.setStatus(SUCCESS_STATUS);
|
||||||
|
response.setMessage(message);
|
||||||
|
response.setData(data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <E> AmisResponse<E> responseSuccess(E data) {
|
||||||
|
return responseSuccess(SUCCESS_MESSAGE, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisMapResponse responseMapData() {
|
||||||
|
AmisMapResponse response = new AmisMapResponse();
|
||||||
|
response.setStatus(SUCCESS_STATUS);
|
||||||
|
response.setMessage(SUCCESS_MESSAGE);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisMapResponse responseMapData(Map<String, Object> data) {
|
||||||
|
AmisMapResponse response = responseMapData();
|
||||||
|
response.setData(data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisMapResponse responseMapData(String key, Object value) {
|
||||||
|
AmisMapResponse response = responseMapData();
|
||||||
|
response.setData(key, value);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisListResponse responseListData(Iterable<?> data) {
|
||||||
|
AmisListResponse response = new AmisListResponse();
|
||||||
|
response.setStatus(SUCCESS_STATUS);
|
||||||
|
response.setMessage(SUCCESS_MESSAGE);
|
||||||
|
response.setData(data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisListResponse responseListData(Iterable<?> data, Integer total) {
|
||||||
|
AmisListResponse response = responseListData(data);
|
||||||
|
response.setTotal(total);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisListResponse responseListData(Iterable<?> data, Long total) {
|
||||||
|
AmisListResponse response = responseListData(data);
|
||||||
|
response.setTotal(total);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AmisItemResponse responseItemData(Object detail) {
|
||||||
|
AmisItemResponse response = new AmisItemResponse();
|
||||||
|
response.setDetail(detail);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.lanyuanxiaoyao.server.configuration.database;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.Instant;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用雪花算法作为ID生成器
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @date 2024-11-14
|
||||||
|
*/
|
||||||
|
public class SnowflakeIdGenerator implements IdentifierGenerator {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SnowflakeIdGenerator.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable generate(SharedSessionContractImplementor session, Object object) {
|
||||||
|
try {
|
||||||
|
return Snowflake.next();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Generate snowflake id failed", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Snowflake {
|
||||||
|
/**
|
||||||
|
* 起始的时间戳
|
||||||
|
*/
|
||||||
|
private final static long START_TIMESTAMP = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列号占用的位数
|
||||||
|
*/
|
||||||
|
private final static long SEQUENCE_BIT = 11;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列号最大值
|
||||||
|
*/
|
||||||
|
private final static long MAX_SEQUENCE_BIT = ~(-1 << SEQUENCE_BIT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳值向左位移
|
||||||
|
*/
|
||||||
|
private final static long TIMESTAMP_OFFSET = SEQUENCE_BIT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列号
|
||||||
|
*/
|
||||||
|
private static long sequence = 0;
|
||||||
|
/**
|
||||||
|
* 上一次时间戳
|
||||||
|
*/
|
||||||
|
private static long lastTimestamp = -1;
|
||||||
|
|
||||||
|
public static synchronized long next() {
|
||||||
|
long currentTimestamp = nowTimestamp();
|
||||||
|
if (currentTimestamp < lastTimestamp) {
|
||||||
|
throw new RuntimeException("Clock have moved backwards.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTimestamp == lastTimestamp) {
|
||||||
|
// 相同毫秒内, 序列号自增
|
||||||
|
sequence = (sequence + 1) & MAX_SEQUENCE_BIT;
|
||||||
|
// 同一毫秒的序列数已经达到最大
|
||||||
|
if (sequence == 0) {
|
||||||
|
currentTimestamp = nextTimestamp();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 不同毫秒内, 序列号置为0
|
||||||
|
sequence = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTimestamp = currentTimestamp;
|
||||||
|
return (currentTimestamp - START_TIMESTAMP) << TIMESTAMP_OFFSET | sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long nextTimestamp() {
|
||||||
|
long milli = nowTimestamp();
|
||||||
|
while (milli <= lastTimestamp) {
|
||||||
|
milli = nowTimestamp();
|
||||||
|
}
|
||||||
|
return milli;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long nowTimestamp() {
|
||||||
|
return Instant.now().toEpochMilli();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.lanyuanxiaoyao.server.controller.base;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.server.configuration.amis.AmisResponse;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理错误信息
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @date 2024-01-02
|
||||||
|
*/
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class ErrorController {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(ErrorController.class);
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
@ExceptionHandler(Throwable.class)
|
||||||
|
public AmisResponse<Object> errorHandler(Throwable throwable) {
|
||||||
|
logger.error("Error", throwable);
|
||||||
|
return AmisResponse.responseError(throwable.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.server.entity;
|
|
||||||
|
|
||||||
import com.yahoo.elide.annotation.LifeCycleHookBinding;
|
|
||||||
import com.yahoo.elide.core.lifecycle.LifeCycleHook;
|
|
||||||
import com.yahoo.elide.core.security.ChangeSpec;
|
|
||||||
import com.yahoo.elide.core.security.RequestScope;
|
|
||||||
import java.util.Optional;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250304
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class LogicDeletedHook implements LifeCycleHook<User> {
|
|
||||||
@Override
|
|
||||||
public void execute(LifeCycleHookBinding.Operation operation, LifeCycleHookBinding.TransactionPhase phase, User user, RequestScope scope, Optional<ChangeSpec> changes) {
|
|
||||||
log.info("Operation: {}, Phase: {}, User: {}, Scope: {}, Changes: {}", operation, phase, user, scope, changes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.server.entity;
|
|
||||||
|
|
||||||
import com.yahoo.elide.annotation.Include;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.GenerationType;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.OneToMany;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.hibernate.annotations.DynamicUpdate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250304
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@Entity
|
|
||||||
@DynamicUpdate
|
|
||||||
@Include
|
|
||||||
public class School {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.UUID)
|
|
||||||
private String id;
|
|
||||||
@Column(nullable = false)
|
|
||||||
private String name;
|
|
||||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "school")
|
|
||||||
@ToString.Exclude
|
|
||||||
private List<User> users;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.server.entity;
|
|
||||||
|
|
||||||
import com.yahoo.elide.annotation.Include;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.ConstraintMode;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ForeignKey;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.GenerationType;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.hibernate.annotations.DynamicUpdate;
|
|
||||||
import org.hibernate.annotations.SoftDelete;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250304
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@Entity
|
|
||||||
@DynamicUpdate
|
|
||||||
@Include
|
|
||||||
@SoftDelete
|
|
||||||
public class User {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.UUID)
|
|
||||||
private String id;
|
|
||||||
@Column(unique = true, nullable = false)
|
|
||||||
private String username;
|
|
||||||
@Column(nullable = false)
|
|
||||||
private String password;
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
|
||||||
@ToString.Exclude
|
|
||||||
private School school;
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,18 @@
|
|||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:mysql://localhost:3307/main?useSSL=false&allowPublicKeyRetrieval=true
|
url: jdbc:h2:file:./database;DB_CLOSE_ON_EXIT=FALSE
|
||||||
username: test
|
username: test
|
||||||
password: test
|
password: test
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: org.h2.Driver
|
||||||
jpa:
|
jpa:
|
||||||
show-sql: true
|
show-sql: true
|
||||||
generate-ddl: true
|
generate-ddl: true
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 10MB
|
||||||
|
max-request-size: 20MB
|
||||||
|
jackson:
|
||||||
|
date-format: 'yyyy-MM-dd HH:mm:ss'
|
||||||
elide:
|
elide:
|
||||||
json-api:
|
json-api:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
Reference in New Issue
Block a user