Quellcode durchsuchen

init:代码模板调整

zuy vor 1 Jahr
Ursprung
Commit
71ddffc786

+ 6 - 15
car-wash-admin/src/main/java/com/kym/admin/utils/CommJdbcCodeGenerator.java

@@ -31,15 +31,6 @@ import java.util.Map;
 public class CommJdbcCodeGenerator {
 
 
-    public static final int CONTROLLER = 1;
-    public static final int SERVICE = 2;
-    public static final int LISTVUE = 3;
-    public static final int EDITVUE = 4;
-    public static final int INFOVUE = 5;
-    public static final int POJO = 6;
-    public static final int PERMISSION = 7;
-    public static final int MAPPER = 8;
-
     private static DBHelper db;
 
 
@@ -56,7 +47,7 @@ public class CommJdbcCodeGenerator {
 
     public static void main(String[] args) {
         CodeGeneratorParam param = new CodeGeneratorParam();
-        param.setTableName("t_admin_user");
+        param.setTableName("t_banner");
         param.setBasePackage("com.kym.admin");
 
 
@@ -64,10 +55,10 @@ public class CommJdbcCodeGenerator {
 
         List<Map<String, String>> pathList = new ArrayList<>();
         pathList.add(ImmutableMap.of("vm", "Controller.java.vm", "output", "/home/zuy/02.code/wash/car-wash-admin/src/main/java/com/kym/admin/controller"));
-//        pathList.add(ImmutableMap.of("vm", "Service.java.vm", "output", "/home/zuy/02.code/wash/car-wash-service/src/main/java/com/kym/service/admin/"));
-//        pathList.add(ImmutableMap.of("vm", "ServiceImpl.java.vm", "output", "/home/zuy/02.code/wash/car-wash-service/src/main/java/com/kym/service/admin/impl"));
-//        pathList.add(ImmutableMap.of("vm", "dao.vm", "output", "src/main/java/com/kym/admin/controller/"));
-//        pathList.add(ImmutableMap.of("vm", "pojo.vm", "output", "src/main/java/com/kym/admin/controller/"));
+        pathList.add(ImmutableMap.of("vm", "Service.java.vm", "output", "/home/zuy/02.code/wash/car-wash-service/src/main/java/com/kym/service/admin/"));
+        pathList.add(ImmutableMap.of("vm", "ServiceImpl.java.vm", "output", "/home/zuy/02.code/wash/car-wash-service/src/main/java/com/kym/service/admin/impl"));
+        pathList.add(ImmutableMap.of("vm", "DAO.java.vm", "output", "/home/zuy/02.code/wash/car-wash-service/src/main/java/com/kym/dao"));
+        pathList.add(ImmutableMap.of("vm", ".java.vm", "output", "/home/zuy/02.code/wash/car-wash-entity/src/main/java/com/kym/entity/admin"));
 //        pathList.add(ImmutableMap.of("vm", "listvue.vm", "output", "src/main/java/com/kym/admin/controller/"));
 //        pathList.add(ImmutableMap.of("vm", "dialog.vm", "output", "src/main/java/com/kym/admin/controller/"));
 //        pathList.add(ImmutableMap.of("vm", "drawer.vm", "output", "src/main/java/com/kym/admin/controller/"));
@@ -193,7 +184,7 @@ public class CommJdbcCodeGenerator {
             varVo.setTableName(CommUtil.null2String(dataMap.get("tablename")));
             varVo.setTableComment(CommUtil.null2String(dataMap.get("tablecomment")));
 
-            log.info("generate list:{}", JacksonUtil.toJSONString(varVo));
+            System.out.println("generate list:\n"+ JacksonUtil.toJSONString(varVo));
 
         //table meta
         StringBuilder sbr = new StringBuilder("insert into t_permission (name,pid,perm,level) values ");

+ 1 - 1
car-wash-admin/src/main/java/com/kym/admin/utils/DBHelper.java

@@ -48,7 +48,7 @@ public class DBHelper implements AutoCloseable {
             while (resultSet.next()) {
                 Map<String, Object> data = new HashMap<>();
                 for (int i = 1; i <= columnCount; i++) {
-                    String columnName = metaData.getColumnName(i);
+                    String columnName = metaData.getColumnLabel(i);
                     data.put(columnName, resultSet.getString(i));
                 }
                 result.add(data);

+ 0 - 0
car-wash-admin/src/main/resources/tmpl/pojo.vm → car-wash-admin/src/main/resources/tmpl/.java.vm


+ 89 - 186
car-wash-admin/src/main/resources/tmpl/Controller.java.vm

@@ -1,12 +1,5 @@
 package ${basePackage}.controller;
 
-import ${basePackage}.controller.IController;
-import com.kym.util.log.annotation.CLP;
-import com.kym.util.page.Res;
-import com.kym.util.permission.PermissionHelper;
-import com.kym.util.permission.annotation.Permission;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import jakarta.annotation.Resource;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -18,190 +11,100 @@ import org.springframework.web.bind.annotation.RestController;
 
 
 /**
-* ${pojoComment}接口
-*
-* @date ${datetime}
-*/
-@Tag(name = "${pojoComment}")
+ * ${pojoComment}接口
+ *
+ * @date ${datetime}
+ */
 @RestController
 @RequestMapping("${firstLowPojoName}")
 public class ${pojoName}Controller extends IController {
 
-@Resource
-private ${pojoName}Service ${firstLowPojoName}Service;
-
-#if(${hasCategory})
-/**
-* ${pojoComment}类型新增接口
-*
-* @param category
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}类型新增")
-@Permission(values ="${firstLowPojoName}Category.add")
-@PostMapping("addCategory")
-@CLP(desc = "${pojoComment}类型新增接口", title = "${pojoComment}-新增类型")
-public Res addCategory(@Valid @RequestBody ${pojoName}Category.${pojoName}CategoryInfo category) {
-return resp(()->${firstLowPojoName}Service.addCategory(category));
-}
-
-
-/**
-* ${pojoComment}类型编辑接口
-*
-*  @param category
-* @param errors
-*  @return Res
-*  @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}类型编辑")
-@Permission(values ="${firstLowPojoName}Category.modify")
-@PostMapping("modifyCategory")
-@CLP(desc = "${pojoComment}类型更新接口", title = "${pojoComment}-编辑类型")
-public Res modifyCategory(@Valid @RequestBody ${pojoName}Category.${pojoName}CategoryInfo category,  BindingResult errors) {
-return resp((t)->${firstLowPojoName}Service.modifyCategory(category));
-}
-
-
-/**
-* 查询${pojoComment}类型列表接口
-*
-* @param query
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}类型列表")
-@Permission(values ="${firstLowPojoName}Category.list",p=P.CMS)
-@PostMapping("listCategory")
-@CLP(desc = "查询${pojoComment}类型列表接口")
-public Res listCategory(@RequestBody ${pojoName}Category.${pojoName}CategoryBasicQuery query) {
-return resp(()->${firstLowPojoName}Service.listCategory(query));
-}
-
-/**
-* 查询${pojoComment}类型详情接口
-*
-* @param id
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}类型详情")
-@Permission(values ="${firstLowPojoName}Category.list",p=P.CMS)
-@GetMapping("detailCategory/{id}")
-@CLP(desc = "查询${pojoComment}类型详情接口")
-public Res detailCategory(@PathVariable long id) {
-return resp(()->${firstLowPojoName}Service.detailCategory(id));
-}
-
-/**
-* ${pojoComment}类型删除接口
-*
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}类型删除")
-@Permission(values ="${firstLowPojoName}Category.remove")
-@GetMapping("removeCategory/{id}")
-@CLP(desc = "删除${pojoComment}类型",title="${pojoComment}-删除")
-public Res removeCategory(@PathVariable long id) {
-return resp((t)->${firstLowPojoName}Service.removeCategory(id));
-}
-
-
-#end
-
-/**
-* ${pojoComment}新增接口
-*
-* @param ${firstLowPojoName} 新增${pojoComment}
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}新增")
-@Permission(values ="${firstLowPojoName}.add")
-@PostMapping("add")
-@CLP(desc = "${pojoComment}新增接口", title = "${pojoComment}-新增")
-public Res add(@Valid @RequestBody ${pojoName}Info ${firstLowPojoName}) {
+    @Resource
+    private ${pojoName}Service ${firstLowPojoName}Service;
+
+
+    /**
+     * ${pojoComment}新增接口
+     *
+     * @param ${firstLowPojoName} 新增${pojoComment}
+     * @return Res
+     * @author   ${datetime}
+     */
+    @SaCheckPermission(value = "${firstLowPojoName}.add")
+    @PostMapping("add")
+    @SysLog(value = "${pojoComment}新增接口")
+    public R<?> add(@Valid @RequestBody ${pojoName}Info ${firstLowPojoName}) {
 //other params checked
-return resp(()->${firstLowPojoName}Service.add(${firstLowPojoName}));
-}
-
-/**
-* ${pojoComment}编辑
-*@return Res
-*  @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}更新")
-@Permission(values ="${firstLowPojoName}.modify")
-@PostMapping("modify")
-@CLP(desc = "${pojoComment}更新接口", title = "${pojoComment}-编辑")
-public Res modify(@Valid @RequestBody  ${pojoName}Info ${firstLowPojoName}) {
-return resp((t)->${firstLowPojoName}Service.modify(${firstLowPojoName}));
-}
-
-
-/**
-* ${pojoComment}查询接口
-*
-* @param query 条件构造对象
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}列表")
-@Permission(values ="${firstLowPojoName}.list",p=PermissionHelper.PLATFORM_CMS)
-@PostMapping("list")
-@CLP(desc = "${pojoComment}列表查询接口")
-public Res list(@RequestBody ${pojoName}.${pojoName}BasicQuery query) {
-return resp(()->${firstLowPojoName}Service.list(query));
-}
-
-
-/**
-* ${pojoComment}查询详情接口
-*
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}详情")
-@Permission(values ="${firstLowPojoName}.list",p=PermissionHelper.PLATFORM_CMS)
-@GetMapping("detail/{id}")
-@CLP(desc = "${pojoComment}详情查询接口")
-public Res detail(@PathVariable long id) {
-return resp(()->${firstLowPojoName}Service.detail(id));
-}
-
-
-
-/**
-* ${pojoComment}变更状态接口
-*
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}变更状态")
-@Permission(values ="${firstLowPojoName}.modify")
-@GetMapping("status/{id}/{status}")
-@CLP(desc = "${pojoComment}变更状态",title="${pojoComment}-状态")
-public Res status(@PathVariable long id,@PathVariable int status) {
-return resp((t)->${firstLowPojoName}Service.status(id,status));
-}
-
-
-
-/**
-* ${pojoComment}删除接口
-*
-* @return Res
-* @author   ${datetime}
-*/
-@Operation(summary="${pojoComment}删除")
-@Permission(values ="${firstLowPojoName}.remove")
-@GetMapping("remove/{id}")
-@CLP(desc = "${pojoComment}删除",title="${pojoComment}-删除")
-public Res remove(@PathVariable long id) {
-return resp((t)->${firstLowPojoName}Service.remove(id));
-}
+        return resp(() -> ${firstLowPojoName}Service.add(${firstLowPojoName}));
+    }
+
+    /**
+     * ${pojoComment}编辑
+     *@return Res
+     *  @author   ${datetime}
+     */
+    @SaCheckPermission(value = "${firstLowPojoName}.modify")
+    @PostMapping("modify")
+    @SysLog(value = "${pojoComment}更新接口")
+    public R<?> modify(@Valid @RequestBody  ${pojoName}Info ${firstLowPojoName}) {
+        return resp((t) -> ${firstLowPojoName}Service.modify(${firstLowPojoName}));
+    }
+
+
+    /**
+     * ${pojoComment}查询接口
+     *
+     * @return Res
+     * @author   ${datetime}
+     */
+    @SaCheckPermission(value = "${firstLowPojoName}.list")
+    @PostMapping("list")
+    @SysLog(value = "${pojoComment}列表查询接口")
+    public R<?> list(@RequestBody ${pojoName}.${pojoName}BasicQuery query) {
+        return resp(() -> ${firstLowPojoName}Service.list(query));
+    }
+
+
+    /**
+     * ${pojoComment}查询详情接口
+     *
+     * @return Res
+     * @author   ${datetime}
+     */
+    @SaCheckPermission(value = "${firstLowPojoName}.list")
+    @GetMapping("detail/{id}")
+    @SysLog(value = "${pojoComment}详情查询接口")
+    public R<?> detail(@PathVariable long id) {
+        return resp(() -> ${firstLowPojoName}Service.detail(id));
+    }
+
+
+    /**
+     * ${pojoComment}变更状态接口
+     *
+     * @return Res
+     * @author   ${datetime}
+     */
+    @SaCheckPermission(value = "${firstLowPojoName}.modify")
+    @GetMapping("status/{id}/{status}")
+    @SysLog(value = "${pojoComment}变更状态")
+    public R<?> status(@PathVariable long id, @PathVariable int status) {
+        return resp((t) -> ${firstLowPojoName}Service.status(id, status));
+    }
+
+
+    /**
+     * ${pojoComment}删除接口
+     *
+     * @return Res
+     * @author   ${datetime}
+     */
+    @SaCheckPermission(value = "${firstLowPojoName}.remove")
+    @GetMapping("remove/{id}")
+    @SysLog(desc = "${pojoComment}删除")
+    public R<?> remove(@PathVariable long id) {
+        return resp((t) -> ${firstLowPojoName}Service.remove(id));
+    }
 
 
 }

+ 0 - 0
car-wash-admin/src/main/resources/tmpl/dao.vm → car-wash-admin/src/main/resources/tmpl/DAO.java.vm


+ 6 - 6
car-wash-admin/src/main/resources/tmpl/Service.java.vm

@@ -19,33 +19,33 @@ public interface  ${pojoName}Service {
     /**
      * ${pojoComment}分页查询
      */
-    public Bean<${pojoName}Info> list(${pojoName}BasicQuery query);
+     Bean<${pojoName}Info> list(${pojoName}BasicQuery query);
 
     /**
      * 查询${pojoComment}详情
      */
-    public ${pojoName}Info detail(long id);
+     ${pojoName}Info detail(long id);
 
 
     /**
      * ${pojoComment}状态变更
      */
-    public void status(long id, int status);
+     void status(long id, int status);
 
 
     /**
      * 新增${pojoComment}
      */
-    public long add(${pojoName}Info ${firstLowPojoName});
+     long add(${pojoName}Info ${firstLowPojoName});
 
     /**
      * 物理删除${pojoComment}
      */
-    public Res remove(long id);
+      R<?> remove(long id);
 
     /**
      * 编辑${pojoComment}
      */
-    public void modify(${pojoName}Info ${firstLowPojoName});
+     void modify(${pojoName}Info ${firstLowPojoName});
 
 }

+ 0 - 0
car-wash-admin/src/main/resources/tmpl/dialog.vm → car-wash-admin/src/main/resources/tmpl/dialog.vue.vm


+ 20 - 0
car-wash-common/src/main/java/com/kym/common/DiffVo.java

@@ -0,0 +1,20 @@
+package com.kym.common;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@Builder
+public class DiffVo {
+    public String field;
+    public String name;
+    public String src;
+    public String dest;
+    public boolean richText;
+
+}

+ 1 - 0
car-wash-common/src/main/java/com/kym/common/constant/ResponseEnum.java

@@ -31,6 +31,7 @@ public enum ResponseEnum implements BusinessExceptionAssert {
     // 登录 权限
     LOGIN_FAILED(10001, "用户名或密码错误"),
     NO_PERMISSION(10002, "无访问权限"),
+    UNLOGIN(10003, "用户名未登录"),
 
     // 订单
     EQUIP_CONNECTOR_ID_ERROR(20000, "设备编码错误"),

+ 235 - 0
car-wash-common/src/main/java/com/kym/common/utils/BeanUtil.java

@@ -0,0 +1,235 @@
+package com.kym.common.utils;
+
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ReflectUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+
+/**
+ * @author yaopeng
+ * @date 2018/8/26 21:48
+ */
+public class BeanUtil {
+    private static Logger logger = LoggerFactory.getLogger(BeanUtil.class);
+
+    private BeanUtil() {
+    }
+
+    public static <T> List<T> copyList(Class<T> clz, List<?> dataList) {
+        List<T> result = new ArrayList<>();
+        for (Object o : dataList) {
+            result.add(copy(clz, o));
+        }
+        return result;
+    }
+
+    /**
+     * 从原实体中拷贝指定字段目标实体中
+     *
+     * @param src
+     * @param dest
+     * @param includes
+     * @param excludes
+     */
+    public static void copyProperties(Object src, Object dest, Set<String> includes, Set<String> excludes) {
+        Set<String> includeList = CommUtil.null2Set(includes, true);
+        Set<String> excludeList = CommUtil.null2Set(excludes, true);
+        Field[] fields = getFields(src.getClass());
+        for (Field field : fields) {
+            if (isClassParameter(field)) {
+                continue;
+            }
+            String name = field.getName();
+            if (excludeList.contains(name)) {
+                continue;
+            }
+            if (!includeList.isEmpty() && includeList.contains(name)) {
+                ReflectUtil.setFieldValue(dest, name, ReflectUtil.getFieldValue(src, name));
+                continue;
+            }
+
+            ReflectUtil.setFieldValue(dest, name, ReflectUtil.getFieldValue(src, name));
+        }
+    }
+
+    /**
+     * 从map集合中复制属性到实体类中
+     *
+     * @param clz
+     * @param map
+     * @param <T>
+     * @return
+     */
+    public static <T> T copy(Class<T> clz, Map<String, Object> map) {
+        try {
+            T to = clz.getDeclaredConstructor().newInstance();
+            Field[] ff = getFields(clz);
+            for (Field f : ff) {
+                if (isClassParameter(f)) {
+                    continue;
+                }
+                try {
+                    f.setAccessible(true);
+                    f.set(to, map.get(f.getName()));
+                } catch (Exception e) {
+                    logger.warn("BeanUtil.copy ignore,msg:{}", e.getMessage());
+                }
+            }
+            return to;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 对象转Map
+     *
+     * @param object
+     * @return
+     */
+    public static Map<String, Object> beanToMap(Object object) {
+        Map<String, Object> map = new HashMap<>(32);
+        Field[] fields = object.getClass().getDeclaredFields();
+        for (Field field : fields) {
+            field.setAccessible(true);
+            try {
+                map.put(field.getName(), field.get(object));
+            } catch (IllegalAccessException e) {
+                logger.warn("beanToMap error", e);
+            }
+        }
+        return map;
+    }
+
+    /**
+     * map转对象
+     *
+     * @param map
+     * @param beanClass
+     * @param <T>
+     * @return
+     */
+    public static <T> T mapToBean(Map map, Class<T> beanClass) {
+        try {
+            T object = beanClass.getDeclaredConstructor().newInstance();
+            Field[] fields = object.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                int mod = field.getModifiers();
+                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
+                    continue;
+                }
+                field.setAccessible(true);
+                if (map.containsKey(field.getName())) {
+                    field.set(object, map.get(field.getName()));
+                }
+            }
+            return object;
+        } catch (Exception e) {
+            logger.error("mapToBean error", e);
+        }
+        throw new RuntimeException();
+    }
+
+    /**
+     * 是否是类变量
+     *
+     * @param field
+     * @return
+     */
+    public static boolean isClassParameter(Field field) {
+        int modifier = field.getModifiers();
+        return Modifier.isFinal(modifier) || Modifier.isStatic(modifier) || Modifier.isNative(modifier);
+    }
+
+    public static <T> T copy(Class<T> clz, Object data) {
+        try {
+            T to = clz.getDeclaredConstructor().newInstance();
+            Field[] ff = getFields(data.getClass());
+            for (Field f : ff) {
+                if (isClassParameter(f)) {
+                    continue;
+                }
+                try {
+                    Field toField = ReflectUtil.getField(clz, f.getName());
+                    f.setAccessible(true);
+                    Object fv = f.get(data);
+                    toField.setAccessible(true);
+                    toField.set(to, fv);
+                    toField.setAccessible(false);
+                } catch (Exception e) {
+                    logger.debug("BeanUtil.copy ignore ,msg:{}", e.getMessage());
+                }
+            }
+            return to;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static boolean compare(Object source, Object target, String... fieldNames) {
+        boolean eq = true;
+        if (null == source || null == target) {
+            return false;
+        }
+        if (null == fieldNames || fieldNames.length == 0) {
+            throw new IllegalArgumentException("cannot get compared fields ERR");
+        }
+        for (String fieldName : fieldNames) {
+            Object v0 = getFieldValue(fieldName, source);
+            Object v1 = getFieldValue(fieldName, target);
+            if (null != v0 || null != v1) {
+                boolean isDate = v0 instanceof Date || v1 instanceof Date;
+                if (isDate) {
+                    eq = Objects.equals(DateUtil.parse(v0.toString()), DateUtil.parse(v1.toString()));
+                } else {
+                    eq = Objects.equals(v0, v1);
+                }
+            }
+        }
+        return eq;
+    }
+
+    private static Object getFieldValue(String fieldName, Object obj) {
+        try {
+            Field f = ReflectUtil.getField(obj.getClass(), fieldName);
+            f.setAccessible(true);
+            return f.get(obj);
+        } catch (Exception e) {
+            logger.warn("BeanUtil.getFieldValue ignore,msg:{}", e.getMessage());
+        }
+        return null;
+    }
+
+    private static Field[] getFields(Class<?> clazz) {
+        List<Field> fieldList = new ArrayList<>();
+        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
+            Field[] fields = clazz.getDeclaredFields();
+            fieldList.addAll(Arrays.asList(fields));
+        }
+        return fieldList.toArray(new Field[0]);
+    }
+
+
+    public static boolean isFieldExists(Class<?> clz, String fieldName) {
+        try {
+            Field field = clz.getField(fieldName);
+            return !isClassParameter(field);
+        } catch (Exception e) {
+            logger.warn("isFieldExists WARN:{}", e.getMessage());
+        }
+        return false;
+    }
+}

+ 96 - 0
car-wash-common/src/main/java/com/kym/common/utils/CommUtil.java

@@ -1,15 +1,23 @@
 package com.kym.common.utils;
 
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ReflectUtil;
+import com.google.common.collect.Lists;
+import com.kym.JacksonUtil;
 import com.kym.common.constant.ResponseEnum;
 import com.kym.common.exception.BusinessException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.lang.reflect.Array;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -175,6 +183,26 @@ public class CommUtil {
     }
 
 
+    public static <T> Set<T> null2Set(Collection<T> col, boolean checkNull) {
+        Set<T> list = new HashSet<>();
+        if (isEmptyOrNull(col)) {
+            return list;
+        }
+        if (checkNull) {
+            try {
+                for (T t : col) {
+                    if (null != t) {
+                        list.add(t);
+                    }
+                }
+            } catch (Exception e) {
+                logger.error("null2Set error", e);
+            }
+        }
+        return list;
+    }
+
+
     /**
      * 集合过滤空转List
      *
@@ -259,4 +287,72 @@ public class CommUtil {
         Map<Object, Boolean> seen = new ConcurrentHashMap<>();
         return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
     }
+
+    public static String print(Object obj) {
+        return isEmptyOrNull(obj) ? "" : JacksonUtil.toJSONString(obj);
+    }
+
+
+
+    public static String logNull2String(Object s) {
+        if (isEmptyOrNull(s)) {
+            return "";
+        }
+        if (isBasicType(s)) {
+            return s.toString().trim();
+        }
+        if (s instanceof Date) {
+            Date d = DateUtil.date((Date)s);
+            long time = d.getTime();
+            if (time % (24 * 3600 * 1000) == 57600000) {
+                return DateUtil.format(d, "yyyy-MM-dd");
+            } else {
+                return DateUtil.format(d, "yyyy-MM-dd HH:mm:ss");
+            }
+        }
+        if (s.getClass().isArray()) {
+            return JacksonUtil.toJSONString(s);
+        }
+        if (s instanceof Collection) {
+            List<String> names = Lists.newArrayList("name", "title");
+            List<String> strs = new ArrayList<>();
+            List<Map> list = JacksonUtil.toJavaObjectList(JacksonUtil.toJSONString(s), Map.class);
+            for (Map map : list) {
+                Object v = null;
+                for (String name : names) {
+                    if (null == v) {
+                        v = map.get(name);
+                    } else {
+                        break;
+                    }
+                }
+                if (null != v) {
+                    strs.add(v.toString());
+                }
+            }
+            return JacksonUtil.toJSONString(strs);
+        }
+
+        return "";
+    }
+
+    /**
+     * 反射获取对象的属性值
+     */
+    public static Object getFieldAlternativeValue(Object bean, String... fieldName) {
+        for (String s : fieldName) {
+            try {
+                Field field = ReflectUtil.getField(bean.getClass(), s);
+                field.setAccessible(true);
+                Object val = field.get(bean);
+                if (null != val) {
+                    return val;
+                }
+            } catch (Exception e) {
+                logger.debug("CommUtil.getFieldAlternativeValue Miss " + e.getMessage());
+            }
+        }
+        return null;
+    }
+
 }

+ 87 - 2
car-wash-entity/src/main/java/com/kym/entity/common/SimpleVo.java

@@ -1,6 +1,91 @@
 package com.kym.entity.common;
 
-public class SimpleVo {
-    public Long id;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 描述: Tag组件参数
+ * create at 2021/2/17 21:11
+ *
+ * @author yaop
+ */
+public class SimpleVo implements Serializable {
+
+    public long id;
+
     public String name;
+
+    public SimpleVo() {
+    }
+
+    public SimpleVo(long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+
+
+    public static class SimpleAttachVo extends SimpleVo {
+        public String uid;
+        public long size;
+        public String createName;
+        public Date createAt;
+
+        public SimpleAttachVo() {
+        }
+
+        public SimpleAttachVo(long id, String name) {
+            super(id, name);
+        }
+
+        public SimpleAttachVo(long id, String name, String uid) {
+            super(id, name);
+            this.uid = uid;
+        }
+    }
+
+
+    public static class SimpleUserVo extends SimpleVo {
+        public String image;
+        public String departName;
+
+        public SimpleUserVo() {
+        }
+
+        public SimpleUserVo(long id, String name) {
+            super(id, name);
+        }
+
+        public SimpleUserVo(long id, String name, String image) {
+            super(id, name);
+            this.image = image;
+        }
+
+
+        public SimpleUserVo(long id, String name, String image, String departName) {
+            super(id, name);
+            this.image = image;
+            this.departName = departName;
+        }
+    }
+
+    public static class SimpleUserStatusVo extends SimpleVo {
+        public String image;
+        public boolean pass;
+
+        public SimpleUserStatusVo() {
+        }
+
+        public SimpleUserStatusVo(long id, String name) {
+            super(id, name);
+        }
+
+        public SimpleUserStatusVo(long id, String name, String image, boolean pass) {
+            super(id, name);
+            this.image = image;
+            this.pass = pass;
+        }
+    }
+
 }

+ 390 - 0
car-wash-service/src/main/java/com/kym/service/IService.java

@@ -0,0 +1,390 @@
+package com.kym.service;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.ReflectUtil;
+import com.kym.common.ContextHelper;
+import com.kym.common.DiffVo;
+import com.kym.common.IUser;
+import com.kym.common.constant.ResponseEnum;
+import com.kym.common.exception.BusinessException;
+import com.kym.common.utils.BeanUtil;
+import com.kym.common.utils.CommUtil;
+import com.kym.dao.DbHandler;
+import com.kym.entity.admin.AdminUser;
+import com.kym.entity.common.SimpleVo;
+import com.kym.entity.common.SimpleVo.SimpleAttachVo;
+import com.kym.entity.common.SimpleVo.SimpleUserVo;
+import com.kym.entity.miniapp.Attachment;
+import com.kym.jdbc.BasicQuery;
+import com.kym.jdbc.Bean;
+import com.kym.jdbc.OBuilder;
+import com.kym.jdbc.annotations.DBF;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+
+/**
+ * 公共注入服务
+ *
+ * @author yaop
+ */
+public class IService {
+
+    @Getter
+    protected DbHandler db;
+
+    @Autowired
+    @Qualifier("dbHandler")
+    public void setDb(DbHandler db) {
+        this.db = db;
+    }
+
+
+    protected <T> Bean<T> toBean(long count, List<T> list) {
+        Bean<T> bean = new Bean<>();
+        bean.count = count;
+        bean.list = list;
+        return bean;
+    }
+
+    protected OBuilder oBuilder() {
+        IUser user = ContextHelper.getUser();
+        if (null == user) {
+            return OBuilder.build();
+        }
+        return OBuilder.build().eq("companyId", user.companyId);
+    }
+
+    protected long getUserId() {
+        IUser user = ContextHelper.getUser();
+        if (null == user) {
+            throw new BusinessException(ResponseEnum.UNLOGIN);
+        }
+        return user.id;
+    }
+
+
+    protected long getOid() {
+        IUser user = ContextHelper.getUser();
+        if (null == user) {
+            throw new BusinessException(ResponseEnum.UNLOGIN);
+        }
+        return ContextHelper.getOid();
+    }
+
+    protected void setupQuery(BasicQuery query) {
+        IUser user = ContextHelper.getUser();
+        if (null != user) {
+            ReflectUtil.setFieldValue(query, "companyId", user.companyId);
+        }
+        ReflectUtil.setFieldValue(query, "deleted", false);
+    }
+
+    /**
+     * 断言已登录
+     */
+    protected void assertLogin() {
+        if (null == ContextHelper.getUser()) {
+            throw new BusinessException(ResponseEnum.UNLOGIN);
+        }
+    }
+
+
+    protected void setAssociateId(long id) {
+        ContextHelper.setAssoId(id);
+    }
+
+    protected void setId(Object bean) {
+        setId(bean, "id");
+    }
+
+    protected long getUserDepartmentId() {
+        IUser user = ContextHelper.getUser();
+        if (CommUtil.isNotEmptyAndNull(user.deptIdList)) {
+            return user.deptIdList.get(0);
+        }
+        return 0L;
+    }
+
+
+    /**
+     * 雪花算法ID生成(默认截取4位往后长度,防止前端展示不全精度丢失问题)
+     *
+     * @param bean
+     * @param key
+     */
+    protected void setId(Object bean, String key) {
+        ReflectUtil.setFieldValue(bean, key, CommUtil.null2Long(String.valueOf(IdUtil.getSnowflakeNextId()).substring(4)));
+    }
+
+    /**
+     * 雪花算法ID生成(默认截取4位往后长度,防止前端展示不全精度丢失问题)
+     *
+     * @return
+     */
+    protected long genId() {
+        return CommUtil.null2Long(String.valueOf(IdUtil.getSnowflakeNextId()).substring(4));
+    }
+
+
+    protected List<DiffVo> diffLog(Object src, Object dest) {
+        return diffLog(src, dest, null);
+    }
+
+    /**
+     * 比较并获取差异字段
+     */
+    protected List<DiffVo> diffLog(Object src, Object dest, Set<String> includes, String... excludeFields) {
+        List<DiffVo> diffVos = new ArrayList<>();
+        if (CommUtil.isEmptyOrNull(src) && CommUtil.isEmptyOrNull(dest)) {
+            return diffVos;
+        }
+        if (CommUtil.isBasicType(src) || CommUtil.isBasicType(dest)) {
+            return diffVos;
+        }
+        List<String> excludes = Arrays.asList(excludeFields.clone());
+        Map<String, Object> map = new HashMap<>(16);
+        if (null == src) {
+            map.put("src", null);
+            map.put("dest", CommUtil.print(dest));
+            return diffVos;
+        }
+        if (null == dest) {
+            map.put("src", CommUtil.print(src));
+            map.put("dest", null);
+            return diffVos;
+        }
+        Field[] fields = src.getClass().getFields();
+        if (!CommUtil.isEmptyOrNull(fields)) {
+            for (Field field : fields) {
+                int modifier = field.getModifiers();
+                if (!Modifier.isPublic(modifier)) {
+                    continue;
+                }
+                String fieldName = field.getName();
+                if (CommUtil.isNotEmptyAndNull(includes) && !includes.contains(fieldName)) {
+                    continue;
+                }
+                //TODO 数组、集合数据结构处理
+                if (!CommUtil.isBasicType(field.getType()) || "id".equalsIgnoreCase(fieldName) || excludes.contains(fieldName)) {
+                    continue;
+                }
+                if (!BeanUtil.compare(src, dest, fieldName)) {
+                    String fieldCommentName = fieldName;
+                    if (field.isAnnotationPresent(DBF.class)) {
+                        fieldCommentName = field.getAnnotation(DBF.class).comment();
+                    }
+                    diffVos.add(DiffVo.builder().field(fieldName).name(fieldCommentName).src(CommUtil.logNull2String(ReflectUtil.getFieldValue(src, fieldName))).dest(CommUtil.logNull2String(ReflectUtil.getFieldValue(dest, fieldName))).build());
+//                    logs.add(ImmutableMap.of("field", fieldName, "name", fieldCommentName, "src", CommUtil.logNull2String(CommUtil.getFieldValue(src, fieldName)), "dest", CommUtil.logNull2String(CommUtil.getFieldValue(dest, fieldName))));
+                }
+            }
+            map.put("logs", diffVos);
+        }
+
+        ContextHelper.setRemark(CommUtil.print(map));
+        return diffVos;
+    }
+
+
+    /**
+     * 比较并获取差异字段
+     */
+    /**
+     * @param src
+     * @param dest
+     * @param field     字段key
+     * @param fieldName 字段名称
+     * @return
+     */
+    protected DiffVo diffLog(Object src, Object dest, String field, String fieldName) {
+        DiffVo diffVo = new DiffVo();
+        diffVo.name = fieldName;
+        diffVo.field = field;
+        if (CommUtil.isEmptyOrNull(src) && CommUtil.isEmptyOrNull(dest)) {
+            return diffVo;
+        }
+        if (CommUtil.isBasicType(src) || CommUtil.isBasicType(dest)) {
+            return diffVo;
+        }
+        if (null == src) {
+            diffVo.src = "";
+            diffVo.dest = CommUtil.print(dest);
+            return diffVo;
+        }
+        if (null == dest) {
+            diffVo.dest = "";
+            diffVo.src = CommUtil.print(src);
+            return diffVo;
+        }
+
+        if (!BeanUtil.compare(src, dest, field)) {
+            diffVo.src = CommUtil.logNull2String(ReflectUtil.getFieldValue(src, field));
+            diffVo.dest = CommUtil.logNull2String(ReflectUtil.getFieldValue(dest, field));
+        } else {
+            return null;
+        }
+        return diffVo;
+    }
+
+
+    //region 实体转换
+    protected SimpleVo getSimpleTagVo(Object entity) {
+        return BeanUtil.copy(SimpleVo.class, entity);
+    }
+
+
+    protected List<Long> getSimpleIdList(Collection<?> beanList) {
+        if (CommUtil.isEmptyOrNull(beanList)) {
+            return Collections.emptyList();
+        } else {
+            return beanList.stream().map(k -> CommUtil.null2Long(ReflectUtil.getFieldValue(k, "id"))).collect(Collectors.toList());
+        }
+    }
+
+    protected List<SimpleVo> getSimpleVoList(Collection<?> beanList) {
+        if (CommUtil.isEmptyOrNull(beanList)) {
+            return Collections.emptyList();
+        } else {
+            return beanList.stream().map(k -> new SimpleVo(CommUtil.null2Long(ReflectUtil.getFieldValue(k, "id")), CommUtil.null2String(CommUtil.getFieldAlternativeValue(k, "name", "title")))).collect(Collectors.toList());
+        }
+    }
+
+    protected List<SimpleAttachVo> getAttachmentVoList(List<Attachment> attachments) {
+        if (CommUtil.isEmptyOrNull(attachments)) {
+            return Collections.emptyList();
+        } else {
+            return attachments.stream().map(k -> new SimpleAttachVo(k.getId(), k.getName(), k.getName())).collect(Collectors.toList());
+        }
+    }
+
+
+    protected List<SimpleUserVo> getUserSimpleVoList(Collection<? extends Number> idList) {
+        if (CommUtil.isEmptyOrNull(idList)) {
+            return Collections.emptyList();
+        }
+        List<AdminUser> userList = db.selectList(AdminUser.class, oBuilder().in("id", idList.toArray()), "id", "name", "avatar");
+//        idList.forEach(id -> userList.add(getCacheUser((Long) id)));
+        if (CommUtil.isEmptyOrNull(userList)) {
+            return Collections.emptyList();
+        } else {
+            return userList.stream().filter(CommUtil.distinctByKey(AdminUser::getId)).map(k -> new SimpleUserVo(k.getId(), k.getUsername(), k.getAvatar())).collect(Collectors.toList());
+        }
+    }
+
+    protected List<SimpleUserVo> getUserSimpleVoPropertiesList(Collection<?> beanList) {
+        if (CommUtil.isEmptyOrNull(beanList)) {
+            return Collections.emptyList();
+        } else {
+            return beanList.stream().map(k -> new SimpleUserVo(CommUtil.null2Long(CommUtil.getFieldAlternativeValue(k, "id", "userId")), CommUtil.null2String(CommUtil.getFieldAlternativeValue(k, "name", "userName")), CommUtil.null2String(CommUtil.getFieldAlternativeValue(k, "avatar", "userAvatar")))).collect(Collectors.toList());
+        }
+    }
+
+    //endregion
+
+    /**
+     * 新增记录后的日志信息写入
+     *
+     * @param id
+     */
+    protected void afterAdd(long id) {
+        ContextHelper.setAssoId(id);
+    }
+
+    /**
+     * 删除记录后的日志信息写入
+     *
+     * @param id
+     */
+    protected void afterRemove(long id) {
+        ContextHelper.setAssoId(id);
+    }
+
+    /**
+     * 修改记录后的日志信息写入
+     */
+    protected void afterModify(Object src, Object dest) {
+        diffLog(src, dest, null);
+    }
+
+
+    //region 权限校验
+
+    /**
+     * 校验全局权限(非应用内权限)
+     *
+     * @param permissions 权限值
+     */
+    protected void validate(String... permissions) {
+        validate(getOid(), permissions);
+    }
+
+    protected boolean isReadPermission(String permission) {
+        return permission.endsWith(".list");
+    }
+
+
+    /**
+     * 校验全局权限(非应用内权限)
+     *
+     * @param permissions 权限值
+     */
+    protected void validate(long orgId, String... permissions) {
+    }
+
+    /**
+     * 校验应用权限
+     *
+     * @param appletId    应用ID
+     * @param permissions 权限码值
+     */
+    protected void validateApplet(long appletId, String... permissions) {
+        validateApplet(appletId, 0, permissions);
+    }
+
+    /**
+     * 校验应用权限
+     *
+     * @param appletId    应用ID
+     * @param permissions 权限码值
+     */
+    protected void validateApplet(long appletId, long modelId, String... permissions) {
+    }
+
+
+    /**
+     * 校验租户信息是否匹配
+     *
+     * @param bean 数据实体
+     */
+    protected void validateOrg(Object bean) {
+        assertLogin();
+        long beanOrgId = CommUtil.null2Long(ReflectUtil.getFieldValue(bean, "companyId"));
+        CommUtil.asserts(beanOrgId == ContextHelper.getUser().companyId, "租户权限不足");
+    }
+
+    /**
+     * 校验租户信息是否匹配
+     *
+     * @param orgId
+     * @param bean
+     */
+    protected void validateOrg(long orgId, Object bean) {
+        long beanOrgId = CommUtil.null2Long(ReflectUtil.getFieldValue(bean, "companyId"));
+        CommUtil.asserts(beanOrgId == orgId, "租户权限不足");
+    }
+
+
+}

+ 0 - 9
car-wash-service/src/main/java/com/kym/service/miniapp/impl/InvoiceServiceImpl.java

@@ -1,16 +1,11 @@
 package com.kym.service.miniapp.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.util.NumberUtil;
-import cn.hutool.poi.excel.ExcelUtil;
-import cn.hutool.poi.excel.ExcelWriter;
 import com.baomidou.dynamic.datasource.annotation.DS;
 import com.github.pagehelper.PageHelper;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.github.yulichang.toolkit.JoinWrappers;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
-import com.kym.common.IQuery;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.OrderUtils;
@@ -18,7 +13,6 @@ import com.kym.entity.admin.InvoiceDetail;
 import com.kym.entity.admin.queryParams.InvoiceQueryParam;
 import com.kym.entity.common.PageBean;
 import com.kym.entity.miniapp.ChargeOrder;
-import com.kym.entity.miniapp.DataDict;
 import com.kym.entity.miniapp.Invoice;
 import com.kym.entity.miniapp.User;
 import com.kym.entity.miniapp.queryParams.ApplyInvoiceParams;
@@ -35,11 +29,8 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * <p>