瀏覽代碼

pom依赖调整

yucheng 4 年之前
父節點
當前提交
3415a74e5b
共有 19 個文件被更改,包括 2607 次插入168 次删除
  1. 4 0
      fm-common/pom.xml
  2. 108 0
      fm-common/src/main/java/com/persagy/fm/common/context/AppContext.java
  3. 38 0
      fm-common/src/main/java/com/persagy/fm/common/context/DefaultAppContext.java
  4. 27 0
      fm-common/src/main/java/com/persagy/fm/common/context/DefaultAppContextFactory.java
  5. 21 0
      fm-common/src/main/java/com/persagy/fm/common/context/IAppContextFactory.java
  6. 995 0
      fm-common/src/main/java/com/persagy/fm/common/helper/RedisHelper.java
  7. 228 0
      fm-common/src/main/java/com/persagy/fm/common/model/data/DataType.java
  8. 0 4
      fm-common/src/main/java/com/persagy/fm/common/model/entity/AuditableEntity.java
  9. 106 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/ChainLogicExpression.java
  10. 238 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/Condition.java
  11. 29 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/ExpressionType.java
  12. 19 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/IExpression.java
  13. 109 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/LogicExpression.java
  14. 161 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/Operator.java
  15. 64 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/SqlExpression.java
  16. 255 0
      fm-common/src/main/java/com/persagy/fm/common/model/query/ValueExpression.java
  17. 43 35
      fm-common/src/main/java/com/persagy/fm/common/utils/TypeConvertUtil.java
  18. 160 125
      fm-parent/pom.xml
  19. 2 4
      fm-server/src/main/java/com/persagy/fm/server/ServerApplication.java

+ 4 - 0
fm-common/pom.xml

@@ -15,5 +15,9 @@
             <groupId>com.persagy</groupId>
             <artifactId>integrated-common-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.persagy</groupId>
+            <artifactId>integrated-redis-spring-boot-starter</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 108 - 0
fm-common/src/main/java/com/persagy/fm/common/context/AppContext.java

@@ -0,0 +1,108 @@
+package com.persagy.fm.common.context;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.Serializable;
+
+
+/**
+ * 应用访问上下文类,主要负责上下文的属性和参数的操作
+ * @author Charlie Yu
+ * @version 1.0 2021-03-04
+ */
+@Slf4j
+public abstract class AppContext implements Serializable {
+
+    /** 序列id */
+    private static final long serialVersionUID = 697592850956445675L;
+
+    /** 工厂对象 */
+    private static IAppContextFactory factory = null;
+
+    /**
+     * 取得当前线程中的上下文对象
+     * @return 上下文对象
+     */
+    public static AppContext getContext() {
+        return getFactory().getContext();
+    }
+
+    /**
+     * 反注册当前上下文对象
+     */
+    public static void unload() {
+        getFactory().unloadContext();
+    }
+
+    /**
+     * 取得上下文工厂类
+     * @return 上下文工厂类
+     */
+    public static IAppContextFactory getFactory() {
+        if (factory == null) {
+            factory = new DefaultAppContextFactory();
+        }
+        return factory;
+    }
+
+    /**
+     * 取得操作用户主键
+     * @return 用户主键
+     */
+    public abstract String getUserId();
+
+    /**
+     * 设置操作用户主键
+     * @param userId 用户主键
+     */
+    public abstract void setUserId(String userId);
+
+    /**
+     * 取得操作用户名
+     * @return 用户名
+     */
+    public abstract String getUserName();
+
+    /**
+     * 设置操作用户名
+     * @param userName 用户名
+     */
+    public abstract void setUserName(String userName);
+
+    /**
+     * 取得租户
+     * @return 租户
+     */
+    public abstract String getTenant();
+
+    /**
+     * 设置租户
+     * @param tenant 租户
+     */
+    public abstract void setTenant(String tenant);
+
+    /**
+     * 取得产品线
+     * @return 产品线
+     */
+    public abstract String getProductLine();
+
+    /**
+     * 设置产品线
+     * @param productLine 产品线
+     */
+    public abstract void setProductLine(String productLine);
+
+    /**
+     * 动态数据源支持
+     * @return java.lang.String
+     **/
+    public abstract String getDataSourceName();
+
+    /**
+     * 设置动态数据源
+     * @param dataSourceName 动态数据源
+     * @return void
+     **/
+    public abstract void setDataSourceName(String dataSourceName);
+}

+ 38 - 0
fm-common/src/main/java/com/persagy/fm/common/context/DefaultAppContext.java

@@ -0,0 +1,38 @@
+package com.persagy.fm.common.context;
+
+import lombok.Data;
+
+/**
+ * 默认应用上下文
+ * @author Charlie Yu
+ * @version 1.0 2021-03-04
+ */
+@Data
+public class DefaultAppContext extends AppContext {
+
+    /**
+     * 用户主键
+     */
+    private String userId;
+
+    /**
+     * 用户名
+     */
+    private String userName;
+
+    /**
+     * 租户
+     */
+    private String tenant;
+
+    /**
+     * 所属产品线
+     */
+    private String productLine;
+
+    /**
+     * 数据源名称
+     */
+    private String dataSourceName;
+
+}

+ 27 - 0
fm-common/src/main/java/com/persagy/fm/common/context/DefaultAppContextFactory.java

@@ -0,0 +1,27 @@
+package com.persagy.fm.common.context;
+
+/**
+ * 默认的appContext工厂
+ * @author Charlie Yu
+ * @version 1.0 2021-03-04
+ */
+public class DefaultAppContextFactory implements IAppContextFactory {
+
+    /** 线程级的上下文 */
+    private ThreadLocal<AppContext> context = new ThreadLocal<>();
+
+    @Override
+    public AppContext getContext() {
+        AppContext c = context.get();
+        if(c == null){
+            c = new DefaultAppContext();
+            context.set(c);
+        }
+        return c;
+    }
+
+    @Override
+    public void unloadContext() {
+        context.remove();
+    }
+}

+ 21 - 0
fm-common/src/main/java/com/persagy/fm/common/context/IAppContextFactory.java

@@ -0,0 +1,21 @@
+package com.persagy.fm.common.context;
+
+/**
+ * app上下问工厂类
+ * @author Charlie Yu
+ * @version 1.0 2021-03-04
+ */
+public interface IAppContextFactory {
+
+    /**
+     * 创建应用上下文对象
+     * @return 应用上下文对象
+     */
+    AppContext getContext();
+
+    /**
+     * 卸载应用上下文对象
+     * @return 应用上下文对象
+     */
+    void unloadContext();
+}

+ 995 - 0
fm-common/src/main/java/com/persagy/fm/common/helper/RedisHelper.java

