Compare commits
5 Commits
511b519925
...
413f376a15
| Author | SHA1 | Date | |
|---|---|---|---|
| 413f376a15 | |||
| 7a52560779 | |||
| 75c8f556a8 | |||
| 7654c3a360 | |||
| 5239b469ac |
1
.gitignore
vendored
1
.gitignore
vendored
@ -57,3 +57,4 @@ dependency-reduced-pom.xml
|
|||||||
buildNumber.properties
|
buildNumber.properties
|
||||||
.mvn/timing.properties
|
.mvn/timing.properties
|
||||||
|
|
||||||
|
.claude
|
||||||
@ -353,7 +353,7 @@ public class TimiSpring {
|
|||||||
*
|
*
|
||||||
* @return 客户端地区语言
|
* @return 客户端地区语言
|
||||||
*/
|
*/
|
||||||
public static Language getLanguage() {
|
public static Language.Enum getLanguage() {
|
||||||
String name = getRequestArg("lang");
|
String name = getRequestArg("lang");
|
||||||
if (TimiJava.isEmpty(name)) {
|
if (TimiJava.isEmpty(name)) {
|
||||||
List<Locale.LanguageRange> rangeList = Locale.LanguageRange.parse(getLanguageRaw());
|
List<Locale.LanguageRange> rangeList = Locale.LanguageRange.parse(getLanguageRaw());
|
||||||
@ -368,9 +368,9 @@ public class TimiSpring {
|
|||||||
name = name.replace("-", "_");
|
name = name.replace("-", "_");
|
||||||
}
|
}
|
||||||
if (TimiJava.isEmpty(name)) { // use for not support
|
if (TimiJava.isEmpty(name)) { // use for not support
|
||||||
return Language.zh_CN;
|
return Language.Enum.zh_CN;
|
||||||
}
|
}
|
||||||
return Ref.toType(Language.class, name);
|
return Ref.toType(Language.Enum.class, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -13,12 +13,14 @@ import java.util.LinkedHashMap;
|
|||||||
* @author 夜雨
|
* @author 夜雨
|
||||||
* @version 2023-06-02 14:47
|
* @version 2023-06-02 14:47
|
||||||
*/
|
*/
|
||||||
public class Page extends BasePage {
|
public class Page<T> extends BasePage {
|
||||||
|
|
||||||
|
protected T equalsExample;
|
||||||
|
|
||||||
|
protected T likeExample;
|
||||||
|
|
||||||
protected LinkedHashMap<String, BaseMapper.OrderType> orderMap;
|
protected LinkedHashMap<String, BaseMapper.OrderType> orderMap;
|
||||||
|
|
||||||
protected LinkedHashMap<String, String> likeMap;
|
|
||||||
|
|
||||||
public Page() {
|
public Page() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,10 +32,26 @@ public class Page extends BasePage {
|
|||||||
return (long) index * size;
|
return (long) index * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLimit() {
|
public long getLimit() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T getEqualsExample() {
|
||||||
|
return equalsExample;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEqualsExample(T equalsExample) {
|
||||||
|
this.equalsExample = equalsExample;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getLikeExample() {
|
||||||
|
return likeExample;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLikeExample(T likeExample) {
|
||||||
|
this.likeExample = likeExample;
|
||||||
|
}
|
||||||
|
|
||||||
public LinkedHashMap<String, BaseMapper.OrderType> getOrderMap() {
|
public LinkedHashMap<String, BaseMapper.OrderType> getOrderMap() {
|
||||||
return orderMap;
|
return orderMap;
|
||||||
}
|
}
|
||||||
@ -46,12 +64,4 @@ public class Page extends BasePage {
|
|||||||
orderMap = TimiJava.firstNotNull(orderMap, new LinkedHashMap<>());
|
orderMap = TimiJava.firstNotNull(orderMap, new LinkedHashMap<>());
|
||||||
orderMap.put(Text.camelCase2underscore(field), orderType);
|
orderMap.put(Text.camelCase2underscore(field), orderType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedHashMap<String, String> getLikeMap() {
|
|
||||||
return likeMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLikeMap(LinkedHashMap<String, String> likeMap) {
|
|
||||||
this.likeMap = likeMap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public interface BaseMapper<T, P> {
|
|||||||
* @return 数据列表
|
* @return 数据列表
|
||||||
*/
|
*/
|
||||||
@SelectProvider(type = SQLProvider.class, method = "listByPage")
|
@SelectProvider(type = SQLProvider.class, method = "listByPage")
|
||||||
List<T> listByPage(Page page);
|
List<T> listByPage(Page<T> page);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据 Page 对象统计数据量
|
* 根据 Page 对象统计数据量
|
||||||
@ -56,7 +56,7 @@ public interface BaseMapper<T, P> {
|
|||||||
* @return 数据量
|
* @return 数据量
|
||||||
*/
|
*/
|
||||||
@SelectProvider(type = SQLProvider.class, method = "countByPage")
|
@SelectProvider(type = SQLProvider.class, method = "countByPage")
|
||||||
long countByPage(Page page);
|
long countByPage(Page<T> page);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询
|
* 分页查询
|
||||||
@ -64,7 +64,7 @@ public interface BaseMapper<T, P> {
|
|||||||
* @param page 分页参数
|
* @param page 分页参数
|
||||||
* @return 分页结果
|
* @return 分页结果
|
||||||
*/
|
*/
|
||||||
default PageResult<T> page(Page page) {
|
default PageResult<T> page(Page<T> page) {
|
||||||
PageResult<T> result = new PageResult<>();
|
PageResult<T> result = new PageResult<>();
|
||||||
result.setTotal(countByPage(page));
|
result.setTotal(countByPage(page));
|
||||||
result.setList(listByPage(page));
|
result.setList(listByPage(page));
|
||||||
|
|||||||
@ -3,6 +3,9 @@ package com.imyeyu.spring.service;
|
|||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.spring.bean.Page;
|
import com.imyeyu.spring.bean.Page;
|
||||||
import com.imyeyu.spring.bean.PageResult;
|
import com.imyeyu.spring.bean.PageResult;
|
||||||
|
import com.imyeyu.spring.entity.Creatable;
|
||||||
|
import com.imyeyu.spring.entity.Deletable;
|
||||||
|
import com.imyeyu.spring.entity.Updatable;
|
||||||
import com.imyeyu.spring.mapper.BaseMapper;
|
import com.imyeyu.spring.mapper.BaseMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,13 +33,19 @@ public abstract class AbstractEntityService<T, P> implements BaseService<T, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<T> page(Page page) {
|
public PageResult<T> page(Page<T> page) {
|
||||||
checkMapper();
|
checkMapper();
|
||||||
return baseMapper.page(page);
|
return baseMapper.page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(T t) {
|
public void create(T t) {
|
||||||
checkMapper();
|
checkMapper();
|
||||||
|
if (t instanceof Updatable updatable) {
|
||||||
|
updatable.setUpdatedAt(null);
|
||||||
|
}
|
||||||
|
if (t instanceof Deletable deletable) {
|
||||||
|
deletable.setDeletedAt(null);
|
||||||
|
}
|
||||||
baseMapper.insert(t);
|
baseMapper.insert(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +56,12 @@ public abstract class AbstractEntityService<T, P> implements BaseService<T, P> {
|
|||||||
|
|
||||||
public void update(T t) {
|
public void update(T t) {
|
||||||
checkMapper();
|
checkMapper();
|
||||||
|
if (t instanceof Creatable creatable) {
|
||||||
|
creatable.setCreatedAt(null);
|
||||||
|
}
|
||||||
|
if (t instanceof Deletable deletable) {
|
||||||
|
deletable.setDeletedAt(null);
|
||||||
|
}
|
||||||
baseMapper.updateSelective(t);
|
baseMapper.updateSelective(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,5 +18,5 @@ public interface PageableService<T> {
|
|||||||
* @param page 页面查询参数
|
* @param page 页面查询参数
|
||||||
* @return 查询页面结果
|
* @return 查询页面结果
|
||||||
*/
|
*/
|
||||||
PageResult<T> page(Page page);
|
PageResult<T> page(Page<T> page);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,25 +50,34 @@ public class SQLProvider {
|
|||||||
* @param page 分页参数
|
* @param page 分页参数
|
||||||
* @return SQL
|
* @return SQL
|
||||||
*/
|
*/
|
||||||
public String listByPage(ProviderContext context, @Param("page") Page page) {
|
public String listByPage(ProviderContext context, @Param("page") Page<?> page) {
|
||||||
EntityMeta meta = getEntityMeta(context);
|
EntityMeta meta = getEntityMeta(context);
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT %s FROM `%s` WHERE 1 = 1".formatted(meta.selectAllClause, meta.table));
|
sql.append("SELECT %s FROM `%s` WHERE 1 = 1".formatted(meta.selectAllClause, meta.table));
|
||||||
|
|
||||||
// 处理软删除
|
|
||||||
if (meta.canDelete) {
|
if (meta.canDelete) {
|
||||||
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now()));
|
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now()));
|
||||||
}
|
}
|
||||||
// 处理模糊查询
|
if (TimiJava.isNotEmpty(page.getEqualsExample())) {
|
||||||
if (TimiJava.isNotEmpty(page.getLikeMap())) {
|
// 精准查询
|
||||||
for (Map.Entry<String, String> item : page.getLikeMap().entrySet()) {
|
Object obj = page.getEqualsExample();
|
||||||
sql.append(" AND `%s` LIKE CONCAT('%%', #{likeMap.%s}, '%%')".formatted(
|
EntityMeta metaExample = getEntityMeta(obj.getClass());
|
||||||
Text.camelCase2underscore(item.getKey()),
|
String conditionClause = metaExample.fieldColumnList.stream()
|
||||||
item.getKey()
|
.filter(fc -> fc.isNotNull(obj))
|
||||||
));
|
.map(fc -> "`%s` = '%s'".formatted(fc.columnName, fc.getAsString(obj)))
|
||||||
|
.collect(Collectors.joining(" AND "));
|
||||||
|
sql.append(" AND ").append(conditionClause);
|
||||||
}
|
}
|
||||||
|
if (TimiJava.isNotEmpty(page.getLikeExample())) {
|
||||||
|
// 模糊查询
|
||||||
|
Object obj = page.getLikeExample();
|
||||||
|
EntityMeta metaExample = getEntityMeta(obj.getClass());
|
||||||
|
String conditionClause = metaExample.fieldColumnList.stream()
|
||||||
|
.filter(fc -> fc.isNotNull(obj))
|
||||||
|
.map(fc -> "`%s` LIKE CONCAT('%%', '%s', '%%')".formatted(fc.columnName, fc.getAsString(obj)))
|
||||||
|
.collect(Collectors.joining(" OR "));
|
||||||
|
sql.append(" AND (").append(conditionClause).append(')');
|
||||||
}
|
}
|
||||||
// 处理排序
|
// 排序
|
||||||
if (TimiJava.isNotEmpty(page.getOrderMap())) {
|
if (TimiJava.isNotEmpty(page.getOrderMap())) {
|
||||||
sql.append(" ORDER BY ");
|
sql.append(" ORDER BY ");
|
||||||
for (Map.Entry<String, BaseMapper.OrderType> item : page.getOrderMap().entrySet()) {
|
for (Map.Entry<String, BaseMapper.OrderType> item : page.getOrderMap().entrySet()) {
|
||||||
@ -99,22 +108,32 @@ public class SQLProvider {
|
|||||||
* @param page 分页参数
|
* @param page 分页参数
|
||||||
* @return SQL
|
* @return SQL
|
||||||
*/
|
*/
|
||||||
public String countByPage(ProviderContext context, @Param("page") com.imyeyu.spring.bean.Page page) {
|
public String countByPage(ProviderContext context, @Param("page") Page<?> page) {
|
||||||
EntityMeta meta = getEntityMeta(context);
|
EntityMeta meta = getEntityMeta(context);
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT COUNT(*) FROM `%s` WHERE 1 = 1".formatted(meta.table));
|
sql.append("SELECT COUNT(*) FROM `%s` WHERE 1 = 1".formatted(meta.table));
|
||||||
// 处理软删除
|
|
||||||
if (meta.canDelete) {
|
if (meta.canDelete) {
|
||||||
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now()));
|
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now()));
|
||||||
}
|
}
|
||||||
// 处理模糊查询
|
if (TimiJava.isNotEmpty(page.getEqualsExample())) {
|
||||||
if (TimiJava.isNotEmpty(page.getLikeMap())) {
|
// 精准查询
|
||||||
for (Map.Entry<String, String> item : page.getLikeMap().entrySet()) {
|
Object obj = page.getEqualsExample();
|
||||||
sql.append(" AND `%s` LIKE CONCAT('%%', #{likeMap.%s}, '%%')".formatted(
|
EntityMeta metaExample = getEntityMeta(obj.getClass());
|
||||||
Text.camelCase2underscore(item.getKey()),
|
String conditionClause = metaExample.fieldColumnList.stream()
|
||||||
item.getKey()
|
.filter(fc -> fc.isNotNull(obj))
|
||||||
));
|
.map(fc -> "`%s` = '%s'".formatted(fc.columnName, fc.getAsString(obj)))
|
||||||
|
.collect(Collectors.joining(" AND "));
|
||||||
|
sql.append(" AND ").append(conditionClause);
|
||||||
}
|
}
|
||||||
|
if (TimiJava.isNotEmpty(page.getLikeExample())) {
|
||||||
|
// 模糊查询
|
||||||
|
Object obj = page.getLikeExample();
|
||||||
|
EntityMeta metaExample = getEntityMeta(obj.getClass());
|
||||||
|
String conditionClause = metaExample.fieldColumnList.stream()
|
||||||
|
.filter(fc -> fc.isNotNull(obj))
|
||||||
|
.map(fc -> "`%s` LIKE CONCAT('%%', '%s', '%%')".formatted(fc.columnName, fc.getAsString(obj)))
|
||||||
|
.collect(Collectors.joining(" OR "));
|
||||||
|
sql.append(" AND (").append(conditionClause).append(')');
|
||||||
}
|
}
|
||||||
return sql.toString();
|
return sql.toString();
|
||||||
}
|
}
|
||||||
@ -528,6 +547,14 @@ public class SQLProvider {
|
|||||||
return !isNull(entity);
|
return !isNull(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAsString(Object obj) {
|
||||||
|
try {
|
||||||
|
return field.get(obj).toString();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Field getField() {
|
public Field getField() {
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user