@@ -69,7 +69,7 @@ public class SwMap extends HashMap<String, Object> { | |||||
} | } | ||||
public Boolean readBool(String name) { | public Boolean readBool(String name) { | ||||
return MapUtil.readBool(this, name, null); | |||||
return MapUtil.readBool(this, name, false); | |||||
} | } | ||||
public Boolean readBool(String name, Boolean defaultValue) { | public Boolean readBool(String name, Boolean defaultValue) { | ||||
@@ -77,7 +77,7 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache< | |||||
} | } | ||||
final @NonNull Caffeine<Object, Object> kvCaffeine = Caffeine.newBuilder() | final @NonNull Caffeine<Object, Object> kvCaffeine = Caffeine.newBuilder() | ||||
.scheduler(Scheduler.forScheduledExecutorService(executorService)); | .scheduler(Scheduler.forScheduledExecutorService(executorService)); | ||||
if (swCache.timeout() > 0) { | |||||
if (swCache != null && swCache.timeout() > 0) { | |||||
kvCaffeine.expireAfterAccess(swCache.timeout(), TimeUnit.MINUTES); | kvCaffeine.expireAfterAccess(swCache.timeout(), TimeUnit.MINUTES); | ||||
} | } | ||||
this.cache = kvCaffeine.build(this::onLoad); | this.cache = kvCaffeine.build(this::onLoad); | ||||
@@ -0,0 +1,39 @@ | |||||
package cc.smtweb.framework.core.cache; | |||||
import com.github.benmanes.caffeine.cache.Cache; | |||||
import com.github.benmanes.caffeine.cache.Caffeine; | |||||
import com.github.benmanes.caffeine.cache.LoadingCache; | |||||
import com.github.benmanes.caffeine.cache.Scheduler; | |||||
import org.checkerframework.checker.nullness.qual.NonNull; | |||||
import java.util.concurrent.TimeUnit; | |||||
/** | |||||
* Created by Akmm at 2022/3/14 10:22 | |||||
*/ | |||||
public class SessionCache { | |||||
private Cache<String, Object> cache; | |||||
public SessionCache(long timeout) { | |||||
if (timeout <= 0L) timeout = Long.MAX_VALUE; | |||||
this.cache = Caffeine.newBuilder() | |||||
.expireAfterAccess(timeout, TimeUnit.MINUTES).build(); | |||||
} | |||||
public void put(String id, Object bean) { | |||||
if (bean != null) cache.put(id, bean); | |||||
} | |||||
public void remove(String id) { | |||||
cache.invalidate(id); | |||||
} | |||||
public void clear() { | |||||
cache.invalidateAll(); | |||||
} | |||||
@SuppressWarnings({"unchecked"}) | |||||
public <T> T get(String id) { | |||||
return (T) cache.getIfPresent(id); | |||||
} | |||||
} |
@@ -0,0 +1,52 @@ | |||||
package cc.smtweb.framework.core.cache; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.concurrent.ConcurrentHashMap; | |||||
/** | |||||
* Created by Akmm at 2022/3/14 10:42 | |||||
*/ | |||||
public class SessionCacheFactory { | |||||
private static SessionCacheFactory INSTANCE = null; | |||||
private Map<Long, SessionCache> buffer = new ConcurrentHashMap<>(); | |||||
private SessionCacheFactory() { | |||||
} | |||||
/*获取单例*/ | |||||
public static SessionCacheFactory getInstance() { | |||||
if (INSTANCE == null) { | |||||
synchronized (SessionCacheFactory.class) { | |||||
if (INSTANCE == null) { | |||||
INSTANCE = new SessionCacheFactory(); | |||||
} | |||||
} | |||||
} | |||||
return INSTANCE; | |||||
} | |||||
//得到用户缓存对象 | |||||
public SessionCache getUserCache(long userId) { | |||||
return getUserCache(userId, 0L); | |||||
} | |||||
public SessionCache getUserCache(long userId, long timeout) { | |||||
SessionCache cache; | |||||
cache = buffer.get(userId); | |||||
if (cache == null) { | |||||
cache = buffer.get(userId); | |||||
if (cache != null) return cache; | |||||
cache = new SessionCache(timeout); | |||||
buffer.put(userId, cache); | |||||
} | |||||
return cache; | |||||
} | |||||
//删除用户缓存 | |||||
public void remove(String userId) { | |||||
buffer.remove(userId); | |||||
} | |||||
} |
@@ -4,12 +4,22 @@ import cc.smtweb.framework.core.SwException; | |||||
import cc.smtweb.framework.core.db.dao.AbstractEntityDao; | import cc.smtweb.framework.core.db.dao.AbstractEntityDao; | ||||
import cc.smtweb.framework.core.db.dao.EntityColumn; | import cc.smtweb.framework.core.db.dao.EntityColumn; | ||||
import cc.smtweb.framework.core.db.jdbc.JdbcEngine; | import cc.smtweb.framework.core.db.jdbc.JdbcEngine; | ||||
import cc.smtweb.framework.core.db.vo.KeyValueVO; | |||||
import cc.smtweb.framework.core.db.vo.ModelField; | |||||
import cc.smtweb.framework.core.db.vo.def.FieldType; | import cc.smtweb.framework.core.db.vo.def.FieldType; | ||||
import cc.smtweb.framework.core.util.CommUtil; | |||||
import lombok.Getter; | import lombok.Getter; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.springframework.dao.DataAccessException; | |||||
import org.springframework.jdbc.core.ResultSetExtractor; | |||||
import org.springframework.jdbc.core.RowMapper; | |||||
import java.sql.ResultSet; | |||||
import java.sql.SQLException; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* 提供数据对象Dao操作 | * 提供数据对象Dao操作 | ||||
@@ -250,6 +260,27 @@ public class EntityDao<T> extends AbstractEntityDao<T> { | |||||
/** | /** | ||||
* 查询对象所有数据,返回列表 | * 查询对象所有数据,返回列表 | ||||
*/ | */ | ||||
public Map<String, String> queryNames(List<String> ids) { | |||||
if (ids == null || ids.isEmpty()) return new HashMap<>(); | |||||
ModelField field = modelTable.findFieldByType(FieldType.NAME); | |||||
if (field == null) return new HashMap<>(); | |||||
StringBuilder sb = new StringBuilder(); | |||||
handleSelect(sb, modelTable.getIdField() + "," + field.getName()); | |||||
sb.append("\nwhere " + modelTable.getIdField() + " in (" + CommUtil.getSqlInIds(ids) + ")"); | |||||
return jdbcEngine.query(sb.toString(), rs -> { | |||||
Map<String, String> map = new HashMap<>(); | |||||
while (rs.next()) { | |||||
map.put(rs.getString(1), rs.getString(2)); | |||||
} | |||||
return map; | |||||
}); | |||||
} | |||||
/** | |||||
* 查询对象所有数据,返回列表 | |||||
*/ | |||||
public List<T> query(String fields) { | public List<T> query(String fields) { | ||||
StringBuilder sb = new StringBuilder(); | StringBuilder sb = new StringBuilder(); | ||||
handleSelect(sb, fields); | handleSelect(sb, fields); | ||||
@@ -280,7 +311,7 @@ public class EntityDao<T> extends AbstractEntityDao<T> { | |||||
if (StringUtils.isEmpty(f)) continue; | if (StringUtils.isEmpty(f)) continue; | ||||
ss += " and " + f + "=?"; | ss += " and " + f + "=?"; | ||||
args.add(readValue(bean, f)); | args.add(readValue(bean, f)); | ||||
sTitle += "+" + modelTable.getFieldTitle(f); | |||||
sTitle += "+" + modelTable.findFieldTitle(f); | |||||
} | } | ||||
if (jdbcEngine.isExists("select 1 from " + tableName + " where " + modelTable.getIdField() + "=? " + ss, args.toArray())) | if (jdbcEngine.isExists("select 1 from " + tableName + " where " + modelTable.getIdField() + "=? " + ss, args.toArray())) | ||||
throw new SwException(sTitle.substring(1) + " 不能重复!"); | throw new SwException(sTitle.substring(1) + " 不能重复!"); | ||||
@@ -61,4 +61,5 @@ public class EntityCache extends AbstractCache<DefaultEntity> { | |||||
EntityDao<DefaultEntity> dao = DbEngine.getInstance().findDao(tableName); | EntityDao<DefaultEntity> dao = DbEngine.getInstance().findDao(tableName); | ||||
return dao.query(); | return dao.query(); | ||||
} | } | ||||
} | } |
@@ -30,7 +30,7 @@ public class ModelTableCache extends AbstractCache<ModelTable> { | |||||
public ModelTableCache() { | public ModelTableCache() { | ||||
regMap(mk, k-> k.getName().toUpperCase()); | regMap(mk, k-> k.getName().toUpperCase()); | ||||
regList(md, k-> String.valueOf(k.getDatabaseId())); | regList(md, k-> String.valueOf(k.getDatabaseId())); | ||||
regList(mf, k-> k.get); | |||||
// regList(mf, k-> k.get); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -41,21 +41,21 @@ public class ModelTableCache extends AbstractCache<ModelTable> { | |||||
@Override | @Override | ||||
protected List<ModelTable> loadAll() { | protected List<ModelTable> loadAll() { | ||||
return DbEngine.getInstance().query("SELECT\n" + | return DbEngine.getInstance().query("SELECT\n" + | ||||
"t.table_id,\n" + | |||||
"t.prjoect_id,\n" + | |||||
"t.catalog_id,\n" + | |||||
"t.database_id,\n" + | |||||
"t.table_extends,\n" + | |||||
"t.table_name,\n" + | |||||
"t.table_title,\n" + | |||||
"t.table_abbr,\n" + | |||||
"t.table_type,\n" + | |||||
"t.need_cache,\n" + | |||||
"t.table_content,\n" + | |||||
"t.table_create_uid,\n" + | |||||
"t.table_update_uid,\n" + | |||||
"t.table_create_at,\n" + | |||||
"t.table_update_at\n" + | |||||
"t.tb_id,\n" + | |||||
"t.tb_prj_id,\n" + | |||||
"t.tb_mc_id,\n" + | |||||
"t.tb_db_id,\n" + | |||||
"t.tb_extends,\n" + | |||||
"t.tb_name,\n" + | |||||
"t.tb_title,\n" + | |||||
"t.tb_abbr,\n" + | |||||
"t.tb_type,\n" + | |||||
"t.tb_need_cache,\n" + | |||||
"t.tb_content,\n" + | |||||
"t.tb_create_uid,\n" + | |||||
"t.tb_update_uid,\n" + | |||||
"t.tb_create_at,\n" + | |||||
"t.tb_update_at\n" + | |||||
"from asp_model_table t\n", new ResultSetExtractor<List<ModelTable>>() { | "from asp_model_table t\n", new ResultSetExtractor<List<ModelTable>>() { | ||||
@Override | @Override | ||||
public List<ModelTable> extractData(ResultSet rs) throws SQLException, DataAccessException { | public List<ModelTable> extractData(ResultSet rs) throws SQLException, DataAccessException { | ||||
@@ -63,20 +63,21 @@ public class ModelTableCache extends AbstractCache<ModelTable> { | |||||
while (rs.next()) { | while (rs.next()) { | ||||
ModelTable table = new ModelTable(); | ModelTable table = new ModelTable(); | ||||
list.add(table); | list.add(table); | ||||
table.setId(rs.getLong("table_id")); | |||||
table.setDatabaseId(rs.getLong("database_id")); | |||||
table.setPrjoectId(rs.getLong("prjoect_id")); | |||||
table.setCatalogId(rs.getLong("catalog_id")); | |||||
table.setTableExtends(rs.getString("table_extends")); | |||||
table.setName(rs.getString("table_name").toUpperCase()); | |||||
table.setTitle(rs.getString("table_title")); | |||||
table.setAbbr(rs.getString("table_abbr")); | |||||
table.setType(rs.getInt("table_type")); | |||||
table.setNeedCache(rs.getInt("need_cache") == 1); | |||||
table.setCreateUid(rs.getLong("table_create_uid")); | |||||
table.setCreateAt(rs.getLong("table_create_at")); | |||||
table.setUpdateAt(rs.getLong("table_update_at")); | |||||
table.setTableContent(rs.getString("table_content")); | |||||
table.setId(rs.getLong("tb_id")); | |||||
table.setDatabaseId(rs.getLong("tb_db_id")); | |||||
table.setPrjoectId(rs.getLong("tb_prj_id")); | |||||
table.setCatalogId(rs.getLong("tb_mc_id")); | |||||
table.setTableExtends(rs.getString("tb_extends")); | |||||
table.setName(rs.getString("tb_name").toUpperCase()); | |||||
table.setTitle(rs.getString("tb_title")); | |||||
table.setAbbr(rs.getString("tb_abbr")); | |||||
table.setType(rs.getInt("tb_type")); | |||||
table.setNeedCache(rs.getInt("tb_need_cache") == 1); | |||||
table.setCreateUid(rs.getLong("tb_create_uid")); | |||||
table.setUpdateUid(rs.getLong("tb_update_uid")); | |||||
table.setCreateAt(rs.getLong("tb_create_at")); | |||||
table.setUpdateAt(rs.getLong("tb_update_at")); | |||||
table.setTableContent(rs.getString("tb_content")); | |||||
} | } | ||||
return list; | return list; | ||||
} | } | ||||
@@ -56,23 +56,28 @@ public abstract class AbstractEntityDao<T> { | |||||
tableName = table.value(); | tableName = table.value(); | ||||
modelTable = ModelTableCache.getInstance().getByName(tableName); | modelTable = ModelTableCache.getInstance().getByName(tableName); | ||||
for (ModelField field : modelTable.getFields()) { | |||||
String voFieldName = getVoFieldName(modelTable.getAbbr(), field.getName()); | |||||
// 处理get method | |||||
try { | |||||
PropertyDescriptor pd = new PropertyDescriptor(voFieldName, type); | |||||
// 获得get方法 | |||||
Method readMethod = pd.getReadMethod(); | |||||
Method writeMethod = pd.getWriteMethod(); | |||||
if (readMethod != null && writeMethod != null) { | |||||
Class<?>[] parameterTypes = writeMethod.getParameterTypes(); | |||||
if (parameterTypes.length == 1 && ClassUtils.isAssignable(parameterTypes[0], readMethod.getReturnType())) { | |||||
add(field, readMethod, writeMethod); | |||||
if (DefaultEntity.class.isAssignableFrom(type)) { | |||||
for (ModelField field : modelTable.getFields()) { | |||||
add(field, null, null); | |||||
} | |||||
} else { | |||||
for (ModelField field : modelTable.getFields()) { | |||||
String voFieldName = getVoFieldName(modelTable.getAbbr(), field.getName()); | |||||
// 处理get method | |||||
try { | |||||
PropertyDescriptor pd = new PropertyDescriptor(voFieldName, type); | |||||
// 获得get方法 | |||||
Method readMethod = pd.getReadMethod(); | |||||
Method writeMethod = pd.getWriteMethod(); | |||||
if (readMethod != null && writeMethod != null) { | |||||
Class<?>[] parameterTypes = writeMethod.getParameterTypes(); | |||||
if (parameterTypes.length == 1 && ClassUtils.isAssignable(parameterTypes[0], readMethod.getReturnType())) { | |||||
add(field, readMethod, writeMethod); | |||||
} | |||||
} | } | ||||
} catch (IntrospectionException ignore) { | |||||
} | } | ||||
} catch (IntrospectionException ignore) { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -306,7 +311,7 @@ public abstract class AbstractEntityDao<T> { | |||||
sql.append("DELETE FROM ").append(tableName).append(" WHERE ").append(idColumn.getField().getName()).append("=?"); | sql.append("DELETE FROM ").append(tableName).append(" WHERE ").append(idColumn.getField().getName()).append("=?"); | ||||
} | } | ||||
protected Object readValue(T obj, String fieldName) { | |||||
public Object readValue(T obj, String fieldName) { | |||||
EntityColumn beanColumn = getBeanColumn(fieldName); | EntityColumn beanColumn = getBeanColumn(fieldName); | ||||
return beanColumn.readValue(obj); | return beanColumn.readValue(obj); | ||||
@@ -3,7 +3,9 @@ package cc.smtweb.framework.core.db.impl; | |||||
import cc.smtweb.framework.core.SwMap; | import cc.smtweb.framework.core.SwMap; | ||||
import cc.smtweb.framework.core.util.JsonUtil; | import cc.smtweb.framework.core.util.JsonUtil; | ||||
import cc.smtweb.framework.core.util.NumberUtil; | import cc.smtweb.framework.core.util.NumberUtil; | ||||
import cc.smtweb.framework.core.util.jackson.BaseBeanSerializer; | |||||
import com.fasterxml.jackson.databind.JsonNode; | import com.fasterxml.jackson.databind.JsonNode; | ||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
@@ -14,6 +16,7 @@ import java.util.Map; | |||||
* Created by Akmm at 2016-02-23 9:31 | * Created by Akmm at 2016-02-23 9:31 | ||||
* bean基类,基于Map, | * bean基类,基于Map, | ||||
*/ | */ | ||||
@JsonSerialize(using = BaseBeanSerializer.class) | |||||
public class BaseBean implements Serializable { | public class BaseBean implements Serializable { | ||||
protected Map<String, Object> data = new HashMap<>(); | protected Map<String, Object> data = new HashMap<>(); | ||||
@@ -0,0 +1,40 @@ | |||||
package cc.smtweb.framework.core.db.jdbc; | |||||
import cc.smtweb.framework.core.db.impl.BaseBean; | |||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.jdbc.core.RowMapper; | |||||
import java.sql.ResultSet; | |||||
import java.sql.ResultSetMetaData; | |||||
import java.sql.SQLException; | |||||
/** | |||||
* ORM映射处理器,实现spring jdbcTemplate的行集映射器 | |||||
* @author xkliu | |||||
*/ | |||||
public class BaseBeanPropertyRowMapper<T> implements RowMapper<T> { | |||||
private Class<T> mappedClass; | |||||
public BaseBeanPropertyRowMapper(Class<T> mappedClass) { | |||||
this.mappedClass = mappedClass; | |||||
} | |||||
@Override | |||||
public T mapRow(ResultSet resultSet, int i) throws SQLException { | |||||
T mappedObject = BeanUtils.instantiateClass(this.mappedClass); | |||||
BaseBean map = (BaseBean) mappedObject; | |||||
ResultSetMetaData rsmd = resultSet.getMetaData(); | |||||
int columnCount = rsmd.getColumnCount(); | |||||
for(int index = 1; index <= columnCount; ++index) { | |||||
Object value = resultSet.getObject(index); | |||||
if (value != null) { | |||||
map.put(rsmd.getColumnLabel(index), value); | |||||
} | |||||
} | |||||
return mappedObject; | |||||
} | |||||
} |
@@ -1,6 +1,8 @@ | |||||
package cc.smtweb.framework.core.db.jdbc; | package cc.smtweb.framework.core.db.jdbc; | ||||
import cc.smtweb.framework.core.SwMap; | import cc.smtweb.framework.core.SwMap; | ||||
import cc.smtweb.framework.core.db.impl.BaseBean; | |||||
import cc.smtweb.framework.core.db.impl.DefaultEntity; | |||||
import cc.smtweb.framework.core.exception.DbException; | import cc.smtweb.framework.core.exception.DbException; | ||||
import cc.smtweb.framework.core.util.JsonUtil; | import cc.smtweb.framework.core.util.JsonUtil; | ||||
import lombok.Getter; | import lombok.Getter; | ||||
@@ -394,7 +396,9 @@ public class JdbcEngine { | |||||
private <T> RowMapper<T> createRowMapper(Class<T> type) { | private <T> RowMapper<T> createRowMapper(Class<T> type) { | ||||
RowMapper<T> rowMapper; | RowMapper<T> rowMapper; | ||||
if (java.util.Map.class.isAssignableFrom(type)) { | |||||
if (BaseBean.class.isAssignableFrom(type)) { | |||||
rowMapper = new BaseBeanPropertyRowMapper<>(type); | |||||
} else if (java.util.Map.class.isAssignableFrom(type)) { | |||||
if (SwMap.class.equals(type)) { | if (SwMap.class.equals(type)) { | ||||
rowMapper = new SwMapPropertyRowMapper<>(type); | rowMapper = new SwMapPropertyRowMapper<>(type); | ||||
} else { | } else { | ||||
@@ -27,7 +27,7 @@ public class SwMapPropertyRowMapper<T> implements RowMapper<T> { | |||||
if (value != null) { | if (value != null) { | ||||
String columnLabel = rsmd.getColumnLabel(index); | String columnLabel = rsmd.getColumnLabel(index); | ||||
map.put(toCamelCase(columnLabel), value); | |||||
map.put(columnLabel, value); //toCamelCase(columnLabel) | |||||
} | } | ||||
} | } | ||||
@@ -0,0 +1,20 @@ | |||||
package cc.smtweb.framework.core.db.vo; | |||||
import lombok.Data; | |||||
/** | |||||
* Created by Akmm at 2022/3/15 10:19 | |||||
* 表关联信息,关联表名称字段信息 | |||||
*/ | |||||
@Data | |||||
public class ModelLinkName { | |||||
private String fieldName; | |||||
private ModelTable linkTable; | |||||
private String linkNameField; | |||||
public ModelLinkName(String fieldName, ModelTable linkTable, String linkNameField) { | |||||
this.fieldName = fieldName; | |||||
this.linkTable = linkTable; | |||||
this.linkNameField = linkNameField; | |||||
} | |||||
} |
@@ -1,9 +1,11 @@ | |||||
package cc.smtweb.framework.core.db.vo; | package cc.smtweb.framework.core.db.vo; | ||||
import cc.smtweb.framework.core.annotation.SwTable; | import cc.smtweb.framework.core.annotation.SwTable; | ||||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||||
import cc.smtweb.framework.core.db.vo.def.FieldType; | import cc.smtweb.framework.core.db.vo.def.FieldType; | ||||
import cc.smtweb.framework.core.util.JsonUtil; | import cc.smtweb.framework.core.util.JsonUtil; | ||||
import lombok.Data; | import lombok.Data; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
@@ -62,7 +64,7 @@ public class ModelTable implements Serializable { | |||||
return null; | return null; | ||||
} | } | ||||
public String getFieldTitle(String fieldName) { | |||||
public String findFieldTitle(String fieldName) { | |||||
ModelField field = findField(fieldName); | ModelField field = findField(fieldName); | ||||
return field != null ? field.getTitle() : fieldName; | return field != null ? field.getTitle() : fieldName; | ||||
} | } | ||||
@@ -128,6 +130,24 @@ public class ModelTable implements Serializable { | |||||
return null; | return null; | ||||
} | } | ||||
public List<ModelLinkName> findLinkeNames() { | |||||
List<ModelLinkName> list = new ArrayList<>(); | |||||
for (ModelField field: fields) { | |||||
if (StringUtils.isEmpty(field.getLink())) { | |||||
continue; | |||||
} | |||||
ModelTable linkTable = ModelTableCache.getInstance().get(field.getLink()); | |||||
if (linkTable == null) { | |||||
continue; | |||||
} | |||||
ModelField linkNameField = linkTable.findFieldByType(FieldType.NAME); | |||||
if (linkNameField != null) { | |||||
list.add(new ModelLinkName(field.getName(), linkTable, linkNameField.getName())); | |||||
} | |||||
} | |||||
return list; | |||||
} | |||||
public void setTableContent(String tableContent) { | public void setTableContent(String tableContent) { | ||||
this.tableContent = tableContent; | this.tableContent = tableContent; | ||||
//读取表定义信息 | //读取表定义信息 | ||||
@@ -134,7 +134,7 @@ public class MethodParser { | |||||
IEditor editor = webDataBinder.findEditor(paramType, bindType); | IEditor editor = webDataBinder.findEditor(paramType, bindType); | ||||
if (paramType.isAssignableFrom(List.class)) { | |||||
if (List.class.isAssignableFrom(paramType)) { | |||||
// List bind类型使用泛型声明的对象 | // List bind类型使用泛型声明的对象 | ||||
ResolvableType resolvableType = ResolvableType.forMethodParameter(method, i); | ResolvableType resolvableType = ResolvableType.forMethodParameter(method, i); | ||||
paramType = resolvableType.getGeneric(0).getRawClass(); | paramType = resolvableType.getGeneric(0).getRawClass(); | ||||
@@ -28,7 +28,7 @@ public class AbstractPermInterceptor { | |||||
protected boolean handle(HttpServletRequest request, String permissionValue) { | protected boolean handle(HttpServletRequest request, String permissionValue) { | ||||
// 如果注解为null, 说明不需要拦截, 直接放过 | // 如果注解为null, 说明不需要拦截, 直接放过 | ||||
if (permissionValue == null || SwPerm.NONE.equals(permissionValue)) { | |||||
if (StringUtils.isEmpty(permissionValue) || SwPerm.NONE.equals(permissionValue)) { | |||||
return true; | return true; | ||||
} | } | ||||
@@ -25,7 +25,9 @@ public abstract class AbstractCompService { | |||||
private R pageHandler(SwMap params, UserSession us, String type) { | private R pageHandler(SwMap params, UserSession us, String type) { | ||||
try { | try { | ||||
IHandler handler = createHanlder(TYPE_SAVE); | |||||
IHandler handler = createHanlder(type); | |||||
if (params == null) params = new SwMap(); | |||||
if (us == null) us = UserSession.createSys(); | |||||
return handler.doWork(params, us); | return handler.doWork(params, us); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
return R.error("操作失败!", e); | return R.error("操作失败!", e); | ||||
@@ -47,4 +49,13 @@ public abstract class AbstractCompService { | |||||
public R list(@SwBody SwMap params, UserSession us) { | public R list(@SwBody SwMap params, UserSession us) { | ||||
return pageHandler(params, us, TYPE_LIST); | return pageHandler(params, us, TYPE_LIST); | ||||
} | } | ||||
public R getTotal(@SwBody SwMap params, UserSession us) { | |||||
try { | |||||
AbstractListHandler handler = (AbstractListHandler)createHanlder(TYPE_LIST); | |||||
return handler.getTotal(params, us); | |||||
} catch (Exception e) { | |||||
return R.error("操作失败!", e); | |||||
} | |||||
} | |||||
} | } |
@@ -14,13 +14,14 @@ import lombok.extern.slf4j.Slf4j; | |||||
public abstract class AbstractDelHandler<T> implements IHandler{ | public abstract class AbstractDelHandler<T> implements IHandler{ | ||||
protected SwMap params; | protected SwMap params; | ||||
protected UserSession us; | protected UserSession us; | ||||
protected long id; | |||||
@Override | @Override | ||||
public R doWork(SwMap params, UserSession us) throws Exception { | public R doWork(SwMap params, UserSession us) throws Exception { | ||||
this.params = params; | this.params = params; | ||||
this.us = us; | this.us = us; | ||||
long id = readId(); | |||||
id = readId(); | |||||
checkValid(); | checkValid(); | ||||
DbEngine.getInstance().doTrans(() -> { | DbEngine.getInstance().doTrans(() -> { | ||||
@@ -0,0 +1,285 @@ | |||||
package cc.smtweb.framework.core.mvc.service; | |||||
import cc.smtweb.framework.core.R; | |||||
import cc.smtweb.framework.core.SwMap; | |||||
import cc.smtweb.framework.core.cache.SessionCache; | |||||
import cc.smtweb.framework.core.cache.SessionCacheFactory; | |||||
import cc.smtweb.framework.core.db.DbEngine; | |||||
import cc.smtweb.framework.core.mvc.service.list.FooterField; | |||||
import cc.smtweb.framework.core.session.UserSession; | |||||
import cc.smtweb.framework.core.util.NumberUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.dao.DataAccessException; | |||||
import org.springframework.jdbc.core.ResultSetExtractor; | |||||
import java.sql.ResultSet; | |||||
import java.sql.SQLException; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* Created by Akmm at 2022/3/2 19:44 | |||||
* 列表服务 | |||||
*/ | |||||
@Slf4j | |||||
public abstract class AbstractListHandler implements IHandler { | |||||
protected static String KEY_SQLPARA = "query-sqlPara"; | |||||
protected static String KEY_SQLPARA_SUM = "query-sqlPara-sum"; | |||||
protected static String KEY_PARAMS = "query-params"; | |||||
protected SwMap params; | |||||
protected UserSession us; | |||||
private SessionCache cacheBean; | |||||
private List<FooterField> footerFields = null; | |||||
// private SqlPara sqlPara = null; | |||||
@Override | |||||
public R doWork(SwMap params, UserSession us) throws Exception { | |||||
this.params = params; | |||||
this.us = us; | |||||
return R.success(listData()); | |||||
} | |||||
protected SwListData listData() throws Exception { | |||||
List<SwMap> listData = new ArrayList<>(); | |||||
SqlPara sqlPara = buildDataSql(); | |||||
int rows = params.readInt("rows", 20); | |||||
int page = params.readInt("page", 1); | |||||
String sort = params.readString("sort"); | |||||
String order = params.readString("order"); | |||||
String sql; | |||||
if (StringUtils.isEmpty(sort)) sql = sqlPara.sql; | |||||
else { | |||||
sql = "select ar.* from (" + sqlPara.sql + ") ar order by ar." + sort + " " + order; | |||||
if (StringUtils.isNotEmpty(getPkFieldName())) { | |||||
sql += "," + getPkFieldName(); | |||||
} | |||||
} | |||||
if (rows == 0) { | |||||
listData = DbEngine.getInstance().query(sql, SwMap.class, sqlPara.paras); | |||||
} else { | |||||
//查分页数据 | |||||
listData = DbEngine.getInstance().pagedQuery(sql, SwMap.class, (page - 1) * rows, rows, sqlPara.paras); | |||||
} | |||||
afterQuery(listData); | |||||
return SwListData.create(listData, false); | |||||
} | |||||
protected SqlPara buildSumSqlPara() { | |||||
final SessionCache userCache = getCacheBean(); | |||||
SqlPara sqlPara = userCache.get(KEY_SQLPARA); | |||||
if (sqlPara == null) return null; | |||||
getFooterFields(); | |||||
StringBuilder sql = new StringBuilder(128); | |||||
sql.append("select count(1) F_1"); | |||||
int n = 2; | |||||
for (FooterField cn : footerFields) { | |||||
if (!FooterField.STATIC_TEXT.equals(cn.type)) { | |||||
if (FooterField.SUM_TYPE_COUNT_ALL.equals(cn.type)) { | |||||
sql.append(",COUNT("); | |||||
} else if (FooterField.SUM_TYPE_SUM_NUM.equals(cn.type)) { | |||||
sql.append(",SUM("); | |||||
} else { | |||||
sql.append(",").append(cn.type).append("("); | |||||
} | |||||
if (FooterField.SUM_TYPE_COUNT.equals(cn.type)) | |||||
sql.append("distinct "); | |||||
sql.append(cn.field).append(") F_").append(n++); | |||||
} | |||||
} | |||||
sql.append(" from (").append(sqlPara.getSqlNoOrderBy()).append(") xxxxxz"); | |||||
return new SqlPara(sql.toString(), sqlPara.paras); | |||||
} | |||||
public R getTotal(SwMap params, UserSession us) { | |||||
try { | |||||
this.params = params; | |||||
this.us = us; | |||||
final SessionCache userCache = getCacheBean(); | |||||
SqlPara sqlParaSum = userCache.get(KEY_SQLPARA_SUM); | |||||
if (sqlParaSum == null) { | |||||
Map<String, Object> map = userCache.get(KEY_PARAMS); | |||||
if (map != null) params.putAll(map); | |||||
sqlParaSum = buildSumSqlPara(); | |||||
} | |||||
if (sqlParaSum == null) return R.success(); | |||||
userCache.put(KEY_SQLPARA_SUM, sqlParaSum); | |||||
Map<String, Object> mapFooter = new HashMap<>(); | |||||
getFooterFields(); | |||||
int total = DbEngine.getInstance().query(sqlParaSum.sql, new ResultSetExtractor<Integer>() { | |||||
public Integer extractData(ResultSet rs) throws SQLException { | |||||
try { | |||||
for (FooterField c : footerFields) { | |||||
if (FooterField.STATIC_TEXT.equals(c.type)) | |||||
mapFooter.put(c.field, c.text); | |||||
} | |||||
int count = 0; | |||||
if (rs.next()) { | |||||
count = rs.getInt(1); | |||||
int n = 2; | |||||
for (FooterField c : footerFields) { | |||||
switch (c.type) { | |||||
case FooterField.STATIC_TEXT: | |||||
mapFooter.put(c.field, c.text); | |||||
break; | |||||
case FooterField.SUM_TYPE_COUNT: | |||||
case FooterField.SUM_TYPE_COUNT_ALL: | |||||
mapFooter.put(c.field, String.valueOf(rs.getInt(n++))); | |||||
break; | |||||
case FooterField.SUM_TYPE_SUM_NUM: | |||||
mapFooter.put(c.field, String.valueOf(rs.getInt(n++))); | |||||
break; | |||||
default: | |||||
mapFooter.put(c.field, rs.getDouble(n++)); | |||||
break; | |||||
} | |||||
} | |||||
} else { | |||||
for (FooterField c : footerFields) { | |||||
if (FooterField.STATIC_TEXT.equals(c.type)) | |||||
mapFooter.put(c.field, c.text); | |||||
} | |||||
} | |||||
return count; | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. | |||||
return 0; | |||||
} | |||||
} | |||||
}, sqlParaSum.paras); | |||||
R r = R.success(); | |||||
r.put("total", total); | |||||
r.put("footer", mapFooter); | |||||
return r; | |||||
} catch (Exception e) { | |||||
return R.error("计算合计失败!", e); | |||||
} | |||||
} | |||||
public SessionCache getCacheBean() { | |||||
if (cacheBean == null) | |||||
cacheBean = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); | |||||
return cacheBean; | |||||
} | |||||
public void clearCache() { | |||||
getCacheBean().clear(); | |||||
} | |||||
protected SqlPara buildDataSql() throws Exception { | |||||
SessionCache userCache = getCacheBean(); | |||||
//从缓存里看看有没有保存的sql缓存; | |||||
SqlPara sqlParaInCache = getCacheBean().get(KEY_SQLPARA); //缓存里面的对象; | |||||
boolean query = sqlParaInCache == null || params.readBool("query"); | |||||
if (!query) { | |||||
Map<String, Object> map = userCache.get(KEY_PARAMS); | |||||
if (map == null) query = true; | |||||
else { | |||||
Map<String, Object> params = getCachedParams(); | |||||
if (params.size() > map.size()) query = true;//本次参数更多 | |||||
else { | |||||
for (String key : params.keySet()) { | |||||
Object v = map.get(key); | |||||
String cv = v != null && StringUtils.isNotEmpty(v.toString()) ? v.toString() : ""; | |||||
v = params.get(key); | |||||
String rv = v != null && StringUtils.isNotEmpty(v.toString()) ? v.toString() : ""; | |||||
if (!cv.equals(rv)) { | |||||
query = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
SqlPara sqlPara = null; | |||||
if (query) {//新查询 | |||||
//缓存里面没有对象,重新构建查询条件,重新计算汇总数; | |||||
buildParam();//构造过滤条件,设默认值 | |||||
sqlPara = buildSqlPara(); //重新构建查询对象; | |||||
userCache.remove(KEY_SQLPARA_SUM); | |||||
userCache.put(KEY_SQLPARA, sqlPara); | |||||
userCache.put(KEY_PARAMS, getCachedParams());//不缓存页码之类的东东,避免下次请求时,页码又回去了 | |||||
} else { | |||||
sqlPara = sqlParaInCache; | |||||
Map<String, Object> map = userCache.get(KEY_PARAMS); | |||||
if (map != null) params.putAll(map); | |||||
} | |||||
return sqlPara; | |||||
} | |||||
/** | |||||
* 构造过滤条件,设默认值 | |||||
* | |||||
* @throws Exception | |||||
*/ | |||||
protected void buildParam() throws Exception { | |||||
} | |||||
/** | |||||
* sql主键字段,用于点击表头排序时保证排序记录唯一性 | |||||
* | |||||
* @return | |||||
*/ | |||||
protected String getPkFieldName() { | |||||
return null; | |||||
} | |||||
protected void afterQuery(List<SwMap> listData) { | |||||
} | |||||
protected abstract SqlPara buildSqlPara() throws Exception; | |||||
//构建合计字段 | |||||
private List<FooterField> getFooterFields() { | |||||
if (footerFields == null) { | |||||
footerFields = new ArrayList<>(); | |||||
buildFooterFields(footerFields); | |||||
} | |||||
return footerFields; | |||||
} | |||||
protected void buildFooterFields(List<FooterField> footer) { | |||||
} | |||||
protected Map<String, Object> getCachedParams() { | |||||
Map<String, Object> map = new HashMap<>(); | |||||
map.putAll(params); | |||||
map.remove("page"); | |||||
map.remove("rows"); | |||||
map.remove("sort"); | |||||
map.remove("order"); | |||||
map.remove("tokenkey"); | |||||
map.remove("tokenval"); | |||||
map.remove("_v"); | |||||
map.remove("_dn"); | |||||
map.remove("_sk"); | |||||
map.remove("_skw"); | |||||
map.remove("_tk"); | |||||
map.remove("_sb"); | |||||
map.remove("__exp_model"); | |||||
map.remove("model"); | |||||
map.remove("data"); | |||||
return map; | |||||
} | |||||
} |
@@ -26,13 +26,8 @@ public class DefaultDelHandler<T extends DefaultEntity> extends AbstractDelHandl | |||||
@Override | @Override | ||||
protected void checkValid() throws Exception { | protected void checkValid() throws Exception { | ||||
ModelTable table = ModelTableCache.getInstance().getByName(tableName); | ModelTable table = ModelTableCache.getInstance().getByName(tableName); | ||||
//todo 检查外键引用的使用情况 | |||||
EntityDao dao = DbEngine.getInstance().findDao(tableName); | |||||
for (ModelIndex mi: table.getIndexes()) { | |||||
if (mi.isUnique()) { | |||||
dao.checkUnique(bean, mi.getFields().split(",")); | |||||
} | |||||
} | |||||
} | } | ||||
@Override | @Override | ||||
@@ -47,17 +42,7 @@ public class DefaultDelHandler<T extends DefaultEntity> extends AbstractDelHandl | |||||
ModelTable table = ModelTableCache.getInstance().getByName(tableName); | ModelTable table = ModelTableCache.getInstance().getByName(tableName); | ||||
if (table.isNeedCache()) { | if (table.isNeedCache()) { | ||||
AbstractCache<T> cache = CacheManager.getIntance().getCache(tableName); | AbstractCache<T> cache = CacheManager.getIntance().getCache(tableName); | ||||
cache.put(bean); | |||||
} | |||||
} | |||||
@Override | |||||
protected void saveFailed() { | |||||
super.saveFailed(); | |||||
ModelTable table = ModelTableCache.getInstance().getByName(tableName); | |||||
if (table.isNeedCache()) { | |||||
AbstractCache<T> cache = CacheManager.getIntance().getCache(tableName); | |||||
cache.reset(bean); | |||||
cache.remove(id); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -0,0 +1,114 @@ | |||||
package cc.smtweb.framework.core.mvc.service; | |||||
import cc.smtweb.framework.core.SwMap; | |||||
import cc.smtweb.framework.core.cache.AbstractCache; | |||||
import cc.smtweb.framework.core.cache.CacheManager; | |||||
import cc.smtweb.framework.core.db.DbEngine; | |||||
import cc.smtweb.framework.core.db.EntityDao; | |||||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||||
import cc.smtweb.framework.core.db.impl.DefaultEntity; | |||||
import cc.smtweb.framework.core.db.vo.ModelField; | |||||
import cc.smtweb.framework.core.db.vo.ModelLinkName; | |||||
import cc.smtweb.framework.core.db.vo.ModelTable; | |||||
import cc.smtweb.framework.core.db.vo.def.FieldType; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.util.*; | |||||
/** | |||||
* Created by Akmm at 2022/3/2 19:52 | |||||
* 默认实体实现 | |||||
*/ | |||||
public class DefaultListHandler<T extends DefaultEntity> extends AbstractListHandler { | |||||
protected String tableName; | |||||
public DefaultListHandler(String tableName) { | |||||
this.tableName = tableName; | |||||
} | |||||
@Override | |||||
protected SqlPara buildSqlPara() throws Exception { | |||||
EntityDao dao = DbEngine.getInstance().findDao(tableName); | |||||
StringBuilder sql = new StringBuilder(512); | |||||
List<Object> args = new ArrayList<>(); | |||||
dao.handleSelect(sql, null); | |||||
buildCondition(sql, args); | |||||
buildOrder(sql); | |||||
return new SqlPara(sql.toString(), args.toArray()); | |||||
} | |||||
protected void buildCondition(StringBuilder sql, List<Object> args) { | |||||
} | |||||
protected void buildOrder(StringBuilder sql) { | |||||
ModelTable table = ModelTableCache.getInstance().getByName(tableName); | |||||
if (table == null) return; | |||||
sql.append(" order by "); | |||||
ModelField field = table.findFieldByType(FieldType.CODE); | |||||
if (field != null) sql.append(field.getName()).append(","); | |||||
sql.append(table.getIdField()); | |||||
} | |||||
@Override | |||||
protected void afterQuery(List<SwMap> listData) { | |||||
super.afterQuery(listData); | |||||
//添加关联字段值 | |||||
ModelTable table = ModelTableCache.getInstance().getByName(tableName); | |||||
if (table == null) return; | |||||
List<ModelLinkName> listLink = table.findLinkeNames(); | |||||
if (listLink.isEmpty()) return; | |||||
//有缓存的,从缓存拿,无缓存的放Map,最后从数据库去拿 | |||||
Map<String, List<String>> mapIds = new HashMap<>(); | |||||
for (SwMap row : listData) { | |||||
for (ModelLinkName l : listLink) { | |||||
String value = row.readString(l.getFieldName()); | |||||
if (StringUtils.isEmpty(value)) continue; | |||||
String[] ids = StringUtils.split(value, ","); | |||||
if (l.getLinkTable().isNeedCache()) { | |||||
EntityDao dao = DbEngine.getInstance().findDao(l.getLinkTable().getName()); | |||||
AbstractCache cache = CacheManager.getIntance().getCache(l.getLinkTable().getName()); | |||||
String names = ""; | |||||
for (String sId : ids) { | |||||
Object b = cache.get(sId); | |||||
String sn = (String) dao.readValue(b, l.getLinkNameField()); | |||||
if (StringUtils.isNotEmpty(sn)) names += "," + sn; | |||||
} | |||||
row.put(l.getFieldName() + "_name", names.substring(1)); | |||||
} else { | |||||
List<String> list = mapIds.computeIfAbsent(l.getLinkTable().getName(), k -> new ArrayList<>()); | |||||
Collections.addAll(list, ids); | |||||
} | |||||
} | |||||
} | |||||
if (mapIds.isEmpty()) return; | |||||
//数据库查询 | |||||
Map<String, Map<String, String>> mapValue = new HashMap<>(); | |||||
for (Map.Entry<String, List<String>> entry : mapIds.entrySet()) { | |||||
EntityDao dao = DbEngine.getInstance().findDao(entry.getKey()); | |||||
mapValue.put(entry.getKey(), dao.queryNames(entry.getValue())); | |||||
} | |||||
//加值 | |||||
for (SwMap row : listData) { | |||||
for (ModelLinkName l : listLink) { | |||||
if (!mapValue.containsKey(l.getLinkTable().getName())) continue; | |||||
Map<String, String> mapV = mapValue.get(l.getLinkTable().getName()); | |||||
String value = row.readString(l.getFieldName()); | |||||
if (StringUtils.isEmpty(value)) continue; | |||||
String[] ids = StringUtils.split(value, ","); | |||||
String names = ""; | |||||
for (String sId : ids) { | |||||
String sn = mapV.get(sId); | |||||
if (StringUtils.isNotEmpty(sn)) names += "," + sn; | |||||
} | |||||
row.put(l.getFieldName() + "_name", names.substring(1)); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,68 @@ | |||||
package cc.smtweb.framework.core.mvc.service; | |||||
import org.apache.commons.lang3.ArrayUtils; | |||||
//一个sql及其参数 | |||||
public class SqlPara { | |||||
public String sql = ""; | |||||
public Object[] paras = null; | |||||
public int[] types = null; | |||||
public boolean hasLob = false; //是否有lob字段 | |||||
public SqlPara(String sql, Object... paras) { | |||||
this.sql = sql; | |||||
this.paras = paras; | |||||
} | |||||
public SqlPara(String sql, int[] types, Object... paras) { | |||||
this.sql = sql; | |||||
this.paras = paras; | |||||
this.types = types; | |||||
} | |||||
public SqlPara(String sql, int[] types, boolean hasLob, Object... paras) { | |||||
this.sql = sql; | |||||
this.paras = paras; | |||||
this.types = types; | |||||
this.hasLob = hasLob; | |||||
} | |||||
@Override | |||||
public int hashCode() { | |||||
//计算Hash值,以判断条件参数是否有变更; | |||||
if (paras == null) return sql.hashCode(); | |||||
int result = 1; | |||||
for (Object element : paras) { | |||||
result = 31 * result + (element == null ? 0: element.hashCode()); | |||||
} | |||||
result = 31 * result + sql.hashCode(); | |||||
return result; | |||||
} | |||||
//获取不带order by 的sql语句 | |||||
public String getSqlNoOrderBy() { | |||||
String sSql = sql.toUpperCase(); | |||||
int n = sSql.lastIndexOf("ORDER BY ");//截取最后一个 order by | |||||
if (n < 0) return sql; | |||||
String retSql = sql.substring(0, n); | |||||
String s = sSql.substring(n); | |||||
if (s.contains("SELECT")) return sql; //最后一个order by之后,有子查询的不算 | |||||
if (!s.contains(")")) return retSql; //校验order by之后带括号的情况,一般是表达式 | |||||
n = 0; | |||||
for (int i = 0, len = s.length(); i < len; i++) { | |||||
final char c = s.charAt(i); | |||||
if (c == '(') n++; | |||||
else if (c == ')') n--; | |||||
if (n < 0) return sql; | |||||
} | |||||
return retSql; | |||||
} | |||||
public void addParas(Object... ps) { | |||||
if (paras == null) { | |||||
paras = ps; | |||||
return; | |||||
} | |||||
paras = ArrayUtils.addAll(paras, ps); | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
package cc.smtweb.framework.core.mvc.service; | |||||
import cc.smtweb.framework.core.SwMap; | |||||
import lombok.Getter; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
@Getter | |||||
public class SwListData { | |||||
public static final SwListData EMPTY = new SwListData(new ArrayList<>(), 0); | |||||
private final List<SwMap> rows; | |||||
// 总数, -1 表示需要异步获取数量, >=0 表示总数 | |||||
private int total; | |||||
private SwListData(List<SwMap> rows, int total) { | |||||
this.rows = rows; | |||||
this.total = total; | |||||
} | |||||
public static SwListData create(List<SwMap> list, boolean loadCount) { | |||||
if (list == null) { | |||||
return SwListData.EMPTY; | |||||
} | |||||
if (loadCount) { | |||||
return new SwListData(list, -1); | |||||
} else { | |||||
return new SwListData(list, list.size()); | |||||
} | |||||
} | |||||
public boolean isEmpty() { | |||||
return rows == null || rows.isEmpty(); | |||||
} | |||||
} |
@@ -0,0 +1,57 @@ | |||||
package cc.smtweb.framework.core.mvc.service.list; | |||||
/** | |||||
* Created by Akmm at 13-4-16 上午10:51 | |||||
* 合计行列定义 | |||||
*/ | |||||
public class FooterField { | |||||
//计数 不同值计数 | |||||
public static final String SUM_TYPE_COUNT = "COUNT"; | |||||
//计数 记录数 | |||||
public static final String SUM_TYPE_COUNT_ALL = "COUNT_A"; | |||||
//求和 | |||||
public static final String SUM_TYPE_SUM = "SUM"; | |||||
//整数求和 | |||||
public static final String SUM_TYPE_SUM_NUM = "SUM_NUM"; | |||||
//平均数 | |||||
public static final String SUM_TYPE_AVG = "AVG"; | |||||
//最大值 | |||||
public static final String SUM_TYPE_MAX = "MAX"; | |||||
//最小值 | |||||
public static final String SUM_TYPE_MIN = "MIN"; | |||||
//静态文本 | |||||
public static final String STATIC_TEXT = "TEXT"; | |||||
public String field; | |||||
public String type; | |||||
public String text; | |||||
public FooterField() { | |||||
} | |||||
public FooterField(String field, String type, String text) { | |||||
this.field = field; | |||||
this.type = type; | |||||
this.text = text; | |||||
} | |||||
public String toString() { | |||||
return "field=" + field + ";type=" + type + ";text=" + text; | |||||
} | |||||
public static FooterField newSumField(String field) { | |||||
return new FooterField(field, SUM_TYPE_SUM, null); | |||||
} | |||||
public static FooterField newCountField(String field) { | |||||
return new FooterField(field, SUM_TYPE_COUNT, null); | |||||
} | |||||
public static FooterField newTextField(String field, String text) { | |||||
return new FooterField(field, STATIC_TEXT, text); | |||||
} | |||||
public static FooterField newSumField(String field, String type) { | |||||
return new FooterField(field, type, null); | |||||
} | |||||
} |
@@ -20,4 +20,12 @@ public class UserSession implements Serializable { | |||||
private long siteId; | private long siteId; | ||||
// 终端类型 | // 终端类型 | ||||
private byte terminalType; | private byte terminalType; | ||||
public static UserSession createSys() { | |||||
UserSession us = new UserSession(); | |||||
us.userId = 1; | |||||
us.companyId = 1; | |||||
us.terminalType = 0; | |||||
return us; | |||||
} | |||||
} | } |
@@ -4,11 +4,14 @@ import cc.smtweb.framework.core.db.impl.BaseBean; | |||||
import cc.smtweb.framework.core.db.impl.DefaultEntity; | import cc.smtweb.framework.core.db.impl.DefaultEntity; | ||||
import cc.smtweb.framework.core.util.kryo.KryoTool; | import cc.smtweb.framework.core.util.kryo.KryoTool; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.lang.reflect.ParameterizedType; | import java.lang.reflect.ParameterizedType; | ||||
import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.HashSet; | |||||
import java.util.Set; | |||||
/** | /** | ||||
* Created by Akmm at 2022/1/5 9:10 | * Created by Akmm at 2022/1/5 9:10 | ||||
@@ -81,4 +84,18 @@ public class CommUtil { | |||||
return null; | return null; | ||||
} | } | ||||
} | } | ||||
public static String getSqlInIds(Collection<String> ids) { | |||||
if (null == ids || ids.isEmpty()) return ""; | |||||
StringBuilder s = new StringBuilder(128); | |||||
Set<String> set = new HashSet<>(); | |||||
for (String id : ids) { | |||||
if (set.contains(id)) continue; | |||||
set.add(id); | |||||
if (StringUtils.isEmpty(id)) continue; | |||||
s.append(id).append(","); | |||||
} | |||||
if (s.length() == 0) return ""; | |||||
return s.substring(0, s.length() - 1); | |||||
} | |||||
} | } |
@@ -1,5 +1,9 @@ | |||||
package cc.smtweb.framework.core.util; | package cc.smtweb.framework.core.util; | ||||
import cc.smtweb.framework.core.SwMap; | |||||
import cc.smtweb.framework.core.db.impl.BaseBean; | |||||
import cc.smtweb.framework.core.db.impl.DefaultEntity; | |||||
import cc.smtweb.framework.core.db.vo.ModelTable; | |||||
import cc.smtweb.framework.core.exception.JsonParseException; | import cc.smtweb.framework.core.exception.JsonParseException; | ||||
import cc.smtweb.framework.core.util.jackson.*; | import cc.smtweb.framework.core.util.jackson.*; | ||||
import com.fasterxml.jackson.annotation.JsonInclude; | import com.fasterxml.jackson.annotation.JsonInclude; | ||||
@@ -30,241 +34,250 @@ import static org.springframework.beans.BeanUtils.getPropertyDescriptors; | |||||
*/ | */ | ||||
@Slf4j | @Slf4j | ||||
public class JsonUtil { | public class JsonUtil { | ||||
public final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); | |||||
public final static ObjectMapper API_OBJECT_MAPPER = new ObjectMapper(); | |||||
public final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); | |||||
public final static ObjectMapper API_OBJECT_MAPPER = new ObjectMapper(); | |||||
static { | |||||
init(OBJECT_MAPPER); | |||||
// 不序列化空值 | |||||
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); | |||||
static { | |||||
init(OBJECT_MAPPER); | |||||
// 不序列化空值 | |||||
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); | |||||
// OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); | // OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); | ||||
// OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); | // OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); | ||||
// // 设置将MAP转换为JSON时候只转换值不等于NULL的 | // // 设置将MAP转换为JSON时候只转换值不等于NULL的 | ||||
// objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); | // objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); | ||||
init(API_OBJECT_MAPPER); | |||||
API_OBJECT_MAPPER.getSerializerProvider().setNullValueSerializer(new NullSerializer()); | |||||
} | |||||
private static void init(ObjectMapper mapper) { | |||||
// JSON转化为对象时忽略未对应的属性 | |||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |||||
init(API_OBJECT_MAPPER); | |||||
API_OBJECT_MAPPER.getSerializerProvider().setNullValueSerializer(new NullSerializer()); | |||||
} | |||||
SimpleModule module = new SimpleModule(); | |||||
LongSerializer longSerializer = new LongSerializer(); | |||||
module.addSerializer(Long.class, longSerializer); | |||||
module.addSerializer(Long.TYPE, longSerializer); | |||||
private static void init(ObjectMapper mapper) { | |||||
// JSON转化为对象时忽略未对应的属性 | |||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |||||
DateSerializer dateSerializer = new DateSerializer(); | |||||
module.addSerializer(java.sql.Date.class, dateSerializer); | |||||
TimeSerializer timeSerializer = new TimeSerializer(); | |||||
module.addSerializer(java.sql.Time.class, timeSerializer); | |||||
SimpleModule module = new SimpleModule(); | |||||
LongSerializer longSerializer = new LongSerializer(); | |||||
module.addSerializer(Long.class, longSerializer); | |||||
module.addSerializer(Long.TYPE, longSerializer); | |||||
module.addDeserializer(Timestamp.class, new TimestampDeserializer()); | |||||
module.addDeserializer(java.util.Date.class, new DateDeserializer()); | |||||
DateSerializer dateSerializer = new DateSerializer(); | |||||
module.addSerializer(java.sql.Date.class, dateSerializer); | |||||
TimeSerializer timeSerializer = new TimeSerializer(); | |||||
module.addSerializer(java.sql.Time.class, timeSerializer); | |||||
// module.addSerializer(BaseBean.class, new BaseBeanSerializer()); | |||||
mapper.registerModule(module); | |||||
} | |||||
module.addDeserializer(Timestamp.class, new TimestampDeserializer()); | |||||
module.addDeserializer(java.util.Date.class, new DateDeserializer()); | |||||
public static JsonNode readTree(String body) { | |||||
try { | |||||
return OBJECT_MAPPER.readTree(body); | |||||
} catch (IOException e) { | |||||
log.error(e.getMessage(), e); | |||||
mapper.registerModule(module); | |||||
} | } | ||||
return null; | |||||
} | |||||
public static JsonNode readTree(String body) { | |||||
try { | |||||
return OBJECT_MAPPER.readTree(body); | |||||
} catch (IOException e) { | |||||
log.error(e.getMessage(), e); | |||||
} | |||||
// 创建新节点 | |||||
public static ObjectNode createObjectNode() { | |||||
return OBJECT_MAPPER.createObjectNode(); | |||||
} | |||||
return null; | |||||
} | |||||
// 将 JsonNode 对象转成 json | |||||
public static String writeValueAsString(JsonNode newNode) { | |||||
try { | |||||
return OBJECT_MAPPER.writeValueAsString(newNode); | |||||
} catch (JsonProcessingException e) { | |||||
log.error(e.getMessage(), e); | |||||
// 创建新节点 | |||||
public static ObjectNode createObjectNode() { | |||||
return OBJECT_MAPPER.createObjectNode(); | |||||
} | } | ||||
return null; | |||||
} | |||||
// 将 JsonNode 对象转成 json | |||||
public static String writeValueAsString(JsonNode newNode) { | |||||
try { | |||||
return OBJECT_MAPPER.writeValueAsString(newNode); | |||||
} catch (JsonProcessingException e) { | |||||
log.error(e.getMessage(), e); | |||||
} | |||||
public static <T> T parse(String str, Class<T> clazz) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | return null; | ||||
} else { | |||||
return OBJECT_MAPPER.readValue(str, clazz); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to " + clazz + " type", e); | |||||
} | } | ||||
} | |||||
/** | |||||
* 将Map对象转换为Bean对象 | |||||
* @param map Map对象 | |||||
* @param clazz Bean对象类 | |||||
* @param <T> Bean对象类型 | |||||
* @return Bean对象实例 | |||||
*/ | |||||
public static <T> T parse(Map map, Class<T> clazz) { | |||||
try { | |||||
if (map == null || map.isEmpty()) { | |||||
return null; | |||||
} else { | |||||
// 对象实例化 | |||||
T bean = BeanUtils.instantiateClass(clazz); | |||||
// 循环设置对象属性 | |||||
PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); | |||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { | |||||
String properName = propertyDescriptor.getName(); | |||||
// 过滤class属性 | |||||
if (!"class".equals(properName)) { | |||||
if (map.containsKey(properName)) { | |||||
Method writeMethod = propertyDescriptor.getWriteMethod(); | |||||
if (writeMethod != null) { | |||||
Object value = map.get(properName); | |||||
if (!writeMethod.isAccessible()) { | |||||
writeMethod.setAccessible(true); | |||||
} | |||||
writeMethod.invoke(bean, value); | |||||
} | |||||
public static <T> T parse(String str, Class<T> clazz) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(str, clazz); | |||||
} | } | ||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to " + clazz + " type", e); | |||||
} | } | ||||
} | |||||
return bean; | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert map to " + clazz + " type", e); | |||||
/** | |||||
* 将Map对象转换为Bean对象 | |||||
* | |||||
* @param map Map对象 | |||||
* @param clazz Bean对象类 | |||||
* @param <T> Bean对象类型 | |||||
* @return Bean对象实例 | |||||
*/ | |||||
public static <T> T parse(Map map, Class<T> clazz) { | |||||
try { | |||||
if (map == null || map.isEmpty()) { | |||||
return null; | |||||
} else { | |||||
// 对象实例化 | |||||
T bean = BeanUtils.instantiateClass(clazz); | |||||
if (SwMap.class.isAssignableFrom(clazz)) { | |||||
((SwMap) bean).putAll(map); | |||||
} else { | |||||
// 循环设置对象属性 | |||||
PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); | |||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { | |||||
String properName = propertyDescriptor.getName(); | |||||
// 过滤class属性 | |||||
if (!"class".equals(properName)) { | |||||
if (map.containsKey(properName)) { | |||||
Method writeMethod = propertyDescriptor.getWriteMethod(); | |||||
if (writeMethod != null) { | |||||
Object value = map.get(properName); | |||||
if (!writeMethod.isAccessible()) { | |||||
writeMethod.setAccessible(true); | |||||
} | |||||
writeMethod.invoke(bean, value); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return bean; | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert map to " + clazz + " type", e); | |||||
} | |||||
} | } | ||||
} | |||||
public static <T> T parse(InputStream is, Class<T> clazz) { | |||||
try { | |||||
if (is == null) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(is, clazz); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to " + clazz + " type", e); | |||||
public static <T> T parse(InputStream is, Class<T> clazz) { | |||||
try { | |||||
if (is == null) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(is, clazz); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to " + clazz + " type", e); | |||||
} | |||||
} | } | ||||
} | |||||
public static <T> T parse(byte[] str, Class<T> clazz) { | |||||
try { | |||||
if (str == null || str.length == 0) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(str, clazz); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to " + clazz + " type", e); | |||||
public static <T> T parse(byte[] str, Class<T> clazz) { | |||||
try { | |||||
if (str == null || str.length == 0) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(str, clazz); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to " + clazz + " type", e); | |||||
} | |||||
} | } | ||||
} | |||||
public static JsonNode parse(String str) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readTree(str); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to JsonNode", e); | |||||
public static JsonNode parse(String str) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readTree(str); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to JsonNode", e); | |||||
} | |||||
} | } | ||||
} | |||||
/** | |||||
* 转换json文本为对象列表 | |||||
* @param is json文本流 | |||||
* @param <T> 列表中对象类 | |||||
* @param clazz 列表中的对象类 | |||||
* @return 列表对象 | |||||
*/ | |||||
public static <T> List<T> parseList(InputStream is, Class<T> clazz) { | |||||
try { | |||||
if (is == null) { | |||||
return null; | |||||
} else { | |||||
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); | |||||
return OBJECT_MAPPER.readValue(is, javaType); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to list<T> type", e); | |||||
/** | |||||
* 转换json文本为对象列表 | |||||
* | |||||
* @param is json文本流 | |||||
* @param <T> 列表中对象类 | |||||
* @param clazz 列表中的对象类 | |||||
* @return 列表对象 | |||||
*/ | |||||
public static <T> List<T> parseList(InputStream is, Class<T> clazz) { | |||||
try { | |||||
if (is == null) { | |||||
return null; | |||||
} else { | |||||
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); | |||||
return OBJECT_MAPPER.readValue(is, javaType); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to list<T> type", e); | |||||
} | |||||
} | } | ||||
} | |||||
/** | |||||
* 转换json文本为对象列表 | |||||
* @param str json文本字节数组 | |||||
* @param <T> 列表中对象类 | |||||
* @param clazz 列表中的对象类 | |||||
* @return 列表对象 | |||||
*/ | |||||
public static <T> List<T> parseList(byte[] str, Class<T> clazz) { | |||||
try { | |||||
if (str == null || str.length == 0) { | |||||
return null; | |||||
} else { | |||||
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); | |||||
return OBJECT_MAPPER.readValue(str, javaType); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to list<T> type", e); | |||||
/** | |||||
* 转换json文本为对象列表 | |||||
* | |||||
* @param str json文本字节数组 | |||||
* @param <T> 列表中对象类 | |||||
* @param clazz 列表中的对象类 | |||||
* @return 列表对象 | |||||
*/ | |||||
public static <T> List<T> parseList(byte[] str, Class<T> clazz) { | |||||
try { | |||||
if (str == null || str.length == 0) { | |||||
return null; | |||||
} else { | |||||
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); | |||||
return OBJECT_MAPPER.readValue(str, javaType); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to list<T> type", e); | |||||
} | |||||
} | } | ||||
} | |||||
/** | |||||
* 转换json文本为对象列表 | |||||
* @param str json文本 | |||||
* @param <T> 列表中对象类 | |||||
* @param clazz 列表中的对象类 | |||||
* @return 列表对象 | |||||
*/ | |||||
public static <T> List<T> parseList(String str, Class<T> clazz) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); | |||||
return OBJECT_MAPPER.readValue(str, javaType); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to list<" + clazz.getSimpleName() + "> type", e); | |||||
/** | |||||
* 转换json文本为对象列表 | |||||
* | |||||
* @param str json文本 | |||||
* @param <T> 列表中对象类 | |||||
* @param clazz 列表中的对象类 | |||||
* @return 列表对象 | |||||
*/ | |||||
public static <T> List<T> parseList(String str, Class<T> clazz) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); | |||||
return OBJECT_MAPPER.readValue(str, javaType); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to list<" + clazz.getSimpleName() + "> type", e); | |||||
} | |||||
} | } | ||||
} | |||||
public static Map parseMap(String str) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(str, Map.class); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to Map type", e); | |||||
public static Map parseMap(String str) { | |||||
try { | |||||
if (StringUtils.isBlank(str)) { | |||||
return null; | |||||
} else { | |||||
return OBJECT_MAPPER.readValue(str, Map.class); | |||||
} | |||||
} catch (Exception e) { | |||||
throw new JsonParseException("can't convert this json to Map type", e); | |||||
} | |||||
} | } | ||||
} | |||||
public static String encodeString(Object obj) { | |||||
try { | |||||
return OBJECT_MAPPER.writeValueAsString(obj); | |||||
} catch (JsonProcessingException e) { | |||||
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); | |||||
public static String encodeString(Object obj) { | |||||
try { | |||||
return OBJECT_MAPPER.writeValueAsString(obj); | |||||
} catch (JsonProcessingException e) { | |||||
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); | |||||
} | |||||
} | } | ||||
} | |||||
public static byte[] encodeBytes(Object obj) { | |||||
try { | |||||
return OBJECT_MAPPER.writeValueAsBytes(obj); | |||||
} catch (JsonProcessingException e) { | |||||
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); | |||||
public static byte[] encodeBytes(Object obj) { | |||||
try { | |||||
return OBJECT_MAPPER.writeValueAsBytes(obj); | |||||
} catch (JsonProcessingException e) { | |||||
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); | |||||
} | |||||
} | } | ||||
} | |||||
} | } |
@@ -173,7 +173,7 @@ public class MapUtil { | |||||
} | } | ||||
public static Boolean readBool(Map map, String name) { | public static Boolean readBool(Map map, String name) { | ||||
return readBool(map, name, null); | |||||
return readBool(map, name, false); | |||||
} | } | ||||
public static Boolean readBool(Map map, String name, Boolean defaultValue) { | public static Boolean readBool(Map map, String name, Boolean defaultValue) { | ||||
@@ -184,7 +184,7 @@ public class MapUtil { | |||||
return (Boolean) s; | return (Boolean) s; | ||||
} else { | } else { | ||||
String value = s.toString(); | String value = s.toString(); | ||||
if ("true".equalsIgnoreCase(value)) { | |||||
if ("true".equalsIgnoreCase(value) || "1".equals(value) || "y".equalsIgnoreCase(value)) { | |||||
return Boolean.TRUE; | return Boolean.TRUE; | ||||
} | } | ||||
} | } | ||||
@@ -0,0 +1,24 @@ | |||||
package cc.smtweb.framework.core.util.jackson; | |||||
import cc.smtweb.framework.core.db.impl.BaseBean; | |||||
import com.fasterxml.jackson.core.JsonGenerator; | |||||
import com.fasterxml.jackson.core.JsonProcessingException; | |||||
import com.fasterxml.jackson.databind.JsonSerializer; | |||||
import com.fasterxml.jackson.databind.SerializerProvider; | |||||
import java.io.IOException; | |||||
import java.util.Date; | |||||
public class BaseBeanSerializer extends JsonSerializer<BaseBean> { | |||||
@Override | |||||
public void serialize(BaseBean value, JsonGenerator gen, | |||||
SerializerProvider serializers) throws IOException, | |||||
JsonProcessingException { | |||||
if (value == null) { | |||||
gen.writeNull(); | |||||
} else { | |||||
gen.writeObject(value.getData()); | |||||
} | |||||
} | |||||
} |
@@ -1,169 +0,0 @@ | |||||
{ | |||||
"fields": [ | |||||
{ | |||||
"name": "table_id", | |||||
"fieldType": "ID", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID" | |||||
}, | |||||
{ | |||||
"name": "prjoect_id", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID", | |||||
"link": "asp_model_project" | |||||
},{ | |||||
"name": "catalog_id", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID", | |||||
"link": "asp_model_catalog" | |||||
},{ | |||||
"name": "database_id", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID", | |||||
"link": "asp_model_database" | |||||
}, | |||||
{ | |||||
"name": "table_extends", | |||||
"fieldType": "", | |||||
"dataType": "REMARK", | |||||
"null": "0", | |||||
"default": "", | |||||
"title": "继承关系", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_name", | |||||
"fieldType": "CODE", | |||||
"dataType": "CODE", | |||||
"null": "0", | |||||
"default": "", | |||||
"title": "表名", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_title", | |||||
"fieldType": "NAME", | |||||
"dataType": "NAME", | |||||
"null": "0", | |||||
"default": "", | |||||
"title": "中文名", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_abbr", | |||||
"fieldType": "", | |||||
"dataType": "CODE", | |||||
"null": "1", | |||||
"default": "", | |||||
"title": "缩写,用于字段和索引组成", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_type", | |||||
"fieldType": "", | |||||
"dataType": "SMALLINT", | |||||
"null": "1", | |||||
"default": "0", | |||||
"title": "类别:0-普通表,1 树型表 2 编码表 9-虚拟抽象表 11 视图", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "need_cache", | |||||
"fieldType": "", | |||||
"dataType": "BOOL", | |||||
"null": "1", | |||||
"default": "0", | |||||
"title": "需要缓存", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_content", | |||||
"fieldType": "", | |||||
"dataType": "TEXT", | |||||
"null": "1", | |||||
"default": "0", | |||||
"title": "表详细信息", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_create_uid", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "创建人", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_update_uid", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "最后更新人", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_create_at", | |||||
"fieldType": "", | |||||
"dataType": "DATETIME", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "创建时间", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_update_at", | |||||
"fieldType": "", | |||||
"dataType": "DATETIME", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "最后更新时间", | |||||
"link": "", | |||||
"editor": "" | |||||
} | |||||
], | |||||
"indexs": [ | |||||
{ | |||||
"name": "pk", | |||||
"fields": "table_id", | |||||
"type": "P" | |||||
} | |||||
], | |||||
"caches": [ | |||||
{ | |||||
"name": "n", | |||||
"title": "按库名", | |||||
"fields": "db_name", | |||||
"type": "M" | |||||
}, | |||||
{ | |||||
"name": "prj", | |||||
"title": "按项目", | |||||
"fields": "db_prj_id", | |||||
"type": "L" | |||||
} | |||||
] | |||||
} | |||||
@@ -1,169 +0,0 @@ | |||||
{ | |||||
"fields": [ | |||||
{ | |||||
"name": "table_id", | |||||
"fieldType": "ID", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID" | |||||
}, | |||||
{ | |||||
"name": "prjoect_id", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID", | |||||
"link": "asp_model_project" | |||||
},{ | |||||
"name": "catalog_id", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID", | |||||
"link": "asp_model_catalog" | |||||
},{ | |||||
"name": "database_id", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "ID", | |||||
"link": "asp_model_database" | |||||
}, | |||||
{ | |||||
"name": "table_extends", | |||||
"fieldType": "", | |||||
"dataType": "REMARK", | |||||
"null": "0", | |||||
"default": "", | |||||
"title": "继承关系", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_name", | |||||
"fieldType": "CODE", | |||||
"dataType": "CODE", | |||||
"null": "0", | |||||
"default": "", | |||||
"title": "表名", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_title", | |||||
"fieldType": "NAME", | |||||
"dataType": "NAME", | |||||
"null": "0", | |||||
"default": "", | |||||
"title": "中文名", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_abbr", | |||||
"fieldType": "", | |||||
"dataType": "CODE", | |||||
"null": "1", | |||||
"default": "", | |||||
"title": "缩写,用于字段和索引组成", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_type", | |||||
"fieldType": "", | |||||
"dataType": "SMALLINT", | |||||
"null": "1", | |||||
"default": "0", | |||||
"title": "类别:0-普通表,1 树型表 2 编码表 9-虚拟抽象表 11 视图", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "need_cache", | |||||
"fieldType": "", | |||||
"dataType": "BOOL", | |||||
"null": "1", | |||||
"default": "0", | |||||
"title": "需要缓存", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_content", | |||||
"fieldType": "", | |||||
"dataType": "TEXT", | |||||
"null": "1", | |||||
"default": "0", | |||||
"title": "表详细信息", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_create_uid", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "创建人", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_update_uid", | |||||
"fieldType": "", | |||||
"dataType": "ID", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "最后更新人", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_create_at", | |||||
"fieldType": "", | |||||
"dataType": "DATETIME", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "创建时间", | |||||
"link": "", | |||||
"editor": "" | |||||
}, | |||||
{ | |||||
"name": "table_update_at", | |||||
"fieldType": "", | |||||
"dataType": "DATETIME", | |||||
"null": "1", | |||||
"default": "-1", | |||||
"title": "最后更新时间", | |||||
"link": "", | |||||
"editor": "" | |||||
} | |||||
], | |||||
"indexs": [ | |||||
{ | |||||
"name": "pk", | |||||
"fields": "table_id", | |||||
"type": "P" | |||||
} | |||||
], | |||||
"caches": [ | |||||
{ | |||||
"name": "n", | |||||
"title": "按库名", | |||||
"fields": "db_name", | |||||
"type": "M" | |||||
}, | |||||
{ | |||||
"name": "prj", | |||||
"title": "按项目", | |||||
"fields": "db_prj_id", | |||||
"type": "L" | |||||
} | |||||
] | |||||
} | |||||
@@ -7,10 +7,7 @@ import cc.smtweb.framework.core.annotation.SwParam; | |||||
import cc.smtweb.framework.core.annotation.SwService; | import cc.smtweb.framework.core.annotation.SwService; | ||||
import cc.smtweb.framework.core.db.DbEngine; | import cc.smtweb.framework.core.db.DbEngine; | ||||
import cc.smtweb.framework.core.db.EntityDao; | import cc.smtweb.framework.core.db.EntityDao; | ||||
import cc.smtweb.framework.core.mvc.service.AbstractCompService; | |||||
import cc.smtweb.framework.core.mvc.service.DefaultLoadHandler; | |||||
import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler; | |||||
import cc.smtweb.framework.core.mvc.service.IHandler; | |||||
import cc.smtweb.framework.core.mvc.service.*; | |||||
import cc.smtweb.framework.core.session.UserSession; | import cc.smtweb.framework.core.session.UserSession; | ||||
import cc.smtweb.system.bpm.engine.entity.AspModelPO; | import cc.smtweb.system.bpm.engine.entity.AspModelPO; | ||||
@@ -28,7 +25,9 @@ public class ModelProjectService extends AbstractCompService { | |||||
case TYPE_SAVE: | case TYPE_SAVE: | ||||
return new DefaultSaveHandler<>(ModelProject.ENTITY_NAME); | return new DefaultSaveHandler<>(ModelProject.ENTITY_NAME); | ||||
case TYPE_DEL: | case TYPE_DEL: | ||||
return new DefaultSaveHandler<>(ModelProject.ENTITY_NAME); | |||||
return new DefaultDelHandler<>(ModelProject.ENTITY_NAME); | |||||
case TYPE_LIST: | |||||
return new DefaultListHandler<>(ModelProject.ENTITY_NAME); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
@@ -32,9 +32,9 @@ spring: | |||||
password: | password: | ||||
datasource: | datasource: | ||||
driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
url: jdbc:mysql://127.0.0.1:3306/sw_user?serverTimezone=UTC&allowMultiQueries=true&useSSL=false | |||||
url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false | |||||
username: root | username: root | ||||
password: 1681860 | |||||
password: root | |||||
servlet: | servlet: | ||||
multipart: | multipart: | ||||
max-file-size: 104857600000 | max-file-size: 104857600000 | ||||
@@ -32,9 +32,9 @@ spring: | |||||
password: | password: | ||||
datasource: | datasource: | ||||
driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
url: jdbc:mysql://127.0.0.1:3306/sw_user?serverTimezone=UTC&allowMultiQueries=true&useSSL=false | |||||
url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false | |||||
username: root | username: root | ||||
password: 1681860 | |||||
password: root | |||||
servlet: | servlet: | ||||
multipart: | multipart: | ||||
max-file-size: 104857600000 | max-file-size: 104857600000 | ||||