@@ -0,0 +1,995 @@
+package com.persagy.fm.common.helper;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.SessionCallback;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.serializer.GenericToStringSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * Redis工具类
+ * @author Charlie Yu
+ * @version 1.0 2021-03-04
+ */
+@Slf4j
+public final class RedisHelper {
+
+    /** jedis模板 */
+    private static RedisTemplate redisTemplate = null;
+
+    /** 助手类,私有构造方法 */
+    private RedisHelper() {
+    }
+
+    /**
+     * 获取缓存模板
+     * @return 获取缓存模板
+     */
+    public static RedisTemplate getTemplate() {
+        if (redisTemplate == null) {
+            redisTemplate = SpringHelper.getBean("redisTemplate", RedisTemplate.class);
+            if (redisTemplate == null) {
+                Map<String, RedisTemplate> beans = SpringHelper.getBeansOfType(RedisTemplate.class);
+                if (!beans.isEmpty()) {
+                    redisTemplate = beans.values().iterator().next();
+                }
+            }
+        }
+        if (redisTemplate == null) {
+            log.error("redis config is error! please init RedisTemplate bean!");
+            throw new RuntimeException("redis config is error! please init RedisTemplate bean!");
+        }
+        return redisTemplate;
+    }
+
+    /**
+     * 按键值模式删除指定键值
+     * @param keyMode 键值匹配模式
+     * @return 清楚记录数组
+     */
+    public static long clearKeys(String keyMode) {
+        String clearScript = "local keys = redis.call('keys', ARGV[1]) for i=1,#keys,5000 do redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) end return #keys";
+        return (long) getTemplate().execute(new DefaultRedisScript<>(clearScript, Long.class), getKeySerializer(), getValueSerializer(), new ArrayList(), keyMode);
+    }
+
+    /**
+     * 按键值模式删除指定键值
+     * @param keys 键值列表
+     * @return 清楚记录数
+     */
+    public static long clearKeys(List<String> keys) {
+        String clearScript = "return redis.call('del', unpack(KEY))";
+        return (long) getTemplate().execute(new DefaultRedisScript<>(clearScript, Long.class), getKeySerializer(), getValueSerializer(), keys, new Object[0]);
+    }
+
+    /**
+     * 指定键值累加操作
+     * @param key 键值
+     * @return 累加结果
+     */
+    public static Long incr(final String key) {
+        return (Long) getTemplate().execute((RedisCallback<Long>) connection -> connection.incr(keySerial(key)));
+    }
+
+    /**
+     * 指定键值累减操作
+     * @param key 键值
+     * @return 累减结果
+     */
+    public static Long decr(final String key) {
+        return (Long) getTemplate().execute((RedisCallback<Long>) connection -> connection.decr(keySerial(key)));
+    }
+
+    /**
+     * 按键值获取存储数据
+     * @param key 键值
+     * @param <T> 存储值泛型
+     * @return 存储值
+     */
+    public static <T> T cmdGet(final String key, Class<T> cl) {
+        return strDeserial(cl, getBytes(keySerial(key)));
+    }
+
+    /**
+     * 按键值获取存储数据
+     * @param key 键值
+     * @param <T> 存储值泛型
+     * @return 存储值
+     */
+    public static <T> T get(String key) {
+        return objDeserial(getBytes(keySerial(key)));
+    }
+
+    /**
+     * 按键值获取存储数据
+     * @param key 键值
+     * @return 存储值
+     */
+    public static byte[] getBytes(final byte[] key) {
+        return (byte[]) getTemplate().execute((RedisCallback<byte[]>) connection -> connection.get(key));
+    }
+
+    /**
+     * 按键值存储新的值并获取旧存储数据
+     * @param key   键值
+     * @param value 新存储值
+     * @param <T>   存储值泛型
+     * @return 旧存储值
+     */
+    public static <T> T cmdGetAndSet(String key, T value) {
+        Class<T> cl = (Class<T>) value.getClass();
+        return strDeserial(cl, getAndSetBytes(keySerial(key), strSerial(value)));
+    }
+
+    /**
+     * 按键值存储新的值并获取旧存储数据
+     * @param key   键值
+     * @param value 新存储值
+     * @param <T>   存储值泛型
+     * @return 旧存储值
+     */
+    public static <T> T getAndSet(String key, T value) {
+        return objDeserial(getAndSetBytes(keySerial(key), objSerial(value)));
+    }
+
+    /**
+     * 按键值存储新的值并获取旧存储数据
+     * @param key   键值
+     * @param value 新存储值
+     * @return 旧存储值
+     */
+    public static byte[] getAndSetBytes(final byte[] key, final byte[] value) {
+        return (byte[]) getTemplate().execute((RedisCallback<byte[]>) connection -> connection.getSet(key, value));
+    }
+
+    /**
+     * 按键值存储数据
+     * @param key   键值
+     * @param value 存储值
+     * @param <T>   值泛型
+     */
+    public static <T extends Serializable> void cmdSet(String key, T value) {
+        setBytes(keySerial(key), strSerial(value));
+    }
+
+    /**
+     * 按键值存储数据
+     * @param key   键值
+     * @param value 存储值
+     * @param <T>   值泛型
+     */
+    public static <T extends Serializable> void set(String key, T value) {
+        setBytes(keySerial(key), objSerial(value));
+    }
+
+    public static <T extends Serializable> Boolean setNx(String key, T value) {
+        return setNxBytes(keySerial(key), objSerial(value));
+    }
+
+    public static Boolean setNxBytes(final byte[] key, final byte[] value) {
+        return (Boolean) getTemplate().execute((RedisCallback<Boolean>) connection -> connection.setNX(key, value));
+    }
+
+    public static <T extends Serializable> Boolean setNxEx(String key, T value, final int timeout) {
+        return setExNxBytes(keySerial(key), objSerial(value), timeout);
+    }
+
+    public static Boolean setExNxBytes(final byte[] key, final byte[] value, final int timeout) {
+        return (Boolean) getTemplate().execute((RedisCallback<Boolean>) connection -> {
+            Boolean success = connection.setNX(key, value);
+            if (success != null && success) {
+                connection.expire(key, timeout);
+            }
+            return success;
+        });
+    }
+
+    /**
+     * 按键值存储数据
+     * @param key   键值
+     * @param value 存储值
+     */
+    public static void setBytes(final byte[] key, final byte[] value) {
+        getTemplate().execute((RedisCallback<Void>) connection -> {
+            connection.set(key, value);
+            return null;
+        });
+    }
+
+    /**
+     * 存储一定时间内过期的值
+     * @param key     键值
+     * @param value   存储值
+     * @param timeout 超时时长
+     * @param <T>     存储值泛型
+     */
+    public static <T extends Serializable> void cmdSetEx(final String key, final T value, final int timeout) {
+        setExBytes(keySerial(key), strSerial(value), timeout);
+    }
+
+    /**
+     * 存储一定时间内过期的值
+     * @param key     键值
+     * @param value   存储值
+     * @param timeout 超时时长
+     * @param <T>     存储值泛型
+     */
+    public static <T extends Serializable> void setEx(final String key, final T value, final int timeout) {
+        setExBytes(keySerial(key), objSerial(value), timeout);
+    }
+
+    /**
+     * 存储一定时间内过期的值
+     * @param key     键值
+     * @param value   存储值
+     * @param timeout 超时时长
+     */
+    public static void setExBytes(final byte[] key, final byte[] value, final int timeout) {
+        getTemplate().execute((RedisCallback<Void>) connection -> {
+            connection.setEx(key, timeout, value);
+            return null;
+        });
+    }
+
+    /**
+     * 为指定键值增加过期时长
+     * @param key     键值
+     * @param timeout 超时时长
+     */
+    public static boolean expire(final String key, final int timeout) {
+        return (Boolean) getTemplate().execute((RedisCallback<Boolean>) connection -> connection.expire(keySerial(key), timeout));
+    }
+
+    /**
+     * 为指定键值增加有效期(日期时间)
+     * @param key  键值
+     * @param date 有效期
+     */
+    public static boolean expireAt(final String key, final long date) {
+        return (Boolean) getTemplate().execute((RedisCallback<Boolean>) connection -> connection.expireAt(keySerial(key), date));
+    }
+
+    /**
+     * 判断键值还有多少秒超时
+     * @param key 键值
+     */
+    public static long ttl(final String key) {
+        return (Long) getTemplate().execute((RedisCallback<Long>) connection -> connection.ttl(keySerial(key)));
+    }
+
+    /**
+     * 判断指定键值是否存在
+     * @param key 键值
+     * @return 布尔值
+     */
+    public static boolean exists(final String key) {
+        return (Boolean) getTemplate().execute((RedisCallback<Boolean>) connection -> connection.exists(keySerial(key)));
+    }
+
+    /**
+     * 删除指定键值数据
+     * @param keys 键值数组
+     * @return 删除的个数
+     */
+    public static long del(final String... keys) {
+        if (keys == null || keys.length == 0) {
+            return 0;
+        }
+        return (Long) getTemplate().execute((RedisCallback<Long>) connection -> connection.del(fields(keys)));
+    }
+
+    /**
+     * 获取指定的hash存储的值
+     * @param key   键值
+     * @param field hash键值
+     * @param <T>   存储值泛型
+     * @return 存储值
+     */
+    public static <T> T cmdHGet(String key, Class<T> cl, String field) {
+        return strDeserial(cl, hGetBytes(keySerial(key), keySerial(field)));
+    }
+
+    /**
+     * 获取指定的hash存储的值
+     * @param key   键值
+     * @param field hash键值
+     * @param <T>   存储值泛型
+     * @return 存储值
+     */
+    public static <T> T hGet(String key, String field) {
+        return objDeserial(hGetBytes(keySerial(key), keySerial(field)));
+    }
+
+    /**
+     * 获取指定的hash存储的值
+     * @param key   键值
+     * @param field hash键值
+     * @return 存储值
+     */
+    public static byte[] hGetBytes(final byte[] key, final byte[] field) {
+        return (byte[]) getTemplate().execute((RedisCallback<byte[]>) connection -> connection.hGet(key, field));
+    }
+
+
+    /**
+     * 获取多个hash存储的值,由于值类型不同,不做反序列化
+     * @param key    键值
+     * @param fields 多个hash键值
+     * @return 存储值
+     */
+    public static List<byte[]> hMGet(final String key, final String... fields) {
+        return (List<byte[]>) getTemplate().execute((RedisCallback<List<byte[]>>) connection -> connection.hMGet(keySerial(key), fields(fields)));
+    }
+
+    /**
+     * 获取多个hash存储的值,值类型相同时使用
+     * @param key    键值
+     * @param fields 多个hash键值
+     * @param <T>    存储值泛型
+     * @return 存储值
+     */
+    public static <T> List<T> hMGetSameType(Class<T> cl, String key, String... fields) {
+        return strListDeserial(cl, hMGet(key, fields));
+    }
+
+    /**
+     * 获取多个hash存储的值,值类型相同时使用
+     * @param key    键值
+     * @param fields 多个hash键值
+     * @param <T>    存储值泛型
+     * @return 存储值
+     */
+    public static <T> List<T> hMGetSameType(String key, String... fields) {
+        return objListDeserial(hMGet(key, fields));
+    }
+
+    /**
+     * 判断指定的hash存储是否存在
+     * @param key   键值
+     * @param field hash键值
+     * @return 布尔值
+     */
+    public static Boolean hExists(final String key, final String field) {
+        return (Boolean) getTemplate().execute((RedisCallback<Boolean>) connection -> connection.hExists(keySerial(key), keySerial(field)));
+    }
+
+    /**
+     * 获取整个hash存储,由于值类型不同,不做反序列化
+     * @param key 键值
+     * @return 存储的数据映射
+     */
+    public static List<String> hKeys(final String key) {
+        return (List<String>) getTemplate().execute((RedisCallback<List<String>>) connection -> strListDeserial(String.class, connection.hKeys(keySerial(key))));
+    }
+
+    /**
+     * 获取整个hash存储,由于值类型不同,不做反序列化
+     * @param key 键值
+     * @return 存储的数据映射
+     */
+    public static Map<byte[], byte[]> hGetAllBytes(final String key) {
+        return (Map<byte[], byte[]>) getTemplate().execute((RedisCallback<Map<byte[], byte[]>>) connection -> connection.hGetAll(keySerial(key)));
+    }
+
+    /**
+     * 获取整个hash存储,由于值类型不同,不做反序列化
+     * @param key 键值
+     * @return 存储的数据映射
+     */
+    public static Map<String, byte[]> hGetAll(String key) {
+        return mapKeyDeserial(hGetAllBytes(key));
+    }
+
+    /**
+     * 获取整个hash存储,值类型相同时使用
+     *
+     * @param key 键值
+     * @param <T> hash存储值泛型
+     * @return 存储的数据映射
+     */
+    public static <T> Map<String, T> hGetAllSameType(String key, Class<T> cl) {
+        return strMapDeserial(cl, hGetAllBytes(key));
+    }
+
+    /**
+     * 获取整个hash存储,值类型相同时使用
+     * @param key 键值
+     * @param <T> hash存储值泛型
+     * @return 存储的数据映射
+     */
+    public static <T> Map<String, T> hGetAllSameType(final String key) {
+        return objMapDeserial(hGetAllBytes(key));
+    }
+
+    /**
+     * 存储单个hash值
+     * @param key   键值
+     * @param field hash存储
+     * @param value 存储值
+     * @param <T>   存储值泛型
+     */
+    public static <T extends Serializable> void cmdHSet(final String key, final String field, final T value) {
+        hSetBytes(key, field, strSerial(value));
+    }
+
+    /**
+     * 存储单个hash值
+     * @param key   键值
+     * @param field hash存储
+     * @param value 存储值
+     * @param <T>   存储值泛型
+     */
+    public static <T extends Serializable> void hSet(final String key, final String field, final T value) {
+        hSetBytes(key, field, objSerial(value));
+    }
+
+    /**
+     * 存储单个hash值
+     * @param key   键值
+     * @param field hash存储
+     * @param value 存储值
+     */
+    public static void hSetBytes(final String key, final String field, final byte[] value) {
+        getTemplate().execute((RedisCallback<Boolean>) connection -> connection.hSet(keySerial(key), keySerial(field), value));
+    }
+
+    /**
+     * hash存储整个map
+     * @param key 键值
+     * @param map 存储map
+     * @param <T> 存储值泛型
+     */
+    public static <T extends Serializable> void cmdHMSet(final String key, final Map<String, T> map) {
+        hMSetBytes(key, strMapSerial(map));
+    }
+
+    /**
+     * hash存储整个map
+     * @param key 键值
+     * @param map 存储map
+     * @param <T> 存储值泛型
+     */
+    public static <T extends Serializable> void hMSet(final String key, final Map<String, T> map) {
+        hMSetBytes(key, objMapSerial(map));
+    }
+
+    /**
+     * hash存储整个map
+     * @param key 键值
+     * @param map 存储map
+     */
+    public static void hMSetBytes(final String key, final Map<byte[], byte[]> map) {
+        getTemplate().execute((RedisCallback<Object>) connection -> {
+            connection.hMSet(keySerial(key), map);
+            return null;
+        });
+    }
+
+    /**
+     * 删除指定hash数据
+     * @param key    键值
+     * @param fields hash键值
+     * @return 删除的数量
+     */
+    public static long hDel(final String key, final String... fields) {
+        if (StringUtils.isEmpty(key) || fields == null || fields.length == 0) {
+            return 0;
+        }
+        return (Long) getTemplate().execute((RedisCallback<Long>) connection -> connection.hDel(keySerial(key), fields(fields)));
+    }
+
+    /**
+     * set获取所有成员
+     * @param key 键值
+     * @param <T> 值泛型
+     * @return 值列表
+     */
+    public static <T> List<T> sMemebers(String key, Class<T> cl) {
+        return strListDeserial(cl, sMemebersBytesList(key));
+    }
+
+    /**
+     * set获取所有成员
+     * @param key 键值
+     * @param <T> 值泛型
+     * @return 值列表
+     */
+    public static <T> List<T> sMemebers(String key) {
+        return objListDeserial(sMemebersBytesList(key));
+    }
+
+    /**
+     * set获取所有成员
+     * @param key 键值
+     * @return 值列表
+     */
+    public static Set<byte[]> sMemebersBytesList(final String key) {
+        return (Set<byte[]>) getTemplate().execute((RedisCallback<Set<byte[]>>) connection -> connection.sMembers(keySerial(key)));
+    }
+
+    /**
+     * 判断是否为set成员
+     * @param key 键值
+     * @param <T> 值泛型
+     * @return 值列表
+     */
+    public static <T> boolean cmdSIsMemeber(String key, T value) {
+        return sIsMemeber(keySerial(key), strSerial(value));
+    }
+
+    /**
+     * 判断是否为set成员
+     * @param key 键值
+     * @param <T> 值泛型
+     * @return 值列表
+     */
+    public static <T> boolean sIsMemeber(String key, T value) {
+        return sIsMemeber(keySerial(key), objSerial(value));
+    }
+
+    /**
+     * 判断是否为set成员
+     *
+     * @param key 键值
+     * @return 值列表
+     */
+    public static boolean sIsMemeber(final byte[] key, final byte[] value) {
+        return (Boolean) getTemplate().execute(new RedisCallback<Boolean>() {
+            @Override
+            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
+                return connection.sIsMember(key, value);
+            }
+        });
+    }
+
+    /**
+     * 判断是否为set成员
+     *
+     * @param key 键值
+     * @param <T> 值泛型
+     * @return 值列表
+     */
+    public static <T> boolean cmdSContainMemeber(final String key, final T... values) {
+        if (values == null || values.length == 0) {
+            return false;
+        }
+        return sContainMemeber(keySerial(key), strArraySerial(values));
+    }
+
+    /**
+     * 判断是否为set成员
+     *
+     * @param key 键值
+     * @param <T> 值泛型
+     * @return 值列表
+     */
+    public static <T> boolean sContainMemeber(final String key, final T... values) {
+        if (values == null || values.length == 0) {
+            return false;
+        }
+        return sContainMemeber(keySerial(key), objArraySerial(values));
+    }
+
+    /**
+     * 判断是否为set成员
+     *
+     * @param key 键值
+     * @return 值列表
+     */
+    public static boolean sContainMemeber(byte[] key, byte[][] values) {
+        String sContainMemeberScript = "local vs = ARGV[1] for i=1,#vs,1 do if (redis.call('SISMEMBER',KEY[1], vs[i]) == 1) then return true end end return false";
+        ArrayList<byte[]> keys = new ArrayList<>();
+        keys.add(key);
+        Object[] objValues = values;
+        return (Boolean) getTemplate().execute(new DefaultRedisScript<>(sContainMemeberScript, Boolean.class), keys, objValues);
+    }
+
+    /**
+     * set添加
+     *
+     * @param key    键值
+     * @param values 值数组
+     * @param <T>    值泛型
+     */
+    public static <T> long cmdSAdd(final String key, final T... values) {
+        return sAdd(keySerial(key), strArraySerial(values));
+    }
+
+    /**
+     * set添加
+     *
+     * @param key    键值
+     * @param values 值数组
+     * @param <T>    值泛型
+     */
+    public static <T> long sAdd(final String key, final T... values) {
+        return sAdd(keySerial(key), objArraySerial(values));
+    }
+
+    /**
+     * set添加
+     *
+     * @param key    键值
+     * @param values 值数组
+     */
+    public static long sAdd(final byte[] key, final byte[][] values) {
+        return (long) getTemplate().execute(new RedisCallback<Long>() {
+
+            @Override
+            public Long doInRedis(RedisConnection connection) throws DataAccessException {
+                return connection.sAdd(key, values);
+            }
+        });
+    }
+
+    /**
+     * set添加所有的
+     *
+     * @param keys   键值组
+     * @param values 值数组
+     * @param <T>    值泛型
+     */
+    public static <T> long cmdSAddAll(final List<String> keys, final List<T[]> values) {
+        return (long) getTemplate().execute(new RedisCallback<Long>() {
+
+            @Override
+            public Long doInRedis(RedisConnection connection) throws DataAccessException {
+                long count = 0;
+                for (int i = 0; i < keys.size(); i++) {
+                    connection.sAdd(keySerial(keys.get(i)), strArraySerial(values.get(i)));
+                }
+                return count;
+            }
+        });
+    }
+
+    /**
+     * set添加所有的
+     *
+     * @param keys
+     * @param values 值数组
+     * @param <T>    值泛型
+     */
+    public static <T> long sAddAll(final List<String> keys, final List<T[]> values) {
+        return (long) getTemplate().execute(new RedisCallback<Long>() {
+            @Override
+            public Long doInRedis(RedisConnection connection) throws DataAccessException {
+                long count = 0;
+                for (int i = 0; i < keys.size(); i++) {
+                    connection.sAdd(keySerial(keys.get(i)), objArraySerial(values.get(i)));
+                }
+                return count;
+            }
+        });
+    }
+
+    /**
+     * set删除
+     *
+     * @param key    键值
+     * @param values 值数组
+     * @param <T>    值泛型
+     */
+    public static <T> long cmdSRem(final String key, final T... values) {
+        return sRem(keySerial(key), strArraySerial(values));
+    }
+
+    /**
+     * set删除
+     *
+     * @param key    键值
+     * @param values 值数组
+     * @param <T>    值泛型
+     */
+    public static <T> long sRem(final String key, final T... values) {
+        return sRem(keySerial(key), objArraySerial(values));
+    }
+
+    /**
+     * set删除
+     *
+     * @param key    键值
+     * @param values 值数组
+     */
+    public static long sRem(final byte[] key, final byte[]... values) {
+        return (Long) getTemplate().execute(new RedisCallback<Long>() {
+            @Override
+            public Long doInRedis(RedisConnection connection) throws DataAccessException {
+                return connection.sRem(key, values);
+            }
+        });
+    }
+
+    /**
+     * 事务模式执行redis操作
+     *
+     * @param callback 回调方法
+     * @return 返回结果
+     */
+    public static <T> T execute(SessionCallback<T> callback) {
+        return (T) getTemplate().execute(callback);
+    }
+
+
+    /**
+     * 键值序列化
+     *
+     * @param key 键值
+     * @return 结果字节数组
+     */
+    public static byte[] keySerial(String key) {
+        return getKeySerializer().serialize(key);
+    }
+
+    /**
+     * 键值反序列化
+     *
+     * @param key 键值字节数组
+     * @return 键值
+     */
+    public static String keyDeserial(byte[] key) {
+        return (String) getKeySerializer().deserialize(key);
+    }
+
+    /**
+     * 多个键值序列化
+     *
+     * @param fields 键值数据
+     * @return 多个键值的字节矩阵
+     */
+    public static byte[][] fields(String... fields) {
+        RedisSerializer<String> s = getKeySerializer();
+        int len = fields.length;
+        byte[][] fs = new byte[len][];
+        for (int i = 0; i < fields.length; i++) {
+            fs[i] = s.serialize(fields[i]);
+        }
+        return fs;
+    }
+
+    /**
+     * 取得值redis序列化对象
+     *
+     * @return redis序列化对象
+     */
+    public static <T> RedisSerializer<T> getValueSerializer(Class<T> type) {
+        return new GenericToStringSerializer<>(type);
+    }
+
+    /**
+     * 取得值redis序列化对象
+     *
+     * @return redis序列化对象
+     */
+    public static <T> RedisSerializer<T> getValueSerializer() {
+        return getTemplate().getValueSerializer();
+    }
+
+    /**
+     * 取得键redis序列化对象
+     *
+     * @return redis序列化对象
+     */
+    public static <T> RedisSerializer<T> getKeySerializer() {
+        return getTemplate().getStringSerializer();
+    }
+
+    /**
+     * 存储值的序列化
+     *
+     * @param v   值对象
+     * @param <T> 值泛型
+     * @return 结果字节数组
+     */
+    public static <T> byte[] strSerial(T v) {
+        Class<T> c = (Class<T>) v.getClass();
+        return getValueSerializer(c).serialize(v);
+    }
+
+    /**
+     * 存储值的序列化
+     *
+     * @param v   值对象
+     * @param <T> 值泛型
+     * @return 结果字节数组
+     */
+    public static <T> byte[] objSerial(T v) {
+        return getValueSerializer().serialize(v);
+    }
+
+    /**
+     * 存储值的反序列化
+     *
+     * @param cl  结果对象类型
+     * @param v   值字节数组
+     * @param <T> 值泛型
+     * @return 值对象
+     */
+    public static <T> T strDeserial(Class<T> cl, byte[] v) {
+        return getValueSerializer(cl).deserialize(v);
+    }
+
+    /**
+     * 存储值的反序列化
+     *
+     * @param v   值字节数组
+     * @param <T> 值泛型
+     * @return 值对象
+     */
+    public static <T> T objDeserial(byte[] v) {
+        return (T) getValueSerializer().deserialize(v);
+    }
+
+    /**
+     * 反序列化值列表
+     *
+     * @param bs  存储值的字节数组列表
+     * @param <T> 值泛型
+     * @return 值对象列表
+     */
+    public static <T> List<T> strListDeserial(Class<T> cl, Collection<byte[]> bs) {
+        List<T> l = new ArrayList<>();
+        RedisSerializer<T> ser = getValueSerializer(cl);
+        for (byte[] b : bs) {
+            l.add(ser.deserialize(b));
+        }
+        return l;
+    }
+
+    /**
+     * 反序列化值列表
+     *
+     * @param bs  存储值的字节数组列表
+     * @param <T> 值泛型
+     * @return 值对象列表
+     */
+    public static <T> List<T> objListDeserial(Collection<byte[]> bs) {
+        List<T> l = new ArrayList<>();
+        RedisSerializer<T> ser = getValueSerializer();
+        for (byte[] b : bs) {
+            l.add(ser.deserialize(b));
+        }
+        return l;
+    }
+
+    /**
+     * 序列化map数据
+     *
+     * @param m   map对象
+     * @param <T> map中值的泛型
+     * @return 字节到字节映射
+     */
+    public static <T> Map<byte[], byte[]> strMapSerial(Map<String, T> m) {
+        Map<byte[], byte[]> bs = new HashMap<>(16);
+        RedisSerializer<T> serializer = null;
+        for (Map.Entry<String, T> e : m.entrySet()) {
+            T v = e.getValue();
+            if (v == null) {
+                continue;
+            }
+            if (serializer == null) {
+                serializer = getValueSerializer((Class<T>) v.getClass());
+            }
+            bs.put(keySerial(e.getKey()), serializer.serialize(v));
+        }
+        return bs;
+    }
+
+    /**
+     * 序列化map数据
+     *
+     * @param m   map对象
+     * @param <T> map中值的泛型
+     * @return 字节到字节映射
+     */
+    public static <T> Map<byte[], byte[]> objMapSerial(Map<String, T> m) {
+        Map<byte[], byte[]> bs = new HashMap<>(16);
+        RedisSerializer<T> serializer = getValueSerializer();
+        for (Map.Entry<String, T> e : m.entrySet()) {
+            T v = e.getValue();
+            if (v == null) {
+                continue;
+            }
+            bs.put(keySerial(e.getKey()), serializer.serialize(v));
+        }
+        return bs;
+    }
+
+    /**
+     * 反序列化字节到字节映射的键值
+     *
+     * @param bs 字节到字节映射
+     * @return 字符串到字节数据的映射
+     */
+    public static Map<String, byte[]> mapKeyDeserial(Map<byte[], byte[]> bs) {
+        Map<String, byte[]> m = new HashMap<>(16);
+        for (Map.Entry<byte[], byte[]> e : bs.entrySet()) {
+            m.put(keyDeserial(e.getKey()), e.getValue());
+        }
+        return m;
+    }
+
+    /**
+     * 反序列化字节到字节映射数据
+     *
+     * @param bs  字节到字节映射
+     * @param <T> map值泛型
+     * @return map数据对象
+     */
+    public static <T> Map<String, T> strMapDeserial(Class<T> cl, Map<byte[], byte[]> bs) {
+        Map<String, T> m = new HashMap<>(16);
+        RedisSerializer<T> ser = getValueSerializer(cl);
+        for (Map.Entry<byte[], byte[]> e : bs.entrySet()) {
+            m.put(keyDeserial(e.getKey()), ser.deserialize(e.getValue()));
+        }
+        return m;
+    }
+
+    /**
+     * 反序列化字节到字节映射数据
+     *
+     * @param bs  字节到字节映射
+     * @param <T> map值泛型
+     * @return map数据对象
+     */
+    public static <T> Map<String, T> objMapDeserial(Map<byte[], byte[]> bs) {
+        Map<String, T> m = new HashMap<>(16);
+        RedisSerializer<T> ser = getValueSerializer();
+        for (Map.Entry<byte[], byte[]> e : bs.entrySet()) {
+            m.put(keyDeserial(e.getKey()), ser.deserialize(e.getValue()));
+        }
+        return m;
+    }
+
+    /**
+     * 序列化数组
+     *
+     * @param vs  值数组
+     * @param <T> 值泛型
+     * @return 字节二维数组
+     */
+    public static <T> byte[][] strArraySerial(T... vs) {
+        byte[][] bss = new byte[vs.length][];
+        RedisSerializer<T> ser = null;
+        for (int i = 0; i < vs.length; i++) {
+            T v = vs[i];
+            if (v == null) {
+                continue;
+            }
+            if (ser == null) {
+                ser = getValueSerializer((Class<T>) v.getClass());
+            }
+            bss[i] = ser.serialize(v);
+        }
+        return bss;
+    }
+
+    /**
+     * 序列化数组
+     *
+     * @param vs  值数组
+     * @param <T> 值泛型
+     * @return 字节二维数组
+     */
+    public static <T> byte[][] objArraySerial(T... vs) {
+        byte[][] bss = new byte[vs.length][];
+        RedisSerializer<T> ser = getValueSerializer();
+        for (int i = 0; i < vs.length; i++) {
+            T v = vs[i];
+            if (v == null) {
+                continue;
+            }
+            bss[i] = ser.serialize(v);
+        }
+        return bss;
+    }
+
+}

+ 228 - 0
fm-common/src/main/java/com/persagy/fm/common/model/data/DataType.java

@@ -0,0 +1,228 @@
+package com.persagy.fm.common.model.data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 数据类型常量
+ *
+ * @author Sun
+ * @version 1.0 2014年9月24日
+ * @since 1.6
+ */
+public enum DataType {
+
+    /** 未知数据类型 */
+    UNKNOWN("未知类型"),
+
+    /** 字符串数据类型 */
+    STRING("字符串"),
+
+    /** 字节数据类型 */
+    BYTE("字节"),
+
+    /** 短整数类型 */
+    SHORT("短整数"),
+
+    /** 整数类型 */
+    INT("整数"),
+
+    /** 长整数类型 */
+    LONG("长整数"),
+
+    /** 浮点类型 */
+    FLOAT("浮点"),
+
+    /** 双精度浮点类型 */
+    DOUBLE("双精度浮点"),
+
+    /** 大数字类型 */
+    BIGDECIMAL("大数字"),
+
+    /** 布尔类型 */
+    BOOLEAN("布尔"),
+
+    /** 日期类型 */
+    DATE("日期"),
+
+    /** 时间类型 */
+    TIME("时间"),
+
+    /** 日期时间类型 */
+    DATETIME("日期时间"),
+
+    /** 二进制类型类型 */
+    BINARY("二进制类型");
+
+    /** 类型名称 */
+    private String name;
+
+    /**
+     * 构造方法
+     * @param name 名称
+     */
+    private DataType(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 取得类型名称
+     * @return 类型名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 判断是否为数字类型
+     * @param dataType 数据类型
+     * @return 布尔值
+     */
+    public static boolean isNumberType(DataType dataType) {
+        return dataType == BYTE || dataType == SHORT || dataType == INT || dataType == LONG || dataType == FLOAT || dataType == DOUBLE || dataType == BIGDECIMAL;
+    }
+
+    /**
+     * 判断是否是时间类型
+     * @param dataType 数据类型
+     * @return 布尔值
+     */
+    public static boolean isDateType(DataType dataType) {
+        return dataType == DATE || dataType == DATETIME || dataType == TIME;
+    }
+
+    /**
+     * 判断类是否为值类型
+     * @param clazz 类对象
+     * @return 布尔值
+     */
+    public static boolean isBaseDataType(Class<?> clazz) {
+        return clazz.isPrimitive() || clazz.equals(String.class) || (Number.class).isAssignableFrom(clazz) || (Boolean.class).isAssignableFrom(clazz) || (Date.class).isAssignableFrom(clazz);
+    }
+
+    /**
+     * 根据类对象取得对应的整型数据类型定义
+     * @param clazz 类对象
+     * @return 对应的数据类型
+     */
+    public static DataType parse(Class<?> clazz) {
+        if (clazz == null) {
+            return UNKNOWN;
+        }
+        if (clazz.equals(String.class)) {
+            return STRING;
+        }
+        if (clazz.equals(Integer.TYPE)) {
+            return INT;
+        }
+        if (clazz.equals(Integer.class)) {
+            return INT;
+        }
+        if (clazz.equals(Long.TYPE)) {
+            return LONG;
+        }
+        if (clazz.equals(Long.class)) {
+            return LONG;
+        }
+        if (clazz.equals(BigDecimal.class)) {
+            return BIGDECIMAL;
+        }
+        if (clazz.equals(Float.TYPE)) {
+            return FLOAT;
+        }
+        if (clazz.equals(Float.class)) {
+            return FLOAT;
+        }
+        if (clazz.equals(Double.TYPE)) {
+            return DOUBLE;
+        }
+        if (clazz.equals(Double.class)) {
+            return DOUBLE;
+        }
+        if (clazz.equals(Boolean.TYPE)) {
+            return BOOLEAN;
+        }
+        if (clazz.equals(Boolean.class)) {
+            return BOOLEAN;
+        }
+        if (clazz.equals(Date.class)) {
+            return DATE;
+        }
+        if (clazz.equals(java.sql.Date.class)) {
+            return DATE;
+        }
+        if (clazz.equals(java.sql.Time.class)) {
+            return TIME;
+        }
+        if (clazz.equals(java.sql.Timestamp.class)) {
+            return DATETIME;
+        }
+        if (clazz.equals(Byte.TYPE)) {
+            return BYTE;
+        }
+        if (clazz.equals(Byte.class)) {
+            return BYTE;
+        }
+        if (clazz.equals(Short.TYPE)) {
+            return SHORT;
+        }
+        if (clazz.equals(Short.class)) {
+            return SHORT;
+        }
+        return UNKNOWN;
+    }
+
+    /**
+     * 数据类型名称转换成数据类型整数
+     * @param type 数据类型名称
+     * @return 数据类型整数
+     */
+    public static DataType parse(String type) {
+        if (type == null) {
+            return UNKNOWN;
+        }
+        try {
+            type = type.toUpperCase();
+            if ("INTEGER".equals(type)) {
+                return INT;
+            }
+            return DataType.valueOf(type.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            return UNKNOWN;
+        }
+    }
+
+    /**
+     * 数据类型转换成对应的类对象
+     * @param type 数据类型整数
+     * @return 类对象
+     */
+    public static Class<?> typeToClass(DataType type) {
+        switch (type) {
+            case STRING:
+                return String.class;
+            case INT:
+                return Integer.class;
+            case LONG:
+                return Long.class;
+            case BIGDECIMAL:
+                return BigDecimal.class;
+            case BOOLEAN:
+                return Boolean.class;
+            case FLOAT:
+                return Float.class;
+            case DOUBLE:
+                return Double.class;
+            case DATE:
+            case TIME:
+            case DATETIME:
+                return Date.class;
+            case BYTE:
+                return Byte.class;
+            case SHORT:
+                return Short.class;
+            default:
+                return null;
+        }
+    }
+}

+ 0 - 4
fm-common/src/main/java/com/persagy/fm/common/model/entity/AuditableEntity.java

@@ -31,25 +31,21 @@ public abstract class AuditableEntity extends BaseEntity implements IAuditableEn
     /**
      * 创建时间
      */
-    @JsonIgnore
     protected Date creationTime;
 
     /**
      * 创建人
      */
-    @JsonIgnore
     protected String creator;
 
     /**
      * 最后一次修改时间
      */
-    @JsonIgnore
     protected Date modifiedTime;
 
     /**
      * 最后一次修改人
      */
-    @JsonIgnore
     protected String modifier;
 
 }

+ 106 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/ChainLogicExpression.java

@@ -0,0 +1,106 @@
+package com.persagy.fm.common.model.query;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 查询条件逻辑表达式表达式
+ * @author Sun
+ * @version 1.0 2014年9月24日
+ * @since 1.6
+ */
+public class ChainLogicExpression implements IExpression {
+
+	/**
+	 * 序列id
+	 */
+	private static final long serialVersionUID = 5682864471973760964L;
+
+	/**
+	 * 表达式列表
+	 */
+	private List<IExpression> expressions = null;
+	
+	/**
+	 * 操作符
+	 */
+	private boolean isOr = false;
+	
+	/**
+	 * 构造方法
+	 */
+	public ChainLogicExpression(){
+		
+	}
+	
+	/**
+	 * 表达式构造方法
+	 * @param isOr       是否为逻辑或相连
+	 * @param expressions 表达式数组
+	 */
+	public ChainLogicExpression(boolean isOr, IExpression...expressions){
+		addExpression(expressions);
+		setOr(isOr);
+	}
+
+	/**
+	 * 取得链式逻辑表达式中包含的表达式列表
+	 * @return 表达式列表
+	 */
+	public List<IExpression> getExpressions() {
+		return expressions;
+	}
+
+	/**
+	 * 设置链式逻辑表达式中包含的表达式列表
+	 * @param expressions 表达式列表
+	 */
+	public void setExpressions(List<IExpression> expressions) {
+		this.expressions = expressions;
+	}
+	
+	/**
+	 * 添加表达式到链式表达式中
+	 * @param expressions 表达式数组
+	 */
+	public void addExpression(IExpression... expressions){
+		if(this.expressions == null) {
+            this.expressions = new ArrayList<>();
+        }
+		CollectionUtils.addAll(this.expressions, expressions);
+	}
+	
+	/**
+	 * 判断是否为‘或’逻辑操作
+	 * @return 布尔值
+	 */
+	public boolean isOr() {
+		return isOr;
+	}
+
+	/**
+	 * 设置是否为‘或’逻辑操作
+	 * @param isOr 布尔值
+	 */
+	public void setOr(boolean isOr) {
+		this.isOr = isOr;
+	}
+
+	@Override
+	public ExpressionType getType() {
+		return ExpressionType.CHAIN;
+	}
+
+	/**
+	 * 取得表达式大小
+	 * @return 表达式大小
+	 */
+	public int size(){
+		if(expressions == null) {
+			return 0;
+		}
+		return expressions.size();
+	}
+}

+ 238 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/Condition.java

@@ -0,0 +1,238 @@
+package com.persagy.fm.common.model.query;
+
+import com.persagy.fm.common.model.data.DataType;
+import lombok.Data;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 查询类,封装查询条件
+ * @author Sun
+ * @version 1.0 2014年9月24日
+ * @since 1.6
+ */
+@Data
+public class Condition implements Serializable {
+    /**
+     * 序列id
+     */
+    private static final long serialVersionUID = 6256786995910707674L;
+    /**
+     * 条件列表
+     */
+    private List<IExpression> expressions = null;
+    /**
+     * 自由条件列表
+     */
+    private List<String> freeConditions = null;
+    /**
+     * 自由搜索值
+     */
+    private String freeValue = null;
+
+    /**
+     * 前置逻辑操作符,为空时不增加逻辑操作符
+     */
+    private String preLogic = null;
+
+    /**
+     * 用于属性别名转换的别名定义,字符串形式如:User as u,
+     * 该别名应用场景,如果定义的条件名为User.name 实际使用的表别名为u,需要在查询执行时进行替换
+     * User.name将被替换成u.name
+     */
+    private String[] fromAlias = null;
+
+    /**
+     * 无条件时是否忽略条件,还是变成不成立条件
+     */
+    private boolean ignore = true;
+
+    /**
+     * 添加查询条件
+     *
+     * @param condition 条件名称
+     */
+    public void addExpressions(IExpression... condition) {
+        if (this.expressions == null) {
+            this.expressions = new ArrayList<IExpression>();
+        }
+        if (this.expressions.size() == 0) {
+            CollectionUtils.addAll(this.expressions, condition);
+        } else {
+            for (IExpression con : condition) {
+                if (this.expressions.indexOf(con) < 0) {
+                    this.expressions.add(con);
+                }
+            }
+        }
+    }
+
+    /**
+     * 添加查询条件
+     *
+     * @param condition 条件名称
+     * @param value     条件值
+     * @param dataType  数据类型
+     * @param operator  操作符
+     */
+    public void addExpression(String condition, Object value, String dataType, String operator) {
+        ValueExpression exp = new ValueExpression(condition, value, dataType, operator);
+        this.addExpressions(exp);
+    }
+
+    /**
+     * 添加查询条件
+     *
+     * @param condition 条件名称
+     * @param value     条件值
+     * @param operator  操作符
+     */
+    public void addExpression(String condition, Object value, String operator) {
+        ValueExpression exp = new ValueExpression(condition, value, operator);
+        this.addExpressions(exp);
+    }
+
+    /**
+     * 添加查询条件
+     *
+     * @param condition 条件名称
+     * @param value     条件值
+     * @param dataType  数据类型
+     * @param operator  操作符
+     */
+    public void addExpression(String condition, Object value, DataType dataType, Operator operator) {
+        ValueExpression exp = new ValueExpression(condition, value, dataType, operator);
+        this.addExpressions(exp);
+    }
+
+    /**
+     * 添加查询条件
+     *
+     * @param condition 条件名称
+     * @param value     条件值
+     * @param operator  操作符
+     */
+    public void addExpression(String condition, Object value, Operator operator) {
+        ValueExpression exp = new ValueExpression(condition, value, operator);
+        this.addExpressions(exp);
+    }
+
+    /**
+     * 添加查询条件
+     *
+     * @param condition 条件名称
+     * @param value     条件值
+     */
+    public void addExpression(String condition, Object value) {
+        ValueExpression exp = new ValueExpression(condition, value);
+        this.addExpressions(exp);
+    }
+
+    /**
+     * 设置自由条件属性列表
+     *
+     * @param freeConditions 自由条件属性列表
+     */
+    public void setFreeConditions(String... freeConditions) {
+        List<String> freeCons = new ArrayList<String>();
+        CollectionUtils.addAll(freeCons, freeConditions);
+        this.freeConditions = freeCons;
+    }
+
+    /**
+     * 添加自由条件属性
+     *
+     * @param freeCondition 自由条件属性
+     */
+    public void setFreeExpressions(String freeValue, String... freeCondition) {
+        if (freeCondition == null || freeCondition.length == 0 || StringUtils.isEmpty(freeValue)) {
+            return;
+        }
+        setFreeConditions(freeCondition);
+        setFreeValue(freeValue);
+    }
+
+    /**
+     * 添加自由条件属性
+     *
+     * @param freeCondition 自由条件属性
+     */
+    public void addFreeCondition(String... freeCondition) {
+        if (this.freeConditions == null) {
+            this.freeConditions = new ArrayList<String>();
+        }
+        if (this.freeConditions.size() == 0) {
+            CollectionUtils.addAll(this.freeConditions, freeCondition);
+        } else {
+            for (String con : freeCondition) {
+                if (this.freeConditions.indexOf(con) < 0) {
+                    this.freeConditions.add(con);
+                }
+            }
+        }
+    }
+
+    /**
+     * 转换成表达式列表
+     *
+     * @return 表达式列表
+     */
+    public List<IExpression> toExpressions() {
+        List<IExpression> cons = getExpressions();
+        if (StringUtils.isEmpty(getFreeValue())) {
+            return cons;
+        }
+        ChainLogicExpression expression = new ChainLogicExpression();
+        if (cons != null && cons.size() > 0) {
+            for (IExpression con : cons) {
+                expression.addExpression(con);
+            }
+        }
+        List<String> freeCons = getFreeConditions();
+        String freeValue = getFreeValue();
+        if (freeCons != null && freeCons.size() > 0 && StringUtils.isNotEmpty(freeValue)) {
+            ChainLogicExpression freeExp = new ChainLogicExpression(true);
+            for (String freeCon : freeCons) {
+                IExpression exp = new ValueExpression(freeCon, freeValue, Operator.LIKEANY);
+                freeExp.addExpression(exp);
+            }
+            expression.addExpression(freeExp);
+        }
+        List<IExpression> expressions = new ArrayList<>();
+        expressions.add(expression);
+        return expressions;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+
+        List<IExpression> es = toExpressions();
+        if (es != null && es.size() > 0) {
+            if (preLogic != null) {
+                builder.append(preLogic).append(StringUtils.SPACE);
+            }
+            builder.append(StringUtils.join(es, " and "));
+            return builder.toString();
+        } else {
+            return StringUtils.EMPTY;
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof Condition)) {
+            return false;
+        }
+        return obj.toString().equals(toString());
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+}

+ 29 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/ExpressionType.java

@@ -0,0 +1,29 @@
+package com.persagy.fm.common.model.query;
+
+/**
+ * 表达式类型
+ * @author Sun
+ * @version 1.0 2017-9-2
+ * @since 1.7
+ */
+public enum ExpressionType {
+
+    /**
+     * 简单值表达式
+     */
+    VALUE,
+    /**
+     * 逻辑表达式“与或”
+     */
+    LOGIC,
+
+    /**
+     * 链式逻辑表达式“与或”,表达式列表中的表达式并列与或者或
+     */
+    CHAIN,
+
+    /**
+     * sql表达式,只能在后端使用
+     */
+    SQL
+}

+ 19 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/IExpression.java

@@ -0,0 +1,19 @@
+package com.persagy.fm.common.model.query;
+
+import java.io.Serializable;
+
+
+/**
+ * 表达式接口
+ * @author Sun
+ * @version 1.0 2014年5月9日
+ * @since 1.7
+ */
+public interface IExpression extends Serializable {
+
+    /**
+     * 取得表达式类型
+     * @return 表达式类型
+     */
+    ExpressionType getType();
+}

+ 109 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/LogicExpression.java

@@ -0,0 +1,109 @@
+package com.persagy.fm.common.model.query;
+
+/**
+ * 查询条件逻辑表达式表达式
+ * @author Sun
+ * @version 1.0 2014年9月24日
+ * @since 1.6
+ */
+public class LogicExpression implements IExpression {
+
+    /**
+     * 序列id
+     */
+    private static final long serialVersionUID = -1756448873214671761L;
+
+    /**
+     * 左侧表达式
+     */
+    private IExpression left = null;
+
+    /**
+     * 右侧表达式
+     */
+    private IExpression right = null;
+
+    /**
+     * 操作符
+     */
+    private boolean isOr = false;
+
+    /**
+     * 构造方法
+     */
+    public LogicExpression() {
+
+    }
+
+    /**
+     * 表达式构造方法
+     *
+     * @param left 左侧表达式
+     * @param right        右侧表达式
+     * @param isOr     是否为或逻辑
+     */
+    public LogicExpression(IExpression left, IExpression right, boolean isOr) {
+        setLeft(left);
+        setRight(right);
+        setOr(isOr);
+    }
+
+    /**
+     * 取得左侧表达式
+     *
+     * @return 左侧表达式
+     */
+    public IExpression getLeft() {
+        return left;
+    }
+
+    /**
+     * 设置左侧表达式
+     *
+     * @param left 左侧表达式
+     */
+    public void setLeft(IExpression left) {
+        this.left = left;
+    }
+
+    /**
+     * 取得右侧表达式
+     *
+     * @return 右侧表达式
+     */
+    public IExpression getRight() {
+        return right;
+    }
+
+    /**
+     * 设置右侧表达式
+     *
+     * @param right 右侧表达式
+     */
+    public void setRight(IExpression right) {
+        this.right = right;
+    }
+
+    /**
+     * 判断是否为‘或’逻辑操作
+     *
+     * @return 布尔值
+     */
+    public boolean isOr() {
+        return isOr;
+    }
+
+    /**
+     * 设置是否为‘或’逻辑操作
+     *
+     * @param isOr 布尔值
+     */
+    public void setOr(boolean isOr) {
+        this.isOr = isOr;
+    }
+
+    @Override
+    public ExpressionType getType() {
+        return ExpressionType.LOGIC;
+    }
+}

+ 161 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/Operator.java

@@ -0,0 +1,161 @@
+/*
+ * Copyright(c) FastSpace Software 2014. All Rights Reserved.
+ */
+package com.persagy.fm.common.model.query;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 操作符枚举
+ *
+ * @author Sun
+ * @version 1.0 2014年9月24日
+ * @since 1.6
+ */
+public enum Operator {
+    /*操作符常量*/
+    /**
+     * =操作符
+     */
+    EQUAL("=", "等于"),
+
+    /**
+     * <>操作符
+     */
+    NOTEQUAL("<>", "不等于"),
+
+    /**
+     * >操作符
+     */
+    GREATER(">", "大于"),
+
+    /**
+     * <操作符
+     */
+    LESS("<", "小于"),
+
+    /**
+     * >=操作符
+     */
+    GREATEREQUAL(">=", "大于等于"),
+
+    /**
+     * <=操作符
+     */
+    LESSEQAUL("<=", "小于等于"),
+
+
+    /**
+     * like操作符,全模糊匹配
+     */
+    LIKEACC("likea", "精确包含"),//前后没有%
+    NOTLIKEACC("not likea", "不精确包含"),//前后没有%
+    LIKEANY("like", "包含"),
+    NOTLIKEANY("not like", "不包含"),
+
+    /**
+     * like操作符,开始匹配,结尾模糊
+     */
+    LIKESTART("likes", "左包含"),
+    NOTLIKESTART("not likes", "不左包含"),
+
+    /**
+     * like操作符,结尾匹配,开始模糊
+     */
+    LIKEEND("likee", "右包含"),
+    NOTLIKEEND("not likee", "不右包含"),
+
+    /**
+     * is null操作符
+     */
+    ISNULL("is null", "为空值"),
+
+    /**
+     * is not null操作符
+     */
+    ISNOTNULL("is not null", "不为空值"),
+
+    /**
+     * in操作符号
+     */
+    IN("in", "列举"),
+
+    /**
+     * not in操作符号
+     */
+    NOTIN("not in", "反列举");
+
+    /**
+     * 操作符编码
+     */
+    private String code;
+
+    /**
+     * 操作符名称
+     */
+    private String name;
+
+    /**
+     * 构造方法
+     *
+     * @param code 编码
+     * @param name 名称
+     */
+    private Operator(String code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    /**
+     * 取得类型编码
+     *
+     * @return 类型编码
+     */
+    public String getCode() {
+        return code;
+    }
+
+    /**
+     * 取得类型名称
+     *
+     * @return 类型名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * (non-Javadoc)
+     *
+     * @see Enum#toString()
+     */
+    @Override
+    public String toString() {
+        return getCode();
+    }
+
+    /**
+     * 根据编码获取操作符
+     *
+     * @param code 操作符编码
+     * @return 操作符
+     */
+    public static Operator parse(String code) {
+        code = code.toLowerCase();
+        if (!STR_VAL_MAP.containsKey(code)) {
+            throw new IllegalArgumentException("Unknown String Value: " + code);
+        }
+        return STR_VAL_MAP.get(code);
+    }
+
+    private static final Map<String, Operator> STR_VAL_MAP;
+
+    static {
+        STR_VAL_MAP = new HashMap<String, Operator>();
+        for (final Operator en : Operator.values()) {
+            STR_VAL_MAP.put(en.getCode(), en);
+        }
+    }
+}

+ 64 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/SqlExpression.java

@@ -0,0 +1,64 @@
+package com.persagy.fm.common.model.query;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+ * 基于sql表达式,只能后台添加
+ * @author Sun
+ * @version 1.0 2014年5月9日
+ * @since 1.7
+ */
+@Data
+public class SqlExpression implements IExpression,Serializable{
+
+
+	/**
+	 * 序列id
+	 */
+	private static final long serialVersionUID = 7826974743759458453L;
+
+	/**
+	 * sql语句
+	 */
+	private String sql = null;
+
+
+	/**
+	 * 构造方法
+	 */
+	public SqlExpression(){
+	}
+
+	/**
+	 * 表达式构造方法,操作符为等于
+	 * @param sql sql语句
+	 */
+	public SqlExpression(String sql){
+		this.sql = sql;
+	}
+
+	@Override
+	public int hashCode() {
+		return toString().hashCode();
+	}
+
+
+	@Override
+	public boolean equals(Object obj) {
+		return obj instanceof SqlExpression && this.toString().equals(obj.toString());
+	}
+
+	@Override
+	public String toString() {
+		return getSql();
+	}
+
+
+	@Override
+	public ExpressionType getType() {
+		return ExpressionType.SQL;
+	}
+}

+ 255 - 0
fm-common/src/main/java/com/persagy/fm/common/model/query/ValueExpression.java

@@ -0,0 +1,255 @@
+package com.persagy.fm.common.model.query;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.persagy.fm.common.model.data.DataType;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.regex.Pattern;
+
+
+/**
+ * 简单值查询表达式
+ * @author Sun
+ * @version 1.0 2014年5月9日
+ * @since 1.7
+ */
+public class ValueExpression implements IExpression{
+
+	/**
+	 * 序列id
+	 */
+	private static final long serialVersionUID = -1127113431925423258L;
+
+	/**
+	 * 查询的实体属性名
+	 */
+	private String propertyName = null;
+	
+	/**
+	 * 属性名测试正则表达式
+	 */
+	private static Pattern propertyParttern = Pattern.compile("^\\w+[\\w+\\.]*\\w*$");
+	
+	/**
+	 * 数据类型
+	 */
+	private DataType dataType = DataType.STRING;
+	
+	/**
+	 * 表达式值
+	 */
+	private Object value = null;
+	
+	/**
+	 * 操作符
+	 */
+	private Operator operator = Operator.EQUAL;
+	
+	/**
+	 * 构造方法
+	 */
+	public ValueExpression(){
+	}
+	
+	/**
+	 * 表达式构造方法,操作符为等于
+	 * @param propertyName 属性名
+	 * @param value 属性值
+	 */
+	public ValueExpression(String propertyName, Object value){
+		this(propertyName,value,Operator.EQUAL);
+	}
+	/**
+	 * 表达式构造方法
+	 * @param propertyName 属性名
+	 * @param value 属性值
+	 * @param operator 操作符
+	 */
+	public ValueExpression(String propertyName, Object value, Operator operator){
+		setPropertyName(propertyName);
+		setOperator(operator);
+		setValue(value);
+	}
+
+	/**
+	 * 表达式构造方法
+	 * @param propertyName 属性名
+	 * @param value 属性值
+	 * @param operator 操作符
+	 */
+	public ValueExpression(String propertyName, Object value, String operator){
+		setPropertyName(propertyName);
+		setOperator(Operator.parse(operator));
+		setValue(value);
+	}
+	/**
+	 * 表达式构造方法
+	 * @param propertyName 属性名
+	 * @param value 属性值
+	 * @param operator 操作符
+	 */
+	public ValueExpression(String propertyName, Object value, DataType dataType,Operator operator){
+		setPropertyName(propertyName);
+		if(dataType != DataType.UNKNOWN) {
+            setDataType(dataType);
+        }
+		setOperator(operator);
+		setValue(value);
+	}
+
+	/**
+	 * 表达式构造方法
+	 * @param propertyName 属性名
+	 * @param value 属性值
+	 * @param operator 操作符
+	 */
+	public ValueExpression(String propertyName, Object value, String dataType, String operator){
+		setPropertyName(propertyName);
+		if(dataType != null){
+			 DataType dt =  DataType.parse(dataType);
+			 if(dt != DataType.UNKNOWN) {
+                 setDataType(dt);
+             }
+		}
+		setOperator(Operator.parse(operator));
+		setValue(value);
+	}
+	/**
+	 * 取得表达式属性名
+	 * @return 属性名
+	 */
+	public String getPropertyName() {
+		return propertyName;
+	}
+
+	/**
+	 * 设置表达式属性名
+	 * @param propertyName 属性名
+	 */
+	public void setPropertyName(String propertyName) {
+		if(propertyName.contains(" ")){
+			String[] temps = propertyName.split(" ");
+			propertyName = temps[0];
+			setDataType(DataType.parse(temps[1]));
+			if(temps.length > 2){
+				setOperator(Operator.parse(temps[2]));
+			}
+		}
+		if(!propertyParttern.matcher(propertyName).matches()) {
+            throw new RuntimeException("非法查询条件");
+        }
+		this.propertyName = propertyName;
+	}
+
+	/**
+	 * 取得表达式条件值
+	 * @return 条件值
+	 */
+	public Object getValue() {
+		return value;
+	}
+
+	/**
+	 * 设置表达式条件值
+	 * @param value 条件值
+	 */
+	public void setValue(Object value) {
+		if(this.operator != Operator.ISNULL || this.operator == Operator.ISNOTNULL) {
+            this.value = value;
+        }
+	}
+
+	/**
+	 * 取得表达式操作符
+	 * @return 表达式操作符
+	 */
+	public Operator getOperator() {
+		return operator;
+	}
+
+	/**
+	 * 设置表达式操作符
+	 * @param operator 表达式操作符
+	 */
+	public void setOperator(Operator operator) {
+		if(this.operator == Operator.ISNULL || this.operator == Operator.ISNOTNULL) {
+            this.value = null;
+        }
+		this.operator = operator;
+	}
+
+	
+	/**
+	 * 取得字段数据类型
+	 * @return 字段数据类型
+	 */
+	public DataType getDataType() {
+		return dataType;
+	}
+
+	/**
+	 * 设置字段数据类型
+	 * @param dataType 字段数据类型
+	 */
+	public void setDataType(DataType dataType) {
+		if(dataType==DataType.UNKNOWN) {
+            return;
+        }
+		this.dataType = dataType;
+	}
+
+	@Override
+	public ExpressionType getType() {
+		return ExpressionType.VALUE;
+	}
+
+	/**
+	 * (non-Javadoc)
+	 * @see Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return toString().hashCode();
+	}
+
+	/**
+	 * (non-Javadoc)
+	 * @see Object#equals(Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if(!(obj instanceof ValueExpression)) {
+            return false;
+        }
+		return this.toString().equals(obj.toString());
+	}
+
+	/**
+	 * (non-Javadoc)
+	 * @see Object#toString()
+	 */
+	@Override
+	public String toString() {
+		if(getValue() == null) {
+            return getPropertyName()+" "+getDataType()+ " " + getOperator();
+        } else {
+            return getPropertyName()+" "+getDataType()+ " " + getOperator()+getValue();
+        }
+	}
+	
+	/**
+	 * 判断当前表达式是否合法
+	 * @return 布尔值
+	 */
+	@JsonIgnore
+	public boolean isValidate(){
+		if(StringUtils.isBlank(propertyName)) {
+            return false;
+        }
+		if(getOperator() == Operator.ISNULL || getOperator() == Operator.ISNOTNULL) {
+            return true;
+        }
+		return value != null;
+	}
+	
+}

+ 43 - 35
fm-common/src/main/java/com/persagy/fm/common/utils/TypeConvertUtil.java

@@ -1,5 +1,6 @@
 package com.persagy.fm.common.utils;
 
+import com.persagy.fm.common.model.data.DataType;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 
@@ -23,7 +24,6 @@ public class TypeConvertUtil {
 
     }
 
-
     /**
      * 将Object对象解析成字符串类型
      * @param obj 需要转换的对象
@@ -273,42 +273,50 @@ public class TypeConvertUtil {
      * @return 目标类型对象
      */
     public static final Object translate(Class clazz, Object obj) {
-        if (clazz == null) {
-            return null;
-        }
-        if (clazz.equals(String.class)) {
-            return parseString(obj);
-        }
-        if (clazz.equals(Integer.TYPE) ||
-                clazz.equals(Integer.class)) {
-            return parseInt(obj);
-        }
-        if (clazz.equals(Long.TYPE) || clazz.equals(Long.class)) {
-            return parseLong(obj);
-        }
-        if (clazz.equals(BigDecimal.class)) {
-            return parseBigDecimal(obj);
-        }
-        if (clazz.equals(Float.TYPE) || clazz.equals(Float.class)) {
-            return parseFloat(obj);
-        }
-        if (clazz.equals(Double.TYPE) || clazz.equals(Double.class)) {
-            return parseDouble(obj);
-        }
-        if (clazz.equals(Boolean.TYPE) || clazz.equals(Boolean.class)) {
-            return parseBoolean(obj);
-        }
-        if (clazz.equals(Date.class) || clazz.equals(java.sql.Date.class) ||
-                clazz.equals(java.sql.Time.class) || clazz.equals(java.sql.Timestamp.class)) {
-            return parseDate(obj);
-        }
-        if (clazz.equals(Byte.TYPE) || clazz.equals(Byte.class)) {
-            return parseByte(obj);
+        return translate(DataType.parse(clazz), obj);
+    }
+
+    /**
+     * 将未知类型的对象转换成指定类型的对象
+     * @param dataType 数据类型
+     * @param obj      未知类型对象
+     * @return 目标类型对象
+     */
+    public static final Object translate(DataType dataType, Object obj) {
+        boolean isBlank = obj == null || (obj instanceof String) && ((String) obj).length() == 0;
+        if (isBlank) {
+            if (dataType == DataType.STRING) {
+                return obj;
+            } else {
+                return null;
+            }
         }
-        if (clazz.equals(Short.TYPE) || clazz.equals(Short.class)) {
-            return parseShort(obj);
+        switch (dataType) {
+            case STRING:
+                return parseString(obj);
+            case INT:
+                return parseInt(obj);
+            case LONG:
+                return parseLong(obj);
+            case BIGDECIMAL:
+                return parseBigDecimal(obj);
+            case BOOLEAN:
+                return parseBoolean(obj);
+            case FLOAT:
+                return parseFloat(obj);
+            case DOUBLE:
+                return parseDouble(obj);
+            case DATE:
+            case TIME:
+            case DATETIME:
+                return parseDate(obj);
+            case BYTE:
+                return parseByte(obj);
+            case SHORT:
+                return parseShort(obj);
+            default:
+                return obj;
         }
-        return obj;
     }
 
     /**

+ 160 - 125
fm-parent/pom.xml

@@ -12,10 +12,22 @@
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.1.14.RELEASE</version>
+        <relativePath/>
     </parent>
+    <!-- 版本管理 -->
     <properties>
         <fm.version>3.0.0</fm.version>
         <platform.version>1.0.0</platform.version>
+        <mybatis.version>3.4.6</mybatis.version>
+        <mybatis-spring.version>1.3.2</mybatis-spring.version>
+        <mybatis.springboot.version>1.3.2</mybatis.springboot.version>
+        <tomcat-jdbc.version>9.0.31</tomcat-jdbc.version>
+        <HikariCP.version>3.2.0</HikariCP.version>
+        <mysql.version>8.0.15</mysql.version>
+        <guava.version>27.0.1-jre</guava.version>
+        <spring.version>5.1.15.RELEASE</spring.version>
+        <spring-data.version>2.1.17.RELEASE</spring-data.version>
+        <spring-data-jpa.version>2.0.11.RELEASE</spring-data-jpa.version>
     </properties>
 
     <dependencyManagement>
@@ -27,6 +39,11 @@
             </dependency>
             <dependency>
                 <groupId>com.persagy</groupId>
+                <artifactId>fm-common</artifactId>
+                <version>${fm.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.persagy</groupId>
                 <artifactId>integrated-common-core</artifactId>
                 <version>${platform.version}</version>
             </dependency>
@@ -35,6 +52,147 @@
                 <artifactId>integrated-log-spring-boot-starter</artifactId>
                 <version>${platform.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.persagy</groupId>
+                <artifactId>integrated-redis-spring-boot-starter</artifactId>
+                <version>${platform.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.persagy</groupId>
+                <artifactId>integrated-config-client</artifactId>
+                <version>${platform.version}</version>
+            </dependency>
+            <!-- 以下是mybatis版本管理 -->
+            <dependency>
+                <groupId>org.mybatis</groupId>
+                <artifactId>mybatis</artifactId>
+                <version>${mybatis.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.mybatis</groupId>
+                <artifactId>mybatis-spring</artifactId>
+                <version>${mybatis-spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.mybatis.spring.boot</groupId>
+                <artifactId>mybatis-spring-boot-starter</artifactId>
+                <version>${mybatis.springboot.version}</version>
+            </dependency>
+            <!-- 以下是数据库连接池版本管理,建议使用provided方式引入-->
+            <dependency>
+                <groupId>org.apache.tomcat</groupId>
+                <artifactId>tomcat-jdbc</artifactId>
+                <version>${tomcat-jdbc.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.zaxxer</groupId>
+                <artifactId>HikariCP</artifactId>
+                <version>${HikariCP.version}</version>
+            </dependency>
+            <!-- 以下是数据库driver版本管理,建议使用provided方式引入 -->
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${mysql.version}</version>
+            </dependency>
+            <!-- 以下是commons工具版本管理 -->
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>${guava.version}</version>
+            </dependency>
+            <!-- 以下是spring版本管理 -->
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-context</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-web</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-tx</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-aop</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-test</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-beans</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-webmvc</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-context-support</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-core</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-expression</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-jcl</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-jdbc</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-messaging</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-oxm</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-webflux</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <!-- 以下是spring data版本管理 -->
+            <dependency>
+                <groupId>org.springframework.data</groupId>
+                <artifactId>spring-data-commons</artifactId>
+                <version>${spring-data.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.data</groupId>
+                <artifactId>spring-data-redis</artifactId>
+                <version>${spring-data.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.data</groupId>
+                <artifactId>spring-data-jpa</artifactId>
+                <version>${spring-data-jpa.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
@@ -53,27 +211,6 @@
                         <showWarnings>true</showWarnings>
                     </configuration>
                 </plugin>
-                <plugin>
-                    <groupId>org.scala-tools</groupId>
-                    <artifactId>maven-scala-plugin</artifactId>
-                    <version>2.15.2</version>
-                    <executions>
-                        <execution>
-                            <id>scala-compile-first</id>
-                            <phase>process-resources</phase>
-                            <goals>
-                                <goal>compile</goal>
-                            </goals>
-                        </execution>
-                        <execution>
-                            <id>scala-test-compile</id>
-                            <phase>process-test-resources</phase>
-                            <goals>
-                                <goal>testCompile</goal>
-                            </goals>
-                        </execution>
-                    </executions>
-                </plugin>
                 <!-- resource插件 -->
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
@@ -102,27 +239,13 @@
                     </dependencies>
                 </plugin>
 
-                <!-- 增加更多的Source和Test Source目录插件 -->
-                <plugin>
-                    <groupId>org.codehaus.mojo</groupId>
-                    <artifactId>build-helper-maven-plugin</artifactId>
-                    <version>3.0.0</version>
-                </plugin>
-
-                <!-- cobertura 测试覆盖率统计插插件 -->
-                <plugin>
-                    <groupId>org.codehaus.mojo</groupId>
-                    <artifactId>cobertura-maven-plugin</artifactId>
-                    <version>2.7</version>
-                </plugin>
-
                 <!-- war打包插件, 设定war包名称不带版本号 -->
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-war-plugin</artifactId>
-                    <version>3.2.0</version>
+                    <version>3.2.3</version>
                     <configuration>
-                        <warName>${project.artifactId}${chassis.version}</warName>
+                        <warName>${project.artifactId}${fm.version}</warName>
                         <failOnMissingWebXml>false</failOnMissingWebXml>
                     </configuration>
                 </plugin>
@@ -177,94 +300,6 @@
                     <artifactId>maven-install-plugin</artifactId>
                     <version>2.5.2</version>
                 </plugin>
-
-                <!-- enforcer插件, 避免被依赖的依赖引入过期的jar包 -->
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-enforcer-plugin</artifactId>
-                    <version>1.4.1</version>
-                    <executions>
-                        <execution>
-                            <id>enforce-banned-dependencies</id>
-                            <goals>
-                                <goal>enforce</goal>
-                            </goals>
-                            <configuration>
-                                <rules>
-                                    <requireMavenVersion>
-                                        <version>3.0.3</version>
-                                    </requireMavenVersion>
-                                    <requireJavaVersion>
-                                        <version>1.7</version>
-                                    </requireJavaVersion>
-                                    <bannedDependencies>
-                                        <searchTransitive>true</searchTransitive>
-                                        <excludes>
-                                            <exclude>commons-logging</exclude>
-                                            <exclude>aspectj:aspectj*</exclude>
-                                            <exclude>org.springframework</exclude>
-                                        </excludes>
-                                        <includes>
-                                            <include>org.springframework:*:4.3.*</include>
-                                        </includes>
-                                    </bannedDependencies>
-                                </rules>
-                                <fail>true</fail>
-                            </configuration>
-                        </execution>
-                    </executions>
-                </plugin>
-                <!-- dependency相关插件 -->
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-dependency-plugin</artifactId>
-                    <version>2.10</version>
-                </plugin>
-                <!-- ant插件 -->
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-antrun-plugin</artifactId>
-                    <version>1.8</version>
-                </plugin>
-
-                <!-- exec java 插件 -->
-                <plugin>
-                    <groupId>org.codehaus.mojo</groupId>
-                    <artifactId>exec-maven-plugin</artifactId>
-                    <version>1.6.0</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-release-plugin</artifactId>
-                    <version>2.5.3</version>
-                    <configuration>
-                        <!--<tagBase>https://192.168.1.100:8443/svn/myapp/tags/</tagBase>-->
-                    </configuration>
-                </plugin>
-                <plugin>
-                    <groupId>org.eclipse.m2e</groupId>
-                    <artifactId>lifecycle-mapping</artifactId>
-                    <version>1.0.0</version>
-                    <configuration>
-                        <lifecycleMappingMetadata>
-                            <pluginExecutions>
-                                <pluginExecution>
-                                    <pluginExecutionFilter>
-                                        <groupId>org.apache.maven.plugins</groupId>
-                                        <artifactId>maven-dependency-plugin</artifactId>
-                                        <versionRange>[2.0,)</versionRange>
-                                        <goals>
-                                            <goal>copy-dependencies</goal>
-                                        </goals>
-                                    </pluginExecutionFilter>
-                                    <action>
-                                        <ignore/>
-                                    </action>
-                                </pluginExecution>
-                            </pluginExecutions>
-                        </lifecycleMappingMetadata>
-                    </configuration>
-                </plugin>
             </plugins>
         </pluginManagement>
         <plugins>

+ 2 - 4
fm-server/src/main/java/com/persagy/fm/server/ServerApplication.java

@@ -5,11 +5,9 @@ import org.springframework.boot.Banner;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
-import org.springframework.boot.context.event.ApplicationStartedEvent;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.cloud.openfeign.EnableFeignClients;
-import org.springframework.context.ApplicationListener;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.EnableScheduling;
@@ -33,8 +31,8 @@ public class ServerApplication {
     public static void main(String[] args) {
         SpringApplication application = new SpringApplication(ServerApplication.class);
         application.setBannerMode(Banner.Mode.OFF);
-        application.addListeners((ApplicationListener<ApplicationStartedEvent>) event ->
-                System.out.println("\033[1;93;44m>>>>>> " + event.getApplicationContext().getApplicationName().substring(1) + " has started!!! \033[m"));
+//        application.addListeners((ApplicationListener<ApplicationStartedEvent>) event ->
+//                System.out.println("\033[1;93;44m>>>>>> " + event.getApplicationContext().getEnvironment().getProperty("spring.application.name") + " has started!!! \033[m"));
         application.run(args);
     }
 }